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 2179 of file TetPolynomialBase.cpp.

2180 {
2182
2184
2185 int nb_gauss_pts = pts.size2();
2186 if (!nb_gauss_pts)
2188
2189 if (pts.size1() < 3)
2190 SETERRQ(
2191 PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2192 "Wrong dimension of pts, should be at least 3 rows with coordinates");
2193
2195 const FieldApproximationBase base = cTx->bAse;
2196 EntitiesFieldData &data = cTx->dAta;
2197 if (cTx->copyNodeBase == LASTBASE) {
2198 data.dataOnEntities[MBVERTEX][0].getN(base).resize(nb_gauss_pts, 4,
2199 false);
2201 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
2202 &pts(0, 0), &pts(1, 0), &pts(2, 0), nb_gauss_pts);
2203 } else {
2204 data.dataOnEntities[MBVERTEX][0].getN(base) =
2205 data.dataOnEntities[MBVERTEX][0].getN(cTx->copyNodeBase);
2206 }
2207 if (data.dataOnEntities[MBVERTEX][0].getN(base).size1() !=
2208 (unsigned int)nb_gauss_pts) {
2209 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2210 "Base functions or nodes has wrong number of integration points "
2211 "for base %s",
2213 }
2214 data.dataOnEntities[MBVERTEX][0].getDiffN(base).resize(4, 3, false);
2215 std::copy(Tools::diffShapeFunMBTET.begin(), Tools::diffShapeFunMBTET.end(),
2216 data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin());
2217 }
2218
2219 switch (cTx->spaceContinuity) {
2220 case CONTINUOUS:
2221
2222 switch (cTx->sPace) {
2223 case H1:
2224 CHKERR getValueH1(pts);
2225 break;
2226 case HDIV:
2227 CHKERR getValueHdiv(pts);
2228 break;
2229 case HCURL:
2230 CHKERR getValueHcurl(pts);
2231 break;
2232 case L2:
2233 CHKERR getValueL2(pts);
2234 break;
2235 default:
2236 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown space %s",
2238 }
2239 break;
2240
2241 case DISCONTINUOUS:
2242
2243 switch (cTx->sPace) {
2244 case HDIV:
2245 CHKERR getValueHdiv(pts);
2246 break;
2247 default:
2248 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown space %s",
2250 }
2251 break;
2252
2253 default:
2254 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown continuity");
2255 }
2256
2258}
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:767
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 // A field which was given a by-order matrix shared with another field on a
313 // previous element must not write into it here: on this element that matrix
314 // may already hold the other field's base. Detach and allocate own storage.
315 auto make_own = [field_name](auto &ent_data) {
316 auto &n_ptr = ent_data.getBBNSharedPtr(field_name);
317 if (!n_ptr)
318 return;
319 for (auto &ptr : ent_data.getBBNByOrderArray()) {
320 if (ptr && ptr.get() == n_ptr.get()) {
321 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
322 ent_data.getBBDiffNSharedPtr(field_name).reset();
323 n_ptr.reset();
324 return;
325 }
326 }
327 };
328
329 // Entity without base functions for this field: no alpha indices and base
330 // matrices with zero columns, consistent with the hierarchical bases.
331 auto set_empty = [&](auto &ent_data) {
332 make_own(ent_data);
333 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
334 get_base(ent_data).resize(nb_gauss_pts, 0, false);
335 get_diff_base(ent_data).resize(nb_gauss_pts, 0, false);
336 };
337
338 // The BB base is not hierarchical: a degree-p function is not in the span
339 // of the degree-(p+1) functions, so mixing degrees between the entities of
340 // one element loses completeness (with a differing vertex degree even the
341 // constant function is lost). H1 therefore requires one order on all
342 // entities which carry DOFs, and vertex degrees between one and that order.
343 // L2 is element-local and has no such restriction.
344 auto check_uniform_order = [&]() {
346 auto &node_order = data.dataOnEntities[MBVERTEX][0].getBBNodeOrder();
347 if (node_order.size() != 4)
348 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
349 "Wrong number of vertex orders for BB base: %d",
350 static_cast<int>(node_order.size()));
351 int order = 0;
352 for (int n = 0; n != 4; ++n)
353 order = std::max(order, node_order[n]);
354 auto max_order_on = [&](const EntityType type) {
355 if (data.spacesOnEntities[type].test(H1))
356 for (auto &ent_data : data.dataOnEntities[type])
357 order = std::max(order, ent_data.getOrder());
358 };
359 max_order_on(MBEDGE);
360 max_order_on(MBTRI);
361 max_order_on(MBTET);
362 if (order < 1)
363 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
364 "Bernstein-Bezier H1 base requires approximation order >= 1");
365 if (static_cast<size_t>(order) >=
367 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
368 "Bernstein-Bezier order %d exceeds the supported maximum %d",
369 order,
370 static_cast<int>(
372 1);
373 for (int n = 0; n != 4; ++n)
374 if (node_order[n] < 1)
375 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
376 "Bernstein-Bezier H1 base requires vertex order between 1 "
377 "and the element order %d; vertex %d has order %d",
378 order, n, node_order[n]);
379 auto check_type = [&](const EntityType type, const int nb_dofs_at_order) {
381 if (!nb_dofs_at_order || !data.spacesOnEntities[type].test(H1))
383 int side = 0;
384 for (auto &ent_data : data.dataOnEntities[type]) {
385 if (ent_data.getOrder() != order)
386 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
387 "Bernstein-Bezier base in H1 space requires uniform "
388 "approximation order on the element: %s %d has order %d, "
389 "element order is %d. BB functions are not hierarchical, "
390 "so mixed degrees do not span a complete polynomial space. "
391 "Set one order for the whole H1 field (L2 fields are not "
392 "restricted).",
393 moab::CN::EntityTypeName(type), side, ent_data.getOrder(),
394 order);
395 ++side;
396 }
398 };
399 CHKERR check_type(MBEDGE, NBEDGE_H1(order));
400 CHKERR check_type(MBTRI, NBFACETRI_H1(order));
401 CHKERR check_type(MBTET, NBVOLUMETET_H1(order));
403 };
404 CHKERR check_uniform_order();
405
406 auto &vert_ent_data = data.dataOnEntities[MBVERTEX][0];
407 auto &vertex_alpha = get_alpha(vert_ent_data);
408 vertex_alpha.resize(4, 4, false);
409 vertex_alpha.clear();
410 for (int n = 0; n != 4; ++n)
411 vertex_alpha(n, n) = data.dataOnEntities[MBVERTEX][0].getBBNodeOrder()[n];
412
413 auto &vert_get_n = get_base(vert_ent_data);
414 auto &vert_get_diff_n = get_diff_base(vert_ent_data);
415 vert_get_n.resize(nb_gauss_pts, 4, false);
416 vert_get_diff_n.resize(nb_gauss_pts, 12, false);
418 1, lambda.size1(), vertex_alpha.size1(), &vertex_alpha(0, 0),
419 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &vert_get_n(0, 0),
420 &vert_get_diff_n(0, 0));
421 for (int n = 0; n != 4; ++n) {
422 const double f = boost::math::factorial<double>(
423 data.dataOnEntities[MBVERTEX][0].getBBNodeOrder()[n]);
424 for (int g = 0; g != nb_gauss_pts; ++g) {
425 vert_get_n(g, n) *= f;
426 for (int d = 0; d != 3; ++d)
427 vert_get_diff_n(g, 3 * n + d) *= f;
428 }
429 }
430
431 // edges
432 if (data.spacesOnEntities[MBEDGE].test(H1)) {
433 if (data.dataOnEntities[MBEDGE].size() != 6)
434 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
435 "Wrong size of ent data");
436
437 constexpr int edges_nodes[6][2] = {{0, 1}, {1, 2}, {2, 0},
438 {0, 3}, {1, 3}, {2, 3}};
439 for (int ee = 0; ee != 6; ++ee) {
440 auto &ent_data = data.dataOnEntities[MBEDGE][ee];
441 const int sense = ent_data.getSense();
442 if (sense == 0)
443 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
444 "Sense of the edge unknown");
445 const int order = ent_data.getOrder();
446 const int nb_dofs = NBEDGE_H1(order);
447
448 if (nb_dofs) {
449 if (get_alpha_by_order_ptr(ent_data, order)) {
450 get_alpha_by_name_ptr(ent_data, field_name) =
451 get_alpha_by_order_ptr(ent_data, order);
452 get_base_by_name_ptr(ent_data, field_name) =
453 get_base_by_order_ptr(ent_data, order);
454 get_diff_base_by_name_ptr(ent_data, field_name) =
455 get_diff_base_by_order_ptr(ent_data, order);
456 } else {
457 make_own(ent_data);
458 auto &get_n = get_base(ent_data);
459 auto &get_diff_n = get_diff_base(ent_data);
460 get_n.resize(nb_gauss_pts, nb_dofs, false);
461 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs, false);
462
463 auto &edge_alpha = get_alpha(ent_data);
464 edge_alpha.resize(nb_dofs, 4, false);
466 &edge_alpha(0, 0));
467 if (sense == -1) {
468 for (int i = 0; i != edge_alpha.size1(); ++i) {
469 int a = edge_alpha(i, edges_nodes[ee][0]);
470 edge_alpha(i, edges_nodes[ee][0]) =
471 edge_alpha(i, edges_nodes[ee][1]);
472 edge_alpha(i, edges_nodes[ee][1]) = a;
473 }
474 }
476 order, lambda.size1(), edge_alpha.size1(), &edge_alpha(0, 0),
477 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &get_n(0, 0),
478 &get_diff_n(0, 0));
479
480 get_alpha_by_order_ptr(ent_data, order) =
481 get_alpha_by_name_ptr(ent_data, field_name);
482 get_base_by_order_ptr(ent_data, order) =
483 get_base_by_name_ptr(ent_data, field_name);
484 get_diff_base_by_order_ptr(ent_data, order) =
485 get_diff_base_by_name_ptr(ent_data, field_name);
486 }
487 } else {
488 set_empty(ent_data);
489 }
490 }
491 } else {
492 for (int ee = 0; ee != 6; ++ee)
493 set_empty(data.dataOnEntities[MBEDGE][ee]);
494 }
495
496 // face
497 if (data.spacesOnEntities[MBTRI].test(H1)) {
498 if (data.dataOnEntities[MBTRI].size() != 4)
499 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
500 "Wrong size of ent data");
501 if (data.facesNodes.size1() != 4)
502 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
503 if (data.facesNodes.size2() != 3)
504 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
505
506 for (int ff = 0; ff != 4; ++ff) {
507 auto &ent_data = data.dataOnEntities[MBTRI][ff];
508 const int order = ent_data.getOrder();
509 const int nb_dofs = NBFACETRI_H1(order);
510
511 if (nb_dofs) {
512 if (get_alpha_by_order_ptr(ent_data, order)) {
513 get_alpha_by_name_ptr(ent_data, field_name) =
514 get_alpha_by_order_ptr(ent_data, order);
515 get_base_by_name_ptr(ent_data, field_name) =
516 get_base_by_order_ptr(ent_data, order);
517 get_diff_base_by_name_ptr(ent_data, field_name) =
518 get_diff_base_by_order_ptr(ent_data, order);
519 } else {
520
521 make_own(ent_data);
522 auto &get_n = get_base(ent_data);
523 auto &get_diff_n = get_diff_base(ent_data);
524 get_n.resize(nb_gauss_pts, nb_dofs, false);
525 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs, false);
526
527 auto &face_alpha = get_alpha(ent_data);
528 face_alpha.resize(nb_dofs, 4, false);
529
531 &face_alpha(0, 0));
532 senseFaceAlpha.resize(face_alpha.size1(), face_alpha.size2(), false);
533 senseFaceAlpha.clear();
534 constexpr int tri_nodes[4][3] = {
535 {0, 1, 3}, {1, 2, 3}, {0, 2, 3}, {0, 1, 2}};
536 for (int d = 0; d != nb_dofs; ++d)
537 for (int n = 0; n != 3; ++n)
538 senseFaceAlpha(d, data.facesNodes(ff, n)) =
539 face_alpha(d, tri_nodes[ff][n]);
540 face_alpha.swap(senseFaceAlpha);
542 order, lambda.size1(), face_alpha.size1(), &face_alpha(0, 0),
543 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &get_n(0, 0),
544 &get_diff_n(0, 0));
545
546 get_alpha_by_order_ptr(ent_data, order) =
547 get_alpha_by_name_ptr(ent_data, field_name);
548 get_base_by_order_ptr(ent_data, order) =
549 get_base_by_name_ptr(ent_data, field_name);
550 get_diff_base_by_order_ptr(ent_data, order) =
551 get_diff_base_by_name_ptr(ent_data, field_name);
552 }
553 } else {
554 set_empty(ent_data);
555 }
556 }
557 } else {
558 for (int ff = 0; ff != 4; ++ff)
559 set_empty(data.dataOnEntities[MBTRI][ff]);
560 }
561
562 if (data.spacesOnEntities[MBTET].test(H1)) {
563 if (data.dataOnEntities[MBTET].size() != 1)
564 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
565 "Wrong size ent of ent data");
566
567 auto &ent_data = data.dataOnEntities[MBTET][0];
568 const int order = ent_data.getOrder();
569 const int nb_dofs = NBVOLUMETET_H1(order);
570 if (get_alpha_by_order_ptr(ent_data, order)) {
571 get_alpha_by_name_ptr(ent_data, field_name) =
572 get_alpha_by_order_ptr(ent_data, order);
573 get_base_by_name_ptr(ent_data, field_name) =
574 get_base_by_order_ptr(ent_data, order);
575 get_diff_base_by_name_ptr(ent_data, field_name) =
576 get_diff_base_by_order_ptr(ent_data, order);
577 } else {
578
579 make_own(ent_data);
580 auto &get_n = get_base(ent_data);
581 auto &get_diff_n = get_diff_base(ent_data);
582 get_n.resize(nb_gauss_pts, nb_dofs, false);
583 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs, false);
584 if (nb_dofs) {
585 auto &tet_alpha = get_alpha(ent_data);
586 tet_alpha.resize(nb_dofs, 4, false);
587
590 order, lambda.size1(), tet_alpha.size1(), &tet_alpha(0, 0),
591 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &get_n(0, 0),
592 &get_diff_n(0, 0));
593
594 get_alpha_by_order_ptr(ent_data, order) =
595 get_alpha_by_name_ptr(ent_data, field_name);
596 get_base_by_order_ptr(ent_data, order) =
597 get_base_by_name_ptr(ent_data, field_name);
598 get_diff_base_by_order_ptr(ent_data, order) =
599 get_diff_base_by_name_ptr(ent_data, field_name);
600 } else {
601 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
602 }
603 }
604 } else {
605 set_empty(data.dataOnEntities[MBTET][0]);
606 }
607
609}
std::string type
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)
static constexpr size_t MaxBernsteinBezierOrder
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 2160 of file TetPolynomialBase.cpp.

