femtic/src/Forward3DBrickElement0thOrder.h
2021-11-09 01:06:52 +09:00

247 lines
15 KiB
C++

//-------------------------------------------------------------------------------------------------------
// The MIT License (MIT)
//
// Copyright (c) 2021 Yoshiya Usui
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//-------------------------------------------------------------------------------------------------------
#ifndef DBLDEF_FORWARD_3D_BRICK_ELEMENT_0TH_ORDER
#define DBLDEF_FORWARD_3D_BRICK_ELEMENT_0TH_ORDER
#include "Forward2DSquareElement.h"
#include "Forward3D.h"
#include "MeshDataBrickElement.h"
#include <set>
// Class of 3D forward calculation by using 0th order brick element
class Forward3DBrickElement0thOrder : public Forward3D {
public:
// Constructer
Forward3DBrickElement0thOrder();
// Destructer
virtual ~Forward3DBrickElement0thOrder();
// Run 3D forward calculation by using brick element
virtual void forwardCalculation( const double freq, const int iPol );
// Calculate X component electric field values for 0th order edge-based elements
virtual std::complex<double> calcValueElectricFieldXDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate Y component electric field values for 0th order edge-based elements
virtual std::complex<double> calcValueElectricFieldYDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate Z component electric field values for 0th order edge-based elements
virtual std::complex<double> calcValueElectricFieldZDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate Z component of rotated electric field
virtual std::complex<double> calcValueRotatedElectricFieldZDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate X component of electric field only from the edges on the Earth's surface
virtual std::complex<double> calcValueElectricFieldXDirectionFromEdgesOnEarthSurface( const int iElem, const int iFace, const double uCoord, const double vCoord ) const;
// Calculate Y component of electric field only from the edges on the Earth's surface
virtual std::complex<double> calcValueElectricFieldYDirectionFromEdgesOnEarthSurface( const int iElem, const int iFace, const double uCoord, const double vCoord ) const;
// Calculate tangential electric field directed to X from all edges of owner element
virtual std::complex<double> calcValueElectricFieldTangentialXFromAllEdges( const int iElem, const int iFace, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate tangential electric field directed to Y from all edges of owner element
virtual std::complex<double> calcValueElectricFieldTangentialYFromAllEdges( const int iElem, const int iFace, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate tangential electric field directed to X
virtual std::complex<double> calcValueElectricFieldTangentialX( const int iElem, const int iFace, const double uCoord, const double vCoord ) const;
// Calculate tangential electric field directed to Y
virtual std::complex<double> calcValueElectricFieldTangentialY( const int iElem, const int iFace, const double uCoord, const double vCoord ) const;
// Calculate X component magnetic field values for 0th order edge-based elements
virtual std::complex<double> calcValueMagneticFieldXDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate Y component magnetic field values for 0th order edge-based elements
virtual std::complex<double> calcValueMagneticFieldYDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate Z component magnetic field values for 0th order edge-based elements
virtual std::complex<double> calcValueMagneticFieldZDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal ) const;
// Calculate difference of voltage
virtual std::complex<double> calcVoltageDifference( const int nElem, const int* elememtsIncludingDipole,
const CommonParameters::locationXY* localCoordinateValuesStartPoint, const CommonParameters::locationXY* localCoordinateValuesEndPoint ) const;
// Calculate difference of voltage for tetra element
virtual std::complex<double> calcVoltageDifference( const int nElem, const int* const elememtsIncludingDipole, const int* const facesIncludingDipole,
const CommonParameters::AreaCoords* const areaCoordValStartPoint, const CommonParameters::AreaCoords* const areaCoordValEndPoint ) const;
// Calculate interpolator vector of X component of electric field
virtual void calcInterpolatorVectorOfElectricFieldXDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of Y component of electric field
virtual void calcInterpolatorVectorOfElectricFieldYDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of Z component of electric field
virtual void calcInterpolatorVectorOfElectricFieldZDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of Z component of rotated electric field
virtual void calcInterpolatorVectorOfRotatedElectricFieldZDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of X component of electric field only from the edges on the Earth's surface
virtual void calcInterpolatorVectorOfElectricFieldXDirectionFromEdgesOnEarthSurface( const int iElem, const int iFace, const double uCoord, const double vCoord, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of Y component of electric field only from the edges on the Earth's surface
virtual void calcInterpolatorVectorOfElectricFieldYDirectionFromEdgesOnEarthSurface( const int iElem, const int iFace, const double uCoord, const double vCoord, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of tangential electric field directed to X from all edges
virtual void calcInterpolatorVectorOfElectricFieldTangentialXFromAllEdges( const int iElem, const int iFace, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of tangential electric field directed to Y from all edges
virtual void calcInterpolatorVectorOfElectricFieldTangentialYFromAllEdges( const int iElem, const int iFace, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of tangential electric field directed to X
virtual void calcInterpolatorVectorOfElectricFieldTangentialX( const int iElem, const int iFace, const double uCoord, const double vCoord, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of tangential electric field directed to Y
virtual void calcInterpolatorVectorOfElectricFieldTangentialY( const int iElem, const int iFace, const double uCoord, const double vCoord, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of X component of magnetic field
virtual void calcInterpolatorVectorOfMagneticFieldXDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of Y component of magnetic field
virtual void calcInterpolatorVectorOfMagneticFieldYDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of Z component of magnetic field
virtual void calcInterpolatorVectorOfMagneticFieldZDirection( const int iElem, const double xLocal, const double yLocal, const double zLocal, const int irhs, const std::complex<double>& factor = std::complex<double>(1.0,0.0) );
// Calculate interpolator vector of difference of voltage
virtual void calcInterpolatorVectorOfVoltageDifference( const int nElem, const int* elememtsIncludingDipole, const CommonParameters::locationXY* localCoordinateValuesStartPoint, const CommonParameters::locationXY* localCoordinateValuesEndPoint, const int irhs );
// Calculate interpolator vector of difference of voltage
virtual void calcInterpolatorVectorOfVoltageDifference( const int nElem, const int* elememtsIncludingDipole, const int* const facesIncludingDipole,
const CommonParameters::AreaCoords* const areaCoordValStartPoint, const CommonParameters::AreaCoords* const areaCoordValEndPoint, const int irhs );
// Set non-zero strucuture of matrix for forward calculation
virtual void setNonZeroStrucuture( ComplexSparseSquareSymmetricMatrix& matrix );
// Set non-zero values of matrix and right-hande side vector for forward calculation
virtual void setNonZeroValues( ComplexSparseSquareSymmetricMatrix& matrix );
//----- DO NOT DELETE FOR FUTURE USE >>>>>
//// Set non-zero strucuture of matrix for calculating derivatives
//virtual void setNonZeroStrucuture( ComplexSparseSquareSymmetricMatrix& matrix, const int blkID, std::set<int>& nonZeroRowsAndCols );
//// Set non-zero values of matrix and right-hande side vector for calculating derivatives
//virtual void setNonZeroValues( ComplexSparseSquareSymmetricMatrix& matrix, const int blkID );
//----- DO NOT DELETE FOR FUTURE USE >>>>>
// Calculate vector x of the reciprocity algorithm of Rodi (1976)
virtual void calVectorXOfReciprocityAlgorithm( const std::complex<double>* const vecIn, const int blkID, std::complex<double>* const vecOut, std::vector<int>& nonZeroRows );
// Call function inputMeshData of the class MeshData
virtual void callInputMeshData();
// Get pointer to the class MeshData
virtual const MeshData* getPointerToMeshData() const;
// Get pointer to the class MeshDataBrickElement
const MeshDataBrickElement* getPointerToMeshDataBrickElement() const;
private:
//const static std::vector<int> m_iVecDummy;
const static int DIRICHLET_BOUNDARY_NONZERO_VALUE = -1;// This must be the same as the ones of other functions !!
const static int DIRICHLET_BOUNDARY_ZERO_VALUE = -2;// This must be the same as the ones of other functions !!
const static int m_numGauss = 2;
const static int m_numIntegralPoints = m_numGauss * m_numGauss * m_numGauss;
double m_xLocal[m_numIntegralPoints];
double m_yLocal[m_numIntegralPoints];
double m_zLocal[m_numIntegralPoints];
double m_weights3D[m_numIntegralPoints];
MeshDataBrickElement m_MeshDataBrickElement;
// Copy constructer
Forward3DBrickElement0thOrder(const Forward3DBrickElement0thOrder& rhs);
// Copy assignment operator
Forward3DBrickElement0thOrder& operator=(const Forward3DBrickElement0thOrder& rhs);
// Class of 2D forward calculation using square elements
//Forward2DSquareElement* m_Fwd2DSquareElement[4][2];
Forward2DSquareElement* m_Fwd2DSquareElement[4];
// Get X component of shape function for 0th order edge-based elements
inline double getShapeFuncX( const double xLocal, const double yLocal, const double zLocal, const int num ) const;
// Get Y component of shape function for 0th order edge-based elements
inline double getShapeFuncY( const double xLocal, const double yLocal, const double zLocal, const int num ) const;
// Get Z component of shape function for 0th order edge-based elements
inline double getShapeFuncZ( const double xLocal, const double yLocal, const double zLocal, const int num ) const;
// Get X component of shape function rotated for 0th order edge-based elements
inline double getShapeFuncRotatedX( const double xLocal, const double yLocal, const double zLocal,
const double lx, const double ly, const double lz, const int num ) const;
// Get Y component of shape function rotated for 0th order edge-based elements
inline double getShapeFuncRotatedY( const double xLocal, const double yLocal, const double zLocal,
const double lx, const double ly, const double lz, const int num ) const;
// Get Z component of shape function rotated for 0th order edge-based elements
inline double getShapeFuncRotatedZ( const double xLocal, const double yLocal, const double zLocal,
const double lx, const double ly, const double lz, const int num ) const;
// Calculate array converting local IDs to global ones
void calcArrayConvertLocalID2Global();
// Calculate array converting global IDs to the ones after degeneration
void calcArrayConvertIDsGlobal2AfterDegenerated();
// Calculate array converting global edge IDs non-zero electric field values specified to the edges
void calcArrayConvertIDGlobal2NonZeroValues();
// Renumber global node IDs after degeneration by coordinate values
void renumberNodes();
//// Calculate flag specifing whether rotation direction of integral route is positive or not
//bool doesRotationDirectionPlus( const CommonParameters::locationXY& startPoint, const CommonParameters::locationXY& endPoint,
// bool& integralXCompFirst ) const;
// Calculate flag specifing whether integral X component first
bool doesIntegralXCompFirst( const CommonParameters::locationXY& startPoint, const CommonParameters::locationXY& endPoint,
bool& rotationDirectionPlus ) const;
// Output results of forward calculation to VTK file
virtual void outputResultToVTK() const;
// Output results of forward calculation to binary file
virtual void outputResultToBinary( const int iFreq, const int iPol ) const;
//// Get total number of element
//virtual int getNumElemTotal() const;
};
#endif