v0.16.3
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
MoFEM::TetPolynomialBase Struct Reference

Calculate base functions on tetrahedral. More...

#include "src/approximation/TetPolynomialBase.hpp"

Inheritance diagram for MoFEM::TetPolynomialBase:
[legend]
Collaboration diagram for MoFEM::TetPolynomialBase:
[legend]

Public Member Functions

MoFEMErrorCode query_interface (boost::typeindex::type_index type_index, UnknownInterface **iface) const
 
 TetPolynomialBase (const void *ptr=nullptr)
 
virtual ~TetPolynomialBase ()
 
MoFEMErrorCode getValue (MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
 
- Public Member Functions inherited from MoFEM::BaseFunction
virtual MoFEMErrorCode getValue (MatrixDouble &pts_x, MatrixDouble &pts_t, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
 
- Public Member Functions inherited from MoFEM::BaseFunctionUnknownInterface
virtual ~BaseFunctionUnknownInterface ()=default
 
- Public Member Functions inherited from MoFEM::UnknownInterface
template<class IFACE >
MoFEMErrorCode registerInterface (bool error_if_registration_failed=true)
 Register interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE *&iface) const
 Get interface reference to pointer of interface.
 
template<class IFACE >
MoFEMErrorCode getInterface (IFACE **const iface) const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_pointer< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get interface pointer to pointer of interface.
 
template<class IFACE , typename boost::enable_if< boost::is_reference< IFACE >, int >::type = 0>
IFACE getInterface () const
 Get reference to interface.
 
template<class IFACE >
IFACE * getInterface () const
 Function returning pointer to interface.
 
virtual ~UnknownInterface ()=default
 

Static Public Member Functions

template<int SPACE>
static bool switchCacheBaseFace (FieldApproximationBase base, void *ptr)
 
template<int SPACE>
static bool switchCacheBaseInterior (FieldApproximationBase base, void *ptr)
 
template<int SPACE>
static bool switchCacheBrokenBaseInterior (FieldApproximationBase base, void *ptr)
 
template<int SPACE>
static void switchCacheBaseOn (FieldApproximationBase base, std::vector< void * > v)
 
template<int SPACE>
static void switchCacheBaseOff (FieldApproximationBase base, std::vector< void * > v)
 
template<int SPACE>
static void switchCacheBaseOn (std::vector< void * > v)
 
template<int SPACE>
static void switchCacheBaseOff (std::vector< void * > v)
 
static MoFEMErrorCode setDofsSideMap (const FieldSpace space, const FieldContinuity continuity, const FieldApproximationBase base, DofsSideMap &)
 Set map of dof to side number.
 
template<>
bool switchCacheBaseFace (FieldApproximationBase base, void *ptr)
 
template<>
bool switchCacheBaseInterior (FieldApproximationBase base, void *ptr)
 
template<>
bool switchCacheBrokenBaseInterior (FieldApproximationBase base, void *ptr)
 
template<>
void switchCacheBaseOn (FieldApproximationBase base, std::vector< void * > v)
 
template<>
void switchCacheBaseOff (FieldApproximationBase base, std::vector< void * > v)
 
template<>
void switchCacheBaseOn (std::vector< void * > v)
 
template<>
void switchCacheBaseOff (std::vector< void * > v)
 
template<>
bool switchCacheBaseInterior (FieldApproximationBase base, void *ptr)
 
template<>
void switchCacheBaseOn (FieldApproximationBase base, std::vector< void * > v)
 
template<>
void switchCacheBaseOff (FieldApproximationBase base, std::vector< void * > v)
 
template<>
void switchCacheBaseOn (std::vector< void * > v)
 
template<>
void switchCacheBaseOff (std::vector< void * > v)
 
template<>
bool switchCacheBaseFace (FieldApproximationBase base, void *ptr)
 
template<>
bool switchCacheBaseInterior (FieldApproximationBase base, void *ptr)
 
template<>
bool switchCacheBrokenBaseInterior (FieldApproximationBase base, void *ptr)
 
template<>
void switchCacheBaseOn (FieldApproximationBase base, std::vector< void * > v)
 
template<>
void switchCacheBaseOff (FieldApproximationBase base, std::vector< void * > v)
 
template<>
void switchCacheBaseOn (std::vector< void * > v)
 
template<>
void switchCacheBaseOff (std::vector< void * > v)
 
template<>
bool switchCacheBaseInterior (FieldApproximationBase base, void *ptr)
 
template<>
void switchCacheBaseOn (FieldApproximationBase base, std::vector< void * > v)
 
template<>
void switchCacheBaseOff (FieldApproximationBase base, std::vector< void * > v)
 
template<>
void switchCacheBaseOn (std::vector< void * > v)
 
template<>
void switchCacheBaseOff (std::vector< void * > v)
 
- Static Public Member Functions inherited from MoFEM::UnknownInterface
static MoFEMErrorCode getLibVersion (Version &version)
 Get library version.
 
static MoFEMErrorCode getFileVersion (moab::Interface &moab, Version &version)
 Get database major version.
 
static MoFEMErrorCode setFileVersion (moab::Interface &moab, Version version=Version(MoFEM_VERSION_MAJOR, MoFEM_VERSION_MINOR, MoFEM_VERSION_BUILD))
 Get database major version.
 
static MoFEMErrorCode getInterfaceVersion (Version &version)
 Get database major version.
 

Protected Member Functions

MoFEMErrorCode getValueH1 (MatrixDouble &pts)
 Get base functions for H1 space.
 
MoFEMErrorCode getValueL2 (MatrixDouble &pts)
 Get base functions for L2 space.
 
MoFEMErrorCode getValueHdiv (MatrixDouble &pts)
 Get base functions for Hdiv space.
 
MoFEMErrorCode getValueHcurl (MatrixDouble &pts)
 Get base functions for Hcurl space.
 
MoFEMErrorCode getValueH1AinsworthBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueH1BernsteinBezierBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueL2AinsworthBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueL2BernsteinBezierBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHdivAinsworthBaseImpl (MatrixDouble &pts, MatrixDouble &shape_functions, MatrixDouble &diff_shape_functions, int volume_order, std::array< int, 4 > &faces_order, std::array< int, 3 *4 > &faces_nodes, boost::function< int(int)> broken_nbfacetri_edge_hdiv, boost::function< int(int)> broken_nbfacetri_face_hdiv, boost::function< int(int)> broken_nbvolumetet_edge_hdiv, boost::function< int(int)> broken_nbvolumetet_face_hdiv, boost::function< int(int)> broken_nbvolumetet_volume_hdiv)
 
MoFEMErrorCode getValueHdivAinsworthBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHdivAinsworthBrokenBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHcurlAinsworthBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHdivDemkowiczBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHdivDemkowiczBrokenBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHcurlDemkowiczBase (MatrixDouble &pts)
 

Static Protected Member Functions

static MoFEMErrorCode setDofsSideMapHdiv (const FieldContinuity continuity, const FieldApproximationBase base, DofsSideMap &dofs_side_map)
 Set the Dofs Side Map Hdiv object.
 

Protected Attributes

const void * vPtr
 
EntPolynomialBaseCtx * cTx
 
MatrixInt senseFaceAlpha
 
ublas::matrix< MatrixDouble > N_face_edge
 
ublas::vector< MatrixDouble > N_face_bubble
 
ublas::vector< MatrixDouble > N_volume_edge
 
ublas::vector< MatrixDouble > N_volume_face
 
MatrixDouble N_volume_bubble
 
ublas::matrix< MatrixDouble > diffN_face_edge
 
ublas::vector< MatrixDouble > diffN_face_bubble
 
ublas::vector< MatrixDouble > diffN_volume_edge
 
ublas::vector< MatrixDouble > diffN_volume_face
 
MatrixDouble diffN_volume_bubble
 

Additional Inherited Members

- Public Types inherited from MoFEM::BaseFunction
using DofsSideMap = multi_index_container< DofsSideMapData, indexed_by< ordered_non_unique< tag< TypeSide_mi_tag >, composite_key< DofsSideMapData, member< DofsSideMapData, EntityType, &DofsSideMapData::type >, member< DofsSideMapData, int, &DofsSideMapData::side > > >, ordered_unique< tag< EntDofIdx_mi_tag >, member< DofsSideMapData, int, &DofsSideMapData::dof > > > >
 Map entity stype and side to element/entity dof index.
 

Detailed Description

Calculate base functions on tetrahedral.

Definition at line 17 of file TetPolynomialBase.hpp.

Constructor & Destructor Documentation

◆ TetPolynomialBase()

TetPolynomialBase::TetPolynomialBase ( const void *  ptr = nullptr)

Definition at line 95 of file TetPolynomialBase.cpp.

95: vPtr(ptr) {}

◆ ~TetPolynomialBase()

TetPolynomialBase::~TetPolynomialBase ( )
virtual

Definition at line 97 of file TetPolynomialBase.cpp.

97 {
98 if (vPtr) {
99
100 auto erase = [&](auto cache) {
101 if (cache.find(vPtr) != cache.end())
102 cache.erase(vPtr);
103 };
104
105 for (auto b = 0; b != LASTBASE; ++b) {
109 }
110 }
111}
@ LASTBASE
Definition definitions.h:69
static std::array< std::map< const void *, BaseCacheMI >, LASTBASE > hdivBaseInterior
static std::array< std::map< const void *, HDivBaseFaceCacheMI >, LASTBASE > hDivBaseFace
static std::array< std::map< const void *, BaseCacheMI >, LASTBASE > hdivBrokenBaseInterior

Member Function Documentation

◆ getValue()

MoFEMErrorCode TetPolynomialBase::getValue ( MatrixDouble &  pts,
boost::shared_ptr< BaseFunctionCtx >  ctx_ptr 
)
virtual

Reimplemented from MoFEM::BaseFunction.

Definition at line 2055 of file TetPolynomialBase.cpp.

2056 {
2058
2060
2061 int nb_gauss_pts = pts.size2();
2062 if (!nb_gauss_pts)
2064
2065 if (pts.size1() < 3)
2066 SETERRQ(
2067 PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2068 "Wrong dimension of pts, should be at least 3 rows with coordinates");
2069
2071 const FieldApproximationBase base = cTx->bAse;
2072 EntitiesFieldData &data = cTx->dAta;
2073 if (cTx->copyNodeBase == LASTBASE) {
2074 data.dataOnEntities[MBVERTEX][0].getN(base).resize(nb_gauss_pts, 4,
2075 false);
2077 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
2078 &pts(0, 0), &pts(1, 0), &pts(2, 0), nb_gauss_pts);
2079 } else {
2080 data.dataOnEntities[MBVERTEX][0].getN(base) =
2081 data.dataOnEntities[MBVERTEX][0].getN(cTx->copyNodeBase);
2082 }
2083 if (data.dataOnEntities[MBVERTEX][0].getN(base).size1() !=
2084 (unsigned int)nb_gauss_pts) {
2085 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2086 "Base functions or nodes has wrong number of integration points "
2087 "for base %s",
2089 }
2090 data.dataOnEntities[MBVERTEX][0].getDiffN(base).resize(4, 3, false);
2091 std::copy(Tools::diffShapeFunMBTET.begin(), Tools::diffShapeFunMBTET.end(),
2092 data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin());
2093 }
2094
2095 switch (cTx->spaceContinuity) {
2096 case CONTINUOUS:
2097
2098 switch (cTx->sPace) {
2099 case H1:
2100 CHKERR getValueH1(pts);
2101 break;
2102 case HDIV:
2103 CHKERR getValueHdiv(pts);
2104 break;
2105 case HCURL:
2106 CHKERR getValueHcurl(pts);
2107 break;
2108 case L2:
2109 CHKERR getValueL2(pts);
2110 break;
2111 default:
2112 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown space %s",
2114 }
2115 break;
2116
2117 case DISCONTINUOUS:
2118
2119 switch (cTx->sPace) {
2120 case HDIV:
2121 CHKERR getValueHdiv(pts);
2122 break;
2123 default:
2124 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown space %s",
2126 }
2127 break;
2128
2129 default:
2130 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown continuity");
2131 }
2132
2134}
FieldApproximationBase
approximation base
Definition definitions.h:58
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
Definition definitions.h:64
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
Definition definitions.h:88
@ H1
continuous field
Definition definitions.h:85
@ HCURL
field with continuous tangents
Definition definitions.h:86
@ HDIV
field with continuous normal traction
Definition definitions.h:87
@ CONTINUOUS
Regular field.
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
static const char *const FieldSpaceNames[]
Definition definitions.h:92
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
static const char *const ApproximationBaseNames[]
Definition definitions.h:72
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
Class used to pass element data to calculate base functions on tet,triangle,edge.
const FieldApproximationBase copyNodeBase
const FieldContinuity spaceContinuity
const FieldApproximationBase bAse
data structure for finite element entity
std::array< boost::ptr_vector< EntData >, MBMAXTYPE > dataOnEntities
EntPolynomialBaseCtx * cTx
MoFEMErrorCode getValueHcurl(MatrixDouble &pts)
Get base functions for Hcurl space.
MoFEMErrorCode getValueH1(MatrixDouble &pts)
Get base functions for H1 space.
MoFEMErrorCode getValueHdiv(MatrixDouble &pts)
Get base functions for Hdiv space.
MoFEMErrorCode getValueL2(MatrixDouble &pts)
Get base functions for L2 space.
static MoFEMErrorCode shapeFunMBTET(double *shape, const double *ksi, const double *eta, const double *zeta, const double nb)
Calculate shape functions on tetrahedron.
Definition Tools.hpp:759
static constexpr std::array< double, 12 > diffShapeFunMBTET
Definition Tools.hpp:271
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ getValueH1()

MoFEMErrorCode TetPolynomialBase::getValueH1 ( MatrixDouble &  pts)
protected

Get base functions for H1 space.

Parameters
ptsmatrix of integration pts
Returns
MoFEMErrorCode
Note
matrix of integration points on rows has local coordinates of finite element on columns are integration pts.

Definition at line 113 of file TetPolynomialBase.cpp.

113 {
115
116 switch (cTx->bAse) {
120 break;
123 break;
124 default:
125 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
126 }
127
129}
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ AINSWORTH_LOBATTO_BASE
Definition definitions.h:62
MoFEMErrorCode getValueH1AinsworthBase(MatrixDouble &pts)
MoFEMErrorCode getValueH1BernsteinBezierBase(MatrixDouble &pts)

◆ getValueH1AinsworthBase()

MoFEMErrorCode TetPolynomialBase::getValueH1AinsworthBase ( MatrixDouble &  pts)
protected