2160 {
2162
2163 switch (cTx->bAse) {
2167 break;
2170 break;
2171 default:
2172 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
2173 }
2174
2176}
@ 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 1910 of file TetPolynomialBase.cpp.

1910 {
1912
1913 EntitiesFieldData &data = cTx->dAta;
1914 const FieldApproximationBase base = cTx->bAse;
1915 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
1916 double *diffL, const int dim) =
1918
1919 int nb_gauss_pts = pts.size2();
1920
1921 // edges
1922 if (data.spacesOnEntities[MBEDGE].test(HCURL)) {
1923 int sense[6], order[6];
1924 if (data.dataOnEntities[MBEDGE].size() != 6) {
1925 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
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 "data inconsistency");
1932 }
1933 sense[ee] = data.dataOnEntities[MBEDGE][ee].getSense();
1934 order[ee] = data.dataOnEntities[MBEDGE][ee].getOrder();
1935 int nb_dofs =
1936 NBEDGE_AINSWORTH_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, base_polynomials);
1951 } else {
1952 for (int ee = 0; ee != 6; ee++) {
1953 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, 0, false);
1954 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts, 0,
1955 false);
1956 }
1957 }
1958
1959 // triangles
1960 if (data.spacesOnEntities[MBTRI].test(HCURL)) {
1961 int order[4];
1962 // faces
1963 if (data.dataOnEntities[MBTRI].size() != 4) {
1964 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1965 }
1966 double *hcurl_base_n[4], *diff_hcurl_base_n[4];
1967 for (int ff = 0; ff != 4; ff++) {
1968 if (data.dataOnEntities[MBTRI][ff].getSense() == 0) {
1969 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1970 "data inconsistency");
1971 }
1972 order[ff] = data.dataOnEntities[MBTRI][ff].getOrder();
1973 int nb_dofs = NBFACETRI_AINSWORTH_HCURL(order[ff]);
1974 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts,
1975 3 * nb_dofs, false);
1976 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1977 9 * nb_dofs, false);
1978 hcurl_base_n[ff] =
1979 &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
1980 diff_hcurl_base_n[ff] =
1981 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
1982 }
1983 if (data.facesNodes.size1() != 4) {
1984 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1985 }
1986 if (data.facesNodes.size2() != 3) {
1987 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1988 }
1990 &*data.facesNodes.data().begin(), order,
1991 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1992 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1993 hcurl_base_n, diff_hcurl_base_n, nb_gauss_pts, base_polynomials);
1994 } else {
1995 for (int ff = 0; ff != 4; ff++) {
1996 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts, 0, false);
1997 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts, 0,
1998 false);
1999 }
2000 }
2001
2002 if (data.spacesOnEntities[MBTET].test(HCURL)) {
2003
2004 // volume
2005 int order = data.dataOnEntities[MBTET][0].getOrder();
2006 int nb_vol_dofs = NBVOLUMETET_AINSWORTH_HCURL(order);
2007 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts,
2008 3 * nb_vol_dofs, false);
2009 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
2010 9 * nb_vol_dofs, false);
2012 data.dataOnEntities[MBTET][0].getOrder(),
2013 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
2014 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2015 &*data.dataOnEntities[MBTET][0].getN(base).data().begin(),
2016 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin(),
2017 nb_gauss_pts, base_polynomials);
2018
2019 } else {
2020 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 0, false);
2021 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 0, false);
2022 }
2023
2025}
#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 2028 of file TetPolynomialBase.cpp.

