39 #include <lifev/core/fem/CurrentFE.hpp> 98 for (
UInt iterNode (0); iterNode <
M_nbNode; ++iterNode )
101 if (M_refFE->hasPhi() )
103 for (UInt iterFEDim (0); iterFEDim < M_refFE->feDim(); ++iterFEDim)
105 M_phi[iterNode][iterFEDim][iterQuad] = M_refFE->phi ( iterNode, iterFEDim,
106 M_quadRule->quadPointCoor (iterQuad) );
111 if (M_refFE->hasDivPhi() )
113 M_divPhiRef[iterNode][iterQuad] = M_refFE->divPhi (iterNode,
114 M_quadRule->quadPointCoor (iterQuad) );
121 if (M_refFE->hasDPhi() )
123 M_dphiRef[iterNode][icoor][iterQuad] = M_refFE->dPhi ( iterNode,
125 M_quadRule->quadPointCoor (iterQuad) );
129 if (M_refFE->hasD2Phi() )
133 M_d2phiRef[iterNode][icoor][jcoor][iterQuad] = M_refFE->d2Phi ( iterNode,
135 M_quadRule->quadPointCoor (iterQuad) );
144 M_dphiGeometricMap[k][icoor][iterQuad] = M_geoMap->dPhi ( k, icoor,
145 M_quadRule->quadPointCoor (iterQuad) );
271 const Real a11 = M_cellNodes[1][0] - M_cellNodes[0][0];
272 const Real b1 = x - M_cellNodes[0][0];
274 Real lambda = b1 / a11;
286 const Real a11 = M_cellNodes[1][0] - M_cellNodes[0][0];
287 const Real a12 = M_cellNodes[2][0] - M_cellNodes[0][0];
288 const Real a21 = M_cellNodes[1][1] - M_cellNodes[0][1];
289 const Real a22 = M_cellNodes[2][1] - M_cellNodes[0][1];
290 const Real b1 = x - M_cellNodes[0][0];
291 const Real b2 = y - M_cellNodes[0][1];
293 Real D = a11 * a22 - a21 * a12;
294 Real lambda_1 = b1 * a22 - b2 * a12;
295 Real lambda_2 = a11 * b2 - a21 * b1;
300 xi = lambda_1 * 1 + lambda_2 * 0;
301 eta = lambda_1 * 0 + lambda_2 * 1;
310 const Real a11 = M_cellNodes[1][0] - M_cellNodes[0][0];
311 const Real a12 = M_cellNodes[2][0] - M_cellNodes[0][0];
312 const Real a13 = M_cellNodes[3][0] - M_cellNodes[0][0];
313 const Real a21 = M_cellNodes[1][1] - M_cellNodes[0][1];
314 const Real a22 = M_cellNodes[2][1] - M_cellNodes[0][1];
315 const Real a23 = M_cellNodes[3][1] - M_cellNodes[0][1];
316 const Real a31 = M_cellNodes[1][2] - M_cellNodes[0][2];
317 const Real a32 = M_cellNodes[2][2] - M_cellNodes[0][2];
318 const Real a33 = M_cellNodes[3][2] - M_cellNodes[0][2];
319 const Real b1 = x - M_cellNodes[0][0];
320 const Real b2 = y - M_cellNodes[0][1];
321 const Real b3 = z - M_cellNodes[0][2];
323 const Real D = a11 * a22 * a33 + a31 * a12 * a23 + a21 * a32 * a13 - a11 * a32 * a23 - a31 * a22 * a13 - a21 * a12 * a33;
324 Real lambda_1 = b1 * a22 * a33 + b3 * a12 * a23 + b2 * a32 * a13 - b1 * a32 * a23 - b3 * a22 * a13 - b2 * a12 * a33;
325 Real lambda_2 = a11 * b2 * a33 + a31 * b1 * a23 + a21 * b3 * a13 - a11 * b3 * a23 - a31 * b2 * a13 - a21 * b1 * a33;
326 Real lambda_3 = a11 * a22 * b3 + a31 * a12 * b2 + a21 * a32 * b1 - a11 * a32 * b2 - a31 * a22 * b1 - a21 * a12 * b3;
332 xi = lambda_1 * 1 + lambda_2 * 0 + lambda_3 * 0;
333 eta = lambda_1 * 0 + lambda_2 * 1 + lambda_3 * 0;
334 zeta = lambda_1 * 0 + lambda_2 * 0 + lambda_3 * 1;
339 ERROR_MSG (
"Impossible dimension to invert coordinates");
351 Int comp_x,
Int comp_zeta)
const 361 jac += M_cellNodes[i][comp_x] * M_geoMap->dPhi ( i , comp_zeta , P );
412 det = a * (ei - fh) + d * (ch - bi) + g * ( bf - ce);
417 ERROR_MSG (
"Dimension (M_nbLocalCoor): only 1, 2 or 3!" );
425 Int comp_x,
Int comp_zeta)
const 440 Int total (comp_x + comp_zeta);
447 return mysign *
pointJacobian (hat_x
, hat_y
, hat_z
, comp_zeta
, comp_x
) / (a11 * a22 - a12 * a21);
463 Real det = a11 * a22 * a33 + a12 * a23 * a31 + a13 * a21 * a32 - a11 * a23 * a32 - a13 * a22 * a31 - a12 * a21 * a33;
465 std::vector<std::vector< Real > > cof (3, std::vector<Real> (3, 0) );
467 cof[0][0] = (a22 * a33 - a23 * a32);
468 cof[0][1] = - (a21 * a33 - a31 * a23);
469 cof[0][2] = (a21 * a32 - a31 * a22);
470 cof[1][0] = - (a12 * a33 - a32 * a13);
471 cof[1][1] = (a11 * a33 - a13 * a31);
472 cof[1][2] = - (a11 * a32 - a31 * a12);
473 cof[2][0] = (a12 * a23 - a13 * a22);
474 cof[2][1] = - (a11 * a23 - a13 * a21);
475 cof[2][2] = (a11 * a22 - a12 * a21);
478 return cof[comp_x][comp_zeta] / det;
482 ERROR_MSG (
"Dimension (M_nbLocalCoor): only 1, 2 or 3!" );
491 ASSERT (M_nbQuadPt != 0 || upFlag == UPDATE_ONLY_CELL_NODES,
" No quadrature rule defined, cannot update!");
496 computeCellNodes (pts);
550 std::vector< std::vector <Real > > newpts (pts.size(), std::vector<Real> (pts[0].size() ) );
552 for (UInt iPt (0); iPt < pts.size(); ++iPt)
554 for (UInt iCoord (0); iCoord < pts[iPt].size(); ++iCoord)
556 newpts[iPt][iCoord] = pts[iPt][iCoord];
560 update (newpts, upFlag);
565 ASSERT (M_wDetJacobianUpdated,
"Weighted jacobian determinant is not updated!");
568 for (
UInt iterQuadNode (0); iterQuadNode <
M_nbQuadPt; ++iterQuadNode )
570 meas += M_wDetJacobian[iterQuadNode];
577 ASSERT (M_cellNodesUpdated,
"Cell nodes are not updated!");
585 x += M_cellNodes[iNode][0];
586 y += M_cellNodes[iNode][1];
587 z += M_cellNodes[iNode][2];
597 ASSERT (M_cellNodesUpdated,
"Cell nodes are not updated!");
608 s += std::fabs ( M_cellNodes[i][icoor] - M_cellNodes[j][icoor] );
622 ASSERT (M_cellNodesUpdated,
"Cell nodes are not updated!");
634 d = ( M_cellNodes[i][icoor] - M_cellNodes[j][icoor] );
651 ASSERT (M_cellNodesUpdated,
"Cell nodes are not updated!");
665 x += M_cellNodes[iNode][0] * geoMap;
666 y += M_cellNodes[iNode][1] * geoMap;
667 z += M_cellNodes[iNode][2] * geoMap;
673 ASSERT (M_cellNodesUpdated,
"Cell nodes are not updated!");
681 Pcurrent[j] += M_cellNodes[i][j] * M_geoMap->phi (i, P);
691 ASSERT (M_quadNodesUpdated,
"Quad nodes are not updated! No export possible");
693 std::ofstream output (filename.c_str() );
694 ASSERT (!output.fail(),
" Unable to open the file for the export of the quadrature ");
697 output <<
"# vtk DataFile Version 3.0" << std::endl;
698 output <<
"LifeV : Quadrature export" << std::endl;
699 output <<
"ASCII" << std::endl;
700 output <<
"DATASET POLYDATA" << std::endl;
701 output <<
"POINTS " << M_nbQuadPt <<
" float" << std::endl;
705 output << M_quadNodes[i][0] <<
" " << M_quadNodes[i][1] <<
" " << M_quadNodes[i][2] << std::endl;
708 output <<
"VERTICES " << M_nbQuadPt <<
" " << 2 * M_nbQuadPt << std::endl;
712 output << 1 <<
" " << i << std::endl;
732 M_quadNodes.resize (boost::extents[M_nbQuadPt][3]);
734 M_dphiGeometricMap.resize (boost::extents[M_nbGeoNode][M_nbLocalCoor][M_nbQuadPt]);
735 M_jacobian.resize (boost::extents[M_nbLocalCoor][M_nbLocalCoor][M_nbQuadPt]);
736 M_detJacobian.resize (boost::extents[M_nbQuadPt]);
737 M_wDetJacobian.resize (boost::extents[M_nbQuadPt]);
738 M_tInverseJacobian.resize (boost::extents[M_nbLocalCoor][M_nbLocalCoor][M_nbQuadPt]);
740 M_phi.resize (boost::extents[M_nbNode][M_refFE->feDim()][M_nbQuadPt]);
741 M_dphi.resize (boost::extents[M_nbNode][M_nbLocalCoor][M_nbQuadPt]);
742 M_d2phi.resize (boost::extents[M_nbNode][M_nbLocalCoor][M_nbLocalCoor][M_nbQuadPt]);
743 M_phiVect.resize (boost::extents[M_nbNode][M_refFE->feDim()][M_nbQuadPt]);
745 M_dphiRef.resize (boost::extents[M_nbNode][M_nbLocalCoor][M_nbQuadPt]);
746 M_d2phiRef.resize (boost::extents[M_nbNode][M_nbLocalCoor][M_nbLocalCoor][M_nbQuadPt]);
747 M_divPhiRef.resize (boost::extents[M_nbNode][M_nbQuadPt]);
771 for (
UInt iterNode (0); iterNode <
M_nbNode; ++iterNode )
774 if (M_refFE->hasPhi() )
776 for (UInt iterFEDim (0); iterFEDim < M_refFE->feDim(); ++iterFEDim)
778 M_phi[iterNode][iterFEDim][iterQuad] = M_refFE->phi ( iterNode, iterFEDim,
779 M_quadRule->quadPointCoor (iterQuad) );
784 if (M_refFE->hasDivPhi() )
786 M_divPhiRef[iterNode][iterQuad] = M_refFE->divPhi (iterNode,
787 M_quadRule->quadPointCoor (iterQuad) );
793 if (M_refFE->hasDPhi() )
795 M_dphiRef[iterNode][icoor][iterQuad] = M_refFE->dPhi ( iterNode,
797 M_quadRule->quadPointCoor (iterQuad) );
801 if (M_refFE->hasD2Phi() )
805 M_d2phiRef[iterNode][icoor][jcoor][iterQuad] = M_refFE->d2Phi ( iterNode,
807 M_quadRule->quadPointCoor (iterQuad) );
816 M_dphiGeometricMap[k][icoor][iterQuad] = M_geoMap->dPhi ( k, icoor,
817 M_quadRule->quadPointCoor (iterQuad) );
834 M_cellNodes[iterNode][iterCoord] = pts[iterNode][iterCoord];
842 ASSERT (M_cellNodesUpdated,
"Missing update: cellNodes");
844 for (
UInt iterQuadNode (0); iterQuadNode <
M_nbQuadPt; ++iterQuadNode)
847 for (UInt i = 0; i < quadNode.size(); i++)
849 M_quadNodes[iterQuadNode][i] = quadNode[i];
863 M_dphiGeometricMap[iterNode][iterCoor][iterQuad] = M_geoMap->dPhi (iterNode, iterCoor,
864 M_quadRule->quadPointCoor (iterQuad) );
873 ASSERT (M_cellNodesUpdated,
"Missing update: cellNodes");
874 ASSERT (M_dphiGeometricMapUpdated,
"Missing update: dphiGeometricMap");
887 partialSum += M_cellNodes[iterNode][icoord] * M_dphiGeometricMap[iterNode][jcoord][iterQuad];
889 M_jacobian[icoord][jcoord][iterQuad] = partialSum;
898 ASSERT (M_jacobianUpdated,
"Missing update: jacobian");
906 Real a ( M_jacobian[0][0][iterQuad] );
908 M_tInverseJacobian[0][0][iterQuad] = 1.0 / a ;
914 Real a ( M_jacobian[0][0][iterQuad] );
915 Real b ( M_jacobian[0][1][iterQuad] );
916 Real c ( M_jacobian[1][0][iterQuad] );
917 Real d ( M_jacobian[1][1][iterQuad] );
919 Real det ( a * d - b * c );
921 M_tInverseJacobian[0][0][iterQuad] = d / det ;
922 M_tInverseJacobian[0][1][iterQuad] = -c / det ;
924 M_tInverseJacobian[1][0][iterQuad] = -b / det ;
925 M_tInverseJacobian[1][1][iterQuad] = a / det ;
931 Real a ( M_jacobian[0][0][iterQuad] );
932 Real b ( M_jacobian[0][1][iterQuad] );
933 Real c ( M_jacobian[0][2][iterQuad] );
934 Real d ( M_jacobian[1][0][iterQuad] );
935 Real e ( M_jacobian[1][1][iterQuad] );
936 Real f ( M_jacobian[1][2][iterQuad] );
937 Real g ( M_jacobian[2][0][iterQuad] );
938 Real h ( M_jacobian[2][1][iterQuad] );
939 Real i ( M_jacobian[2][2][iterQuad] );
947 Real det ( a * ( ei - fh ) + d * ( ch - bi ) + g * ( bf - ce ) );
949 M_tInverseJacobian[0][0][iterQuad] = ( ei - fh ) / det ;
950 M_tInverseJacobian[0][1][iterQuad] = ( -d * i + f * g ) / det ;
951 M_tInverseJacobian[0][2][iterQuad] = ( d * h - e * g ) / det ;
953 M_tInverseJacobian[1][0][iterQuad] = ( -bi + ch ) / det ;
954 M_tInverseJacobian[1][1][iterQuad] = ( a * i - c * g ) / det ;
955 M_tInverseJacobian[1][2][iterQuad] = ( -a * h + b * g ) / det ;
957 M_tInverseJacobian[2][0][iterQuad] = ( bf - ce ) / det ;
958 M_tInverseJacobian[2][1][iterQuad] = ( -a * f + c * d ) / det ;
959 M_tInverseJacobian[2][2][iterQuad] = ( a * e - b * d ) / det ;
964 ERROR_MSG (
"Dimension (M_nbLocalCoor): only 1, 2 or 3!" );
975 ASSERT (M_jacobianUpdated,
"Missing update: jacobian");
983 Real a ( M_jacobian[0][0][iterQuad] );
985 M_detJacobian[iterQuad] = det;
991 Real a ( M_jacobian[0][0][iterQuad] );
992 Real b ( M_jacobian[0][1][iterQuad] );
993 Real c ( M_jacobian[1][0][iterQuad] );
994 Real d ( M_jacobian[1][1][iterQuad] );
996 Real det ( a * d - b * c);
997 M_detJacobian[iterQuad] = det;
1002 Real a ( M_jacobian[0][0][iterQuad] );
1003 Real b ( M_jacobian[0][1][iterQuad] );
1004 Real c ( M_jacobian[0][2][iterQuad] );
1005 Real d ( M_jacobian[1][0][iterQuad] );
1006 Real e ( M_jacobian[1][1][iterQuad] );
1007 Real f ( M_jacobian[1][2][iterQuad] );
1008 Real g ( M_jacobian[2][0][iterQuad] );
1009 Real h ( M_jacobian[2][1][iterQuad] );
1010 Real i ( M_jacobian[2][2][iterQuad] );
1019 Real det ( a * (ei - fh) + d * (ch - bi) + g * ( bf - ce) );
1020 M_detJacobian[iterQuad] = det;
1024 ERROR_MSG (
"Dimension (M_nbLocalCoor): only 1, 2 or 3!" );
1033 ASSERT (M_detJacobianUpdated,
"Missing update: determinant of the jacobian");
1037 M_wDetJacobian[iterQuad] = M_detJacobian[iterQuad] * M_quadRule->weight (iterQuad);
1047 for (
UInt iterNode (0); iterNode <
M_nbNode; ++iterNode)
1051 M_dphiRef[iterNode][iterCoor][iterQuad] = M_refFE->dPhi (iterNode, iterCoor,
1052 M_quadRule->quadPointCoor (iterQuad) );
1061 ASSERT (M_jacobianUpdated,
"Missing update: tInverseJacobian");
1062 ASSERT (M_dphiRefUpdated,
"Missing update: dphiRef");
1064 Real partialSum (0);
1068 for (
UInt iterNode (0); iterNode <
M_nbNode; ++iterNode)
1075 partialSum += M_tInverseJacobian[iterCoor][iter][iterQuad] * M_dphiRef[iterNode][iter][iterQuad];
1077 M_dphi[iterNode][iterCoor][iterQuad] = partialSum;
1089 for (
UInt iterNode (0); iterNode <
M_nbNode; ++iterNode)
1095 M_d2phiRef[iterNode][iterCoor][iterCoor2][iterQuad] = M_refFE->d2Phi (iterNode, iterCoor, iterCoor2,
1096 M_quadRule->quadPointCoor (iterQuad) );
1107 ASSERT (M_jacobianUpdated,
"Missing update: tInverseJacobian");
1108 ASSERT (M_d2phiRefUpdated,
"Missing update: d2phiRef");
1110 Real partialSum (0);
1113 for (
UInt iterNode (0); iterNode <
M_nbNode; ++iterNode )
1124 partialSum += M_tInverseJacobian[icoor][k1][iterQuad]
1125 * M_d2phiRef[iterNode][k1][k2][iterQuad]
1126 * M_tInverseJacobian[jcoor][k2][iterQuad];
1129 M_d2phi[iterNode][icoor][jcoor][iterQuad] = partialSum;
1140 ASSERT (M_detJacobianUpdated,
"Missing update: detJacobian");
1152 sum += M_jacobian[ icoor ][ jcoor ][ ig ] * M_phi[ idof ][ jcoor ][ ig ];
1154 M_phiVect[ idof ][ icoor ][ ig ] = sum / M_detJacobian[ ig ];
void computeDphiRef()
Compute the value of the derivatives in the reference frame.
GeometricMap - Structure for the geometrical mapping.
void computeDetJacobian()
Compute the determinant of the jacobian.
void computeWDetJacobian()
Compute the determinant of the jacobian in the quadrature nodes.
Real pointInverseJacobian(Real hat_x, Real hat_y, Real hat_z, int compx, int compzeta) const
const flag_Type UPDATE_ONLY_PHI_VECT(1024)
const flag_Type UPDATE_ONLY_W_DET_JACOBIAN(32)
uint32_type flag_Type
bit-flag with up to 32 different flags
QuadratureRule * M_quadRule
bool M_wDetJacobianUpdated
const flag_Type UPDATE_ONLY_JACOBIAN(8)
const flag_Type UPDATE_ONLY_DPHI(128)
Real diameter2() const
return the diameter of the element in the 2-norm
void computePhiVect()
Compute the value of the vectorial FE using Piola transform.
void computeCellNodes(const std::vector< std::vector< Real > > &pts)
Update only the nodes of the cells to the current one.
void coorBackMap(Real x, Real y, Real z, Real &xi, Real &eta, Real &zeta) const
const ReferenceFE * M_refFE
CurrentFE(const CurrentFE &)
void computeDphiGeometricMap()
Compute the values of the derivatives of the mapping in the quadrature nodes.
int32_type Int
Generic integer data.
void computeQuadNodes()
Update the location of the quadrature in the current cell.
boost::numeric::ublas::vector< Real > GeoVector
const GeometricMap * M_geoMap
GeoVector coorMap(const GeoVector &P) const
QuadratureRule(const QuadratureRule &qr)
Copy constructor.
void updateInverseJacobian(const UInt &iQuadPt)
void update(const std::vector< GeoVector > &pts, flag_Type upFlag)
Update method using only point coordinates. It used the flags, as defined in this page...
void computeD2phiRef()
Compute the value of the second derivatives in the reference frame.
void computeD2phi()
Compute the value of the derivatives in the current element.
const flag_Type UPDATE_ONLY_DET_JACOBIAN(4096)
const flag_Type UPDATE_ONLY_QUAD_NODES(2)
const GeoVector & quadPointCoor(const UInt &ig) const
quadPointCoor(ig) is the full coordinates of the quadrature point ig
bool M_detJacobianUpdated
bool M_tInverseJacobianUpdated
void computeTInverseJacobian()
Compute the transposed inverse of the jacobian in the quadrature nodes.
virtual Real measure() const
Return the measure of the current element.
const UInt & nbDof() const
Return the number of degrees of freedom for this reference element.
Real diameter() const
return the diameter of the element in the 1-norm
void computeDphi()
Compute the value of the derivatives in the current element.
const flag_Type UPDATE_ONLY_D2PHI(512)
double Real
Generic real data.
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
void computeJacobian()
Compute the jacobian in the quadrature nodes.
const flag_Type UPDATE_ONLY_T_INVERSE_JACOBIAN(16)
The class for a reference Lagrangian finite element.
void barycenter(Real &x, Real &y, Real &z) const
return the barycenter of the element
const UInt nDimensions(NDIM)
CurrentFE(const ReferenceFE &refFE, const GeometricMap &geoMap)
Constructor without quadrature specification.
Real pointJacobian(Real hat_x, Real hat_y, Real hat_z, int compx, int compzeta) const
CurrentFE(const ReferenceFE &refFE, const GeometricMap &geoMap, const QuadratureRule &qr)
Full constructor with default quadrature.
void setQuadRule(const QuadratureRule &newQuadRule)
Setter for the quadrature rule.
Real phi(UInt i, const Real &x, const Real &y, const Real &z) const
return the value of the i-th basis function on point (x,y,z)
QuadratureRule - The basis class for storing and accessing quadrature rules.
bool M_dphiGeometricMapUpdated
Real pointDetJacobian(Real hat_x, Real hat_y, Real hat_z) const
const UInt & nbQuadPt() const
Getter for the number of quadrature points.
void quadRuleVTKexport(const std::string &filename) const
Export the quadrature rule on the current FE.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
void coorMap(Real &x, Real &y, Real &z, Real xi, Real eta, Real zeta) const
const flag_Type UPDATE_ONLY_CELL_NODES(1)