Definition at line 131 of file TetPolynomialBase.cpp.

131 {
133
134 EntitiesFieldData &data = cTx->dAta;
135 const FieldApproximationBase base = cTx->bAse;
136 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
137 double *diffL, const int dim) =
139
140 int nb_gauss_pts = pts.size2();
141
142 int sense[6], order[6];
143 if (data.spacesOnEntities[MBEDGE].test(H1)) {
144 // edges
145 if (data.dataOnEntities[MBEDGE].size() != 6) {
146 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
147 }
148 double *h1_edge_n[6], *diff_h1_egde_n[6];
149 for (int ee = 0; ee != 6; ++ee) {
150 if (data.dataOnEntities[MBEDGE][ee].getSense() == 0) {
151 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
152 "data inconsistency");
153 }
154 sense[ee] = data.dataOnEntities[MBEDGE][ee].getSense();
155 order[ee] = data.dataOnEntities[MBEDGE][ee].getOrder();
156 int nb_dofs = NBEDGE_H1(data.dataOnEntities[MBEDGE][ee].getOrder());
157 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, nb_dofs,
158 false);
159 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
160 3 * nb_dofs, false);
161 h1_edge_n[ee] =
162 &*data.dataOnEntities[MBEDGE][ee].getN(base).data().begin();
163 diff_h1_egde_n[ee] =
164 &*data.dataOnEntities[MBEDGE][ee].getDiffN(base).data().begin();
165 }
167 sense, order,
168 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
169 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
170 h1_edge_n, diff_h1_egde_n, nb_gauss_pts, base_polynomials);
171 } else {
172 for (int ee = 0; ee != 6; ++ee) {
173 data.dataOnEntities[MBEDGE][ee].getN(base).resize(0, 0, false);
174 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(0, 0, false);
175 }
176 }
177
178 if (data.spacesOnEntities[MBTRI].test(H1)) {
179 // faces
180 if (data.dataOnEntities[MBTRI].size() != 4) {
181 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
182 }
183 double *h1_face_n[4], *diff_h1_face_n[4];
184 for (int ff = 0; ff != 4; ++ff) {
185 if (data.dataOnEntities[MBTRI][ff].getSense() == 0) {
186 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
187 "data inconsistency");
188 }
189 int nb_dofs = NBFACETRI_H1(data.dataOnEntities[MBTRI][ff].getOrder());
190 order[ff] = data.dataOnEntities[MBTRI][ff].getOrder();
191 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts, nb_dofs,
192 false);
193 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
194 3 * nb_dofs, false);
195 h1_face_n[ff] =
196 &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
197 diff_h1_face_n[ff] =
198 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
199 }
200 if (data.facesNodes.size1() != 4) {
201 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
202 }
203 if (data.facesNodes.size2() != 3) {
204 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
205 }
207 &*data.facesNodes.data().begin(), order,
208 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
209 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
210 h1_face_n, diff_h1_face_n, nb_gauss_pts, base_polynomials);
211
212 } else {
213 for (int ff = 0; ff != 4; ++ff) {
214 data.dataOnEntities[MBTRI][ff].getN(base).resize(0, false);
215 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(0, 0, false);
216 }
217 }
218
219 if (data.spacesOnEntities[MBTET].test(H1)) {
220 // volume
221 int order = data.dataOnEntities[MBTET][0].getOrder();
222 int nb_vol_dofs = NBVOLUMETET_H1(order);
223 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, nb_vol_dofs,
224 false);
225 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
226 3 * nb_vol_dofs, false);
228 data.dataOnEntities[MBTET][0].getOrder(),
229 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
230 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
231 &*data.dataOnEntities[MBTET][0].getN(base).data().begin(),
232 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin(),
233 nb_gauss_pts, base_polynomials);
234 } else {
235 data.dataOnEntities[MBTET][0].getN(base).resize(0, 0, false);
236 data.dataOnEntities[MBTET][0].getDiffN(base).resize(0, 0, false);
237 }
238
240}
constexpr int order
#define NBVOLUMETET_H1(P)
Number of base functions on tetrahedron for H1 space.
PetscErrorCode H1_EdgeShapeFunctions_MBTET(int *sense, int *p, double *N, double *diffN, double *edgeN[], double *diff_edgeN[], int GDIM, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Definition h1.c:274
#define NBEDGE_H1(P)
Number of base function on edge for H1 space.
PetscErrorCode H1_VolumeShapeFunctions_MBTET(int p, double *N, double *diffN, double *volumeN, double *diff_volumeN, int GDIM, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Definition h1.c:475
PetscErrorCode H1_FaceShapeFunctions_MBTET(int *faces_nodes, int *p, double *N, double *diffN, double *faceN[], double *diff_faceN[], int GDIM, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Definition h1.c:373
#define NBFACETRI_H1(P)
Number of base function on triangle for H1 space.
PetscErrorCode(* basePolynomialsType0)(int p, double s, double *diff_s, double *L, double *diffL, const int dim)

◆ getValueH1BernsteinBezierBase()

MoFEMErrorCode TetPolynomialBase::getValueH1BernsteinBezierBase ( MatrixDouble &  pts)
protected

Definition at line 243 of file TetPolynomialBase.cpp.

243 {
245
246 EntitiesFieldData &data = cTx->dAta;
247 const std::string field_name = cTx->fieldName;
248 const int nb_gauss_pts = pts.size2();
249
250 if (data.dataOnEntities[MBVERTEX][0].getN(NOBASE).size1() !=
251 (unsigned int)nb_gauss_pts)
252 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
253 "Base functions or nodes has wrong number of integration points "
254 "for base %s",
256 auto &lambda = data.dataOnEntities[MBVERTEX][0].getN(NOBASE);
257
258 auto get_alpha = [field_name](auto &data) -> MatrixInt & {
259 auto &ptr = data.getBBAlphaIndicesSharedPtr(field_name);
260 if (!ptr)
261 ptr.reset(new MatrixInt());
262 return *ptr;
263 };
264
265 auto get_base = [field_name](auto &data) -> MatrixDouble & {
266 auto &ptr = data.getBBNSharedPtr(field_name);
267 if (!ptr)
268 ptr.reset(new MatrixDouble());
269 return *ptr;
270 };
271
272 auto get_diff_base = [field_name](auto &data) -> MatrixDouble & {
273 auto &ptr = data.getBBDiffNSharedPtr(field_name);
274 if (!ptr)
275 ptr.reset(new MatrixDouble());
276 return *ptr;
277 };
278
279 auto get_alpha_by_name_ptr =
280 [](auto &data,
281 const std::string &field_name) -> boost::shared_ptr<MatrixInt> & {
282 return data.getBBAlphaIndicesSharedPtr(field_name);
283 };
284
285 auto get_base_by_name_ptr =
286 [](auto &data,
287 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
288 return data.getBBNSharedPtr(field_name);
289 };
290
291 auto get_diff_base_by_name_ptr =
292 [](auto &data,
293 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
294 return data.getBBDiffNSharedPtr(field_name);
295 };
296
297 auto get_alpha_by_order_ptr =
298 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixInt> & {
299 return data.getBBAlphaIndicesByOrderSharedPtr(o);
300 };
301
302 auto get_base_by_order_ptr =
303 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
304 return data.getBBNByOrderSharedPtr(o);
305 };
306
307 auto get_diff_base_by_order_ptr =
308 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
309 return data.getBBDiffNByOrderSharedPtr(o);
310 };
311
312 auto &vert_ent_data = data.dataOnEntities[MBVERTEX][0];
313 auto &vertex_alpha = get_alpha(vert_ent_data);
314 vertex_alpha.resize(4, 4, false);
315 vertex_alpha.clear();
316 for (int n = 0; n != 4; ++n)
317 vertex_alpha(n, n) = data.dataOnEntities[MBVERTEX][0].getBBNodeOrder()[n];
318
319 auto &vert_get_n = get_base(vert_ent_data);
320 auto &vert_get_diff_n = get_diff_base(vert_ent_data);
321 vert_get_n.resize(nb_gauss_pts, 4, false);
322 vert_get_diff_n.resize(nb_gauss_pts, 12, false);
324 1, lambda.size1(), vertex_alpha.size1(), &vertex_alpha(0, 0),
325 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &vert_get_n(0, 0),
326 &vert_get_diff_n(0, 0));
327 for (int n = 0; n != 4; ++n) {
328 const double f = boost::math::factorial<double>(
329 data.dataOnEntities[MBVERTEX][0].getBBNodeOrder()[n]);
330 for (int g = 0; g != nb_gauss_pts; ++g) {
331 vert_get_n(g, n) *= f;
332 for (int d = 0; d != 3; ++d)
333 vert_get_diff_n(g, 3 * n + d) *= f;
334 }
335 }
336
337 // edges
338 if (data.spacesOnEntities[MBEDGE].test(H1)) {
339 if (data.dataOnEntities[MBEDGE].size() != 6)
340 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
341 "Wrong size of ent data");
342
343 constexpr int edges_nodes[6][2] = {{0, 1}, {1, 2}, {2, 0},
344 {0, 3}, {1, 3}, {2, 3}};
345 for (int ee = 0; ee != 6; ++ee) {
346 auto &ent_data = data.dataOnEntities[MBEDGE][ee];
347 const int sense = ent_data.getSense();
348 if (sense == 0)
349 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
350 "Sense of the edge unknown");
351 const int order = ent_data.getOrder();
352 const int nb_dofs = NBEDGE_H1(order);
353
354 if (nb_dofs) {
355 if (get_alpha_by_order_ptr(ent_data, order)) {
356 get_alpha_by_name_ptr(ent_data, field_name) =
357 get_alpha_by_order_ptr(ent_data, order);
358 get_base_by_name_ptr(ent_data, field_name) =
359 get_base_by_order_ptr(ent_data, order);
360 get_diff_base_by_name_ptr(ent_data, field_name) =
361 get_diff_base_by_order_ptr(ent_data, order);
362 } else {
363 auto &get_n = get_base(ent_data);
364 auto &get_diff_n = get_diff_base(ent_data);
365 get_n.resize(nb_gauss_pts, nb_dofs, false);
366 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs, false);
367
368 auto &edge_alpha = get_alpha(data.dataOnEntities[MBEDGE][ee]);
369 edge_alpha.resize(nb_dofs, 4, false);
371 &edge_alpha(0, 0));
372 if (sense == -1) {
373 for (int i = 0; i != edge_alpha.size1(); ++i) {
374 int a = edge_alpha(i, edges_nodes[ee][0]);
375 edge_alpha(i, edges_nodes[ee][0]) =
376 edge_alpha(i, edges_nodes[ee][1]);
377 edge_alpha(i, edges_nodes[ee][1]) = a;
378 }
379 }
381 order, lambda.size1(), edge_alpha.size1(), &edge_alpha(0, 0),
382 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &get_n(0, 0),
383 &get_diff_n(0, 0));
384
385 get_alpha_by_order_ptr(ent_data, order) =
386 get_alpha_by_name_ptr(ent_data, field_name);
387 get_base_by_order_ptr(ent_data, order) =
388 get_base_by_name_ptr(ent_data, field_name);
389 get_diff_base_by_order_ptr(ent_data, order) =
390 get_diff_base_by_name_ptr(ent_data, field_name);
391 }
392 }
393 }
394 } else {
395 for (int ee = 0; ee != 6; ++ee) {
396 auto &ent_data = data.dataOnEntities[MBEDGE][ee];
397 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
398 auto &get_n = get_base(ent_data);
399 auto &get_diff_n = get_diff_base(ent_data);
400 get_n.resize(nb_gauss_pts, 0, false);
401 get_diff_n.resize(nb_gauss_pts, 0, false);
402 }
403 }
404
405 // face
406 if (data.spacesOnEntities[MBTRI].test(H1)) {
407 if (data.dataOnEntities[MBTRI].size() != 4)
408 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
409 "Wrong size of ent data");
410 if (data.facesNodes.size1() != 4)
411 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
412 if (data.facesNodes.size2() != 3)
413 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
414
415 for (int ff = 0; ff != 4; ++ff) {
416 auto &ent_data = data.dataOnEntities[MBTRI][ff];
417 const int order = ent_data.getOrder();
418 const int nb_dofs = NBFACETRI_H1(order);
419
420 if (nb_dofs) {
421 if (get_alpha_by_order_ptr(ent_data, order)) {
422 get_alpha_by_name_ptr(ent_data, field_name) =
423 get_alpha_by_order_ptr(ent_data, order);
424 get_base_by_name_ptr(ent_data, field_name) =
425 get_base_by_order_ptr(ent_data, order);
426 get_diff_base_by_name_ptr(ent_data, field_name) =
427 get_diff_base_by_order_ptr(ent_data, order);
428 } else {
429
430 auto &get_n = get_base(ent_data);
431 auto &get_diff_n = get_diff_base(ent_data);
432 get_n.resize(nb_gauss_pts, nb_dofs, false);
433 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs, false);
434
435 auto &face_alpha = get_alpha(ent_data);
436 face_alpha.resize(nb_dofs, 4, false);
437
439 &face_alpha(0, 0));
440 senseFaceAlpha.resize(face_alpha.size1(), face_alpha.size2(), false);
441 senseFaceAlpha.clear();
442 constexpr int tri_nodes[4][3] = {
443 {0, 1, 3}, {1, 2, 3}, {0, 2, 3}, {0, 1, 2}};
444 for (int d = 0; d != nb_dofs; ++d)
445 for (int n = 0; n != 3; ++n)
446 senseFaceAlpha(d, data.facesNodes(ff, n)) =
447 face_alpha(d, tri_nodes[ff][n]);
448 face_alpha.swap(senseFaceAlpha);
450 order, lambda.size1(), face_alpha.size1(), &face_alpha(0, 0),
451 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &get_n(0, 0),
452 &get_diff_n(0, 0));
453
454 get_alpha_by_order_ptr(ent_data, order) =
455 get_alpha_by_name_ptr(ent_data, field_name);
456 get_base_by_order_ptr(ent_data, order) =
457 get_base_by_name_ptr(ent_data, field_name);
458 get_diff_base_by_order_ptr(ent_data, order) =
459 get_diff_base_by_name_ptr(ent_data, field_name);
460 }
461 }
462 }
463 } else {
464 for (int ff = 0; ff != 4; ++ff) {
465 auto &ent_data = data.dataOnEntities[MBTRI][ff];
466 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
467 auto &get_n = get_base(ent_data);
468 auto &get_diff_n = get_diff_base(ent_data);
469 get_n.resize(nb_gauss_pts, 0, false);
470 get_diff_n.resize(nb_gauss_pts, 0, false);
471 }
472 }
473
474 if (data.spacesOnEntities[MBTET].test(H1)) {
475 if (data.dataOnEntities[MBTET].size() != 1)
476 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
477 "Wrong size ent of ent data");
478
479 auto &ent_data = data.dataOnEntities[MBTET][0];
480 const int order = ent_data.getOrder();
481 const int nb_dofs = NBVOLUMETET_H1(order);
482 if (get_alpha_by_order_ptr(ent_data, order)) {
483 get_alpha_by_name_ptr(ent_data, field_name) =
484 get_alpha_by_order_ptr(ent_data, order);
485 get_base_by_name_ptr(ent_data, field_name) =
486 get_base_by_order_ptr(ent_data, order);
487 get_diff_base_by_name_ptr(ent_data, field_name) =
488 get_diff_base_by_order_ptr(ent_data, order);
489 } else {
490
491 auto &get_n = get_base(ent_data);
492 auto &get_diff_n = get_diff_base(ent_data);
493 get_n.resize(nb_gauss_pts, nb_dofs, false);
494 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs, false);
495 if (nb_dofs) {
496 auto &tet_alpha = get_alpha(ent_data);
497 tet_alpha.resize(nb_dofs, 4, false);
498
501 order, lambda.size1(), tet_alpha.size1(), &tet_alpha(0, 0),
502 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &get_n(0, 0),
503 &get_diff_n(0, 0));
504
505 get_alpha_by_order_ptr(ent_data, order) =
506 get_alpha_by_name_ptr(ent_data, field_name);
507 get_base_by_order_ptr(ent_data, order) =
508 get_base_by_name_ptr(ent_data, field_name);
509 get_diff_base_by_order_ptr(ent_data, order) =
510 get_diff_base_by_name_ptr(ent_data, field_name);
511 }
512 }
513 } else {
514 auto &ent_data = data.dataOnEntities[MBTET][0];
515 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
516 auto &get_n = get_base(ent_data);
517 auto &get_diff_n = get_diff_base(ent_data);
518 get_n.resize(nb_gauss_pts, 0, false);
519 get_diff_n.resize(nb_gauss_pts, 0, false);
520 }
521
523}
constexpr double a
@ NOBASE
Definition definitions.h:59
FTensor::Index< 'i', SPACE_DIM > i
static double lambda
const double n
refractive index of diffusive medium
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
UBlasMatrix< int > MatrixInt
Definition Types.hpp:76
constexpr auto field_name
constexpr double g
static MoFEMErrorCode generateIndicesTriTet(const int N[], int *alpha[])
static MoFEMErrorCode baseFunctionsTet(const int N, const int gdim, const int n_alpha, const int *alpha, const double *lambda, const double *grad_lambda, double *base, double *grad_base)
static MoFEMErrorCode generateIndicesEdgeTet(const int N[], int *alpha[])
static MoFEMErrorCode generateIndicesTetTet(const int N, int *alpha)
MatrixInt facesNodes
nodes on finite element faces
std::array< std::bitset< LASTSPACE >, MBMAXTYPE > spacesOnEntities
spaces on entity types