2028 {
2030
2031 EntitiesFieldData &data = cTx->dAta;
2032 const FieldApproximationBase base = cTx->bAse;
2033 if (base != DEMKOWICZ_JACOBI_BASE) {
2034 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2035 "This should be used only with DEMKOWICZ_JACOBI_BASE "
2036 "but base is %s",
2038 }
2039
2040 int nb_gauss_pts = pts.size2();
2041
2042 // edges
2043 if (data.spacesOnEntities[MBEDGE].test(HCURL)) {
2044 int sense[6], order[6];
2045 if (data.dataOnEntities[MBEDGE].size() != 6) {
2046 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2047 "wrong size of data structure, expected space for six edges "
2048 "but is %zu",
2049 data.dataOnEntities[MBEDGE].size());
2050 }
2051 double *hcurl_edge_n[6], *diff_hcurl_edge_n[6];
2052 for (int ee = 0; ee != 6; ee++) {
2053 if (data.dataOnEntities[MBEDGE][ee].getSense() == 0) {
2054 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2055 "orintation of edges is not set");
2056 }
2057 sense[ee] = data.dataOnEntities[MBEDGE][ee].getSense();
2058 order[ee] = data.dataOnEntities[MBEDGE][ee].getOrder();
2059 int nb_dofs =
2060 NBEDGE_DEMKOWICZ_HCURL(data.dataOnEntities[MBEDGE][ee].getOrder());
2061 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts,
2062 3 * nb_dofs, false);
2063 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
2064 9 * nb_dofs, false);
2065 hcurl_edge_n[ee] =
2066 &*data.dataOnEntities[MBEDGE][ee].getN(base).data().begin();
2067 diff_hcurl_edge_n[ee] =
2068 &*data.dataOnEntities[MBEDGE][ee].getDiffN(base).data().begin();
2069 }
2071 sense, order,
2072 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
2073 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2074 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts);
2075 } else {
2076 // No DOFs on edges, resize base function matrices, indicating that no
2077 // dofs on them.
2078 for (int ee = 0; ee != 6; ee++) {
2079 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, 0, false);
2080 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts, 0,
2081 false);
2082 }
2083 }
2084
2085 // triangles
2086 if (data.spacesOnEntities[MBTRI].test(HCURL)) {
2087 int order[4];
2088 // faces
2089 if (data.dataOnEntities[MBTRI].size() != 4) {
2090 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2091 "data structure for storing face h-curl base have wrong size "
2092 "should be four but is %zu",
2093 data.dataOnEntities[MBTRI].size());
2094 }
2095 double *hcurl_base_n[4], *diff_hcurl_base_n[4];
2096 for (int ff = 0; ff != 4; ff++) {
2097 if (data.dataOnEntities[MBTRI][ff].getSense() == 0) {
2098 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2099 "orintation of face is not set");
2100 }
2101 order[ff] = data.dataOnEntities[MBTRI][ff].getOrder();
2102 int nb_dofs = NBFACETRI_DEMKOWICZ_HCURL(order[ff]);
2103 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts,
2104 3 * nb_dofs, false);
2105 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
2106 9 * nb_dofs, false);
2107 hcurl_base_n[ff] =
2108 &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
2109 diff_hcurl_base_n[ff] =
2110 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
2111 }
2112 if (data.facesNodes.size1() != 4) {
2113 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2114 "data inconsistency, should be four faces");
2115 }
2116 if (data.facesNodes.size2() != 3) {
2117 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2118 "data inconsistency, should be three nodes on face");
2119 }
2121 &*data.facesNodes.data().begin(), order,
2122 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
2123 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2124 hcurl_base_n, diff_hcurl_base_n, nb_gauss_pts);
2125 } else {
2126 // No DOFs on faces, resize base function matrices, indicating that no
2127 // dofs on them.
2128 for (int ff = 0; ff != 4; ff++) {
2129 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts, 0, false);
2130 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts, 0,
2131 false);
2132 }
2133 }
2134
2135 if (data.spacesOnEntities[MBTET].test(HCURL)) {
2136 // volume
2137 int order = data.dataOnEntities[MBTET][0].getOrder();
2138 int nb_vol_dofs = NBVOLUMETET_DEMKOWICZ_HCURL(order);
2139 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts,
2140 3 * nb_vol_dofs, false);
2141 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
2142 9 * nb_vol_dofs, false);
2144 data.dataOnEntities[MBTET][0].getOrder(),
2145 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
2146 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2147 &*data.dataOnEntities[MBTET][0].getN(base).data().begin(),
2148 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin(),
2149 nb_gauss_pts);
2150 } else {
2151 // No DOFs on faces, resize base function matrices, indicating that no
2152 // dofs on them.
2153 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 0, false);
2154 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 0, false);
2155 }
2156
2158}
#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 1875 of file TetPolynomialBase.cpp.

1875 {
1877
1878 switch (cTx->spaceContinuity) {
1879 case CONTINUOUS:
1880 switch (cTx->bAse) {
1886 default:
1887 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
1888 }
1889 break;
1890 case DISCONTINUOUS:
1891 switch (cTx->bAse) {
1897 default:
1898 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
1899 }
1900 break;
1901
1902 default:
1903 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown continuity");
1904 }
1905
1907}
#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 1027 of file TetPolynomialBase.cpp.

1027 {
1029
1030 std::array<int, 4> faces_order;
1031 std::array<int, 4 * 3> faces_nodes;
1032
1034 EntitiesFieldData &data = cTx->dAta;
1035
1036 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
1037 std::copy(data.facesNodes.data().begin(), data.facesNodes.data().end(),
1038 faces_nodes.begin());
1039 for (int ff = 0; ff != 4; ff++) {
1040 faces_order[ff] = cTx->dAta.dataOnEntities[MBTRI][ff].getOrder();
1041 }
1042
1044 pts, data.dataOnEntities[MBVERTEX][0].getN(base),
1045 data.dataOnEntities[MBVERTEX][0].getDiffN(base), volume_order,
1046 faces_order, faces_nodes,
1047
1053
1054 );
1055
1056 // Set shape functions into data structure Shape functions hast to be put
1057 // in arrays in order which guarantee hierarchical series of degrees of
1058 // freedom, i.e. in other words dofs form sub-entities has to be group
1059 // by order.
1060
1061 FTENSOR_INDEX(3, i);
1062 FTENSOR_INDEX(3, j);
1063
1064 int nb_gauss_pts = pts.size2();
1065 auto get_data_ptr = [](MatrixDouble &m) -> double * {
1066 return (m.size1() && m.size2()) ? &*m.data().begin() : nullptr;
1067 };
1068
1069 // faces
1070 if (data.dataOnEntities[MBTRI].size() != 4) {
1071 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
1072 }
1073
1074 // face-face
1075 using Tensor1Ptr3 =
1076 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
1077 Tensor1Ptr3 t_base_f_f[] = {
1078 getFTensor1FromPtr<3>(get_data_ptr(N_face_bubble[0])),
1079 getFTensor1FromPtr<3>(get_data_ptr(N_face_bubble[1])),
1080 getFTensor1FromPtr<3>(get_data_ptr(N_face_bubble[2])),
1081 getFTensor1FromPtr<3>(get_data_ptr(N_face_bubble[3]))};
1082 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_f_f[] = {
1087 // face-edge
1088 Tensor1Ptr3 t_base_f_e[] = {
1089 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(0, 0))),
1090 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(0, 1))),
1091 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(0, 2))),
1092 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(1, 0))),
1093 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(1, 1))),
1094 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(1, 2))),
1095 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(2, 0))),
1096 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(2, 1))),
1097 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(2, 2))),
1098 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(3, 0))),
1099 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(3, 1))),
1100 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(3, 2)))};
1101 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_f_e[] = {
1102 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(0, 0))),
1103 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(0, 1))),
1104 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(0, 2))),
1105 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(1, 0))),
1106 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(1, 1))),
1107 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(1, 2))),
1108 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(2, 0))),
1109 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(2, 1))),
1110 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(2, 2))),
1111 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(3, 0))),
1112 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(3, 1))),
1113 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(3, 2)))};
1114
1115 for (int ff = 0; ff != 4; ff++) {
1116 int face_order = faces_order[ff];
1117 auto face_dofs =
1122 data.dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts,
1123 3 * face_dofs, false);
1124 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1125 9 * face_dofs, false);
1126 if (face_dofs) {
1127 double *base_ptr =
1128 &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
1129 double *diff_base_ptr =
1130 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
1131 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1132 auto t_diff_base = getFTensor2HVecFromPtr<3, 3>(diff_base_ptr);
1133
1134 auto max_face_order =
1135 std::max(face_order,
1137 max_face_order =
1138 std::max(max_face_order,
1140
1141 for (int gg = 0; gg != nb_gauss_pts; gg++) {
1142 for (int oo = 0; oo != max_face_order; oo++) {
1143
1144 // face-edge
1146 for (int dd = NBFACETRI_AINSWORTH_EDGE_HDIV(oo);
1147 dd != NBFACETRI_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
1148 for (int ee = 0; ee != 3; ++ee) {
1149 t_base(i) = t_base_f_e[ff * 3 + ee](i);
1150 ++t_base;
1151 ++t_base_f_e[ff * 3 + ee];
1152 }
1153 for (int ee = 0; ee != 3; ++ee) {
1154 t_diff_base(i, j) = t_diff_base_f_e[ff * 3 + ee](i, j);
1155 ++t_diff_base;
1156 ++t_diff_base_f_e[ff * 3 + ee];
1157 }
1158 }
1159
1160 // face-face
1162 for (int dd = NBFACETRI_AINSWORTH_FACE_HDIV(oo);
1163 dd != NBFACETRI_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
1164 t_base(i) = t_base_f_f[ff](i);
1165 ++t_base;
1166 ++t_base_f_f[ff];
1167 t_diff_base(i, j) = t_diff_base_f_f[ff](i, j);
1168 ++t_diff_base;
1169 ++t_diff_base_f_f[ff];
1170 }
1171 }
1172 }
1173 }
1174 }
1175
1176 // volume
1177 int volume_dofs =
1184 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * volume_dofs,
1185 false);
1186 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
1187 9 * volume_dofs, false);
1188 if (volume_dofs) {
1189 double *base_ptr =
1190 &*data.dataOnEntities[MBTET][0].getN(base).data().begin();
1191 double *diff_base_ptr =
1192 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin();
1193 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1194 auto t_diff_base = getFTensor2HVecFromPtr<3, 3>(diff_base_ptr);
1195
1196 // volume-edge
1197 using Tensor1Ptr3 =
1198 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
1199 Tensor1Ptr3 t_base_v_e[] = {
1200 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[0])),
1201 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[1])),
1202 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[2])),
1203 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[3])),
1204 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[4])),
1205 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[5]))};
1206 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_e[] = {
1213
1214 // volume-faces
1215 Tensor1Ptr3 t_base_v_f[] = {
1216 getFTensor1FromPtr<3>(get_data_ptr(N_volume_face[0])),
1217 getFTensor1FromPtr<3>(get_data_ptr(N_volume_face[1])),
1218 getFTensor1FromPtr<3>(get_data_ptr(N_volume_face[2])),
1219 getFTensor1FromPtr<3>(get_data_ptr(N_volume_face[3]))};
1220 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_f[] = {
1225
1226 // volume-bubble
1227 base_ptr = get_data_ptr(N_volume_bubble);
1228 diff_base_ptr = get_data_ptr(diffN_volume_bubble);
1229 auto t_base_v = getFTensor1FromPtr<3>(base_ptr);
1230 auto t_diff_base_v = getFTensor2HVecFromPtr<3, 3>(diff_base_ptr);
1231
1232 auto max_volume_order = std::max(
1233 volume_order,
1235 max_volume_order = std::max(
1236 max_volume_order,
1238 max_volume_order = std::max(
1239 max_volume_order,
1241
1242 for (int gg = 0; gg != nb_gauss_pts; gg++) {
1243 for (int oo = 0; oo < max_volume_order; oo++) {
1244
1245 // volume-edge
1246 if (oo <
1248 for (int dd = NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo);
1249 dd != NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
1250 for (int ee = 0; ee < 6; ee++) {
1251 t_base(i) = t_base_v_e[ee](i);
1252 ++t_base;
1253 ++t_base_v_e[ee];
1254 t_diff_base(i, j) = t_diff_base_v_e[ee](i, j);
1255 ++t_diff_base;
1256 ++t_diff_base_v_e[ee];
1257 }
1258 }
1259
1260 // volume-face
1261 if (oo <
1263 for (int dd = NBVOLUMETET_AINSWORTH_FACE_HDIV(oo);
1264 dd < NBVOLUMETET_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
1265 for (int ff = 0; ff < 4; ff++) {
1266 t_base(i) = t_base_v_f[ff](i);
1267 ++t_base;
1268 ++t_base_v_f[ff];
1269 t_diff_base(i, j) = t_diff_base_v_f[ff](i, j);
1270 ++t_diff_base;
1271 ++t_diff_base_v_f[ff];
1272 }
1273 }
1274
1275 // volume-bubble
1276 if (oo <
1278 for (int dd = NBVOLUMETET_AINSWORTH_VOLUME_HDIV(oo);
1280 t_base(i) = t_base_v(i);
1281 ++t_base;
1282 ++t_base_v;
1283 t_diff_base(i, j) = t_diff_base_v(i, j);
1284 ++t_diff_base;
1285 ++t_diff_base_v;
1286 }
1287 }
1288 }
1289 }
1290
1292}
#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)
FTensor::Index< 'm', 3 > m
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 896 of file TetPolynomialBase.cpp.

911 {
913
914 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
915 double *diffL, const int dim) =
917
918 int nb_gauss_pts = pts.size2();
919 auto get_data_ptr = [](MatrixDouble &m) -> double * {
920 return (m.size1() && m.size2()) ? &*m.data().begin() : nullptr;
921 };
922
923 // face shape functions
924
925 double *phi_f_e[4][3];
926 double *phi_f[4];
927 double *diff_phi_f_e[4][3];
928 double *diff_phi_f[4];
929
930 N_face_edge.resize(4, 3, false);
931 N_face_bubble.resize(4, false);
932 diffN_face_edge.resize(4, 3, false);
933 diffN_face_bubble.resize(4, false);
934
935 for (int ff = 0; ff != 4; ++ff) {
936 const auto face_edge_dofs = NBFACETRI_AINSWORTH_EDGE_HDIV(
937 broken_nbfacetri_edge_hdiv(faces_order[ff]));
938 // three edges on face
939 for (int ee = 0; ee < 3; ee++) {
940 N_face_edge(ff, ee).resize(nb_gauss_pts, 3 * face_edge_dofs, false);
941 diffN_face_edge(ff, ee).resize(nb_gauss_pts, 9 * face_edge_dofs, false);
942 phi_f_e[ff][ee] = get_data_ptr(N_face_edge(ff, ee));
943 diff_phi_f_e[ff][ee] = get_data_ptr(diffN_face_edge(ff, ee));
944 }
945 auto face_bubble_dofs = NBFACETRI_AINSWORTH_FACE_HDIV(
946 broken_nbfacetri_face_hdiv(faces_order[ff]));
947 N_face_bubble[ff].resize(nb_gauss_pts, 3 * face_bubble_dofs, false);
948 diffN_face_bubble[ff].resize(nb_gauss_pts, 9 * face_bubble_dofs, false);
949 phi_f[ff] = get_data_ptr(N_face_bubble[ff]);
950 diff_phi_f[ff] = get_data_ptr(diffN_face_bubble[ff]);
951 }
952
953 constexpr int nb_nodes_on_tet = 4;
954
955 for (int ff = 0; ff < 4; ff++) {
957 &faces_nodes[3 * ff], broken_nbfacetri_edge_hdiv(faces_order[ff]),
958 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
959 phi_f_e[ff], diff_phi_f_e[ff], nb_gauss_pts, nb_nodes_on_tet,
960 base_polynomials);
961 }
962
963 for (int ff = 0; ff < 4; ff++) {
965 &faces_nodes[3 * ff], broken_nbfacetri_face_hdiv(faces_order[ff]),
966 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
967 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, nb_nodes_on_tet,
968 base_polynomials);
969 }
970
971 // volume shape functions
972
973 double *phi_v_e[6];
974 double *phi_v_f[4];
975 double *phi_v;
976 double *diff_phi_v_e[6];
977 double *diff_phi_v_f[4];
978 double *diff_phi_v;
979
980 const auto volume_edge_dofs = NBVOLUMETET_AINSWORTH_EDGE_HDIV(
981 broken_nbvolumetet_edge_hdiv(volume_order));
982 N_volume_edge.resize(6, false);
983 diffN_volume_edge.resize(6, false);
984 for (int ee = 0; ee != 6; ++ee) {
985 N_volume_edge[ee].resize(nb_gauss_pts, 3 * volume_edge_dofs, false);
986 diffN_volume_edge[ee].resize(nb_gauss_pts, 9 * volume_edge_dofs, false);
987 phi_v_e[ee] = get_data_ptr(N_volume_edge[ee]);
988 diff_phi_v_e[ee] = get_data_ptr(diffN_volume_edge[ee]);
989 }
990 if (volume_edge_dofs)
992 broken_nbvolumetet_edge_hdiv(volume_order),
993 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
994 phi_v_e, diff_phi_v_e, nb_gauss_pts, base_polynomials);
995
996 const auto volume_face_dofs = NBVOLUMETET_AINSWORTH_FACE_HDIV(
997 broken_nbvolumetet_face_hdiv(volume_order));
998 N_volume_face.resize(4, false);
999 diffN_volume_face.resize(4, false);
1000 for (int ff = 0; ff != 4; ++ff) {
1001 N_volume_face[ff].resize(nb_gauss_pts, 3 * volume_face_dofs, false);
1002 diffN_volume_face[ff].resize(nb_gauss_pts, 9 * volume_face_dofs, false);
1003 phi_v_f[ff] = get_data_ptr(N_volume_face[ff]);
1004 diff_phi_v_f[ff] = get_data_ptr(diffN_volume_face[ff]);
1005 }
1006 if (volume_face_dofs)
1008 broken_nbvolumetet_face_hdiv(volume_order),
1009 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
1010 phi_v_f, diff_phi_v_f, nb_gauss_pts, base_polynomials);
1011
1012 auto volume_bubble_dofs = NBVOLUMETET_AINSWORTH_VOLUME_HDIV(
1013 broken_nbvolumetet_volume_hdiv(volume_order));
1014 N_volume_bubble.resize(nb_gauss_pts, 3 * volume_bubble_dofs, false);
1015 diffN_volume_bubble.resize(nb_gauss_pts, 9 * volume_bubble_dofs, false);
1016 phi_v = get_data_ptr(N_volume_bubble);
1017 diff_phi_v = get_data_ptr(diffN_volume_bubble);
1018 if (volume_bubble_dofs)
1020 broken_nbvolumetet_volume_hdiv(volume_order),
1021 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
1022 phi_v, diff_phi_v, nb_gauss_pts, base_polynomials);
1023
1025}
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:97
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:450
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:224
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:357
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:556

◆ getValueHdivAinsworthBrokenBase()

MoFEMErrorCode TetPolynomialBase::getValueHdivAinsworthBrokenBase ( MatrixDouble &  pts)
protected

Definition at line 1295 of file TetPolynomialBase.cpp.

1295 {
1297
1298 // Set shape functions into data structure Shape functions has to be put
1299 // in arrays in order which guarantee hierarchical series of degrees of
1300 // freedom, i.e. in other words dofs form sub-entities has to be group
1301 // by order.
1302
1304 EntitiesFieldData &data = cTx->dAta;
1305
1306 FTENSOR_INDEX(3, i);
1307 FTENSOR_INDEX(3, j);
1308
1309 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
1310 int nb_gauss_pts = pts.size2();
1311 auto get_data_ptr = [](MatrixDouble &m) -> double * {
1312 return (m.size1() && m.size2()) ? &*m.data().begin() : nullptr;
1313 };
1314 int nb_dofs_face =
1319 int nb_dofs_volume =
1326
1327 int nb_dofs = 4 * nb_dofs_face + nb_dofs_volume;
1328 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
1329 false);
1330 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 9 * nb_dofs,
1331 false);
1332 if (nb_dofs == 0)
1334
1335 auto get_interior_cache = [this](auto base) -> TetBaseCache::BaseCacheMI * {
1336 if (vPtr) {
1337 auto it = TetBaseCache::hdivBrokenBaseInterior[base].find(vPtr);
1338 if (it != TetBaseCache::hdivBrokenBaseInterior[base].end()) {
1339 return &it->second;
1340 }
1341 }
1342 return nullptr;
1343 };
1344
1345 auto interior_cache_ptr = get_interior_cache(base);
1346
1347 if (interior_cache_ptr) {
1348 auto it =
1349 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
1350 if (it != interior_cache_ptr->end()) {
1351 noalias(data.dataOnEntities[MBTET][0].getN(base)) = it->N;
1352 noalias(data.dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1354 }
1355 }
1356
1357 std::array<int, 4 * 3> faces_nodes = {0, 1, 3, 1, 2, 3, 0, 3, 2, 0, 2, 1};
1358 std::array<int, 4> faces_order{volume_order, volume_order, volume_order,
1359 volume_order};
1361 pts, data.dataOnEntities[MBVERTEX][0].getN(base),
1362 data.dataOnEntities[MBVERTEX][0].getDiffN(base), volume_order,
1363 faces_order, faces_nodes,
1364
1370
1371 );
1372
1373 auto *base_ptr = &*data.dataOnEntities[MBTET][0].getN(base).data().begin();
1374 auto *diff_base_ptr =
1375 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin();
1376 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1377 auto t_diff_base = getFTensor2HVecFromPtr<3, 3>(diff_base_ptr);
1378
1379 // face-edge
1380 using Tensor1Ptr3 =
1381 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
1382 Tensor1Ptr3 t_base_f_e[] = {
1383 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(0, 0))),
1384 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(0, 1))),
1385 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(0, 2))),
1386 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(1, 0))),
1387 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(1, 1))),
1388 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(1, 2))),
1389 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(2, 0))),
1390 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(2, 1))),
1391 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(2, 2))),
1392 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(3, 0))),
1393 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(3, 1))),
1394 getFTensor1FromPtr<3>(get_data_ptr(N_face_edge(3, 2)))};
1395 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_f_e[] = {
1396 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(0, 0))),
1397 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(0, 1))),
1398 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(0, 2))),
1399 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(1, 0))),
1400 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(1, 1))),
1401 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(1, 2))),
1402 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(2, 0))),
1403 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(2, 1))),
1404 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(2, 2))),
1405 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(3, 0))),
1406 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(3, 1))),
1407 getFTensor2HVecFromPtr<3, 3>(get_data_ptr(diffN_face_edge(3, 2)))};
1408
1409 // face-face
1410 Tensor1Ptr3 t_base_f_f[] = {
1411 getFTensor1FromPtr<3>(get_data_ptr(N_face_bubble[0])),
1412 getFTensor1FromPtr<3>(get_data_ptr(N_face_bubble[1])),
1413 getFTensor1FromPtr<3>(get_data_ptr(N_face_bubble[2])),
1414 getFTensor1FromPtr<3>(get_data_ptr(N_face_bubble[3]))};
1415 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_f_f[] = {
1420
1421 // volume-edge
1422 Tensor1Ptr3 t_base_v_e[] = {
1423 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[0])),
1424 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[1])),
1425 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[2])),
1426 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[3])),
1427 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[4])),
1428 getFTensor1FromPtr<3>(get_data_ptr(N_volume_edge[5]))};
1429 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_e[] = {
1436
1437 // volume-faces
1438 Tensor1Ptr3 t_base_v_f[] = {
1439 getFTensor1FromPtr<3>(get_data_ptr(N_volume_face[0])),
1440 getFTensor1FromPtr<3>(get_data_ptr(N_volume_face[1])),
1441 getFTensor1FromPtr<3>(get_data_ptr(N_volume_face[2])),
1442 getFTensor1FromPtr<3>(get_data_ptr(N_volume_face[3]))};
1443 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_f[] = {
1448
1449 // volume-bubble
1450 auto *base_vol_ptr = get_data_ptr(N_volume_bubble);
1451 auto *diff_base_vol_ptr = get_data_ptr(diffN_volume_bubble);
1452 auto t_base_v = getFTensor1FromPtr<3>(base_vol_ptr);
1453 auto t_diff_base_v = getFTensor2HVecFromPtr<3, 3>(diff_base_vol_ptr);
1454
1455 int count_dofs = 0;
1456 int count_dofs_face = 0;
1457 int count_dofs_volume = 0;
1458
1459 auto max_volume_order =
1460 std::max(volume_order,
1462 max_volume_order =
1463 std::max(max_volume_order,
1465 max_volume_order =
1466 std::max(max_volume_order,
1468 max_volume_order =
1469 std::max(max_volume_order,
1471 max_volume_order = std::max(
1472 max_volume_order,
1474
1475 for (int gg = 0; gg != nb_gauss_pts; gg++) {
1476 for (int oo = 0; oo < max_volume_order; oo++) {
1477
1478 // faces-edge (((P) > 0) ? (P) : 0)
1480 for (int dd = NBFACETRI_AINSWORTH_EDGE_HDIV(oo);
1481 dd != NBFACETRI_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
1482 for (auto ff = 0; ff != 4; ++ff) {
1483 for (int ee = 0; ee != 3; ++ee) {
1484 t_base(i) = t_base_f_e[ff * 3 + ee](i);
1485 ++t_base;
1486 ++t_base_f_e[ff * 3 + ee];
1487 ++count_dofs;
1488 ++count_dofs_face;
1489 }
1490 for (int ee = 0; ee != 3; ++ee) {
1491 t_diff_base(i, j) = t_diff_base_f_e[ff * 3 + ee](i, j);
1492 ++t_diff_base;
1493 ++t_diff_base_f_e[ff * 3 + ee];
1494 }
1495 }
1496 }
1497
1498 // face-face (P - 1) * (P - 2) / 2
1500 for (int dd = NBFACETRI_AINSWORTH_FACE_HDIV(oo);
1501 dd != NBFACETRI_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
1502 for (auto ff = 0; ff != 4; ++ff) {
1503 t_base(i) = t_base_f_f[ff](i);
1504 ++t_base;
1505 ++t_base_f_f[ff];
1506 t_diff_base(i, j) = t_diff_base_f_f[ff](i, j);
1507 ++t_diff_base;
1508 ++t_diff_base_f_f[ff];
1509 ++count_dofs;
1510 ++count_dofs_face;
1511 }
1512 }
1513
1514 // volume-edge (P - 1)
1516 for (int dd = NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo);
1517 dd != NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
1518 for (int ee = 0; ee < 6; ++ee) {
1519 t_base(i) = t_base_v_e[ee](i);
1520 ++t_base;
1521 ++t_base_v_e[ee];
1522 t_diff_base(i, j) = t_diff_base_v_e[ee](i, j);
1523 ++t_diff_base;
1524 ++t_diff_base_v_e[ee];
1525 ++count_dofs;
1526 ++count_dofs_volume;
1527 }
1528 }
1529
1530 // volume-face (P - 1) * (P - 2)
1532 for (int dd = NBVOLUMETET_AINSWORTH_FACE_HDIV(oo);
1533 dd != NBVOLUMETET_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
1534 for (int ff = 0; ff < 4; ff++) {
1535 t_base(i) = t_base_v_f[ff](i);
1536 ++t_base;
1537 ++t_base_v_f[ff];
1538 t_diff_base(i, j) = t_diff_base_v_f[ff](i, j);
1539 ++t_diff_base;
1540 ++t_diff_base_v_f[ff];
1541 ++count_dofs;
1542 ++count_dofs_volume;
1543 }
1544 }
1545
1546 // volume-bubble (P - 3) * (P - 2) * (P - 1) / 2
1547 if (oo <
1549 for (int dd = NBVOLUMETET_AINSWORTH_VOLUME_HDIV(oo);
1550 dd != NBVOLUMETET_AINSWORTH_VOLUME_HDIV(oo + 1); dd++) {
1551 t_base(i) = t_base_v(i);
1552 ++t_base;
1553 ++t_base_v;
1554 t_diff_base(i, j) = t_diff_base_v(i, j);
1555 ++t_diff_base;
1556 ++t_diff_base_v;
1557 ++count_dofs;
1558 ++count_dofs_volume;
1559 }
1560 }
1561 }
1562
1563#ifndef NDEBUG
1564 if (nb_dofs != count_dofs / nb_gauss_pts) {
1565 MOFEM_LOG_CHANNEL("SELF");
1566 MOFEM_LOG("SELF", Sev::error) << "Nb dofs face: " << 4 * nb_dofs_face
1567 << " -> " << count_dofs_face / nb_gauss_pts;
1568 MOFEM_LOG("SELF", Sev::error) << "Nb dofs volume: " << nb_dofs_volume
1569 << " -> " << count_dofs_volume / nb_gauss_pts;
1570 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1571 "Number of dofs %d is different than expected %d",
1572 count_dofs / nb_gauss_pts, nb_dofs);
1573 }
1574#endif // NDEBUG
1575
1576 if (interior_cache_ptr) {
1577 auto p = interior_cache_ptr->emplace(
1578 TetBaseCache::BaseCacheItem{volume_order, nb_gauss_pts});
1579 p.first->N = data.dataOnEntities[MBTET][0].getN(base);
1580 p.first->diffN = data.dataOnEntities[MBTET][0].getDiffN(base);
1581 }
1582
1584}
#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 1586 of file TetPolynomialBase.cpp.

1586 {
1588
1589 EntitiesFieldData &data = cTx->dAta;
1590 const FieldApproximationBase base = cTx->bAse;
1591 if (base != DEMKOWICZ_JACOBI_BASE) {
1592 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1593 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1594 "but base is %s",
1596 }
1597 int nb_gauss_pts = pts.size2();
1598
1599 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
1600
1601 int p_f[4];
1602 double *phi_f[4];
1603 double *diff_phi_f[4];
1604
1605 auto get_face_cache_ptr = [this]() -> TetBaseCache::HDivBaseFaceCacheMI * {
1606 if (vPtr) {
1609 return &it->second;
1610 }
1611 }
1612 return nullptr;
1613 };
1614
1615 auto face_cache_ptr = get_face_cache_ptr();
1616
1617 // Calculate base function on tet faces
1618 for (int ff = 0; ff != 4; ff++) {
1619 int face_order = data.dataOnEntities[MBTRI][ff].getOrder();
1620 int order = volume_order > face_order ? volume_order : face_order;
1621 data.dataOnEntities[MBTRI][ff].getN(base).resize(
1622 nb_gauss_pts, 3 * NBFACETRI_DEMKOWICZ_HDIV(order), false);
1623 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(
1624 nb_gauss_pts, 9 * NBFACETRI_DEMKOWICZ_HDIV(order), false);
1626 continue;
1627
1628 if (face_cache_ptr) {
1629 auto it = face_cache_ptr->find(boost::make_tuple(
1630
1631 face_order, nb_gauss_pts,
1632
1633 data.facesNodes(ff, 0), data.facesNodes(ff, 1), data.facesNodes(ff, 2)
1634
1635 ));
1636 if (it != face_cache_ptr->end()) {
1637 noalias(data.dataOnEntities[MBTRI][ff].getN(base)) = it->N;
1638 noalias(data.dataOnEntities[MBTRI][ff].getDiffN(base)) = it->diffN;
1639 continue;
1640 }
1641 }
1642
1643 p_f[ff] = order;
1644 phi_f[ff] = &*data.dataOnEntities[MBTRI][ff].getN(base).data().begin();
1645 diff_phi_f[ff] =
1646 &*data.dataOnEntities[MBTRI][ff].getDiffN(base).data().begin();
1647
1649 &data.facesNodes(ff, 0), order,
1650 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1651 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1652 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, 4);
1653 if (face_cache_ptr) {
1654 auto p = face_cache_ptr->emplace(TetBaseCache::HDivBaseCacheItem{
1655 face_order, nb_gauss_pts, data.facesNodes(ff, 0),
1656 data.facesNodes(ff, 1), data.facesNodes(ff, 2)});
1657 p.first->N = data.dataOnEntities[MBTRI][ff].getN(base);
1658 p.first->diffN = data.dataOnEntities[MBTRI][ff].getDiffN(base);
1659 }
1660 }
1661
1662 auto get_interior_cache = [this]() -> TetBaseCache::BaseCacheMI * {
1663 if (vPtr) {
1664 auto it =
1667 return &it->second;
1668 }
1669 }
1670 return nullptr;
1671 };
1672
1673 auto interior_cache_ptr = get_interior_cache();
1674
1675 // Calculate base functions in tet interior
1676 if (NBVOLUMETET_DEMKOWICZ_HDIV(volume_order) > 0) {
1677 data.dataOnEntities[MBTET][0].getN(base).resize(
1678 nb_gauss_pts, 3 * NBVOLUMETET_DEMKOWICZ_HDIV(volume_order), false);
1679 data.dataOnEntities[MBTET][0].getDiffN(base).resize(
1680 nb_gauss_pts, 9 * NBVOLUMETET_DEMKOWICZ_HDIV(volume_order), false);
1681
1682 for (int v = 0; v != 1; ++v) {
1683 if (interior_cache_ptr) {
1684 auto it = interior_cache_ptr->find(
1685 boost::make_tuple(volume_order, nb_gauss_pts));
1686 if (it != interior_cache_ptr->end()) {
1687 noalias(data.dataOnEntities[MBTET][0].getN(base)) = it->N;
1688 noalias(data.dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1689 continue;
1690 }
1691 }
1692
1693 double *phi_v = &*data.dataOnEntities[MBTET][0].getN(base).data().begin();
1694 double *diff_phi_v =
1695 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin();
1696
1698 volume_order, &data.dataOnEntities[MBVERTEX][0].getN(base)(0, 0),
1699 &data.dataOnEntities[MBVERTEX][0].getDiffN(base)(0, 0), p_f, phi_f,
1700 diff_phi_f, phi_v, diff_phi_v, nb_gauss_pts);
1701 if (interior_cache_ptr) {
1702 auto p = interior_cache_ptr->emplace(
1703 TetBaseCache::BaseCacheItem{volume_order, nb_gauss_pts});
1704 p.first->N = data.dataOnEntities[MBTET][0].getN(base);
1705 p.first->diffN = data.dataOnEntities[MBTET][0].getDiffN(base);
1706 }
1707 }
1708 }
1709
1710 // Set size of face base correctly
1711 for (int ff = 0; ff != 4; ff++) {
1712 int face_order = data.dataOnEntities[MBTRI][ff].getOrder();
1713 data.dataOnEntities[MBTRI][ff].getN(base).resize(
1714 nb_gauss_pts, 3 * NBFACETRI_DEMKOWICZ_HDIV(face_order), true);
1715 data.dataOnEntities[MBTRI][ff].getDiffN(base).resize(
1716 nb_gauss_pts, 9 * NBFACETRI_DEMKOWICZ_HDIV(face_order), true);
1717 }
1718
1720}
#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:683
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:829
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 1723 of file TetPolynomialBase.cpp.

1723 {
1725
1726 EntitiesFieldData &data = cTx->dAta;
1727 const FieldApproximationBase base = cTx->bAse;
1728 if (base != DEMKOWICZ_JACOBI_BASE) {
1729 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1730 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1731 "but base is %s",
1733 }
1734 int nb_gauss_pts = pts.size2();
1735
1736 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
1737 int nb_dofs_face = NBFACETRI_DEMKOWICZ_HDIV(volume_order);
1738 int nb_dofs_volume = NBVOLUMETET_DEMKOWICZ_HDIV(volume_order);
1739 int nb_dofs = 4 * nb_dofs_face + nb_dofs_volume;
1740 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
1741 false);
1742 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 9 * nb_dofs,
1743 false);
1744 if (nb_dofs == 0)
1746
1747 auto get_interior_cache = [this]() -> TetBaseCache::BaseCacheMI * {
1748 if (vPtr) {
1749 auto it =
1751 vPtr);
1752 if (it !=
1754 return &it->second;
1755 }
1756 }
1757 return nullptr;
1758 };
1759
1760 auto interior_cache_ptr = get_interior_cache();
1761
1762 if (interior_cache_ptr) {
1763 auto it =
1764 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
1765 if (it != interior_cache_ptr->end()) {
1766 noalias(data.dataOnEntities[MBTET][0].getN(base)) = it->N;
1767 noalias(data.dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1769 }
1770 }
1771
1772 std::array<MatrixDouble, 4> face_base_fun{
1773 MatrixDouble(nb_gauss_pts, 3 * nb_dofs_face),
1774 MatrixDouble(nb_gauss_pts, 3 * nb_dofs_face),
1775 MatrixDouble(nb_gauss_pts, 3 * nb_dofs_face),
1776 MatrixDouble(nb_gauss_pts, 3 * nb_dofs_face)};
1777 std::array<MatrixDouble, 4> face_diff_base{
1778 MatrixDouble(nb_gauss_pts, 9 * nb_dofs_face),
1779 MatrixDouble(nb_gauss_pts, 9 * nb_dofs_face),
1780 MatrixDouble(nb_gauss_pts, 9 * nb_dofs_face),
1781 MatrixDouble(nb_gauss_pts, 9 * nb_dofs_face)};
1782
1783 int faces_nodes[4][3] = {{0, 1, 3}, {1, 2, 3}, {0, 3, 2}, {0, 2, 1}};
1784
1785 std::array<int, 4> p_f{volume_order, volume_order, volume_order,
1786 volume_order};
1787 std::array<double *, 4> phi_f{
1788 &*face_base_fun[0].data().begin(), &*face_base_fun[1].data().begin(),
1789 &*face_base_fun[2].data().begin(), &*face_base_fun[3].data().begin()};
1790 std::array<double *, 4> diff_phi_f{
1791 &*face_diff_base[0].data().begin(), &*face_diff_base[1].data().begin(),
1792 &*face_diff_base[2].data().begin(), &*face_diff_base[3].data().begin()};
1793
1794 // Calculate base function on tet faces
1795 for (int ff = 0; ff != 4; ff++) {
1797 // &data.facesNodes(ff, 0)
1798 faces_nodes[ff], p_f[ff],
1799 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1800 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1801 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, 4);
1802 }
1803
1804 MatrixDouble vol_bases(nb_gauss_pts, 3 * nb_dofs_volume);
1805 MatrixDouble vol_diff_bases(nb_gauss_pts, 9 * nb_dofs_volume);
1806 auto *phi_v = &*vol_bases.data().begin();
1807 auto *diff_phi_v = &*vol_diff_bases.data().begin();
1809 volume_order, &data.dataOnEntities[MBVERTEX][0].getN(base)(0, 0),
1810 &data.dataOnEntities[MBVERTEX][0].getDiffN(base)(0, 0), p_f.data(),
1811 phi_f.data(), diff_phi_f.data(), phi_v, diff_phi_v, nb_gauss_pts);
1812
1813 // faces
1814 using Tensor1Ptr3 =
1815 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
1816 Tensor1Ptr3 t_base_v_f[] = {
1817 getFTensor1FromPtr<3>(phi_f[0]), getFTensor1FromPtr<3>(phi_f[1]),
1818 getFTensor1FromPtr<3>(phi_f[2]), getFTensor1FromPtr<3>(phi_f[3])};
1819 FTensor::Tensor2<FTensor::PackPtr<double *, 9>, 3, 3> t_diff_base_v_f[] = {
1820 getFTensor2HVecFromPtr<3, 3>(diff_phi_f[0]),
1821 getFTensor2HVecFromPtr<3, 3>(diff_phi_f[1]),
1822 getFTensor2HVecFromPtr<3, 3>(diff_phi_f[2]),
1823 getFTensor2HVecFromPtr<3, 3>(diff_phi_f[3])};
1824
1825 // volumes
1826 auto t_base_v = getFTensor1FromPtr<3>(&*vol_bases.data().begin());
1828 getFTensor2HVecFromPtr<3, 3>(&*vol_diff_bases.data().begin());
1829
1830 auto t_base = getFTensor1FromPtr<3>(
1831 &*data.dataOnEntities[MBTET][0].getN(base).data().begin());
1832 auto t_diff_base = getFTensor2HVecFromPtr<3, 3>(
1833 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin());
1834
1835 FTENSOR_INDEX(3, i);
1836 FTENSOR_INDEX(3, j);
1837
1838 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
1839 for (int oo = 0; oo < volume_order; oo++) {
1840 // face
1841 for (auto dd = NBFACETRI_DEMKOWICZ_HDIV(oo);
1842 dd != NBFACETRI_DEMKOWICZ_HDIV(oo + 1); ++dd) {
1843 for (auto ff = 0; ff != 4; ++ff) {
1844 t_base(i) = t_base_v_f[ff](i);
1845 ++t_base;
1846 ++t_base_v_f[ff];
1847 t_diff_base(i, j) = t_diff_base_v_f[ff](i, j);
1848 ++t_diff_base;
1849 ++t_diff_base_v_f[ff];
1850 }
1851 }
1852 // volume
1853 for (auto dd = NBVOLUMETET_DEMKOWICZ_HDIV(oo);
1854 dd != NBVOLUMETET_DEMKOWICZ_HDIV(oo + 1); ++dd) {
1855 t_base(i) = t_base_v(i);
1856 ++t_base;
1857 ++t_base_v;
1858 t_diff_base(i, j) = t_diff_base_v(i, j);
1859 ++t_diff_base;
1860 ++t_diff_base_v;
1861 }
1862 }
1863 }
1864
1865 if (interior_cache_ptr) {
1866 auto p = interior_cache_ptr->emplace(
1867 TetBaseCache::BaseCacheItem{volume_order, nb_gauss_pts});
1868 p.first->N = data.dataOnEntities[MBTET][0].getN(base);
1869 p.first->diffN = data.dataOnEntities[MBTET][0].getDiffN(base);
1870 }
1871
1873}

◆ 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 611 of file TetPolynomialBase.cpp.

611 {
613
614 switch (cTx->bAse) {
619 break;
622 break;
623 default:
624 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
625 }
626
628}
MoFEMErrorCode getValueL2BernsteinBezierBase(MatrixDouble &pts)
MoFEMErrorCode getValueL2AinsworthBase(MatrixDouble &pts)

◆ getValueL2AinsworthBase()

MoFEMErrorCode TetPolynomialBase::getValueL2AinsworthBase ( MatrixDouble &  pts)
protected

Definition at line 630 of file TetPolynomialBase.cpp.

630 {
632
633 EntitiesFieldData &data = cTx->dAta;
634 const FieldApproximationBase base = cTx->bAse;
635 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
636 double *diffL, const int dim) =
638
639 int nb_gauss_pts = pts.size2();
640 int volume_order = data.dataOnEntities[MBTET][0].getOrder();
641 int nb_dofs = NBVOLUMETET_L2(volume_order);
642
643 data.dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, nb_dofs, false);
644 data.dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 3 * nb_dofs,
645 false);
646
647 if (!nb_dofs)
649
650 auto get_interior_cache = [this](auto base) -> TetBaseCache::BaseCacheMI * {
651 if (vPtr) {
652 auto it = TetBaseCache::l2BaseInterior[base].find(vPtr);
653 if (it != TetBaseCache::l2BaseInterior[base].end()) {
654 return &it->second;
655 }
656 }
657 return nullptr;
658 };
659
660 auto interior_cache_ptr = get_interior_cache(base);
661
662 if (interior_cache_ptr) {
663 auto it =
664 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
665 if (it != interior_cache_ptr->end()) {
666 noalias(data.dataOnEntities[MBTET][0].getN(base)) = it->N;
667 noalias(data.dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
669 }
670 }
671
673 data.dataOnEntities[MBTET][0].getOrder(),
674 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
675 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
676 &*data.dataOnEntities[MBTET][0].getN(base).data().begin(),
677 &*data.dataOnEntities[MBTET][0].getDiffN(base).data().begin(),
678 nb_gauss_pts, base_polynomials);
679
680 if (interior_cache_ptr) {
681 auto p = interior_cache_ptr->emplace(
682 TetBaseCache::BaseCacheItem{volume_order, nb_gauss_pts});
683 p.first->N = data.dataOnEntities[MBTET][0].getN(base);
684 p.first->diffN = data.dataOnEntities[MBTET][0].getDiffN(base);
685 }
686
688}
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 691 of file TetPolynomialBase.cpp.

691 {
693
694 EntitiesFieldData &data = cTx->dAta;
695 const std::string field_name = cTx->fieldName;
696 const int nb_gauss_pts = pts.size2();
697
698 if (data.dataOnEntities[MBVERTEX][0].getN(NOBASE).size1() !=
699 (unsigned int)nb_gauss_pts)
700 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
701 "Base functions or nodes has wrong number of integration points "
702 "for base %s",
704 auto &lambda = data.dataOnEntities[MBVERTEX][0].getN(NOBASE);
705
706 auto get_alpha = [field_name](auto &data) -> MatrixInt & {
707 auto &ptr = data.getBBAlphaIndicesSharedPtr(field_name);
708 if (!ptr)
709 ptr.reset(new MatrixInt());
710 return *ptr;
711 };
712
713 auto get_base = [field_name](auto &data) -> MatrixDouble & {
714 auto &ptr = data.getBBNSharedPtr(field_name);
715 if (!ptr)
716 ptr.reset(new MatrixDouble());
717 return *ptr;
718 };
719
720 auto get_diff_base = [field_name](auto &data) -> MatrixDouble & {
721 auto &ptr = data.getBBDiffNSharedPtr(field_name);
722 if (!ptr)
723 ptr.reset(new MatrixDouble());
724 return *ptr;
725 };
726
727 auto get_alpha_by_name_ptr =
728 [](auto &data,
729 const std::string &field_name) -> boost::shared_ptr<MatrixInt> & {
730 return data.getBBAlphaIndicesSharedPtr(field_name);
731 };
732
733 auto get_base_by_name_ptr =
734 [](auto &data,
735 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
736 return data.getBBNSharedPtr(field_name);
737 };
738
739 auto get_diff_base_by_name_ptr =
740 [](auto &data,
741 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
742 return data.getBBDiffNSharedPtr(field_name);
743 };
744
745 auto get_alpha_by_order_ptr =
746 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixInt> & {
747 return data.getBBAlphaIndicesByOrderSharedPtr(o);
748 };
749
750 auto get_base_by_order_ptr =
751 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
752 return data.getBBNByOrderSharedPtr(o);
753 };
754
755 auto get_diff_base_by_order_ptr =
756 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
757 return data.getBBDiffNByOrderSharedPtr(o);
758 };
759
760 // See make_own in getValueH1BernsteinBezierBase: detach from a by-order
761 // matrix shared with another field before writing into it.
762 auto make_own = [field_name](auto &ent_data) {
763 auto &n_ptr = ent_data.getBBNSharedPtr(field_name);
764 if (!n_ptr)
765 return;
766 for (auto &ptr : ent_data.getBBNByOrderArray()) {
767 if (ptr && ptr.get() == n_ptr.get()) {
768 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
769 ent_data.getBBDiffNSharedPtr(field_name).reset();
770 n_ptr.reset();
771 return;
772 }
773 }
774 };
775
776 if (data.spacesOnEntities[MBTET].test(L2)) {
777 if (data.dataOnEntities[MBTET].size() != 1)
778 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
779 "Wrong size ent of ent data");
780
781 auto &ent_data = data.dataOnEntities[MBTET][0];
782 const int order = ent_data.getOrder();
783 const int nb_dofs = NBVOLUMETET_L2(order);
784 // L2 is element-local, so the order may differ between elements; only the
785 // storage limit applies.
786 if (order < 0 || static_cast<size_t>(order) >=
788 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
789 "Bernstein-Bezier order %d is outside the supported range "
790 "[0, %d]",
791 order,
792 static_cast<int>(
794 1);
795
796 if (get_alpha_by_order_ptr(ent_data, order)) {
797 get_alpha_by_name_ptr(ent_data, field_name) =
798 get_alpha_by_order_ptr(ent_data, order);
799 get_base_by_name_ptr(ent_data, field_name) =
800 get_base_by_order_ptr(ent_data, order);
801 get_diff_base_by_name_ptr(ent_data, field_name) =
802 get_diff_base_by_order_ptr(ent_data, order);
803 } else {
804
805 make_own(ent_data);
806 auto &get_n = get_base(ent_data);
807 auto &get_diff_n = get_diff_base(ent_data);
808 get_n.resize(nb_gauss_pts, nb_dofs, false);
809 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs, false);
810
811 if (nb_dofs) {
812
813 if (order == 0) {
814
815 if (nb_dofs != 1)
816 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
817 "Inconsistent number of DOFs");
818
819 // The single degree-zero function is one at every integration
820 // point, with the zero multi-index.
821 auto &tet_alpha = get_alpha(ent_data);
822 tet_alpha.resize(1, 4, false);
823 tet_alpha.clear();
824 std::fill(get_n.data().begin(), get_n.data().end(), 1.);
825 get_diff_n.clear();
826
827 } else {
828
829 if (nb_dofs != 4 + 6 * NBEDGE_H1(order) + 4 * NBFACETRI_H1(order) +
831 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
832 "Inconsistent number of DOFs");
833
834 auto &tet_alpha = get_alpha(ent_data);
835 tet_alpha.resize(nb_dofs, 4, false);
836
838 &tet_alpha(0, 0));
839 if (order > 1) {
840 std::array<int, 6> edge_n{order, order, order, order, order, order};
841 std::array<int *, 6> tet_edge_ptr{
842 &tet_alpha(4, 0),
843 &tet_alpha(4 + 1 * NBEDGE_H1(order), 0),
844 &tet_alpha(4 + 2 * NBEDGE_H1(order), 0),
845 &tet_alpha(4 + 3 * NBEDGE_H1(order), 0),
846 &tet_alpha(4 + 4 * NBEDGE_H1(order), 0),
847 &tet_alpha(4 + 5 * NBEDGE_H1(order), 0)};
849 tet_edge_ptr.data());
850 if (order > 2) {
851 std::array<int, 4> face_n{order, order, order, order};
852 std::array<int *, 4> tet_face_ptr{
853 &tet_alpha(4 + 6 * NBEDGE_H1(order), 0),
854 &tet_alpha(4 + 6 * NBEDGE_H1(order) + 1 * NBFACETRI_H1(order),
855 0),
856 &tet_alpha(4 + 6 * NBEDGE_H1(order) + 2 * NBFACETRI_H1(order),
857 0),
858 &tet_alpha(4 + 6 * NBEDGE_H1(order) + 3 * NBFACETRI_H1(order),
859 0),
860 };
862 face_n.data(), tet_face_ptr.data());
863 if (order > 3)
865 order,
866 &tet_alpha(
867 4 + 6 * NBEDGE_H1(order) + 4 * NBFACETRI_H1(order), 0));
868 }
869 }
870
872 order, lambda.size1(), tet_alpha.size1(), &tet_alpha(0, 0),
873 &lambda(0, 0), Tools::diffShapeFunMBTET.data(), &get_n(0, 0),
874 &get_diff_n(0, 0));
875
876 get_alpha_by_order_ptr(ent_data, order) =
877 get_alpha_by_name_ptr(ent_data, field_name);
878 get_base_by_order_ptr(ent_data, order) =
879 get_base_by_name_ptr(ent_data, field_name);
880 get_diff_base_by_order_ptr(ent_data, order) =
881 get_diff_base_by_name_ptr(ent_data, field_name);
882 }
883 }
884 }
885 } else {
886 auto &ent_data = data.dataOnEntities[MBTET][0];
887 make_own(ent_data);
888 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
889 get_base(ent_data).resize(nb_gauss_pts, 0, false);
890 get_diff_base(ent_data).resize(nb_gauss_pts, 0, false);
891 }
892
894}
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 2260 of file TetPolynomialBase.cpp.

2265 {
2267
2268 switch (continuity) {
2269 case DISCONTINUOUS:
2270
2271 switch (space) {
2272 case HDIV:
2273 CHKERR setDofsSideMapHdiv(continuity, base, dofs_side_map);
2274 break;
2275 default:
2276 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown space %s",
2277 FieldSpaceNames[space]);
2278 }
2279 break;
2280
2281 default:
2282 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
2283 "Unknown (or not implemented) continuity");
2284 }
2285
2287}
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 2290 of file TetPolynomialBase.cpp.

2292 {
2294
2295 // That has to be consistent with implementation of getValueHdiv for
2296 // particular base functions.
2297
2298 auto set_ainsworth = [&dofs_side_map]() {
2300
2301 dofs_side_map.clear();
2302
2303 const auto map_order = Field::maxBrokenDofsOrder;
2304 const auto face_edge_order =
2306 const auto face_face_order =
2308 const auto volume_edge_order =
2310 const auto volume_face_order =
2312 const auto volume_bubble_order =
2314
2315 auto max_order = std::max(map_order, face_edge_order);
2316 max_order = std::max(max_order, face_face_order);
2317 max_order = std::max(max_order, volume_edge_order);
2318 max_order = std::max(max_order, volume_face_order);
2319 max_order = std::max(max_order, volume_bubble_order);
2320
2321 int dof = 0;
2322 for (int oo = 0; oo < max_order; oo++) {
2323
2324 // faces-edge (((P) > 0) ? (P) : 0)
2325 if (oo < face_edge_order)
2326 for (int dd = NBFACETRI_AINSWORTH_EDGE_HDIV(oo);
2327 dd != NBFACETRI_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
2328 for (auto ff = 0; ff != 4; ++ff) {
2329 for (int ee = 0; ee != 3; ++ee) {
2330 dofs_side_map.insert(DofsSideMapData{MBTRI, ff, dof});
2331 ++dof;
2332 }
2333 }
2334 }
2335
2336 // face-face (P - 1) * (P - 2) / 2
2337 if (oo < face_face_order)
2338 for (int dd = NBFACETRI_AINSWORTH_FACE_HDIV(oo);
2339 dd != NBFACETRI_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
2340 for (auto ff = 0; ff != 4; ++ff) {
2341 dofs_side_map.insert(DofsSideMapData{MBTRI, ff, dof});
2342 ++dof;
2343 }
2344 }
2345
2346 // volume-edge (P - 1)
2347 if (oo < volume_edge_order)
2348 for (int dd = NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo);
2349 dd != NBVOLUMETET_AINSWORTH_EDGE_HDIV(oo + 1); dd++) {
2350 for (int ee = 0; ee < 6; ee++) {
2351 dofs_side_map.insert(DofsSideMapData{MBTET, 0, dof});
2352 ++dof;
2353 }
2354 }
2355
2356 // volume-face (P - 1) * (P - 2)
2357 if (oo < volume_face_order)
2358 for (int dd = NBVOLUMETET_AINSWORTH_FACE_HDIV(oo);
2359 dd < NBVOLUMETET_AINSWORTH_FACE_HDIV(oo + 1); dd++) {
2360 for (int ff = 0; ff < 4; ff++) {
2361 dofs_side_map.insert(DofsSideMapData{MBTET, 0, dof});
2362 ++dof;
2363 }
2364 }
2365
2366 // volume-bubble (P - 3) * (P - 2) * (P - 1) / 2
2367 if (oo < volume_bubble_order)
2368 for (int dd = NBVOLUMETET_AINSWORTH_VOLUME_HDIV(oo);
2370 dofs_side_map.insert(DofsSideMapData{MBTET, 0, dof});
2371 ++dof;
2372 }
2373 }
2374
2376 };
2377
2378 auto set_demkowicz = [&dofs_side_map]() {
2380
2381 dofs_side_map.clear();
2382
2383 int dof = 0;
2384 for (int oo = 0; oo < Field::maxBrokenDofsOrder; oo++) {
2385
2386 // face
2387 for (auto dd = NBFACETRI_DEMKOWICZ_HDIV(oo);
2388 dd != NBFACETRI_DEMKOWICZ_HDIV(oo + 1); ++dd) {
2389 for (auto ff = 0; ff != 4; ++ff) {
2390 dofs_side_map.insert(DofsSideMapData{MBTRI, ff, dof});
2391 ++dof;
2392 }
2393 }
2394 // volume
2395 for (auto dd = NBVOLUMETET_DEMKOWICZ_HDIV(oo);
2396 dd != NBVOLUMETET_DEMKOWICZ_HDIV(oo + 1); ++dd) {
2397 dofs_side_map.insert(DofsSideMapData{MBTET, 0, dof});
2398 ++dof;
2399 }
2400 }
2401
2403 };
2404
2405 switch (continuity) {
2406 case DISCONTINUOUS:
2407 switch (base) {
2410 MoFEMFunctionReturnHot(set_ainsworth());
2412 MoFEMFunctionReturnHot(set_demkowicz());
2413 default:
2414 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
2415 }
2416 break;
2417
2418 default:
2419 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
2420 "Unknown (or not implemented) continuity");
2421 }
2422
2424}
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 2445 of file TetPolynomialBase.cpp.

2446 {
2448 std::string("hDivBaseFace") +
2450}
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 2453 of file TetPolynomialBase.cpp.

2454 {
2456 std::string("hdivBaseInterior") +
2458}

◆ switchCacheBaseInterior() [2/5]

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

Definition at line 2515 of file TetPolynomialBase.cpp.

2516 {
2518 std::string("hdivBaseInterior") +
2520}

◆ 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 2485 of file TetPolynomialBase.cpp.

2486 {
2487 for (auto fe_ptr : v) {
2488 if (TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr)) {
2489 TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr);
2490 }
2491 if (TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr)) {
2492 TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr);
2493 }
2494 if (TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr)) {
2495 TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr);
2496 }
2497 }
2498}

◆ switchCacheBaseOff() [2/10]

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

Definition at line 2533 of file TetPolynomialBase.cpp.

2534 {
2535 for (auto fe_ptr : v) {
2536 if (TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr)) {
2537 TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr);
2538 }
2539 }
2540}

◆ 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 2508 of file TetPolynomialBase.cpp.

2508 {
2509 for (auto b = 0; b != LASTBASE; ++b) {
2510 switchCacheBaseOff<HDIV>(static_cast<FieldApproximationBase>(b), v);
2511 }
2512}

◆ switchCacheBaseOff() [7/10]

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

Definition at line 2550 of file TetPolynomialBase.cpp.

2550 {
2551 for (auto b = 0; b != LASTBASE; ++b) {
2552 switchCacheBaseOff<L2>(static_cast<FieldApproximationBase>(b), v);
2553 }
2554}

◆ 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 2469 of file TetPolynomialBase.cpp.

2470 {
2471 for (auto fe_ptr : v) {
2472 if (!TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr)) {
2473 TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr);
2474 }
2475 if (!TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr)) {
2476 TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr);
2477 }
2478 if (!TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr)) {
2479 TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr);
2480 }
2481 }
2482}

◆ switchCacheBaseOn() [2/10]

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

Definition at line 2523 of file TetPolynomialBase.cpp.

2524 {
2525 for (auto fe_ptr : v) {
2526 if (!TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr)) {
2527 TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr);
2528 }
2529 }
2530}

◆ 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 2501 of file TetPolynomialBase.cpp.

2501 {
2502 for (auto b = 0; b != LASTBASE; ++b) {
2503 switchCacheBaseOn<HDIV>(static_cast<FieldApproximationBase>(b), v);
2504 }
2505}

◆ switchCacheBaseOn() [7/10]

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

Definition at line 2543 of file TetPolynomialBase.cpp.

2543 {
2544 for (auto b = 0; b != LASTBASE; ++b) {
2545 switchCacheBaseOn<L2>(static_cast<FieldApproximationBase>(b), v);
2546 }
2547}

◆ 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 2461 of file TetPolynomialBase.cpp.

2462 {
2464 std::string("hdivBrokenBaseInterior") +
2466}

◆ 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: