50 #include <lifev/core/LifeV.hpp> 52 #include <lifev/core/fem/BCHandler.hpp> 53 #include <lifev/core/fem/CurrentFE.hpp> 54 #include <lifev/core/fem/CurrentFEManifold.hpp> 55 #include <lifev/core/fem/DOF.hpp> 56 #include <lifev/core/fem/SobolevNorms.hpp> 58 #include <lifev/core/mesh/MeshPartitioner.hpp> 64 template <
typename MeshType,
typename MapType,
typename ReturnType >
77 template <
typename MeshType,
typename MapType>
86 typedef std::function < Real ( Real
const&, Real
const&, Real
const&,
87 Real
const&, ID
const& ) > function_Type;
88 typedef MeshType mesh_Type;
89 typedef std::shared_ptr<mesh_Type> meshPtr_Type;
90 typedef MapType map_Type;
91 typedef std::shared_ptr<map_Type> mapPtr_Type;
92 typedef typename map_Type::commPtr_Type commPtr_Type;
117 const commPtr_Type& commptr
121 const std::string& space,
123 const commPtr_Type& commptr
126 FESpace ( meshPtr_Type mesh,
131 const commPtr_Type& commptr
134 FESpace ( meshPtr_Type mesh,
135 const std::string& space,
137 const commPtr_Type& commptr
141 virtual ~FESpace() {}
150 template<
typename vector_type>
151 void interpolate (
const function_Type& fct, vector_type& vect,
const Real time = 0.);
153 template<
typename vector_type>
154 void interpolateBC (
BCHandler& BCh, vector_type& vect,
const Real time);
162 template <
typename ReturnType,
typename vector_type >
163 void interpolate (
const FEFunction<MeshType, MapType, ReturnType>* fEFunction,
164 vector_type& vector,
const Real time = 0. );
172 template<
typename vector_type>
173 void l2ScalarProduct (
const function_Type& fct,
177 template<
typename vector_type>
178 Real l20Error (
const function_Type& fexact,
179 const vector_type& vec,
181 Real* relError = 0 );
183 template<
typename vector_type>
184 Real l2Error (
const function_Type& fexact,
185 const vector_type& vec,
187 Real* relError = 0 );
189 template<
typename function,
typename vector_type>
190 Real h1Error (
const function& fexact,
191 const vector_type& vec,
193 Real* relError = 0 );
196 template<
typename vector_type>
197 Real l2Norm (
const vector_type& vec );
199 template<
typename function>
200 Real l2NormFunction (
const function& f,
const Real time = 0);
202 template<
typename vector_type>
203 Real h1Norm (
const vector_type& vec );
211 template<
typename vector_type>
212 Real l2ErrorWeighted (
const function_Type& exactSolution,
213 const vector_type& solution,
214 const function_Type& weight,
241 template<
typename point_type,
typename vector_type>
242 Real feInterpolateValue (
const ID& elementID,
const vector_type& solutionVector,
243 const point_type& pt,
const UInt& component = 0)
const;
260 template<
typename point_type,
typename vector_type>
261 Real feInterpolateValueLocal (
const ID& elementID,
const vector_type& solutionVector,
262 const point_type& pt )
const;
280 template<
typename point_type,
typename vector_type>
281 Real feInterpolateGradient (
const ID& elementID,
const vector_type& solutionVector,
const point_type& pt,
282 const UInt& gradientElement,
const UInt& component = 0 )
const;
296 template<
typename point_type,
typename vector_type>
297 Real feInterpolateGradientLocal (
const ID& elementID,
const vector_type& solutionVector,
const point_type& pt,
298 const UInt& gradientElement )
const;
325 template <
typename vector_type>
326 vector_type feToFEInterpolate (
const FESpace<mesh_Type, map_Type>& originalSpace,
344 template <
typename vector_type>
345 vector_type gradientRecovery (
const vector_type& solution,
const UInt& component)
const;
362 template <
typename vector_type>
363 vector_type recoveryFunction (
const vector_type& solution)
const;
372 template <
typename vector_type>
373 vector_type laplacianRecovery (
const vector_type& solution)
const;
376 UInt polynomialDegree()
const;
401 const meshPtr_Type& mesh()
const 411 const map_Type& map()
const 420 const mapPtr_Type& mapPtr()
const 434 const std::shared_ptr<DOF>& dofPtr()
const 491 FESpace (
const FESpace& fespace );
494 void createMap (
const commPtr_Type& commptr);
497 void resetBoundaryFE();
500 inline void setSpace (
const std::string& space,
UInt dimension );
512 template<
typename vector_type>
513 vector_type interpolateGeneric (
const FESpace<mesh_Type, map_Type>& OriginalSpace,
514 const vector_type& OriginalVector)
const;
527 template<
typename vector_type>
528 vector_type linearInterpolate (
const FESpace<mesh_Type, map_Type>& originalSpace,
529 const vector_type& originalVector)
const;
540 template<
typename vector_type>
541 vector_type P2Interpolate (
const FESpace<mesh_Type, map_Type>& original_space,
542 const vector_type& original_vector)
const;
550 template<
typename vector_type>
551 vector_type RT0ToP0Interpolate (
const FESpace<mesh_Type, map_Type>& original_space,
552 const vector_type& original_vector)
const;
559 enum spaceData {P0 = 1, P1 = 10, P1_HIGH = 15, P1Bubble = 16, P2 = 20, P2_HIGH = 25, P2Bubble = 26};
560 std::map<std::string, spaceData> M_spaceMap;
578 std::shared_ptr<DOF> M_dof;
584 std::shared_ptr<CurrentFE> M_fe;
585 std::shared_ptr<CurrentFEManifold> M_feBd;
596 template <
typename MeshType,
typename MapType>
597 FESpace<MeshType, MapType>::
598 FESpace ( MeshPartitioner<MeshType>& mesh,
603 const commPtr_Type& commptr
605 M_mesh ( mesh.meshPartition() ),
610 M_dof (
new DOF ( *M_mesh, *M_refFE ) ),
611 M_dim ( M_dof->numTotalDof() ),
612 M_fe (
new CurrentFE ( *M_refFE, getGeometricMap ( *M_mesh ), *M_Qr ) ),
614 M_map (
new map_Type() )
620 template <
typename MeshType,
typename MapType>
621 FESpace<MeshType, MapType>::
622 FESpace ( MeshPartitioner<MeshType>& mesh,
623 const std::string& space,
625 const commPtr_Type& commptr
627 M_mesh ( mesh.meshPartition() ),
632 M_map (
new map_Type() )
635 M_spaceMap[
"P0"] = P0;
636 M_spaceMap[
"P1"] = P1;
637 M_spaceMap[
"P1_HIGH"] = P1_HIGH;
638 M_spaceMap[
"P1Bubble"] = P1Bubble;
639 M_spaceMap[
"P2"] = P2;
640 M_spaceMap[
"P2_HIGH"] = P2_HIGH;
641 M_spaceMap[
"P2Bubble"] = P2Bubble;
644 setSpace ( space, mesh_Type::S_geoDimensions );
647 M_dof.reset (
new DOF ( *M_mesh, *M_refFE ) );
648 M_dim = M_dof->numTotalDof();
649 M_fe.reset (
new CurrentFE ( *M_refFE, getGeometricMap ( *M_mesh ), *M_Qr ) );
654 template <
typename MeshType,
typename MapType>
655 FESpace<MeshType, MapType>::
656 FESpace ( meshPtr_Type mesh,
661 const commPtr_Type& commptr
668 M_dof (
new DOF ( *M_mesh, *M_refFE ) ),
669 M_dim ( M_dof->numTotalDof() ),
670 M_fe (
new CurrentFE ( *M_refFE, getGeometricMap ( *M_mesh ), *M_Qr ) ),
672 M_map (
new map_Type() )
678 template <
typename MeshType,
typename MapType>
679 FESpace<MeshType, MapType>::
680 FESpace ( meshPtr_Type mesh,
681 const std::string& space,
683 const commPtr_Type& commptr
690 M_map (
new map_Type() )
693 M_spaceMap[
"P0"] = P0;
694 M_spaceMap[
"P1"] = P1;
695 M_spaceMap[
"P1_HIGH"] = P1_HIGH;
696 M_spaceMap[
"P1Bubble"] = P1Bubble;
697 M_spaceMap[
"P2"] = P2;
698 M_spaceMap[
"P2_HIGH"] = P2_HIGH;
699 M_spaceMap[
"P2Bubble"] = P2Bubble;
702 setSpace ( space, mesh_Type::S_geoDimensions );
705 M_dof.reset (
new DOF ( *M_mesh, *M_refFE ) );
706 M_dim = M_dof->numTotalDof();
707 M_fe.reset (
new CurrentFE ( *M_refFE, getGeometricMap ( *M_mesh ), *M_Qr ) );
718 template<
typename vector_type>
720 FESpace<MeshType, MapType>::interpolate (
const function_Type& fct,
726 interpQuad.setDimensionShape (shapeDimension (M_refFE->shape() ), M_refFE->shape() );
727 interpQuad.setPoints (M_refFE->refCoor(), std::vector<Real> (M_refFE->nbDof(), 0) );
730 CurrentFE interpCFE (*M_refFE, getGeometricMap (*M_mesh ), interpQuad);
733 UInt totalNumberElements (M_mesh->numElements() );
734 UInt numberLocalDof (M_dof->numLocalDof() );
737 std::vector<Real> nodalValues (numberLocalDof, 0);
738 std::vector<Real> FEValues (numberLocalDof, 0);
741 for (
UInt iterElement (0); iterElement < totalNumberElements; ++iterElement)
744 interpCFE.update (M_mesh->element (iterElement), UPDATE_QUAD_NODES);
747 for (
UInt iDim (0); iDim < M_fieldDim; ++iDim)
750 for (
UInt iterDof (0); iterDof < numberLocalDof; ++iterDof)
753 nodalValues[iterDof] = fct (time, interpCFE.quadNode (iterDof, 0), interpCFE.quadNode (iterDof, 1)
754 , interpCFE.quadNode (iterDof, 2), iDim);
758 FEValues = M_refFE->nodalToFEValues (nodalValues);
761 for (
UInt iterDof (0); iterDof < numberLocalDof; ++iterDof)
764 ID globalDofID (M_dof->localToGlobalMap (iterElement, iterDof) + iDim * M_dim);
767 vect.setCoefficient (globalDofID, FEValues[iterDof]);
775 template <
typename ReturnType,
typename vector_type>
776 void FESpace<MeshType, MapType>::
777 interpolate (
const FEFunction<MeshType, MapType, ReturnType>* fEFunction,
778 vector_type& vector,
const Real time )
783 interpQuad.setDimensionShape ( shapeDimension (M_refFE->shape() ), M_refFE->shape() );
784 interpQuad.setPoints ( M_refFE->refCoor(), std::vector<Real> (M_refFE->nbDof(), 0) );
787 CurrentFE interpCFE ( *M_refFE, getGeometricMap ( *M_mesh ), interpQuad );
790 const UInt totalNumberElements ( M_mesh->numElements() );
791 const UInt numberLocalDof ( M_dof->numLocalDof() );
794 typename FEFunction<MeshType, MapType, ReturnType>::point_Type point;
795 std::vector<Real> nodalValues (numberLocalDof, 0);
796 std::vector<Real> FEValues (numberLocalDof, 0);
799 for (
UInt iterElement (0); iterElement < totalNumberElements; ++iterElement)
802 interpCFE.update ( M_mesh->element (iterElement), UPDATE_QUAD_NODES );
805 for (
UInt iDim (0); iDim < M_fieldDim; ++iDim)
808 for (
UInt iterDof (0); iterDof < numberLocalDof; ++iterDof)
814 nodalValues[iterDof] = fEFunction->eval ( iterElement, point, time );
818 FEValues = M_refFE->nodalToFEValues ( nodalValues );
821 for (
UInt iterDof (0); iterDof < numberLocalDof; ++iterDof)
824 const ID globalDofID ( M_dof->localToGlobalMap ( iterElement, iterDof ) + iDim * M_dim );
827 vector.setCoefficient ( globalDofID, FEValues[iterDof] );
836 template<
typename vector_type>
838 FESpace<MeshType, MapType>::interpolateBC (
BCHandler& BCh,
844 UInt totalDof = dof().numTotalDof();
851 BCh.bcUpdate ( *mesh(), feBd(), dof() );
869 for (
ID j = 0; j < nComp; ++j )
875 vect.setCoefficient (idDof, val);
889 template<
typename vector_type>
891 FESpace<MeshType, MapType>::l2ScalarProduct (
const function_Type& fct, vector_type& vec,
const Real t)
894 for (
UInt iVol = 0; iVol <
this->mesh()->numElements(); iVol++ )
900 UInt i, inod, iQuadPt, ic;
901 UInt eleID =
this->fe().currentLocalId();
904 for ( iQuadPt = 0; iQuadPt <
this->fe().nbQuadPt(); iQuadPt++ )
906 x =
this->fe().quadNode (iQuadPt, 0);
907 y =
this->fe().quadNode (iQuadPt, 1);
908 z =
this->fe().quadNode (iQuadPt, 2);
909 for ( ic = 0; ic < M_fieldDim; ic++ )
911 f = fct ( t, x, y, z, ic );
913 for ( i = 0; i <
this->fe().nbFEDof(); i++ )
915 inod =
this->dof().localToGlobalMap ( eleID, i ) + ic * dim();
916 u_ig = f *
this->fe().phi ( i, iQuadPt );
917 vec.sumIntoGlobalValues (inod, u_ig *
this->fe().weightDet ( iQuadPt ) );
924 vec.globalAssemble();
930 template<
typename vector_type>
932 FESpace<MeshType, MapType>::l20Error (
const function_Type& fexact,
933 const vector_type& vec,
943 for (
UInt iVol = 0; iVol <
this->mesh()->numElements(); iVol++ )
947 normU += elementaryDifferenceL2NormSquare ( vec, fexact,
this->fe(),
this->dof(), time, M_fieldDim );
949 meanU += elementaryDifferenceIntegral ( vec, fexact,
this->fe(),
this->dof(), time, M_fieldDim );
950 mass +=
this->fe().measure();
954 sumExact1 += elementaryFctIntegral ( fexact,
this->fe(), time, M_fieldDim );
959 Real sendbuff[5] = {mass, meanU, normU, sumExact1, sumExact2};
962 this->map().comm().SumAll (&sendbuff[0], &recvbuff[0], 5);
968 sumExact1 = recvbuff[3];
969 sumExact2 = recvbuff[4];
971 Real absError = std::sqrt ( normU - meanU * meanU / mass );
975 Real normExact = std::sqrt ( sumExact2 - sumExact1 * sumExact1 / mass );
976 *relError = absError / normExact;
984 template<
typename vector_type>
986 FESpace<MeshType, MapType>::l2Error (
const function_Type& fexact,
987 const vector_type& vec,
994 for (
UInt iVol = 0; iVol <
this->mesh()->numElements(); iVol++ )
996 if (
this->mesh()->element ( iVol ).isOwned() )
1003 normU += elementaryDifferenceL2NormSquare ( vec, fexact,
1020 Real sendbuff[2] = {normU, sumExact};
1023 this->map().comm().SumAll (&sendbuff[0], &recvbuff[0], 2);
1025 normU = recvbuff[0];
1026 sumExact = recvbuff[1];
1030 *relError = std::sqrt ( normU / sumExact );
1033 return std::sqrt ( normU );
1037 template<
typename function>
1039 FESpace<MeshType, MapType>::l2NormFunction (
const function& f,
const Real time)
1046 for (
UInt ielem = 0; ielem <
this->mesh()->numElements(); ielem++ )
1053 Real sendbuff[1] = {sumExact};
1056 this->map().comm().SumAll (&sendbuff[0], &recvbuff[0], 1);
1058 sumExact = recvbuff[0];
1060 return std::sqrt ( sumExact );
1065 template<
typename vector_type>
1067 FESpace<MeshType, MapType>:: l2ErrorWeighted (
const function_Type& exactSolution,
1068 const vector_type& solution,
1069 const function_Type& weight,
1073 if (solution.mapType() ==
Unique)
1078 Real sumOfSquare (0.0);
1082 for (
UInt iVol (0); iVol <
this->mesh()->numElements(); ++iVol)
1086 for (
UInt iQuad (0); iQuad <
this->fe().nbQuadPt(); ++iQuad)
1088 Real solutionInQuadNode (0.0);
1090 for (
UInt iDim (0); iDim < M_fieldDim; ++iDim)
1092 for (
UInt iDof (0); iDof <
this->fe().nbFEDof(); ++iDof)
1094 UInt dofID (
this->dof().localToGlobalMap (iVol, iDof) + iDim *
this->dof().numTotalDof() );
1095 solutionInQuadNode +=
this->fe().phi (iDof, iQuad) * solution[dofID];
1098 Real x (
this->fe().quadNode (iQuad, 0) );
1099 Real y (
this->fe().quadNode (iQuad, 1) );
1100 Real z (
this->fe().quadNode (iQuad, 2) );
1101 Real weightInQuadNode (weight (time, x, y, z, iDim) );
1102 Real exactInQuadNode (exactSolution (time, x, y, z, iDim) );
1104 sumOfSquare += weightInQuadNode
1105 * (exactInQuadNode - solutionInQuadNode)
1106 * (exactInQuadNode - solutionInQuadNode)
1107 *
this->fe().wDetJacobian (iQuad);
1114 Real sendbuff (sumOfSquare);
1117 this->map().comm().SumAll (&sendbuff, &recvbuff, 1);
1119 sumOfSquare = recvbuff;
1121 return std::sqrt (sumOfSquare);
1128 template<
typename function,
typename vector_type>
1130 FESpace<MeshType, MapType>::h1Error (
const function& fexact,
1131 const vector_type& vec,
1138 for (
UInt iVol = 0; iVol <
this->mesh()->numElements(); iVol++ )
1140 this->fe().updateFirstDerivQuadPt (
this->mesh()->element ( iVol ) );
1142 normU += elementaryDifferenceH1NormSquare ( vec, fexact,
1150 sumExact += elementaryFctH1NormSquare ( fexact,
1159 Real sendbuff[2] = {normU, sumExact};
1162 this->map().comm().SumAll (&sendbuff[0], &recvbuff[0], 2);
1169 normU = recvbuff[0];
1170 sumExact = recvbuff[1];
1174 *relError = std::sqrt ( normU / sumExact );
1178 return std::sqrt ( normU );
1183 template<
typename vector_type>
1185 FESpace<MeshType, MapType>::l2Norm (
const vector_type& vec)
1188 ID nbComp = M_fieldDim;
1192 for (
UInt ielem = 0; ielem <
this->mesh()->numElements(); ielem++ )
1197 norm += elementaryL2NormSquare ( vec,
this->fe(),
this->dof(), nbComp );
1200 Real sendbuff[1] = {norm};
1203 this->map().comm().SumAll (&sendbuff[0], &recvbuff[0], 1);
1207 return std::sqrt ( norm );
1213 template<
typename vector_type>
1215 FESpace<MeshType, MapType>::h1Norm (
const vector_type& vec)
1218 ID nbComp = M_fieldDim;
1222 for (
UInt ielem = 0; ielem <
this->mesh()->numElements(); ielem++ )
1225 this->fe().updateFirstDerivQuadPt (
this->mesh()->element ( ielem ) );
1228 norm += elementaryH1NormSquare ( vec,
this->fe(),
this->dof(), nbComp );
1231 Real sendbuff[1] = {norm};
1234 this->map().comm().SumAll (&sendbuff[0], &recvbuff[0], 1);
1238 return std::sqrt ( norm );
1245 template<
typename point_type,
typename vector_type>
1247 FESpace<MeshType, MapType>::
1248 feInterpolateValue (
const ID& elementID,
const vector_type& solutionVector,
const point_type& pt,
const UInt& component )
const 1251 if (solutionVector.mapType() !=
Repeated )
1253 vector_type repeatedSolutionVector (solutionVector,
Repeated);
1254 return feInterpolateValue (elementID, repeatedSolutionVector, pt, component);
1258 M_fe->update ( M_mesh->element ( elementID ), UPDATE_ONLY_CELL_NODES);
1281 M_fe->coorBackMap (x, y, z, hat_x, hat_y, hat_z);
1284 UInt nDof (dof().numLocalDof() );
1285 UInt totalDof (dof().numTotalDof() );
1291 for (
UInt iter_dof (0); iter_dof < nDof ; ++iter_dof)
1296 ID globalDofID (component * totalDof + dof().localToGlobalMap (elementID, iter_dof) );
1300 value += solutionVector[globalDofID] * M_refFE->phi (iter_dof, hat_x, hat_y, hat_z);
1308 template<
typename point_type,
typename vector_type>
1310 FESpace<MeshType, MapType>::
1311 feInterpolateValueLocal (
const ID& elementID,
const vector_type& solutionVector,
const point_type& pt )
const 1314 M_fe->update ( M_mesh->element ( elementID ), UPDATE_ONLY_CELL_NODES);
1338 M_fe->coorBackMap (x, y, z, hat_x, hat_y, hat_z);
1341 UInt nDof (dof().numLocalDof() );
1347 for (
UInt iter_dof (0); iter_dof < nDof ; ++iter_dof)
1350 value += solutionVector[iter_dof] * M_refFE->phi (iter_dof, hat_x, hat_y, hat_z);
1358 template<
typename point_type,
typename vector_type>
1360 FESpace<MeshType, MapType>::
1361 feInterpolateGradient (
const ID& elementID,
const vector_type& solutionVector,
const point_type& pt,
1362 const UInt& gradientElement,
const UInt& component )
const 1365 if (solutionVector.getMaptype() !=
Repeated )
1367 vector_type repeatedSolutionVector (solutionVector,
Repeated);
1368 return feInterpolateGradient (elementID, repeatedSolutionVector, pt, gradientElement, component);
1373 M_fe->updateFirstDeriv ( M_mesh->element ( elementID ) );
1396 M_fe->coorBackMap (x, y, z, hat_x, hat_y, hat_z);
1399 UInt nDof (dof().numLocalDof() );
1400 UInt totalDof (dof().numTotalDof() );
1406 std::vector<Real> invJac (3, 0);
1407 invJac[0] = M_fe->pointInverseJacobian (hat_x, hat_y, hat_z, gradientElement, 0);
1408 invJac[1] = M_fe->pointInverseJacobian (hat_x, hat_y, hat_z, gradientElement, 1);
1409 invJac[2] = M_fe->pointInverseJacobian (hat_x, hat_y, hat_z, gradientElement, 2);
1411 for (
UInt iter_dof (0); iter_dof < nDof ; ++iter_dof)
1414 ID globalDofID (totalDof * component + dof().localToGlobalMap (elementID, iter_dof) );
1416 for (
UInt iter_dim (0); iter_dim < 3; ++iter_dim)
1418 grad += solutionVector (globalDofID) * M_refFE->dPhi (iter_dof, iter_dim, hat_x, hat_y, hat_z)
1428 template<
typename point_type,
typename vector_type>
1430 FESpace<MeshType, MapType>::
1431 feInterpolateGradientLocal (
const ID& elementID,
const vector_type& solutionVector,
const point_type& pt,
1432 const UInt& gradientElement )
const 1435 M_fe->updateFirstDeriv ( M_mesh->element ( elementID ) );
1458 M_fe->coorBackMap (x, y, z, hat_x, hat_y, hat_z);
1461 UInt nDof (dof().numLocalDof() );
1467 for (
UInt iter_dof (0); iter_dof < nDof ; ++iter_dof)
1470 for (
UInt iter_dim (0); iter_dim < 3; ++iter_dim)
1472 grad += solutionVector[iter_dof] * M_refFE->dPhi (iter_dof, iter_dim, hat_x, hat_y, hat_z)
1473 * M_fe->pointInverseJacobian (hat_x, hat_y, hat_z, gradientElement, iter_dim);
1482 template<
typename vector_type>
1484 FESpace<MeshType, MapType>::
1485 feToFEInterpolate (
const FESpace<mesh_Type, map_Type>& OriginalSpace,
1486 const vector_type& OriginalVector,
const MapEpetraType& outputMapType)
const 1492 ASSERT (fieldDim() == OriginalSpace.fieldDim() ||
1493 OriginalSpace.refFE().type() == FE_RT0_TETRA_3D ||
1494 OriginalSpace.refFE().type() == FE_RT0_TRIA_2D,
"Incompatible field dimension for interpolation");
1495 ASSERT (refFE().shape() == OriginalSpace.refFE().shape() ,
"Incompatible element shape for interpolation");
1498 std::shared_ptr<vector_type> InterpolatedVectorPtr;
1501 if (refFE().type() == OriginalSpace.refFE().type() )
1504 InterpolatedVectorPtr.reset (
new vector_type (OriginalVector) );
1508 else if ( ( (refFE().type() ==
FE_P1_3D) && ( (OriginalSpace.refFE().type() ==
FE_P1bubble_3D) || (OriginalSpace.refFE().type() ==
FE_P2_3D) ) ) ||
1510 ( (refFE().type() ==
FE_P1_2D) && ( OriginalSpace.refFE().type() ==
FE_P2_2D ) ) ||
1511 ( (refFE().type() ==
FE_Q1_3D) && ( OriginalSpace.refFE().type() ==
FE_Q2_3D ) ) ||
1512 ( (refFE().type() ==
FE_Q1_2D) && ( OriginalSpace.refFE().type() ==
FE_Q2_2D ) ) ||
1516 InterpolatedVectorPtr.reset (
new vector_type ( linearInterpolate (OriginalSpace, OriginalVector) ) );
1522 if ( OriginalVector.mapType() ==
Unique )
1524 const vector_type OriginalRepeated (OriginalVector,
Repeated);
1525 return feToFEInterpolate (OriginalSpace, OriginalRepeated);
1530 ( (refFE().type() ==
FE_P2_2D) && ( OriginalSpace.refFE().type() ==
FE_P1_2D ) ) )
1532 InterpolatedVectorPtr.reset (
new vector_type ( P2Interpolate (OriginalSpace, OriginalVector) ) );
1540 InterpolatedVectorPtr.reset (
new vector_type ( RT0ToP0Interpolate (OriginalSpace, OriginalVector) ) );
1544 ERROR_MSG (
" The interpolation with this host space has not been yet implemented. Please, add it!");
1549 InterpolatedVectorPtr.reset (
new vector_type ( interpolateGeneric ( OriginalSpace, OriginalVector) ) );
1553 if (InterpolatedVectorPtr->mapType() == outputMapType)
1555 return *InterpolatedVectorPtr;
1563 return vector_type (*InterpolatedVectorPtr, outputMapType, Insert);
1569 template<
typename vector_type>
1571 FESpace<MeshType, MapType>::
1572 gradientRecovery (
const vector_type& solution,
const UInt& dxi)
const 1574 if (solution.mapType() !=
Repeated)
1576 return gradientRecovery (vector_type (solution,
Repeated), dxi);
1579 Real refElemArea (0);
1589 interpQuad.setDimensionShape (shapeDimension (M_refFE->shape() ), M_refFE->shape() );
1590 Real wQuad (refElemArea / M_refFE->nbDof() );
1592 for (UInt i (0); i < M_refFE->nbDof(); ++i)
1594 interpQuad.addPoint (QuadraturePoint (M_refFE->xi (i), M_refFE->eta (i), M_refFE->zeta (i), wQuad) );
1598 vector_type patchArea (solution,
Repeated);
1601 vector_type gradientSum (solution,
Repeated);
1605 UInt totalNumberElements (M_mesh->numElements() );
1606 UInt numberLocalDof (M_dof->numLocalDof() );
1608 CurrentFE interpCFE (*M_refFE, getGeometricMap (*M_mesh ), interpQuad);
1611 for (
UInt iterElement (0); iterElement < totalNumberElements; ++iterElement)
1615 for (
UInt iterDof (0); iterDof < numberLocalDof; ++iterDof)
1617 for (
UInt iDim (0); iDim < M_fieldDim; ++iDim)
1619 ID globalDofID (dof().localToGlobalMap (iterElement, iterDof) + iDim * dof().numTotalDof() );
1621 patchArea[globalDofID] += interpCFE
.measure();
1622 for (
UInt iterDofGrad (0); iterDofGrad < numberLocalDof; ++iterDofGrad)
1624 ID globalDofIDGrad (dof().localToGlobalMap (iterElement, iterDofGrad) + iDim * dof().numTotalDof() );
1625 gradientSum[globalDofID] += interpCFE
.measure() * solution[globalDofIDGrad] * interpCFE
.dphi (iterDofGrad
, dxi
, iterDof
);
1632 return vector_type (gradientSum, Unique, Add) / vector_type (patchArea, Unique, Add);
1636 template<
typename vector_type>
1638 FESpace<MeshType, MapType>::
1639 laplacianRecovery (
const vector_type& solution)
const 1641 if (solution.getMaptype() !=
Repeated)
1643 return laplacianRecovery (vector_type (solution,
Repeated) );
1646 vector_type laplacian (solution);
1649 for (
UInt iterDim (0); iterDim < 3; ++iterDim)
1651 laplacian += gradientRecovery (gradientRecovery (solution, iterDim), iterDim);
1663 template <
typename MeshType,
typename MapType>
1665 FESpace<MeshType, MapType>::setSpace (
const std::string& space,
UInt dimension )
1671 switch ( M_spaceMap[space] )
1675 M_Qr = &quadRuleSeg1pt;
1676 M_bdQr = &quadRuleNode1pt;
1679 M_Qr = &quadRuleSeg2pt;
1680 M_bdQr = &quadRuleNode1pt;
1685 M_Qr = &quadRuleSeg3pt;
1686 M_bdQr = &quadRuleNode1pt;
1693 M_Qr = &quadRuleSeg3pt;
1694 M_bdQr = &quadRuleNode1pt;
1699 M_Qr = &quadRuleSeg4pt;
1700 M_bdQr = &quadRuleNode1pt;
1704 std::cout <<
"!!! WARNING: Space " << space <<
"not implemented for " << dimension <<
"D FESpaces!" << std::endl;
1711 switch ( M_spaceMap[space] )
1714 M_refFE = &feTriaP0;
1715 M_Qr = &quadRuleTria3pt;
1716 M_bdQr = &quadRuleSeg2pt;
1718 M_refFE = &feTriaP1;
1719 M_Qr = &quadRuleTria3pt;
1720 M_bdQr = &quadRuleSeg2pt;
1724 M_refFE = &feTriaP1;
1725 M_Qr = &quadRuleTria6pt;
1726 M_bdQr = &quadRuleSeg3pt;
1730 M_refFE = &feTriaP1bubble;
1731 M_Qr = &quadRuleTria6pt;
1732 M_bdQr = &quadRuleSeg2pt;
1736 M_refFE = &feTriaP2;
1737 M_Qr = &quadRuleTria6pt;
1738 M_bdQr = &quadRuleSeg3pt;
1742 M_refFE = &feTriaP2;
1743 M_Qr = &quadRuleTria7pt;
1744 M_bdQr = &quadRuleSeg3pt;
1748 std::cout <<
"!!! WARNING: Space " << space <<
"not implemented for " << dimension <<
"D FESpaces!" << std::endl;
1755 switch ( M_spaceMap[space] )
1758 M_refFE = &feTetraP0;
1759 M_Qr = &quadRuleTetra4pt;
1760 M_bdQr = &quadRuleTria3pt;
1764 M_refFE = &feTetraP1;
1765 M_Qr = &quadRuleTetra4pt;
1766 M_bdQr = &quadRuleTria3pt;
1770 M_refFE = &feTetraP1;
1771 M_Qr = &quadRuleTetra15pt;
1772 M_bdQr = &quadRuleTria4pt;
1776 M_refFE = &feTetraP1bubble;
1777 M_Qr = &quadRuleTetra64pt;
1778 M_bdQr = &quadRuleTria3pt;
1782 M_refFE = &feTetraP2;
1783 M_Qr = &quadRuleTetra15pt;
1784 M_bdQr = &quadRuleTria4pt;
1788 M_refFE = &feTetraP2;
1789 M_Qr = &quadRuleTetra64pt;
1790 M_bdQr = &quadRuleTria4pt;
1794 M_refFE = &feTetraP2tilde;
1795 M_Qr = &quadRuleTetra64pt;
1796 M_bdQr = &quadRuleTria4pt;
1800 std::cout <<
"!!! WARNING: Space " << space <<
"not implemented for " << dimension <<
"D FESpaces!" << std::endl;
1807 ERROR_MSG (
"Error! This dimension is not supported by LifeV.\n");
1811 template<
typename MeshType,
typename MapType>
1813 FESpace<MeshType, MapType>::
1817 M_fe.reset (
new CurrentFE ( *M_refFE, getGeometricMap ( *M_mesh ), *M_Qr ) );
1821 template<
typename MeshType,
typename MapType>
1823 FESpace<MeshType, MapType>::
1848 template<
typename MeshType,
typename MapType>
1850 FESpace<MeshType, MapType>::
1851 createMap (
const commPtr_Type& commptr)
1854 ASSERT_PRE (
this->M_dof->numTotalDof() > 0,
" Cannot create FeSpace with no degrees of freedom");
1857 typename MapType::mapData_Type mapData =
this->M_dof->createMapData ( *
this->M_mesh );
1859 MapType map ( mapData, commptr );
1863 for (
UInt ii = 0; ii < M_fieldDim; ++ii )
1870 template<
typename MeshType,
typename MapType>
1872 FESpace<MeshType, MapType>::
1877 M_feBd.reset (
new CurrentFEManifold ( M_refFE->boundaryFE(), getGeometricMap ( *M_mesh ).boundaryMap(), *M_bdQr ) );
1883 template<
typename vector_type>
1885 FESpace<MeshType, MapType>::
1886 interpolateGeneric (
const FESpace<mesh_Type, map_Type>& OriginalSpace,
1887 const vector_type& OriginalVector)
const 1890 vector_type Interpolated (map(),
Repeated);
1893 UInt size_comp_in = OriginalSpace.dim();
1896 UInt numberLocalDof (M_dof->numLocalDof() );
1901 std::vector<Real> phi (OriginalSpace.dof().numLocalDof() *numberLocalDof, 0.);
1904 std::vector<std::vector<Real> > nodalValues (M_fieldDim, std::vector<Real> (numberLocalDof, 0.) );
1907 std::vector<Real> FEValues (numberLocalDof, 0.);
1910 for (
UInt iterDof = 0 ; iterDof < numberLocalDof ; ++iterDof )
1912 xi = M_refFE->xi (iterDof);
1913 yi = M_refFE->eta (iterDof);
1914 zi = M_refFE->zeta (iterDof);
1915 for (
UInt iterDofOrig (0) ; iterDofOrig < OriginalSpace.dof().numLocalDof(); ++iterDofOrig)
1917 phi[iterDofOrig * numberLocalDof + iterDof] += OriginalSpace.refFE().phi (iterDofOrig, xi, yi, zi);
1922 for ( UInt iElem (0); iElem < M_mesh->numElements(); ++iElem )
1925 for ( UInt iterDof = 0 ; iterDof < numberLocalDof ; ++iterDof )
1926 for (UInt iterDofOrig (0) ; iterDofOrig < OriginalSpace.dof().numLocalDof(); ++iterDofOrig)
1928 size_t index = OriginalSpace.dof().localToGlobalMap ( iElem, iterDofOrig );
1929 for ( UInt iDim = 0; iDim < M_fieldDim; ++iDim )
1931 nodalValues[iDim][iterDof] += OriginalVector[iDim * size_comp_in + index] * phi[iterDofOrig * numberLocalDof + iterDof];
1936 for ( UInt iDim = 0; iDim < M_fieldDim; ++iDim )
1938 FEValues = M_refFE->nodalToFEValues (nodalValues[iDim]);
1939 for ( UInt iterDof (0) ; iterDof < numberLocalDof; ++iterDof )
1941 ID globalDofId (M_dof->localToGlobalMap ( iElem, iterDof ) + iDim * M_dim);
1944 Interpolated.setCoefficient (globalDofId, FEValues[iterDof]);
1945 nodalValues[iDim][iterDof] = 0;
1950 return Interpolated;
1958 template<
typename vector_type>
1960 FESpace<MeshType, MapType>::
1961 linearInterpolate (
const FESpace<mesh_Type, map_Type>& OriginalSpace,
1962 const vector_type& OriginalVector)
const 1965 vector_type Interpolated (map(),
Unique);
1966 UInt totalDofsOriginal (OriginalSpace.dof().numTotalDof() );
1967 UInt totalDofsPresent (dof().numTotalDof() );
1970 if (totalDofsPresent > totalDofsOriginal)
1972 myLinearDofs = OriginalSpace.map().map (
Unique)->NumMyElements() / fieldDim();
1976 myLinearDofs = map().map (
Unique)->NumMyElements() / fieldDim();
1980 for (
UInt j = 0; j < myLinearDofs; j++)
1982 UInt ig1 = map().map (
Unique)->MyGlobalElements() [j];
1983 UInt ig2 = OriginalSpace.map().map (
Unique)->MyGlobalElements() [j];
1984 for (
UInt iComponent (0); iComponent < fieldDim(); ++iComponent)
1986 Interpolated[ig1 + iComponent * totalDofsPresent] = OriginalVector[ig2 + iComponent * totalDofsOriginal];
1990 return Interpolated;
1997 template<
typename vector_type>
1999 FESpace<MeshType, MapType>::
2000 P2Interpolate (
const FESpace<mesh_Type, map_Type>& OriginalSpace,
2001 const vector_type& OriginalVector)
const 2004 vector_type Interpolated (map(),
Repeated);
2005 Interpolated *= 0.0;
2008 UInt FieldDim (fieldDim() );
2010 UInt numElements (mesh()->numElements() );
2012 UInt totalDofsOriginal (OriginalSpace.dof().numTotalDof() );
2013 UInt totalDofsPresent (dof().numTotalDof() );
2014 UInt localDofsPresent (dof().numLocalDof() );
2017 std::vector<Real> DofValues (localDofsPresent, 0.0);
2020 for (
ID iElem = 0; iElem < numElements ; ++iElem )
2022 UInt elemId (mesh()->element (iElem).localId() );
2029 for (
UInt iComponent (0); iComponent < FieldDim; ++iComponent)
2032 for (
UInt iP1dof (0); iP1dof < 4; ++iP1dof)
2034 ID globalDofID_original (iComponent * totalDofsOriginal + OriginalSpace.dof().localToGlobalMap (elemId, iP1dof) );
2036 DofValues[iP1dof] = OriginalVector[globalDofID_original];
2040 DofValues[4] = 0.5 * (DofValues[0] + DofValues[1]);
2041 DofValues[5] = 0.5 * (DofValues[1] + DofValues[2]);
2042 DofValues[6] = 0.5 * (DofValues[0] + DofValues[2]);
2043 DofValues[7] = 0.5 * (DofValues[0] + DofValues[3]);
2044 DofValues[8] = 0.5 * (DofValues[1] + DofValues[3]);
2045 DofValues[9] = 0.5 * (DofValues[2] + DofValues[3]);
2048 for (
UInt iP2dof (0); iP2dof < localDofsPresent; ++iP2dof)
2050 ID globalDofID_present (iComponent * totalDofsPresent + dof().localToGlobalMap (elemId, iP2dof) );
2052 Interpolated[globalDofID_present] = DofValues[iP2dof];
2058 return Interpolated;
2065 template<
typename vector_type>
2067 FESpace<MeshType, MapType>::
2068 RT0ToP0Interpolate (
const FESpace<mesh_Type, map_Type>& OriginalSpace,
2069 const vector_type& OriginalVector)
const 2072 vector_type Interpolated (map(),
Repeated);
2073 Interpolated *= 0.0;
2076 const UInt FieldDim (fieldDim() );
2079 const UInt numElements (mesh()->numElements() );
2082 const UInt totalDofsPresent (dof().numTotalDof() );
2085 for (
ID iElem (0); iElem < numElements ; ++iElem )
2089 const UInt elemId (mesh()->element (iElem).localId() );
2092 Vector3D barCurrentFE, barRefFE, Jac;
2095 M_fe->update (
this->mesh()->element (elemId), UPDATE_QUAD_NODES | UPDATE_WDET);
2098 const UInt nDof (OriginalSpace.dof().numLocalDof() );
2101 M_fe->barycenter ( barCurrentFE[0], barCurrentFE[1], barCurrentFE[2] );
2104 M_fe->coorBackMap ( barCurrentFE[0], barCurrentFE[1], barCurrentFE[2],
2105 barRefFE[0], barRefFE[1], barRefFE[2] );
2108 const Real det = M_fe->pointDetJacobian (barRefFE[0], barRefFE[1], barRefFE[2]);
2111 for (
UInt iComponent (0); iComponent < FieldDim; ++iComponent)
2116 for (
UInt localComponent (0); localComponent < FieldDim; ++localComponent )
2118 Jac[localComponent] = M_fe->pointJacobian ( barRefFE[0], barRefFE[1], barRefFE[2],
2119 iComponent, localComponent);
2122 const UInt iGlobalFacePresent ( iComponent * totalDofsPresent + dof().localToGlobalMap (elemId, 0) );
2125 for (
UInt iter_dof (0); iter_dof < nDof ; ++iter_dof)
2128 const ID globalDofID ( OriginalSpace.dof().localToGlobalMap ( elemId, iter_dof) );
2131 const UInt iGlobalFacet ( mesh()->localFacetId ( elemId, iter_dof ) );
2134 if ( mesh()->facet ( iGlobalFacet ).firstAdjacentElementIdentity() != iElem )
2137 for (
UInt jComponent (0); jComponent < FieldDim; ++jComponent)
2139 value -= OriginalVector[globalDofID] * Jac
[jComponent] *
2140 OriginalSpace.refFE().phi (iter_dof, jComponent, barRefFE
[0
], barRefFE
[1
], barRefFE
[2
]);
2146 for (
UInt jComponent (0); jComponent < FieldDim; ++jComponent)
2148 value += OriginalVector[globalDofID] * Jac
[jComponent] *
2149 OriginalSpace.refFE().phi (iter_dof, jComponent, barRefFE
[0
], barRefFE
[1
], barRefFE
[2
]);
2155 Interpolated[iGlobalFacePresent] = value / det;
2159 return Interpolated;
2163 template<
typename MeshType,
typename MapType>
2165 FESpace<MeshType, MapType>::
2166 polynomialDegree()
const 2204 std::cerr <<
" FESpace: No polynomial degre for this type of finite element " << std::endl;
2205 std::cerr <<
" FESpace: " << M_refFE->name() << std::endl;
VectorEpetra - The Epetra Vector format Wrapper.
const Real & weight(const UInt &ig) const
weight(ig) is the ig-th quadrature weight
bcType_Type type() const
Returns the boundary condition type.
const Real & y() const
Recovering the node's y-coordinate.
const flag_Type UPDATE_DPHI(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_DPHI_GEO_MAP|UPDATE_ONLY_JACOBIAN|UPDATE_ONLY_T_INVERSE_JACOBIAN|UPDATE_ONLY_DPHI_REF|UPDATE_ONLY_DPHI|UPDATE_ONLY_DET_JACOBIAN)
const Real & z() const
Recovering the node's z-coordinate.
A class for a finite element on a manifold.
BCHandler - class for handling boundary conditions.
int32_type Int
Generic integer data.
const FE_TYPE & type() const
Getter for the type of the finite element.
bool hasBoundaryFE() const
Check if the reference element has boundary elements.
BCBase & operator[](const ID &)
Extract a BC in the list.
void updateInverseJacobian(const UInt &iQuadPt)
const flag_Type UPDATE_WDET(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_DPHI_GEO_MAP|UPDATE_ONLY_JACOBIAN|UPDATE_ONLY_DET_JACOBIAN|UPDATE_ONLY_W_DET_JACOBIAN)
Real operator()(const Real &t, const Real &x, const Real &y, const Real &z, const ID &iComponent) const
Overloading function operator by calling the BCFunctionBase user specified function.
UInt numberOfComponents() const
Returns the number of components involved in this boundary condition.
Real dphi(UInt node, UInt derivative, UInt quadNode) const
Getter for the derivatives of the basis functions.
Real & operator[](UInt const &i)
Operator [].
virtual Real measure() const
Return the measure of the current element.
Real elementaryFctL2NormSquare(std::function< Real(Real, Real, Real) > fct, const CurrentFE &fe)
returns the square of the L2 norm of fct on the current element
Real quadNode(UInt node, UInt coordinate) const
Getter for the quadrature nodes.
double Real
Generic real data.
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
The class for a reference Lagrangian finite element.
const BCIdentifierBase * operator[](const ID &i) const
Returns a pointer to the (i)-th element of the list of identifiers.
const ID & id() const
Returns the ID of the BCIdentifier.
const flag_Type UPDATE_QUAD_NODES(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_QUAD_NODES)
BCIdentifierEssential - BCIdentifier for implementing Essential Boundary Conditions.
const Real & x() const
Recovering the node's x-coordinate.
#define LIFEV_DEPRECATED(func)
bool bcUpdateDone() const
Determine whether bcUpdate has been done before.
VectorSmall< 3 > Vector3D
ID component(const ID i) const
Returns the index of the component of the solution associated to the iComponent-th component prescrib...
UInt size() const
Number of the stored boundary conditions.
QuadratureRule - The basis class for storing and accessing quadrature rules.
UInt list_size() const
Returns the size of the identifiers list.
const UInt & nbQuadPt() const
Getter for the number of quadrature points.
uint32_type UInt
generic unsigned integer (used mainly for addressing)