◆ getValueHcurl()

MoFEMErrorCode TetPolynomialBase::getValueHcurl ( MatrixDouble &  pts)
protected

Get base functions for Hcurl space.

Parameters
ptsmatrix of integration pts
Returns
MoFEMErrorCode
Note
matrix of integration points on rows has local coordinates of finite element on columns are integration pts.

Definition at line 2036 of file TetPolynomialBase.cpp.

2036 {
2038
2039 switch (cTx->bAse) {
2043 break;
2046 break;
2047 default:
2048 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
2049 }
2050
2052}
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
MoFEMErrorCode getValueHcurlDemkowiczBase(MatrixDouble &pts)
MoFEMErrorCode getValueHcurlAinsworthBase(MatrixDouble &pts)

◆ getValueHcurlAinsworthBase()

MoFEMErrorCode TetPolynomialBase::getValueHcurlAinsworthBase ( MatrixDouble &  pts)
protected

Definition at line 1786 of file TetPolynomialBase.cpp.

1786 {
1788
1789 EntitiesFieldData &data = cTx->dAta;
1790 const FieldApproximationBase base = cTx->bAse;
1791 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
1792 double *diffL, const int dim) =
1794
1795 int nb_gauss_pts = pts.size2();
1796
1797 // edges
1798 if (data.spacesOnEntities[MBEDGE].test(HCURL)) {
1799 int sense[6], order[6];
1800 if (data.dataOnEntities[MBEDGE].size() != 6) {
1801 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1802 }
1803 double *hcurl_edge_n[6], *diff_hcurl_edge_n[6];
1804 for (int ee = 0; ee != 6; ee++) {
1805 if (data.dataOnEntities[MBEDGE][ee].getSense() == 0) {
1806 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1807 "data inconsistency");
1808 }
1809 sense[ee] = data.dataOnEntities[MBEDGE][ee].getSense();
1810 order[ee] = data.dataOnEntities[MBEDGE][ee].getOrder();
1811 int nb_dofs =
1812 NBEDGE_AINSWORTH_HCURL(data.dataOnEntities[MBEDGE][ee].getOrder());
1813 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts,
1814 3 * nb_dofs, false);
1815 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
1816 9 * nb_dofs, false);
1817 hcurl_edge_n[ee] =
1818 &*data.dataOnEntities[MBEDGE][ee].getN(base).data().begin();
1819 diff_hcurl_edge_n[ee] =
1820 &*data.dataOnEntities[MBEDGE][ee].getDiffN(base).data().begin();
1821 }
1823 sense, order,
1824 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1825 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1826 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts, base_polynomials);
1827 } else {
1828 for (int ee = 0; ee != 6; ee++) {
1829 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, 0, false);
1830 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts, 0,
1831 false);
1832 }
1833 }
1834
1835 // triangles
1836 if (data.spacesOnEntities[MBTRI].test(HCURL)) {
1837 int order[4];
1838 // faces
1839 if (data.dataOnEntities[MBTRI].size() != 4) {
1840 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1841 }
1842 double *hcurl_base_n[4], *diff_hcurl_base_n[4];
1843 for (int ff = 0; ff != 4; ff++) {
1844 if (data.dataOnEntities[MBTRI][ff].getSense() == 0) {
1845 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1846 "data inconsistency");
1847 }
1848 order[ff] = data.dataOnEntities[MBTRI][ff].getOrder();
1849 int nb_dofs = NBFACETRI_AINSWORTH_HCURL(order[ff]);
1850 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts,
1851 3 * nb_dofs, false);
1852 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1853 9 * nb_dofs, false);
1854 hcurl_base_n[ff] =
1855 &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
1856 diff_hcurl_base_n[ff] =
1857 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
1858 }
1859 if (data.facesNodes.size1() != 4) {
1860 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1861 }
1862 if (data.facesNodes.size2() != 3) {
1863 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1864 }
1866 &*data.facesNodes.data().begin(), order,
1867 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1868 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1869 hcurl_base_n, diff_hcurl_base_n, nb_gauss_pts, base_polynomials);
1870 } else {
1871 for (int ff = 0; ff != 4; ff++) {
1872 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts, 0, false);
1873 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts, 0,
1874 false);
1875 }
1876 }
1877
1878 if (data.spacesOnEntities[MBTET].test(HCURL)) {
1879
1880 // volume
1881 int order = data.dataOnEntities[MBTET][0].getOrder();
1882 int nb_vol_dofs = NBVOLUMETET_AINSWORTH_HCURL(order);
1883 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts,
1884 3 * nb_vol_dofs, false);
1885 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
1886 9 * nb_vol_dofs, false);
1888 data.dataOnEntities[MBTET][0].getOrder(),
1889 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1890 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1891 &*data.dataOnEntities[MBTET][0].getN(base).data().begin(),
1892 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin(),
1893 nb_gauss_pts, base_polynomials);
1894
1895 } else {
1896 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 0, false);
1897 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 0, false);
1898 }
1899
1901}
#define NBVOLUMETET_AINSWORTH_HCURL(P)
#define NBFACETRI_AINSWORTH_HCURL(P)
#define NBEDGE_AINSWORTH_HCURL(P)
MoFEMErrorCode Hcurl_Ainsworth_VolumeFunctions_MBTET(int p, double *N, double *diffN, double *phi_v, double *diff_phi_v, int nb_integration_pts, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
H-curl volume base functions.
Definition Hcurl.cpp:1403
MoFEMErrorCode Hcurl_Ainsworth_EdgeBaseFunctions_MBTET(int *sense, int *p, double *N, double *diffN, double *edgeN[], double *diff_edgeN[], int nb_integration_pts, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Edge based H-curl base functions on tetrahedral.
Definition Hcurl.cpp:16
MoFEMErrorCode Hcurl_Ainsworth_FaceFunctions_MBTET(int *face_nodes, int *p, double *N, double *diffN, double *phi_f[4], double *diff_phi_f[4], int nb_integration_pts, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Face H-curl functions.
Definition Hcurl.cpp:1052

◆ getValueHcurlDemkowiczBase()

MoFEMErrorCode TetPolynomialBase::getValueHcurlDemkowiczBase ( MatrixDouble &  pts)
protected

Definition at line 1904 of file TetPolynomialBase.cpp.

1904 {
1906
1907 EntitiesFieldData &data = cTx->dAta;
1908 const FieldApproximationBase base = cTx->bAse;
1909 if (base != DEMKOWICZ_JACOBI_BASE) {
1910 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1911 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1912 "but base is %s",
1914 }
1915
1916 int nb_gauss_pts = pts.size2();
1917
1918 // edges
1919 if (data.spacesOnEntities[MBEDGE].test(HCURL)) {
1920 int sense[6], order[6];
1921 if (data.dataOnEntities[MBEDGE].size() != 6) {
1922 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1923 "wrong size of data structure, expected space for six edges "
1924 "but is %zu",
1925 data.dataOnEntities[MBEDGE].size());
1926 }
1927 double *hcurl_edge_n[6], *diff_hcurl_edge_n[6];
1928 for (int ee = 0; ee != 6; ee++) {
1929 if (data.dataOnEntities[MBEDGE][ee].getSense() == 0) {
1930 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1931 "orintation of edges is not set");
1932 }
1933 sense[ee] = data.dataOnEntities[MBEDGE][ee].getSense();
1934 order[ee] = data.dataOnEntities[MBEDGE][ee].getOrder();
1935 int nb_dofs =
1936 NBEDGE_DEMKOWICZ_HCURL(data.dataOnEntities[MBEDGE][ee].getOrder());
1937 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts,
1938 3 * nb_dofs, false);
1939 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
1940 9 * nb_dofs, false);
1941 hcurl_edge_n[ee] =
1942 &*data.dataOnEntities[MBEDGE][ee].getN(base).data().begin();
1943 diff_hcurl_edge_n[ee] =
1944 &*data.dataOnEntities[MBEDGE][ee].getDiffN(base).data().begin();
1945 }
1947 sense, order,
1948 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1949 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1950 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts);
1951 } else {
1952 // No DOFs on edges, resize base function matrices, indicating that no
1953 // dofs on them.
1954 for (int ee = 0; ee != 6; ee++) {
1955 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, 0, false);
1956 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts, 0,
1957 false);
1958 }
1959 }
1960
1961 // triangles
1962 if (data.spacesOnEntities[MBTRI].test(HCURL)) {
1963 int order[4];
1964 // faces
1965 if (data.dataOnEntities[MBTRI].size() != 4) {
1966 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1967 "data structure for storing face h-curl base have wrong size "
1968 "should be four but is %zu",
1969 data.dataOnEntities[MBTRI].size());
1970 }
1971 double *hcurl_base_n[4], *diff_hcurl_base_n[4];
1972 for (int ff = 0; ff != 4; ff++) {
1973 if (data.dataOnEntities[MBTRI][ff].getSense() == 0) {
1974 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1975 "orintation of face is not set");
1976 }
1977 order[ff] = data.dataOnEntities[MBTRI][ff].getOrder();
1978 int nb_dofs = NBFACETRI_DEMKOWICZ_HCURL(order[ff]);
1979 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts,
1980 3 * nb_dofs, false);
1981 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1982 9 * nb_dofs, false);
1983 hcurl_base_n[ff] =
1984 &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
1985 diff_hcurl_base_n[ff] =
1986 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
1987 }
1988 if (data.facesNodes.size1() != 4) {
1989 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1990 "data inconsistency, should be four faces");
1991 }
1992 if (data.facesNodes.size2() != 3) {
1993 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1994 "data inconsistency, should be three nodes on face");
1995 }
1997 &*data.facesNodes.data().begin(), order,
1998 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1999 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2000 hcurl_base_n, diff_hcurl_base_n, nb_gauss_pts);
2001 } else {
2002 // No DOFs on faces, resize base function matrices, indicating that no
2003 // dofs on them.
2004 for (int ff = 0; ff != 4; ff++) {
2005 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts, 0, false);
2006 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts, 0,
2007 false);
2008 }
2009 }
2010
2011 if (data.spacesOnEntities[MBTET].test(HCURL)) {
2012 // volume
2013 int order = data.dataOnEntities[MBTET][0].getOrder();
2014 int nb_vol_dofs = NBVOLUMETET_DEMKOWICZ_HCURL(order);
2015 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts,
2016 3 * nb_vol_dofs, false);
2017 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
2018 9 * nb_vol_dofs, false);
2020 data.dataOnEntities[MBTET][0].getOrder(),
2021 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
2022 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2023 &*data.dataOnEntities[MBTET][0].getN(base).data().begin(),
2024 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin(),
2025 nb_gauss_pts);
2026 } else {
2027 // No DOFs on faces, resize base function matrices, indicating that no
2028 // dofs on them.
2029 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 0, false);
2030 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 0, false);
2031 }
2032
2034}
#define NBEDGE_DEMKOWICZ_HCURL(P)
#define NBVOLUMETET_DEMKOWICZ_HCURL(P)
#define NBFACETRI_DEMKOWICZ_HCURL(P)
MoFEMErrorCode Hcurl_Demkowicz_FaceBaseFunctions_MBTET(int *faces_nodes, int *p, double *n, double *diff_n, double *phi[], double *diff_phi[], int nb_integration_pts)
Face base interior function.
Definition Hcurl.cpp:2402
MoFEMErrorCode Hcurl_Demkowicz_VolumeBaseFunctions_MBTET(int p, double *n, double *diff_n, double *phi, double *diff_phi, int nb_integration_pts)
Volume base interior function.
Definition Hcurl.cpp:2475
MoFEMErrorCode Hcurl_Demkowicz_EdgeBaseFunctions_MBTET(int *sense, int *p, double *n, double *diff_n, double *phi[], double *diff_phi[], int nb_integration_pts)
Edge based H-curl base functions on tetrahedral.
Definition Hcurl.cpp:2079

◆ getValueHdiv()

MoFEMErrorCode TetPolynomialBase::getValueHdiv ( MatrixDouble &  pts)
protected

Get base functions for Hdiv space.

Parameters
ptsmatrix of integration pts
Returns
MoFEMErrorCode
Note
matrix of integration points on rows has local coordinates of finite element on columns are integration pts.

Definition at line 1751 of file TetPolynomialBase.cpp.

1751 {
1753
1754 switch (cTx->spaceContinuity) {
1755 case CONTINUOUS:
1756 switch (cTx->bAse) {
1762 default:
1763 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
1764 }
1765 break;
1766 case DISCONTINUOUS:
1767 switch (cTx->bAse) {
1773 default:
1774 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
1775 }
1776 break;
1777
1778 default:
1779 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown continuity");
1780 }
1781
1783}
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
MoFEMErrorCode getValueHdivAinsworthBrokenBase(MatrixDouble &pts)
MoFEMErrorCode getValueHdivAinsworthBase(MatrixDouble &pts)
MoFEMErrorCode getValueHdivDemkowiczBase(MatrixDouble &pts)
MoFEMErrorCode getValueHdivDemkowiczBrokenBase(MatrixDouble &pts)

◆ getValueHdivAinsworthBase()

MoFEMErrorCode TetPolynomialBase::getValueHdivAinsworthBase ( MatrixDouble &  pts)
protected

Definition at line 909 of file TetPolynomialBase.cpp.

909 {
911
912 std::array<int, 4> faces_order;
913 std::array<int, 4 * 3> faces_nodes;
914
916 EntitiesFieldData &data = cTx->dAta;
917
918 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
919 std::copy(data.facesNodes.data().begin(), data.facesNodes.data().end(),
920 faces_nodes.begin());
921 for (int ff = 0; ff != 4; ff++) {
922 faces_order[ff] = cTx->dAta.dataOnEntities[MBTRI][ff].getOrder();
923 }
924
926 pts, data.dataOnEntities[MBVERTEX][0].getN(base),
927 data.dataOnEntities[MBVERTEX][0].getDiffN(base), volume_order,
928 faces_order, faces_nodes,
929
935
936 );
937
938 // Set shape functions into data structure Shape functions hast to be put
939 // in arrays in order which guarantee hierarchical series of degrees of
940 // freedom, i.e. in other words dofs form sub-entities has to be group
941 // by order.
942
943 FTENSOR_INDEX(3, i);
944 FTENSOR_INDEX(3, j);
945
946 int nb_gauss_pts = pts.size2();
947
948 // faces
949 if (data.dataOnEntities[MBTRI].size() != 4) {
950 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
951 }
952
953 // face-face
954 using Tensor1Ptr3 =
955 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
956 Tensor1Ptr3 t_base_f_f[] = {
957 getFTensor1FromPtr<3>(&*(N_face_bubble[0].data().begin())),
958 getFTensor1FromPtr<3>(&*(N_face_bubble[1].data().begin())),
959 getFTensor1FromPtr<3>(&*(N_face_bubble[2].data().begin())),
960 getFTensor1FromPtr<3>(&*(N_face_bubble[3].data().begin()))};
961 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_f_f[] = {
962 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_bubble[0].data().begin())),
963 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_bubble[1].data().begin())),
964 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_bubble[2].data().begin())),
965 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_bubble[3].data().begin()))};
966 // face-edge
967 Tensor1Ptr3 t_base_f_e[] = {
968 getFTensor1FromPtr<3>(&*(N_face_edge(0, 0).data().begin())),
969 getFTensor1FromPtr<3>(&*(N_face_edge(0, 1).data().begin())),
970 getFTensor1FromPtr<3>(&*(N_face_edge(0, 2).data().begin())),
971 getFTensor1FromPtr<3>(&*(N_face_edge(1, 0).data().begin())),
972 getFTensor1FromPtr<3>(&*(N_face_edge(1, 1).data().begin())),
973 getFTensor1FromPtr<3>(&*(N_face_edge(1, 2).data().begin())),
974 getFTensor1FromPtr<3>(&*(N_face_edge(2, 0).data().begin())),
975 getFTensor1FromPtr<3>(&*(N_face_edge(2, 1).data().begin())),
976 getFTensor1FromPtr<3>(&*(N_face_edge(2, 2).data().begin())),
977 getFTensor1FromPtr<3>(&*(N_face_edge(3, 0).data().begin())),
978 getFTensor1FromPtr<3>(&*(N_face_edge(3, 1).data().begin())),
979 getFTensor1FromPtr<3>(&*(N_face_edge(3, 2).data().begin()))};
980 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_f_e[] = {
981 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(0, 0).data().begin())),
982 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(0, 1).data().begin())),
983 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(0, 2).data().begin())),
984 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(1, 0).data().begin())),
985 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(1, 1).data().begin())),
986 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(1, 2).data().begin())),
987 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(2, 0).data().begin())),
988 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(2, 1).data().begin())),
989 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(2, 2).data().begin())),
990 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(3, 0).data().begin())),
991 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(3, 1).data().begin())),
992 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(3, 2).data().begin()))};
993
994 for (int ff = 0; ff != 4; ff++) {
995 int face_order = faces_order[ff];
996 auto face_dofs =
1001 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts,
1002 3 * face_dofs, false);
1003 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1004 9 * face_dofs, false);
1005 if (face_dofs) {
1006 double *base_ptr =
1007 &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
1008 double *diff_base_ptr =
1009 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
1010 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1011 auto t_diff_base = getFTensor2HVecFromPtr<3, 3>(diff_base_ptr);
1012
1013 auto max_face_order =
1014 std::max(face_order,
1016 max_face_order =
1017 std::max(max_face_order,
1019
1020 for (int gg = 0; gg != nb_gauss_pts; gg++) {
1021 for (int oo = 0; oo != max_face_order; oo++) {
1022
1023 // face-edge
1025 for (int dd = NBFACETRI_AINSWORTH_EDGE_HDIV(oo);
1026 dd != NBFACETRI_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
1027 for (int ee = 0; ee != 3; ++ee) {
1028 t_base(i) = t_base_f_e[ff * 3 + ee](i);
1029 ++t_base;
1030 ++t_base_f_e[ff * 3 + ee];
1031 }
1032 for (int ee = 0; ee != 3; ++ee) {
1033 t_diff_base(i, j) = t_diff_base_f_e[ff * 3 + ee](i, j);
1034 ++t_diff_base;
1035 ++t_diff_base_f_e[ff * 3 + ee];
1036 }
1037 }
1038
1039 // face-face
1041 for (int dd = NBFACETRI_AINSWORTH_FACE_HDIV(oo);
1042 dd != NBFACETRI_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
1043 t_base(i) = t_base_f_f[ff](i);
1044 ++t_base;
1045 ++t_base_f_f[ff];
1046 t_diff_base(i, j) = t_diff_base_f_f[ff](i, j);
1047 ++t_diff_base;
1048 ++t_diff_base_f_f[ff];
1049 }
1050 }
1051 }
1052 }
1053 }
1054
1055 // volume
1056 int volume_dofs =
1063 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * volume_dofs,
1064 false);
1065 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
1066 9 * volume_dofs, false);
1067 if (volume_dofs) {
1068 double *base_ptr =
1069 &*data.dataOnEntities[MBTET][0].getN(base).data().begin();
1070 double *diff_base_ptr =
1071 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin();
1072 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1073 auto t_diff_base = getFTensor2HVecFromPtr<3, 3>(diff_base_ptr);
1074
1075 // volume-edge
1076 using Tensor1Ptr3 =
1077 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
1078 Tensor1Ptr3 t_base_v_e[] = {
1079 getFTensor1FromPtr<3>(&*N_volume_edge[0].data().begin()),
1080 getFTensor1FromPtr<3>(&*N_volume_edge[1].data().begin()),
1081 getFTensor1FromPtr<3>(&*N_volume_edge[2].data().begin()),
1082 getFTensor1FromPtr<3>(&*N_volume_edge[3].data().begin()),
1083 getFTensor1FromPtr<3>(&*N_volume_edge[4].data().begin()),
1084 getFTensor1FromPtr<3>(&*N_volume_edge[5].data().begin())};
1085 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_e[] = {
1091 getFTensor2HVecFromPtr<3, 3>(&*diffN_volume_edge[5].data().begin())};
1092
1093 // volume-faces
1094 Tensor1Ptr3 t_base_v_f[] = {
1095 getFTensor1FromPtr<3>(&*N_volume_face[0].data().begin()),
1096 getFTensor1FromPtr<3>(&*N_volume_face[1].data().begin()),
1097 getFTensor1FromPtr<3>(&*N_volume_face[2].data().begin()),
1098 getFTensor1FromPtr<3>(&*N_volume_face[3].data().begin())};
1099 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_f[] = {
1103 getFTensor2HVecFromPtr<3, 3>(&*diffN_volume_face[3].data().begin())};
1104
1105 // volume-bubble
1106 base_ptr = &*(N_volume_bubble.data().begin());
1107 diff_base_ptr = &*(diffN_volume_bubble.data().begin());
1108 auto t_base_v = getFTensor1FromPtr<3>(base_ptr);
1109 auto t_diff_base_v = getFTensor2HVecFromPtr<3, 3>(diff_base_ptr);
1110
1111 auto max_volume_order = std::max(
1112 volume_order,
1114 max_volume_order = std::max(
1115 max_volume_order,
1117 max_volume_order = std::max(
1118 max_volume_order,
1120
1121 for (int gg = 0; gg != nb_gauss_pts; gg++) {
1122 for (int oo = 0; oo < max_volume_order; oo++) {
1123
1124 // volume-edge
1125 if (oo <
1127 for (int dd = NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo);
1128 dd != NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
1129 for (int ee = 0; ee < 6; ee++) {
1130 t_base(i) = t_base_v_e[ee](i);
1131 ++t_base;
1132 ++t_base_v_e[ee];
1133 t_diff_base(i, j) = t_diff_base_v_e[ee](i, j);
1134 ++t_diff_base;
1135 ++t_diff_base_v_e[ee];
1136 }
1137 }
1138
1139 // volume-face
1140 if (oo <
1142 for (int dd = NBVOLUMETET_AINSWORTH_FACE_HDIV(oo);
1143 dd < NBVOLUMETET_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
1144 for (int ff = 0; ff < 4; ff++) {
1145 t_base(i) = t_base_v_f[ff](i);
1146 ++t_base;
1147 ++t_base_v_f[ff];
1148 t_diff_base(i, j) = t_diff_base_v_f[ff](i, j);
1149 ++t_diff_base;
1150 ++t_diff_base_v_f[ff];
1151 }
1152 }
1153
1154 // volume-bubble
1155 if (oo <
1157 for (int dd = NBVOLUMETET_AINSWORTH_VOLUME_HDIV(oo);
1159 t_base(i) = t_base_v(i);
1160 ++t_base;
1161 ++t_base_v;
1162 t_diff_base(i, j) = t_diff_base_v(i, j);
1163 ++t_diff_base;
1164 ++t_diff_base_v;
1165 }
1166 }
1167 }
1168 }
1169
1171}
#define FTENSOR_INDEX(DIM, I)
#define NBVOLUMETET_AINSWORTH_EDGE_HDIV(P)
#define NBVOLUMETET_AINSWORTH_FACE_HDIV(P)
#define NBFACETRI_AINSWORTH_FACE_HDIV(P)
#define NBVOLUMETET_AINSWORTH_VOLUME_HDIV(P)
#define NBFACETRI_AINSWORTH_EDGE_HDIV(P)
FTensor::Index< 'j', 3 > j
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition ddTensor0.hpp:33
auto getFTensor2HVecFromPtr< 3, 3 >(double *ptr)
static boost::function< int(int)> broken_nbvolumetet_edge_hdiv
Definition Hdiv.hpp:27
static boost::function< int(int)> broken_nbvolumetet_face_hdiv
Definition Hdiv.hpp:28
static boost::function< int(int)> broken_nbfacetri_face_hdiv
Definition Hdiv.hpp:26
static boost::function< int(int)> broken_nbvolumetet_volume_hdiv
Definition Hdiv.hpp:29
static boost::function< int(int)> broken_nbfacetri_edge_hdiv
Definition Hdiv.hpp:25
ublas::matrix< MatrixDouble > diffN_face_edge
MoFEMErrorCode getValueHdivAinsworthBaseImpl(MatrixDouble &pts, MatrixDouble &shape_functions, MatrixDouble &diff_shape_functions, int volume_order, std::array< int, 4 > &faces_order, std::array< int, 3 *4 > &faces_nodes, boost::function< int(int)> broken_nbfacetri_edge_hdiv, boost::function< int(int)> broken_nbfacetri_face_hdiv, boost::function< int(int)> broken_nbvolumetet_edge_hdiv, boost::function< int(int)> broken_nbvolumetet_face_hdiv, boost::function< int(int)> broken_nbvolumetet_volume_hdiv)
ublas::vector< MatrixDouble > diffN_volume_face
ublas::vector< MatrixDouble > diffN_face_bubble
ublas::vector< MatrixDouble > N_volume_edge
ublas::vector< MatrixDouble > N_volume_face
ublas::vector< MatrixDouble > N_face_bubble
ublas::matrix< MatrixDouble > N_face_edge
ublas::vector< MatrixDouble > diffN_volume_edge

◆ getValueHdivAinsworthBaseImpl()

MoFEMErrorCode TetPolynomialBase::getValueHdivAinsworthBaseImpl ( MatrixDouble &  pts,
MatrixDouble &  shape_functions,
MatrixDouble &  diff_shape_functions,
int  volume_order,
std::array< int, 4 > &  faces_order,
std::array< int, 3 *4 > &  faces_nodes,
boost::function< int(int)>  broken_nbfacetri_edge_hdiv,
boost::function< int(int)>  broken_nbfacetri_face_hdiv,
boost::function< int(int)>  broken_nbvolumetet_edge_hdiv,
boost::function< int(int)>  broken_nbvolumetet_face_hdiv,
boost::function< int(int)>  broken_nbvolumetet_volume_hdiv 
)
protected

Definition at line 781 of file TetPolynomialBase.cpp.

796 {
798
799 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
800 double *diffL, const int dim) =
802
803 int nb_gauss_pts = pts.size2();
804
805 // face shape functions
806
807 double *phi_f_e[4][3];
808 double *phi_f[4];
809 double *diff_phi_f_e[4][3];
810 double *diff_phi_f[4];
811
812 N_face_edge.resize(4, 3, false);
813 N_face_bubble.resize(4, false);
814 diffN_face_edge.resize(4, 3, false);
815 diffN_face_bubble.resize(4, false);
816
817 for (int ff = 0; ff != 4; ++ff) {
818 const auto face_edge_dofs = NBFACETRI_AINSWORTH_EDGE_HDIV(
819 broken_nbfacetri_edge_hdiv(faces_order[ff]));
820 // three edges on face
821 for (int ee = 0; ee < 3; ee++) {
822 N_face_edge(ff, ee).resize(nb_gauss_pts, 3 * face_edge_dofs, false);
823 diffN_face_edge(ff, ee).resize(nb_gauss_pts, 9 * face_edge_dofs, false);
824 phi_f_e[ff][ee] = &*N_face_edge(ff, ee).data().begin();
825 diff_phi_f_e[ff][ee] = &*diffN_face_edge(ff, ee).data().begin();
826 }
827 auto face_bubble_dofs = NBFACETRI_AINSWORTH_FACE_HDIV(
828 broken_nbfacetri_face_hdiv(faces_order[ff]));
829 N_face_bubble[ff].resize(nb_gauss_pts, 3 * face_bubble_dofs, false);
830 diffN_face_bubble[ff].resize(nb_gauss_pts, 9 * face_bubble_dofs, false);
831 phi_f[ff] = &*(N_face_bubble[ff].data().begin());
832 diff_phi_f[ff] = &*(diffN_face_bubble[ff].data().begin());
833 }
834
835 constexpr int nb_nodes_on_tet = 4;
836
837 for (int ff = 0; ff < 4; ff++) {
839 &faces_nodes[3 * ff], broken_nbfacetri_edge_hdiv(faces_order[ff]),
840 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
841 phi_f_e[ff], diff_phi_f_e[ff], nb_gauss_pts, nb_nodes_on_tet,
842 base_polynomials);
843 }
844
845 for (int ff = 0; ff < 4; ff++) {
847 &faces_nodes[3 * ff], broken_nbfacetri_face_hdiv(faces_order[ff]),
848 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
849 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, nb_nodes_on_tet,
850 base_polynomials);
851 }
852
853 // volume shape functions
854
855 double *phi_v_e[6];
856 double *phi_v_f[4];
857 double *phi_v;
858 double *diff_phi_v_e[6];
859 double *diff_phi_v_f[4];
860 double *diff_phi_v;
861
862 const auto volume_edge_dofs = NBVOLUMETET_AINSWORTH_EDGE_HDIV(
863 broken_nbvolumetet_edge_hdiv(volume_order));
864 N_volume_edge.resize(6, false);
865 diffN_volume_edge.resize(6, false);
866 for (int ee = 0; ee != 6; ++ee) {
867 N_volume_edge[ee].resize(nb_gauss_pts, 3 * volume_edge_dofs, false);
868 diffN_volume_edge[ee].resize(nb_gauss_pts, 9 * volume_edge_dofs, false);
869 phi_v_e[ee] = &*(N_volume_edge[ee].data().begin());
870 diff_phi_v_e[ee] = &*(diffN_volume_edge[ee].data().begin());
871 }
872 if (volume_edge_dofs)
874 broken_nbvolumetet_edge_hdiv(volume_order),
875 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
876 phi_v_e, diff_phi_v_e, nb_gauss_pts, base_polynomials);
877
878 const auto volume_face_dofs = NBVOLUMETET_AINSWORTH_FACE_HDIV(
879 broken_nbvolumetet_face_hdiv(volume_order));
880 N_volume_face.resize(4, false);
881 diffN_volume_face.resize(4, false);
882 for (int ff = 0; ff != 4; ++ff) {
883 N_volume_face[ff].resize(nb_gauss_pts, 3 * volume_face_dofs, false);
884 diffN_volume_face[ff].resize(nb_gauss_pts, 9 * volume_face_dofs, false);
885 phi_v_f[ff] = &*(N_volume_face[ff].data().begin());
886 diff_phi_v_f[ff] = &*(diffN_volume_face[ff].data().begin());
887 }
888 if (volume_face_dofs)
890 broken_nbvolumetet_face_hdiv(volume_order),
891 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
892 phi_v_f, diff_phi_v_f, nb_gauss_pts, base_polynomials);
893
894 auto volume_bubble_dofs = NBVOLUMETET_AINSWORTH_VOLUME_HDIV(
895 broken_nbvolumetet_volume_hdiv(volume_order));
896 N_volume_bubble.resize(nb_gauss_pts, 3 * volume_bubble_dofs, false);
897 diffN_volume_bubble.resize(nb_gauss_pts, 9 * volume_bubble_dofs, false);
898 phi_v = &*(N_volume_bubble.data().begin());
899 diff_phi_v = &*(diffN_volume_bubble.data().begin());
900 if (volume_bubble_dofs)
902 broken_nbvolumetet_volume_hdiv(volume_order),
903 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
904 phi_v, diff_phi_v, nb_gauss_pts, base_polynomials);
905
907}
MoFEMErrorCode Hdiv_Ainsworth_EdgeFaceShapeFunctions_MBTET_ON_FACE(int *faces_nodes, int p, double *N, double *diffN, double *phi_f_e[3], double *diff_phi_f_e[3], int gdim, int nb, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Hdiv base functions, Edge-based face functions by Ainsworth .
Definition Hdiv.cpp:47
MoFEMErrorCode Hdiv_Ainsworth_FaceBasedVolumeShapeFunctions_MBTET(int p, double *N, double *diffN, double *phi_v_f[], double *diff_phi_v_f[], int gdim, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Definition Hdiv.cpp:401
MoFEMErrorCode Hdiv_Ainsworth_FaceBubbleShapeFunctions_ON_FACE(int *faces_nodes, int p, double *N, double *diffN, double *phi_f, double *diff_phi_f, int gdim, int nb, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Face bubble functions by Ainsworth .
Definition Hdiv.cpp:174
MoFEMErrorCode Hdiv_Ainsworth_EdgeBasedVolumeShapeFunctions_MBTET(int p, double *N, double *diffN, double *phi_v_e[6], double *diff_phi_v_e[6], int gdim, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Hdiv base function, Edge-based interior (volume) functions by Ainsworth .
Definition Hdiv.cpp:307
MoFEMErrorCode Hdiv_Ainsworth_VolumeBubbleShapeFunctions_MBTET(int p, double *N, double *diffN, double *phi_v, double *diff_phi_v, int gdim, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Interior bubble functions by Ainsworth .
Definition Hdiv.cpp:507

◆ getValueHdivAinsworthBrokenBase()

MoFEMErrorCode TetPolynomialBase::getValueHdivAinsworthBrokenBase ( MatrixDouble &  pts)
protected

Definition at line 1174 of file TetPolynomialBase.cpp.

1174 {
1176
1177 // Set shape functions into data structure Shape functions has to be put
1178 // in arrays in order which guarantee hierarchical series of degrees of
1179 // freedom, i.e. in other words dofs form sub-entities has to be group
1180 // by order.
1181
1183 EntitiesFieldData &data = cTx->dAta;
1184
1185 FTENSOR_INDEX(3, i);
1186 FTENSOR_INDEX(3, j);
1187
1188 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
1189 int nb_gauss_pts = pts.size2();
1190 int nb_dofs_face =
1195 int nb_dofs_volume =
1202
1203 int nb_dofs = 4 * nb_dofs_face + nb_dofs_volume;
1204 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
1205 false);
1206 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 9 * nb_dofs,
1207 false);
1208 if (nb_dofs == 0)
1210
1211 auto get_interior_cache = [this](auto base) -> TetBaseCache::BaseCacheMI * {
1212 if (vPtr) {
1213 auto it = TetBaseCache::hdivBrokenBaseInterior[base].find(vPtr);
1214 if (it != TetBaseCache::hdivBrokenBaseInterior[base].end()) {
1215 return &it->second;
1216 }
1217 }
1218 return nullptr;
1219 };
1220
1221 auto interior_cache_ptr = get_interior_cache(base);
1222
1223 if (interior_cache_ptr) {
1224 auto it =
1225 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
1226 if (it != interior_cache_ptr->end()) {
1227 noalias(data.dataOnEntities[MBTET][0].getN(base)) = it->N;
1228 noalias(data.dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1230 }
1231 }
1232
1233 std::array<int, 4 * 3> faces_nodes = {0, 1, 3, 1, 2, 3, 0, 3, 2, 0, 2, 1};
1234 std::array<int, 4> faces_order{volume_order, volume_order, volume_order,
1235 volume_order};
1237 pts, data.dataOnEntities[MBVERTEX][0].getN(base),
1238 data.dataOnEntities[MBVERTEX][0].getDiffN(base), volume_order,
1239 faces_order, faces_nodes,
1240
1246
1247 );
1248
1249 auto *base_ptr = &*data.dataOnEntities[MBTET][0].getN(base).data().begin();
1250 auto *diff_base_ptr =
1251 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin();
1252 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1253 auto t_diff_base = getFTensor2HVecFromPtr<3, 3>(diff_base_ptr);
1254
1255 // face-edge
1256 using Tensor1Ptr3 =
1257 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
1258 Tensor1Ptr3 t_base_f_e[] = {
1259 getFTensor1FromPtr<3>(&*(N_face_edge(0, 0).data().begin())),
1260 getFTensor1FromPtr<3>(&*(N_face_edge(0, 1).data().begin())),
1261 getFTensor1FromPtr<3>(&*(N_face_edge(0, 2).data().begin())),
1262 getFTensor1FromPtr<3>(&*(N_face_edge(1, 0).data().begin())),
1263 getFTensor1FromPtr<3>(&*(N_face_edge(1, 1).data().begin())),
1264 getFTensor1FromPtr<3>(&*(N_face_edge(1, 2).data().begin())),
1265 getFTensor1FromPtr<3>(&*(N_face_edge(2, 0).data().begin())),
1266 getFTensor1FromPtr<3>(&*(N_face_edge(2, 1).data().begin())),
1267 getFTensor1FromPtr<3>(&*(N_face_edge(2, 2).data().begin())),
1268 getFTensor1FromPtr<3>(&*(N_face_edge(3, 0).data().begin())),
1269 getFTensor1FromPtr<3>(&*(N_face_edge(3, 1).data().begin())),
1270 getFTensor1FromPtr<3>(&*(N_face_edge(3, 2).data().begin()))};
1271 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_f_e[] = {
1272 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(0, 0).data().begin())),
1273 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(0, 1).data().begin())),
1274 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(0, 2).data().begin())),
1275 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(1, 0).data().begin())),
1276 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(1, 1).data().begin())),
1277 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(1, 2).data().begin())),
1278 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(2, 0).data().begin())),
1279 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(2, 1).data().begin())),
1280 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(2, 2).data().begin())),
1281 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(3, 0).data().begin())),
1282 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(3, 1).data().begin())),
1283 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_edge(3, 2).data().begin()))};
1284
1285 // face-face
1286 Tensor1Ptr3 t_base_f_f[] = {
1287 getFTensor1FromPtr<3>(&*(N_face_bubble[0].data().begin())),
1288 getFTensor1FromPtr<3>(&*(N_face_bubble[1].data().begin())),
1289 getFTensor1FromPtr<3>(&*(N_face_bubble[2].data().begin())),
1290 getFTensor1FromPtr<3>(&*(N_face_bubble[3].data().begin()))};
1291 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_f_f[] = {
1292 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_bubble[0].data().begin())),
1293 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_bubble[1].data().begin())),
1294 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_bubble[2].data().begin())),
1295 getFTensor2HVecFromPtr<3, 3>(&*(diffN_face_bubble[3].data().begin()))};
1296
1297 // volume-edge
1298 Tensor1Ptr3 t_base_v_e[] = {
1299 getFTensor1FromPtr<3>(&*N_volume_edge[0].data().begin()),
1300 getFTensor1FromPtr<3>(&*N_volume_edge[1].data().begin()),
1301 getFTensor1FromPtr<3>(&*N_volume_edge[2].data().begin()),
1302 getFTensor1FromPtr<3>(&*N_volume_edge[3].data().begin()),
1303 getFTensor1FromPtr<3>(&*N_volume_edge[4].data().begin()),
1304 getFTensor1FromPtr<3>(&*N_volume_edge[5].data().begin())};
1305 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_e[] = {
1311 getFTensor2HVecFromPtr<3, 3>(&*diffN_volume_edge[5].data().begin())};
1312
1313 // volume-faces
1314 Tensor1Ptr3 t_base_v_f[] = {
1315 getFTensor1FromPtr<3>(&*N_volume_face[0].data().begin()),
1316 getFTensor1FromPtr<3>(&*N_volume_face[1].data().begin()),
1317 getFTensor1FromPtr<3>(&*N_volume_face[2].data().begin()),
1318 getFTensor1FromPtr<3>(&*N_volume_face[3].data().begin())};
1319 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_f[] = {
1323 getFTensor2HVecFromPtr<3, 3>(&*diffN_volume_face[3].data().begin())};
1324
1325 // volume-bubble
1326 auto *base_vol_ptr = &*(N_volume_bubble.data().begin());
1327 auto *diff_base_vol_ptr = &*(diffN_volume_bubble.data().begin());
1328 auto t_base_v = getFTensor1FromPtr<3>(base_vol_ptr);
1329 auto t_diff_base_v = getFTensor2HVecFromPtr<3, 3>(diff_base_vol_ptr);
1330
1331 int count_dofs = 0;
1332 int count_dofs_face = 0;
1333 int count_dofs_volume = 0;
1334
1335 auto max_volume_order =
1336 std::max(volume_order,
1338 max_volume_order =
1339 std::max(max_volume_order,
1341 max_volume_order =
1342 std::max(max_volume_order,
1344 max_volume_order =
1345 std::max(max_volume_order,
1347 max_volume_order = std::max(
1348 max_volume_order,
1350
1351 for (int gg = 0; gg != nb_gauss_pts; gg++) {
1352 for (int oo = 0; oo < max_volume_order; oo++) {
1353
1354 // faces-edge (((P) > 0) ? (P) : 0)
1356 for (int dd = NBFACETRI_AINSWORTH_EDGE_HDIV(oo);
1357 dd != NBFACETRI_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
1358 for (auto ff = 0; ff != 4; ++ff) {
1359 for (int ee = 0; ee != 3; ++ee) {
1360 t_base(i) = t_base_f_e[ff * 3 + ee](i);
1361 ++t_base;
1362 ++t_base_f_e[ff * 3 + ee];
1363 ++count_dofs;
1364 ++count_dofs_face;
1365 }
1366 for (int ee = 0; ee != 3; ++ee) {
1367 t_diff_base(i, j) = t_diff_base_f_e[ff * 3 + ee](i, j);
1368 ++t_diff_base;
1369 ++t_diff_base_f_e[ff * 3 + ee];
1370 }
1371 }
1372 }
1373
1374 // face-face (P - 1) * (P - 2) / 2
1376 for (int dd = NBFACETRI_AINSWORTH_FACE_HDIV(oo);
1377 dd != NBFACETRI_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
1378 for (auto ff = 0; ff != 4; ++ff) {
1379 t_base(i) = t_base_f_f[ff](i);
1380 ++t_base;
1381 ++t_base_f_f[ff];
1382 t_diff_base(i, j) = t_diff_base_f_f[ff](i, j);
1383 ++t_diff_base;
1384 ++t_diff_base_f_f[ff];
1385 ++count_dofs;
1386 ++count_dofs_face;
1387 }
1388 }
1389
1390 // volume-edge (P - 1)
1392 for (int dd = NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo);
1393 dd != NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
1394 for (int ee = 0; ee < 6; ++ee) {
1395 t_base(i) = t_base_v_e[ee](i);
1396 ++t_base;
1397 ++t_base_v_e[ee];
1398 t_diff_base(i, j) = t_diff_base_v_e[ee](i, j);
1399 ++t_diff_base;
1400 ++t_diff_base_v_e[ee];
1401 ++count_dofs;
1402 ++count_dofs_volume;
1403 }
1404 }
1405
1406 // volume-face (P - 1) * (P - 2)
1408 for (int dd = NBVOLUMETET_AINSWORTH_FACE_HDIV(oo);
1409 dd != NBVOLUMETET_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
1410 for (int ff = 0; ff < 4; ff++) {
1411 t_base(i) = t_base_v_f[ff](i);
1412 ++t_base;
1413 ++t_base_v_f[ff];
1414 t_diff_base(i, j) = t_diff_base_v_f[ff](i, j);
1415 ++t_diff_base;
1416 ++t_diff_base_v_f[ff];
1417 ++count_dofs;
1418 ++count_dofs_volume;
1419 }
1420 }
1421
1422 // volume-bubble (P - 3) * (P - 2) * (P - 1) / 2
1423 if (oo <
1425 for (int dd = NBVOLUMETET_AINSWORTH_VOLUME_HDIV(oo);
1426 dd != NBVOLUMETET_AINSWORTH_VOLUME_HDIV(oo + 1); dd++) {
1427 t_base(i) = t_base_v(i);
1428 ++t_base;
1429 ++t_base_v;
1430 t_diff_base(i, j) = t_diff_base_v(i, j);
1431 ++t_diff_base;
1432 ++t_diff_base_v;
1433 ++count_dofs;
1434 ++count_dofs_volume;
1435 }
1436 }
1437 }
1438
1439#ifndef NDEBUG
1440 if (nb_dofs != count_dofs / nb_gauss_pts) {
1441 MOFEM_LOG_CHANNEL("SELF");
1442 MOFEM_LOG("SELF", Sev::error) << "Nb dofs face: " << 4 * nb_dofs_face
1443 << " -> " << count_dofs_face / nb_gauss_pts;
1444 MOFEM_LOG("SELF", Sev::error) << "Nb dofs volume: " << nb_dofs_volume
1445 << " -> " << count_dofs_volume / nb_gauss_pts;
1446 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1447 "Number of dofs %d is different than expected %d",
1448 count_dofs / nb_gauss_pts, nb_dofs);
1449 }
1450#endif // NDEBUG
1451
1452 if (interior_cache_ptr) {
1453 auto p = interior_cache_ptr->emplace(
1454 TetBaseCache::BaseCacheItem{volume_order, nb_gauss_pts});
1455 p.first->N = data.dataOnEntities[MBTET][0].getN(base);
1456 p.first->diffN = data.dataOnEntities[MBTET][0].getDiffN(base);
1457 }
1458
1460}
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
boost::multi_index_container< BaseCacheItem, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< composite_key< BaseCacheItem, member< BaseCacheItem, int, &BaseCacheItem::order >, member< BaseCacheItem, int, &BaseCacheItem::nb_gauss_pts > > > > > BaseCacheMI

◆ getValueHdivDemkowiczBase()

MoFEMErrorCode TetPolynomialBase::getValueHdivDemkowiczBase ( MatrixDouble &  pts)
protected

Definition at line 1462 of file TetPolynomialBase.cpp.

1462 {
1464
1465 EntitiesFieldData &data = cTx->dAta;
1466 const FieldApproximationBase base = cTx->bAse;
1467 if (base != DEMKOWICZ_JACOBI_BASE) {
1468 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1469 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1470 "but base is %s",
1472 }
1473 int nb_gauss_pts = pts.size2();
1474
1475 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
1476
1477 int p_f[4];
1478 double *phi_f[4];
1479 double *diff_phi_f[4];
1480
1481 auto get_face_cache_ptr = [this]() -> TetBaseCache::HDivBaseFaceCacheMI * {
1482 if (vPtr) {
1485 return &it->second;
1486 }
1487 }
1488 return nullptr;
1489 };
1490
1491 auto face_cache_ptr = get_face_cache_ptr();
1492
1493 // Calculate base function on tet faces
1494 for (int ff = 0; ff != 4; ff++) {
1495 int face_order = data.dataOnEntities[MBTRI][ff].getOrder();
1496 int order = volume_order > face_order ? volume_order : face_order;
1497 data.dataOnEntities[MBTRI][ff].getN(base).resize(
1498 nb_gauss_pts, 3 * NBFACETRI_DEMKOWICZ_HDIV(order), false);
1499 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(
1500 nb_gauss_pts, 9 * NBFACETRI_DEMKOWICZ_HDIV(order), false);
1502 continue;
1503
1504 if (face_cache_ptr) {
1505 auto it = face_cache_ptr->find(boost::make_tuple(
1506
1507 face_order, nb_gauss_pts,
1508
1509 data.facesNodes(ff, 0), data.facesNodes(ff, 1), data.facesNodes(ff, 2)
1510
1511 ));
1512 if (it != face_cache_ptr->end()) {
1513 noalias(data.dataOnEntities[MBTRI][ff].getN(base)) = it->N;
1514 noalias(data.dataOnEntities[MBTRI][ff].getDiffN(base)) = it->diffN;
1515 continue;
1516 }
1517 }
1518
1519 p_f[ff] = order;
1520 phi_f[ff] = &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
1521 diff_phi_f[ff] =
1522 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
1523
1525 &data.facesNodes(ff, 0), order,
1526 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1527 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1528 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, 4);
1529 if (face_cache_ptr) {
1530 auto p = face_cache_ptr->emplace(TetBaseCache::HDivBaseCacheItem{
1531 face_order, nb_gauss_pts, data.facesNodes(ff, 0),
1532 data.facesNodes(ff, 1), data.facesNodes(ff, 2)});
1533 p.first->N = data.dataOnEntities[MBTRI][ff].getN(base);
1534 p.first->diffN = data.dataOnEntities[MBTRI][ff].getDiffN(base);
1535 }
1536 }
1537
1538 auto get_interior_cache = [this]() -> TetBaseCache::BaseCacheMI * {
1539 if (vPtr) {
1540 auto it =
1543 return &it->second;
1544 }
1545 }
1546 return nullptr;
1547 };
1548
1549 auto interior_cache_ptr = get_interior_cache();
1550
1551 // Calculate base functions in tet interior
1552 if (NBVOLUMETET_DEMKOWICZ_HDIV(volume_order) > 0) {
1553 data.dataOnEntities[MBTET][0].getN(base).resize(
1554 nb_gauss_pts, 3 * NBVOLUMETET_DEMKOWICZ_HDIV(volume_order), false);
1555 data.dataOnEntities[MBTET][0].getDiffN(base).resize(
1556 nb_gauss_pts, 9 * NBVOLUMETET_DEMKOWICZ_HDIV(volume_order), false);
1557
1558 for (int v = 0; v != 1; ++v) {
1559 if (interior_cache_ptr) {
1560 auto it = interior_cache_ptr->find(
1561 boost::make_tuple(volume_order, nb_gauss_pts));
1562 if (it != interior_cache_ptr->end()) {
1563 noalias(data.dataOnEntities[MBTET][0].getN(base)) = it->N;
1564 noalias(data.dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1565 continue;
1566 }
1567 }
1568
1569 double *phi_v = &*data.dataOnEntities[MBTET][0].getN(base).data().begin();
1570 double *diff_phi_v =
1571 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin();
1572
1574 volume_order, &data.dataOnEntities[MBVERTEX][0].getN(base)(0, 0),
1575 &data.dataOnEntities[MBVERTEX][0].getDiffN(base)(0, 0), p_f, phi_f,
1576 diff_phi_f, phi_v, diff_phi_v, nb_gauss_pts);
1577 if (interior_cache_ptr) {
1578 auto p = interior_cache_ptr->emplace(
1579 TetBaseCache::BaseCacheItem{volume_order, nb_gauss_pts});
1580 p.first->N = data.dataOnEntities[MBTET][0].getN(base);
1581 p.first->diffN = data.dataOnEntities[MBTET][0].getDiffN(base);
1582 }
1583 }
1584 }
1585
1586 // Set size of face base correctly
1587 for (int ff = 0; ff != 4; ff++) {
1588 int face_order = data.dataOnEntities[MBTRI][ff].getOrder();
1589 data.dataOnEntities[MBTRI][ff].getN(base).resize(
1590 nb_gauss_pts, 3 * NBFACETRI_DEMKOWICZ_HDIV(face_order), true);
1591 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(
1592 nb_gauss_pts, 9 * NBFACETRI_DEMKOWICZ_HDIV(face_order), true);
1593 }
1594
1596}
#define NBVOLUMETET_DEMKOWICZ_HDIV(P)
#define NBFACETRI_DEMKOWICZ_HDIV(P)
const double v
phase velocity of light in medium (cm/ns)
MoFEMErrorCode Hdiv_Demkowicz_Face_MBTET_ON_FACE(int *faces_nodes, int p, double *N, double *diffN, double *phi_f, double *diff_phi_f, int gdim, int nb)
Definition Hdiv.cpp:634
MoFEMErrorCode Hdiv_Demkowicz_Interior_MBTET(int p, double *N, double *diffN, int p_face[], double *phi_f[4], double *diff_phi_f[4], double *phi_v, double *diff_phi_v, int gdim)
Definition Hdiv.cpp:780
boost::multi_index_container< HDivBaseCacheItem, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< composite_key< HDivBaseCacheItem, member< HDivBaseCacheItem, int, &HDivBaseCacheItem::order >, member< HDivBaseCacheItem, int, &HDivBaseCacheItem::nb_gauss_pts >, member< HDivBaseCacheItem, int, &HDivBaseCacheItem::n0 >, member< HDivBaseCacheItem, int, &HDivBaseCacheItem::n1 >, member< HDivBaseCacheItem, int, &HDivBaseCacheItem::n2 > > > > > HDivBaseFaceCacheMI

◆ getValueHdivDemkowiczBrokenBase()

MoFEMErrorCode TetPolynomialBase::getValueHdivDemkowiczBrokenBase ( MatrixDouble &  pts)
protected

Definition at line 1599 of file TetPolynomialBase.cpp.

1599 {
1601
1602 EntitiesFieldData &data = cTx->dAta;
1603 const FieldApproximationBase base = cTx->bAse;
1604 if (base != DEMKOWICZ_JACOBI_BASE) {
1605 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1606 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1607 "but base is %s",
1609 }
1610 int nb_gauss_pts = pts.size2();
1611
1612 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
1613 int nb_dofs_face = NBFACETRI_DEMKOWICZ_HDIV(volume_order);
1614 int nb_dofs_volume = NBVOLUMETET_DEMKOWICZ_HDIV(volume_order);
1615 int nb_dofs = 4 * nb_dofs_face + nb_dofs_volume;
1616 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
1617 false);
1618 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 9 * nb_dofs,
1619 false);
1620 if (nb_dofs == 0)
1622
1623 auto get_interior_cache = [this]() -> TetBaseCache::BaseCacheMI * {
1624 if (vPtr) {
1625 auto it =
1627 vPtr);
1628 if (it !=
1630 return &it->second;
1631 }
1632 }
1633 return nullptr;
1634 };
1635
1636 auto interior_cache_ptr = get_interior_cache();
1637
1638 if (interior_cache_ptr) {
1639 auto it =
1640 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
1641 if (it != interior_cache_ptr->end()) {
1642 noalias(data.dataOnEntities[MBTET][0].getN(base)) = it->N;
1643 noalias(data.dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1645 }
1646 }
1647
1648 std::array<MatrixDouble, 4> face_base_fun{
1649 MatrixDouble(nb_gauss_pts, 3 * nb_dofs_face),
1650 MatrixDouble(nb_gauss_pts, 3 * nb_dofs_face),
1651 MatrixDouble(nb_gauss_pts, 3 * nb_dofs_face),
1652 MatrixDouble(nb_gauss_pts, 3 * nb_dofs_face)};
1653 std::array<MatrixDouble, 4> face_diff_base{
1654 MatrixDouble(nb_gauss_pts, 9 * nb_dofs_face),
1655 MatrixDouble(nb_gauss_pts, 9 * nb_dofs_face),
1656 MatrixDouble(nb_gauss_pts, 9 * nb_dofs_face),
1657 MatrixDouble(nb_gauss_pts, 9 * nb_dofs_face)};
1658
1659 int faces_nodes[4][3] = {{0, 1, 3}, {1, 2, 3}, {0, 3, 2}, {0, 2, 1}};
1660
1661 std::array<int, 4> p_f{volume_order, volume_order, volume_order,
1662 volume_order};
1663 std::array<double *, 4> phi_f{
1664 &*face_base_fun[0].data().begin(), &*face_base_fun[1].data().begin(),
1665 &*face_base_fun[2].data().begin(), &*face_base_fun[3].data().begin()};
1666 std::array<double *, 4> diff_phi_f{
1667 &*face_diff_base[0].data().begin(), &*face_diff_base[1].data().begin(),
1668 &*face_diff_base[2].data().begin(), &*face_diff_base[3].data().begin()};
1669
1670 // Calculate base function on tet faces
1671 for (int ff = 0; ff != 4; ff++) {
1673 // &data.facesNodes(ff, 0)
1674 faces_nodes[ff], p_f[ff],
1675 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1676 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1677 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, 4);
1678 }
1679
1680 MatrixDouble vol_bases(nb_gauss_pts, 3 * nb_dofs_volume);
1681 MatrixDouble vol_diff_bases(nb_gauss_pts, 9 * nb_dofs_volume);
1682 auto *phi_v = &*vol_bases.data().begin();
1683 auto *diff_phi_v = &*vol_diff_bases.data().begin();
1685 volume_order, &data.dataOnEntities[MBVERTEX][0].getN(base)(0, 0),
1686 &data.dataOnEntities[MBVERTEX][0].getDiffN(base)(0, 0), p_f.data(),
1687 phi_f.data(), diff_phi_f.data(), phi_v, diff_phi_v, nb_gauss_pts);
1688
1689 // faces
1690 using Tensor1Ptr3 =
1691 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
1692 Tensor1Ptr3 t_base_v_f[] = {
1693 getFTensor1FromPtr<3>(phi_f[0]), getFTensor1FromPtr<3>(phi_f[1]),
1694 getFTensor1FromPtr<3>(phi_f[2]), getFTensor1FromPtr<3>(phi_f[3])};
1695 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_f[] = {
1696 getFTensor2HVecFromPtr<3, 3>(diff_phi_f[0]),
1697 getFTensor2HVecFromPtr<3, 3>(diff_phi_f[1]),
1698 getFTensor2HVecFromPtr<3, 3>(diff_phi_f[2]),
1699 getFTensor2HVecFromPtr<3, 3>(diff_phi_f[3])};
1700
1701 // volumes
1702 auto t_base_v = getFTensor1FromPtr<3>(&*vol_bases.data().begin());
1704 getFTensor2HVecFromPtr<3, 3>(&*vol_diff_bases.data().begin());
1705
1706 auto t_base = getFTensor1FromPtr<3>(
1707 &*data.dataOnEntities[MBTET][0].getN(base).data().begin());
1708 auto t_diff_base = getFTensor2HVecFromPtr<3, 3>(
1709 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin());
1710
1711 FTENSOR_INDEX(3, i);
1712 FTENSOR_INDEX(3, j);
1713
1714 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
1715 for (int oo = 0; oo < volume_order; oo++) {
1716 // face
1717 for (auto dd = NBFACETRI_DEMKOWICZ_HDIV(oo);
1718 dd != NBFACETRI_DEMKOWICZ_HDIV(oo + 1); ++dd) {
1719 for (auto ff = 0; ff != 4; ++ff) {
1720 t_base(i) = t_base_v_f[ff](i);
1721 ++t_base;
1722 ++t_base_v_f[ff];
1723 t_diff_base(i, j) = t_diff_base_v_f[ff](i, j);
1724 ++t_diff_base;
1725 ++t_diff_base_v_f[ff];
1726 }
1727 }
1728 // volume
1729 for (auto dd = NBVOLUMETET_DEMKOWICZ_HDIV(oo);
1730 dd != NBVOLUMETET_DEMKOWICZ_HDIV(oo + 1); ++dd) {
1731 t_base(i) = t_base_v(i);
1732 ++t_base;
1733 ++t_base_v;
1734 t_diff_base(i, j) = t_diff_base_v(i, j);
1735 ++t_diff_base;
1736 ++t_diff_base_v;
1737 }
1738 }
1739 }
1740
1741 if (interior_cache_ptr) {
1742 auto p = interior_cache_ptr->emplace(
1743 TetBaseCache::BaseCacheItem{volume_order, nb_gauss_pts});
1744 p.first->N = data.dataOnEntities[MBTET][0].getN(base);
1745 p.first->diffN = data.dataOnEntities[MBTET][0].getDiffN(base);
1746 }
1747
1749}

◆ getValueL2()

MoFEMErrorCode TetPolynomialBase::getValueL2 ( MatrixDouble &  pts)
protected

Get base functions for L2 space.

Parameters
ptsmatrix of integration pts
Returns
MoFEMErrorCode
Note
matrix of integration points on rows has local coordinates of finite element on columns are integration pts.

Definition at line 525 of file TetPolynomialBase.cpp.

525 {
527
528 switch (cTx->bAse) {
533 break;
536 break;
537 default:
538 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
539 }
540
542}
MoFEMErrorCode getValueL2BernsteinBezierBase(MatrixDouble &pts)
MoFEMErrorCode getValueL2AinsworthBase(MatrixDouble &pts)

◆ getValueL2AinsworthBase()

MoFEMErrorCode TetPolynomialBase::getValueL2AinsworthBase ( MatrixDouble &  pts)
protected

Definition at line 544 of file TetPolynomialBase.cpp.

544 {
546
547 EntitiesFieldData &data = cTx->dAta;
548 const FieldApproximationBase base = cTx->bAse;
549 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
550 double *diffL, const int dim) =
552
553 int nb_gauss_pts = pts.size2();
554 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
555 int nb_dofs = NBVOLUMETET_L2(volume_order);
556
557 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, nb_dofs, false);
558 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 3 * nb_dofs,
559 false);
560
561 if (!nb_dofs)
563
564 auto get_interior_cache = [this](auto base) -> TetBaseCache::BaseCacheMI * {
565 if (vPtr) {
566 auto it = TetBaseCache::l2BaseInterior[base].find(vPtr);
567 if (it != TetBaseCache::l2BaseInterior[base].end()) {
568 return &it->second;
569 }
570 }
571 return nullptr;
572 };
573
574 auto interior_cache_ptr = get_interior_cache(base);
575
576 if (interior_cache_ptr) {
577 auto it =
578 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
579 if (it != interior_cache_ptr->end()) {
580 noalias(data.dataOnEntities[MBTET][0].getN(base)) = it->N;
581 noalias(data.dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
583 }
584 }
585
587 data.dataOnEntities[MBTET][0].getOrder(),
588 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
589 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
590 &*data.dataOnEntities[MBTET][0].getN(base).data().begin(),
591 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin(),
592 nb_gauss_pts, base_polynomials);
593
594 if (interior_cache_ptr) {
595 auto p = interior_cache_ptr->emplace(
596 TetBaseCache::BaseCacheItem{volume_order, nb_gauss_pts});
597 p.first->N = data.dataOnEntities[MBTET][0].getN(base);
598 p.first->diffN = data.dataOnEntities[MBTET][0].getDiffN(base);
599 }
600
602}
PetscErrorCode L2_Ainsworth_ShapeFunctions_MBTET(int p, double *N, double *diffN, double *L2N, double *diff_L2N, int GDIM, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
Get base functions on tetrahedron for L2 space.
Definition l2.c:74
#define NBVOLUMETET_L2(P)
Number of base functions on tetrahedron for L2 space.
static std::array< std::map< const void *, BaseCacheMI >, LASTBASE > l2BaseInterior

◆ getValueL2BernsteinBezierBase()

MoFEMErrorCode TetPolynomialBase::getValueL2BernsteinBezierBase ( MatrixDouble &  pts)
protected

Definition at line 605 of file TetPolynomialBase.cpp.

605 {
607
608 EntitiesFieldData &data = cTx->dAta;
609 const std::string field_name = cTx->fieldName;
610 const int nb_gauss_pts = pts.size2();
611
612 if (data.dataOnEntities[MBVERTEX][0].getN(NOBASE).size1() !=
613 (unsigned int)nb_gauss_pts)
614 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
615 "Base functions or nodes has wrong number of integration points "
616 "for base %s",
618 auto &lambda = data.dataOnEntities[MBVERTEX][0].getN(NOBASE);
619
620 auto get_alpha = [field_name](auto &data) -> MatrixInt & {
621 auto &ptr = data.getBBAlphaIndicesSharedPtr(field_name);
622 if (!ptr)
623 ptr.reset(new MatrixInt());
624 return *ptr;
625 };
626
627 auto get_base = [field_name](auto &data) -> MatrixDouble & {
628 auto &ptr = data.getBBNSharedPtr(field_name);
629 if (!ptr)
630 ptr.reset(new MatrixDouble());
631 return *ptr;
632 };
633
634 auto get_diff_base = [field_name](auto &data) -> MatrixDouble & {
635 auto &ptr = data.getBBDiffNSharedPtr(field_name);
636 if (!ptr)
637 ptr.reset(new MatrixDouble());
638 return *ptr;
639 };
640
641 auto get_alpha_by_name_ptr =
642 [](auto &data,
643 const std::string &field_name) -> boost::shared_ptr<MatrixInt> & {
644 return data.getBBAlphaIndicesSharedPtr(field_name);
645 };
646
647 auto get_base_by_name_ptr =
648 [](auto &data,
649 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
650 return data.getBBNSharedPtr(field_name);
651 };
652
653 auto get_diff_base_by_name_ptr =
654 [](auto &data,
655 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
656 return data.getBBDiffNSharedPtr(field_name);
657 };
658
659 auto get_alpha_by_order_ptr =
660 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixInt> & {
661 return data.getBBAlphaIndicesByOrderSharedPtr(o);
662 };
663
664 auto get_base_by_order_ptr =
665 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
666 return data.getBBNByOrderSharedPtr(o);
667 };
668
669 auto get_diff_base_by_order_ptr =
670 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
671 return data.getBBDiffNByOrderSharedPtr(o);
672 };
673
674 if (data.spacesOnEntities[MBTET].test(L2)) {
675 if (data.dataOnEntities[MBTET].size() != 1)
676 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
677 "Wrong size ent of ent data");
678
679 auto &ent_data = data.dataOnEntities[MBTET][0];
680 const int order = ent_data.getOrder();
681 const int nb_dofs = NBVOLUMETET_L2(order);
682
683 if (get_alpha_by_order_ptr(ent_data, order)) {
684 get_alpha_by_name_ptr(ent_data, field_name) =
685 get_alpha_by_order_ptr(ent_data, order);
686 get_base_by_name_ptr(ent_data, field_name) =
687 get_base_by_order_ptr(ent_data, order);
688 get_diff_base_by_name_ptr(ent_data, field_name) =
689 get_diff_base_by_order_ptr(ent_data, order);
690 } else {
691
692 auto &get_n = get_base(ent_data);
693 auto &get_diff_n = get_diff_base(ent_data);
694 get_n.resize(nb_gauss_pts, nb_dofs, false);
695 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs, false);
696
697 if (nb_dofs) {
698
699 if (order == 0) {
700
701 if (nb_dofs != 1)
702 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
703 "Inconsistent number of DOFs");
704
705 auto &tri_alpha = get_alpha(ent_data);
706 tri_alpha.clear();
707 get_n(0, 0) = 1;
708 get_diff_n.clear();
709
710 } else {
711
712 if (nb_dofs != 4 + 6 * NBEDGE_H1(order) + 4 * NBFACETRI_H1(order) +
714 nb_dofs != NBVOLUMETET_L2(order))
715 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
716 "Inconsistent number of DOFs");
717
718 auto &tet_alpha = get_alpha(ent_data);
719 tet_alpha.resize(nb_dofs, 4, false);
720
722 &tet_alpha(0, 0));
723 if (order > 1) {
724 std::array<int, 6> edge_n{order, order, order, order, order, order};
725 std::array<int *, 6> tet_edge_ptr{
726 &tet_alpha(4, 0),
727 &tet_alpha(4 + 1 * NBEDGE_H1(order), 0),
728 &tet_alpha(4 + 2 * NBEDGE_H1(order), 0),
729 &tet_alpha(4 + 3 * NBEDGE_H1(order), 0),
730 &tet_alpha(4 + 4 * NBEDGE_H1(order), 0),
731 &tet_alpha(4 + 5 * NBEDGE_H1(order), 0)};
733 tet_edge_ptr.data());
734 if (order > 2) {
735 std::array<int, 6> face_n{order, order, order, order};
736 std::array<int *, 6> tet_face_ptr{
737 &tet_alpha(4 + 6 * NBEDGE_H1(order), 0),
738 &tet_alpha(4 + 6 * NBEDGE_H1(order) + 1 * NBFACETRI_H1(order),
739 0),
740 &tet_alpha(4 + 6 * NBEDGE_H1(order) + 2 * NBFACETRI_H1(order),
741 0),
742 &tet_alpha(4 + 6 * NBEDGE_H1(order) + 3 * NBFACETRI_H1(order),
743 0),
744 };
746 face_n.data(), tet_face_ptr.data());
747 if (order > 3)
749 order,
750 &tet_alpha(
751 4 + 6 * NBEDGE_H1(order) + 4 * NBFACETRI_H1(order), 0));
752 }
753 }
754
756 order, lambda.size1(), tet_alpha.size1(), &tet_alpha(0, 0),
757 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &get_n(0, 0),
758 &get_diff_n(0, 0));
759
760 get_alpha_by_order_ptr(ent_data, order) =
761 get_alpha_by_name_ptr(ent_data, field_name);
762 get_base_by_order_ptr(ent_data, order) =
763 get_base_by_name_ptr(ent_data, field_name);
764 get_diff_base_by_order_ptr(ent_data, order) =
765 get_diff_base_by_name_ptr(ent_data, field_name);
766 }
767 }
768 }
769 } else {
770 auto &ent_data = data.dataOnEntities[MBTET][0];
771 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
772 auto &get_n = get_base(ent_data);
773 auto &get_diff_n = get_diff_base(ent_data);
774 get_n.resize(nb_gauss_pts, 0, false);
775 get_diff_n.resize(nb_gauss_pts, 0, false);
776 }
777
779}
static MoFEMErrorCode generateIndicesVertexTet(const int N, int *alpha)

◆ query_interface()

MoFEMErrorCode TetPolynomialBase::query_interface ( boost::typeindex::type_index  type_index,
UnknownInterface **  iface 
) const
virtual

Reimplemented from MoFEM::BaseFunction.

Definition at line 87 of file TetPolynomialBase.cpp.

88 {
89
91 *iface = const_cast<TetPolynomialBase *>(this);
93}
Calculate base functions on tetrahedral.

◆ setDofsSideMap()

MoFEMErrorCode TetPolynomialBase::setDofsSideMap ( const FieldSpace  space,
const FieldContinuity  continuity,
const FieldApproximationBase  base,
DofsSideMap &  dofs_side_map 
)
static

Set map of dof to side number.

That is used for broken space to establish connection between dofs in the interior of element/entity and side of element/entity to which that dof is associated. That depends on implementation of the base for given space, and has to be implemented while implementing base function for given space.

Parameters
space
continuity
base
DofsSideMap
Returns
MoFEMErrorCode

Definition at line 2136 of file TetPolynomialBase.cpp.

2141 {
2143
2144 switch (continuity) {
2145 case DISCONTINUOUS:
2146
2147 switch (space) {
2148 case HDIV:
2149 CHKERR setDofsSideMapHdiv(continuity, base, dofs_side_map);
2150 break;
2151 default:
2152 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown space %s",
2153 FieldSpaceNames[space]);
2154 }
2155 break;
2156
2157 default:
2158 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
2159 "Unknown (or not implemented) continuity");
2160 }
2161
2163}
static MoFEMErrorCode setDofsSideMapHdiv(const FieldContinuity continuity, const FieldApproximationBase base, DofsSideMap &dofs_side_map)
Set the Dofs Side Map Hdiv object.

◆ setDofsSideMapHdiv()

MoFEMErrorCode TetPolynomialBase::setDofsSideMapHdiv ( const FieldContinuity  continuity,
const FieldApproximationBase  base,
DofsSideMap &  dofs_side_map 
)
staticprotected

Set the Dofs Side Map Hdiv object.

Parameters
space
continuity
base
dofs_side_map
Returns
MoFEMErrorCode

Definition at line 2166 of file TetPolynomialBase.cpp.

2168 {
2170
2171 // That has to be consistent with implementation of getValueHdiv for
2172 // particular base functions.
2173
2174 auto set_ainsworth = [&dofs_side_map]() {
2176
2177 dofs_side_map.clear();
2178
2179 int dof = 0;
2180 for (int oo = 0; oo < Field::maxBrokenDofsOrder; oo++) {
2181
2182 // faces-edge (((P) > 0) ? (P) : 0)
2183 for (int dd = NBFACETRI_AINSWORTH_EDGE_HDIV(oo);
2184 dd != NBFACETRI_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
2185 for (auto ff = 0; ff != 4; ++ff) {
2186 for (int ee = 0; ee != 3; ++ee) {
2187 dofs_side_map.insert(DofsSideMapData{MBTRI, ff, dof});
2188 ++dof;
2189 }
2190 }
2191 }
2192
2193 // face-face (P - 1) * (P - 2) / 2
2194 for (int dd = NBFACETRI_AINSWORTH_FACE_HDIV(oo);
2195 dd != NBFACETRI_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
2196 for (auto ff = 0; ff != 4; ++ff) {
2197 dofs_side_map.insert(DofsSideMapData{MBTRI, ff, dof});
2198 ++dof;
2199 }
2200 }
2201
2202 // volume-edge (P - 1)
2203 for (int dd = NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo);
2204 dd != NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
2205 for (int ee = 0; ee < 6; ee++) {
2206 dofs_side_map.insert(DofsSideMapData{MBTET, 0, dof});
2207 ++dof;
2208 }
2209 }
2210 // volume-face (P - 1) * (P - 2)
2211 for (int dd = NBVOLUMETET_AINSWORTH_FACE_HDIV(oo);
2212 dd < NBVOLUMETET_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
2213 for (int ff = 0; ff < 4; ff++) {
2214 dofs_side_map.insert(DofsSideMapData{MBTET, 0, dof});
2215 ++dof;
2216 }
2217 }
2218 // volume-bubble (P - 3) * (P - 2) * (P - 1) / 2
2219 for (int dd = NBVOLUMETET_AINSWORTH_VOLUME_HDIV(oo);
2221 dofs_side_map.insert(DofsSideMapData{MBTET, 0, dof});
2222 ++dof;
2223 }
2224 }
2225
2227 };
2228
2229 auto set_demkowicz = [&dofs_side_map]() {
2231
2232 dofs_side_map.clear();
2233
2234 int dof = 0;
2235 for (int oo = 0; oo < Field::maxBrokenDofsOrder; oo++) {
2236
2237 // face
2238 for (auto dd = NBFACETRI_DEMKOWICZ_HDIV(oo);
2239 dd != NBFACETRI_DEMKOWICZ_HDIV(oo + 1); ++dd) {
2240 for (auto ff = 0; ff != 4; ++ff) {
2241 dofs_side_map.insert(DofsSideMapData{MBTRI, ff, dof});
2242 ++dof;
2243 }
2244 }
2245 // volume
2246 for (auto dd = NBVOLUMETET_DEMKOWICZ_HDIV(oo);
2247 dd != NBVOLUMETET_DEMKOWICZ_HDIV(oo + 1); ++dd) {
2248 dofs_side_map.insert(DofsSideMapData{MBTET, 0, dof});
2249 ++dof;
2250 }
2251 }
2252
2254 };
2255
2256 switch (continuity) {
2257 case DISCONTINUOUS:
2258 switch (base) {
2261 MoFEMFunctionReturnHot(set_ainsworth());
2263 MoFEMFunctionReturnHot(set_demkowicz());
2264 default:
2265 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
2266 }
2267 break;
2268
2269 default:
2270 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
2271 "Unknown (or not implemented) continuity");
2272 }
2273
2275}
static constexpr int maxBrokenDofsOrder
Maximum order for broken space DOFs.

◆ switchCacheBaseFace() [1/3]

template<>
bool MoFEM::TetPolynomialBase::switchCacheBaseFace ( FieldApproximationBase  base,
void *  ptr 
)
static

Definition at line 2296 of file TetPolynomialBase.cpp.

2297 {
2299 std::string("hDivBaseFace") +
2301}
auto tetCacheSwitch(const void *ptr, T &cache, std::string cache_name)

◆ switchCacheBaseFace() [2/3]

template<int SPACE>
static bool MoFEM::TetPolynomialBase::switchCacheBaseFace ( FieldApproximationBase  base,
void *  ptr 
)
static

◆ switchCacheBaseFace() [3/3]

template<>
bool MoFEM::TetPolynomialBase::switchCacheBaseFace ( FieldApproximationBase  base,
void *  ptr 
)
static

◆ switchCacheBaseInterior() [1/5]

template<>
bool MoFEM::TetPolynomialBase::switchCacheBaseInterior ( FieldApproximationBase  base,
void *  ptr 
)
static

Definition at line 2304 of file TetPolynomialBase.cpp.

2305 {
2307 std::string("hdivBaseInterior") +
2309}

◆ switchCacheBaseInterior() [2/5]

template<>
bool MoFEM::TetPolynomialBase::switchCacheBaseInterior ( FieldApproximationBase  base,
void *  ptr 
)
static

Definition at line 2366 of file TetPolynomialBase.cpp.

2367 {
2369 std::string("hdivBaseInterior") +
2371}

◆ switchCacheBaseInterior() [3/5]

template<int SPACE>
static bool MoFEM::TetPolynomialBase::switchCacheBaseInterior ( FieldApproximationBase  base,
void *  ptr 
)
static

◆ switchCacheBaseInterior() [4/5]

template<>
bool MoFEM::TetPolynomialBase::switchCacheBaseInterior ( FieldApproximationBase  base,
void *  ptr 
)
static

◆ switchCacheBaseInterior() [5/5]

template<>
bool MoFEM::TetPolynomialBase::switchCacheBaseInterior ( FieldApproximationBase  base,
void *  ptr 
)
static

◆ switchCacheBaseOff() [1/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOff ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

Definition at line 2336 of file TetPolynomialBase.cpp.

2337 {
2338 for (auto fe_ptr : v) {
2339 if (TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr)) {
2340 TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr);
2341 }
2342 if (TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr)) {
2343 TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr);
2344 }
2345 if (TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr)) {
2346 TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr);
2347 }
2348 }
2349}

◆ switchCacheBaseOff() [2/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOff ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

Definition at line 2384 of file TetPolynomialBase.cpp.

2385 {
2386 for (auto fe_ptr : v) {
2387 if (TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr)) {
2388 TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr);
2389 }
2390 }
2391}

◆ switchCacheBaseOff() [3/10]

template<int SPACE>
static void MoFEM::TetPolynomialBase::switchCacheBaseOff ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

◆ switchCacheBaseOff() [4/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOff ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

◆ switchCacheBaseOff() [5/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOff ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

◆ switchCacheBaseOff() [6/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOff ( std::vector< void * >  v)
static

Definition at line 2359 of file TetPolynomialBase.cpp.

2359 {
2360 for (auto b = 0; b != LASTBASE; ++b) {
2361 switchCacheBaseOff<HDIV>(static_cast<FieldApproximationBase>(b), v);
2362 }
2363}

◆ switchCacheBaseOff() [7/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOff ( std::vector< void * >  v)
static

Definition at line 2401 of file TetPolynomialBase.cpp.

2401 {
2402 for (auto b = 0; b != LASTBASE; ++b) {
2403 switchCacheBaseOff<L2>(static_cast<FieldApproximationBase>(b), v);
2404 }
2405}

◆ switchCacheBaseOff() [8/10]

template<int SPACE>
static void MoFEM::TetPolynomialBase::switchCacheBaseOff ( std::vector< void * >  v)
static

◆ switchCacheBaseOff() [9/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOff ( std::vector< void * >  v)
static

◆ switchCacheBaseOff() [10/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOff ( std::vector< void * >  v)
static

◆ switchCacheBaseOn() [1/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOn ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

Definition at line 2320 of file TetPolynomialBase.cpp.

2321 {
2322 for (auto fe_ptr : v) {
2323 if (!TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr)) {
2324 TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr);
2325 }
2326 if (!TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr)) {
2327 TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr);
2328 }
2329 if (!TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr)) {
2330 TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr);
2331 }
2332 }
2333}

◆ switchCacheBaseOn() [2/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOn ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

Definition at line 2374 of file TetPolynomialBase.cpp.

2375 {
2376 for (auto fe_ptr : v) {
2377 if (!TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr)) {
2378 TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr);
2379 }
2380 }
2381}

◆ switchCacheBaseOn() [3/10]

template<int SPACE>
static void MoFEM::TetPolynomialBase::switchCacheBaseOn ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

◆ switchCacheBaseOn() [4/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOn ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

◆ switchCacheBaseOn() [5/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOn ( FieldApproximationBase  base,
std::vector< void * >  v 
)
static

◆ switchCacheBaseOn() [6/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOn ( std::vector< void * >  v)
static

Definition at line 2352 of file TetPolynomialBase.cpp.

2352 {
2353 for (auto b = 0; b != LASTBASE; ++b) {
2354 switchCacheBaseOn<HDIV>(static_cast<FieldApproximationBase>(b), v);
2355 }
2356}

◆ switchCacheBaseOn() [7/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOn ( std::vector< void * >  v)
static

Definition at line 2394 of file TetPolynomialBase.cpp.

2394 {
2395 for (auto b = 0; b != LASTBASE; ++b) {
2396 switchCacheBaseOn<L2>(static_cast<FieldApproximationBase>(b), v);
2397 }
2398}

◆ switchCacheBaseOn() [8/10]

template<int SPACE>
static void MoFEM::TetPolynomialBase::switchCacheBaseOn ( std::vector< void * >  v)
static

◆ switchCacheBaseOn() [9/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOn ( std::vector< void * >  v)
static

◆ switchCacheBaseOn() [10/10]

template<>
void MoFEM::TetPolynomialBase::switchCacheBaseOn ( std::vector< void * >  v)
static

◆ switchCacheBrokenBaseInterior() [1/3]

template<>
bool MoFEM::TetPolynomialBase::switchCacheBrokenBaseInterior ( FieldApproximationBase  base,
void *  ptr 
)
static

Definition at line 2312 of file TetPolynomialBase.cpp.

2313 {
2315 std::string("hdivBrokenBaseInterior") +
2317}

◆ switchCacheBrokenBaseInterior() [2/3]

template<int SPACE>
static bool MoFEM::TetPolynomialBase::switchCacheBrokenBaseInterior ( FieldApproximationBase  base,
void *  ptr 
)
static

◆ switchCacheBrokenBaseInterior() [3/3]

template<>
bool MoFEM::TetPolynomialBase::switchCacheBrokenBaseInterior ( FieldApproximationBase  base,
void *  ptr 
)
static

Member Data Documentation

◆ cTx

EntPolynomialBaseCtx* MoFEM::TetPolynomialBase::cTx
protected

Definition at line 71 of file TetPolynomialBase.hpp.

◆ diffN_face_bubble

ublas::vector<MatrixDouble> MoFEM::TetPolynomialBase::diffN_face_bubble
protected

Definition at line 171 of file TetPolynomialBase.hpp.

◆ diffN_face_edge

ublas::matrix<MatrixDouble> MoFEM::TetPolynomialBase::diffN_face_edge
protected

Definition at line 170 of file TetPolynomialBase.hpp.

◆ diffN_volume_bubble

MatrixDouble MoFEM::TetPolynomialBase::diffN_volume_bubble
protected

Definition at line 174 of file TetPolynomialBase.hpp.

◆ diffN_volume_edge

ublas::vector<MatrixDouble> MoFEM::TetPolynomialBase::diffN_volume_edge
protected

Definition at line 172 of file TetPolynomialBase.hpp.

◆ diffN_volume_face

ublas::vector<MatrixDouble> MoFEM::TetPolynomialBase::diffN_volume_face
protected

Definition at line 173 of file TetPolynomialBase.hpp.

◆ N_face_bubble

ublas::vector<MatrixDouble> MoFEM::TetPolynomialBase::N_face_bubble
protected

Definition at line 165 of file TetPolynomialBase.hpp.

◆ N_face_edge

ublas::matrix<MatrixDouble> MoFEM::TetPolynomialBase::N_face_edge
protected

Definition at line 164 of file TetPolynomialBase.hpp.

◆ N_volume_bubble

MatrixDouble MoFEM::TetPolynomialBase::N_volume_bubble
protected

Definition at line 168 of file TetPolynomialBase.hpp.

◆ N_volume_edge

ublas::vector<MatrixDouble> MoFEM::TetPolynomialBase::N_volume_edge
protected

Definition at line 166 of file TetPolynomialBase.hpp.

◆ N_volume_face

ublas::vector<MatrixDouble> MoFEM::TetPolynomialBase::N_volume_face
protected

Definition at line 167 of file TetPolynomialBase.hpp.

◆ senseFaceAlpha

MatrixInt MoFEM::TetPolynomialBase::senseFaceAlpha
protected

Definition at line 162 of file TetPolynomialBase.hpp.

◆ vPtr

const void* MoFEM::TetPolynomialBase::vPtr
protected

Definition at line 70 of file TetPolynomialBase.hpp.


The documentation for this struct was generated from the following files: