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

Calculate base functions on triangle. More...

#include "src/approximation/TriPolynomialBase.hpp"

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

Public Member Functions

MoFEMErrorCode query_interface (boost::typeindex::type_index type_index, UnknownInterface **iface) const
 
 TriPolynomialBase ()=default
 
virtual ~TriPolynomialBase ()=default
 
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

static MoFEMErrorCode setDofsSideMap (const FieldSpace space, const FieldContinuity continuity, const FieldApproximationBase base, DofsSideMap &)
 Set map of dof to side number.
 
- 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.
 

Private Member Functions

MoFEMErrorCode getValueH1 (MatrixDouble &pts)
 
MoFEMErrorCode getValueH1AinsworthBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueH1BernsteinBezierBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueL2 (MatrixDouble &pts)
 
MoFEMErrorCode getValueL2AinsworthBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueL2BernsteinBezierBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHdiv (MatrixDouble &pts)
 
MoFEMErrorCode getValueHcurl (MatrixDouble &pts)
 
MoFEMErrorCode getValueHdivAinsworthBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHcurlAinsworthBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHdivDemkowiczBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHcurlDemkowiczBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHcurlAinsworthBrokenBase (MatrixDouble &pts)
 
MoFEMErrorCode getValueHcurlDemkowiczBrokenBase (MatrixDouble &pts)
 

Static Private Member Functions

static MoFEMErrorCode setDofsSideMapHcurl (const FieldSpace space, const FieldContinuity continuity, const FieldApproximationBase base, DofsSideMap &dofs_side_map)
 

Private Attributes

EntPolynomialBaseCtx * cTx
 
ublas::matrix< MatrixDouble > N_face_edge
 
ublas::vector< MatrixDouble > N_face_bubble
 
ublas::matrix< MatrixDouble > diffN_face_edge
 
ublas::vector< MatrixDouble > diffN_face_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 triangle.

Definition at line 16 of file TriPolynomialBase.hpp.

Constructor & Destructor Documentation

◆ TriPolynomialBase()

MoFEM::TriPolynomialBase::TriPolynomialBase ( )
default

◆ ~TriPolynomialBase()

virtual MoFEM::TriPolynomialBase::~TriPolynomialBase ( )
virtualdefault

Member Function Documentation

◆ getValue()

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

Reimplemented from MoFEM::BaseFunction.

Definition at line 1243 of file TriPolynomialBase.cpp.

1244 {
1246
1248
1249 int nb_gauss_pts = pts.size2();
1250 if (!nb_gauss_pts) {
1252 }
1253
1254 if (pts.size1() < 2)
1255 SETERRQ(
1256 PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1257 "Wrong dimension of pts, should be at least 3 rows with coordinates");
1258
1259 const FieldApproximationBase base = cTx->bAse;
1260 EntitiesFieldData &data = cTx->dAta;
1261
1262 if (base != AINSWORTH_BERNSTEIN_BEZIER_BASE) {
1263 if (cTx->copyNodeBase == LASTBASE) {
1264 data.dataOnEntities[MBVERTEX][0].getN(base).resize(nb_gauss_pts, 3,
1265 false);
1267 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1268 &pts(0, 0), &pts(1, 0), nb_gauss_pts);
1269 data.dataOnEntities[MBVERTEX][0].getDiffN(base).resize(3, 2, false);
1271 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin());
1272 } else {
1273 data.dataOnEntities[MBVERTEX][0].getN(base) =
1274 data.dataOnEntities[MBVERTEX][0].getN(cTx->copyNodeBase);
1275 data.dataOnEntities[MBVERTEX][0].getDiffN(base) =
1276 data.dataOnEntities[MBVERTEX][0].getDiffN(cTx->copyNodeBase);
1277 }
1278 if (data.dataOnEntities[MBVERTEX][0].getN(base).size1() !=
1279 (unsigned int)nb_gauss_pts) {
1280 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1281 "Base functions or nodes has wrong number of integration points "
1282 "for base %s",
1284 }
1285 }
1286
1287 auto set_node_derivative_for_all_gauss_pts = [&]() {
1289 // In linear geometry derivatives are constant,
1290 // this in expense of efficiency makes implementation
1291 // consistent between vertices and other types of entities
1292 data.dataOnEntities[MBVERTEX][0].getDiffN(base).resize(nb_gauss_pts, 6,
1293 false);
1294 for (int gg = 0; gg != nb_gauss_pts; ++gg)
1295 std::copy(Tools::diffShapeFunMBTRI.begin(),
1297 &data.dataOnEntities[MBVERTEX][0].getDiffN(base)(gg, 0));
1299 };
1300
1301 CHKERR set_node_derivative_for_all_gauss_pts();
1302
1303 switch (cTx->spaceContinuity) {
1304 case CONTINUOUS:
1305
1306 switch (cTx->sPace) {
1307 case H1:
1309 case HDIV:
1311 case HCURL:
1313 case L2:
1315 default:
1316 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not yet implemented");
1317 }
1318
1319 case DISCONTINUOUS:
1320 switch (cTx->sPace) {
1321 case HCURL:
1323 default:
1324 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not yet implemented");
1325 }
1326
1327 default:
1328 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown continuity");
1329 }
1330
1332}
FieldApproximationBase
approximation base
Definition definitions.h:58
@ LASTBASE
Definition definitions.h:69
@ 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)
#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.
PetscErrorCode ShapeDiffMBTRI(double *diffN)
calculate derivatives of shape functions
Definition fem_tools.c:194
PetscErrorCode ShapeMBTRI(double *N, const double *X, const double *Y, const int G_DIM)
calculate shape functions on triangle
Definition fem_tools.c:182
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
static constexpr std::array< double, 6 > diffShapeFunMBTRI
Definition Tools.hpp:104
MoFEMErrorCode getValueH1(MatrixDouble &pts)
MoFEMErrorCode getValueL2(MatrixDouble &pts)
MoFEMErrorCode getValueHcurl(MatrixDouble &pts)
EntPolynomialBaseCtx * cTx
MoFEMErrorCode getValueHdiv(MatrixDouble &pts)
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.

◆ getValueH1()

MoFEMErrorCode TriPolynomialBase::getValueH1 ( MatrixDouble &  pts)
private

Definition at line 16 of file TriPolynomialBase.cpp.

16 {
18
19 switch (cTx->bAse) {
25 default:
26 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
27 }
28
30}
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ AINSWORTH_LOBATTO_BASE
Definition definitions.h:62
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
MoFEMErrorCode getValueH1BernsteinBezierBase(MatrixDouble &pts)
MoFEMErrorCode getValueH1AinsworthBase(MatrixDouble &pts)

◆ getValueH1AinsworthBase()

MoFEMErrorCode TriPolynomialBase::getValueH1AinsworthBase ( MatrixDouble &  pts)
private

Definition at line 332 of file TriPolynomialBase.cpp.

332 {
334
335 EntitiesFieldData &data = cTx->dAta;
336 const FieldApproximationBase base = cTx->bAse;
337
338 if (cTx->basePolynomialsType0 == NULL)
339 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
340 "Polynomial type not set");
341
342 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
343 double *diffL, const int dim) =
345
346 int nb_gauss_pts = pts.size2();
347
348 if (data.spacesOnEntities[MBEDGE].test(H1)) {
349 // edges
350 if (data.dataOnEntities[MBEDGE].size() != 3)
351 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
352 "expected size of data.dataOnEntities[MBEDGE] is 3");
353
354 int sense[3], order[3];
355 double *H1edgeN[3], *diffH1edgeN[3];
356 for (int ee = 0; ee < 3; ee++) {
357
358 if (data.dataOnEntities[MBEDGE][ee].getSense() == 0)
359 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
360 "sense of the edge unknown");
361
362 sense[ee] = data.dataOnEntities[MBEDGE][ee].getSense();
363 order[ee] = data.dataOnEntities[MBEDGE][ee].getOrder();
364 int nb_dofs = NBEDGE_H1(data.dataOnEntities[MBEDGE][ee].getOrder());
365 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, nb_dofs,
366 false);
367 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
368 2 * nb_dofs, false);
369 H1edgeN[ee] = &*data.dataOnEntities[MBEDGE][ee].getN(base).data().begin();
370 diffH1edgeN[ee] =
371 &*data.dataOnEntities[MBEDGE][ee].getDiffN(base).data().begin();
372 }
374 sense, order,
375 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
376 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
377 H1edgeN, diffH1edgeN, nb_gauss_pts, base_polynomials);
378 }
379
380 if (data.spacesOnEntities[MBTRI].test(H1)) {
381 // face
382 if (data.dataOnEntities[MBTRI].size() != 1) {
383 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
384 "expected that size data.dataOnEntities[MBTRI] is one");
385 }
386
387 int nb_dofs = NBFACETRI_H1(data.dataOnEntities[MBTRI][0].getOrder());
388 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, nb_dofs,
389 false);
390 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts,
391 2 * nb_dofs, false);
392 const int face_nodes[] = {0, 1, 2};
394 face_nodes, data.dataOnEntities[MBTRI][0].getOrder(),
395 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
396 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
397 &*data.dataOnEntities[MBTRI][0].getN(base).data().begin(),
398 &*data.dataOnEntities[MBTRI][0].getDiffN(base).data().begin(),
399 nb_gauss_pts, base_polynomials);
400 }
401
403}
constexpr int order
#define NBEDGE_H1(P)
Number of base function on edge for H1 space.
PetscErrorCode H1_EdgeShapeFunctions_MBTRI(int *sense, int *p, double *N, double *diffN, double *edgeN[3], double *diff_edgeN[3], int GDIM, PetscErrorCode(*base_polynomials)(int p, double s, double *diff_s, double *L, double *diffL, const int dim))
H1_EdgeShapeFunctions_MBTRI.
Definition h1.c:17
PetscErrorCode H1_FaceShapeFunctions_MBTRI(const int *face_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:191
#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)
std::array< std::bitset< LASTSPACE >, MBMAXTYPE > spacesOnEntities
spaces on entity types

◆ getValueH1BernsteinBezierBase()

MoFEMErrorCode TriPolynomialBase::getValueH1BernsteinBezierBase ( MatrixDouble &  pts)
private

Definition at line 33 of file TriPolynomialBase.cpp.

33 {
35 EntitiesFieldData &data = cTx->dAta;
36 const std::string &field_name = cTx->fieldName;
37 int nb_gauss_pts = pts.size2();
38
39 auto get_alpha = [field_name](auto &data) -> MatrixInt & {
40 auto &ptr = data.getBBAlphaIndicesSharedPtr(field_name);
41 if (!ptr)
42 ptr.reset(new MatrixInt());
43 return *ptr;
44 };
45
46 auto get_base = [field_name](auto &data) -> MatrixDouble & {
47 auto &ptr = data.getBBNSharedPtr(field_name);
48 if (!ptr)
49 ptr.reset(new MatrixDouble());
50 return *ptr;
51 };
52
53 auto get_diff_base = [field_name](auto &data) -> MatrixDouble & {
54 auto &ptr = data.getBBDiffNSharedPtr(field_name);
55 if (!ptr)
56 ptr.reset(new MatrixDouble());
57 return *ptr;
58 };
59
60 auto get_alpha_by_name_ptr =
61 [](auto &data,
62 const std::string &field_name) -> boost::shared_ptr<MatrixInt> & {
63 return data.getBBAlphaIndicesSharedPtr(field_name);
64 };
65
66 auto get_base_by_name_ptr =
67 [](auto &data,
68 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
69 return data.getBBNSharedPtr(field_name);
70 };
71
72 auto get_diff_base_by_name_ptr =
73 [](auto &data,
74 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
75 return data.getBBDiffNSharedPtr(field_name);
76 };
77
78 auto get_alpha_by_order_ptr =
79 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixInt> & {
80 return data.getBBAlphaIndicesByOrderSharedPtr(o);
81 };
82
83 auto get_base_by_order_ptr =
84 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
85 return data.getBBNByOrderSharedPtr(o);
86 };
87
88 auto get_diff_base_by_order_ptr =
89 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
90 return data.getBBDiffNByOrderSharedPtr(o);
91 };
92
93 // A field which was given a by-order matrix shared with another field on a
94 // previous element must not write into it here: on this element that matrix
95 // may already hold the other field's base. Detach and allocate own storage.
96 auto make_own = [field_name](auto &ent_data) {
97 auto &n_ptr = ent_data.getBBNSharedPtr(field_name);
98 if (!n_ptr)
99 return;
100 for (auto &ptr : ent_data.getBBNByOrderArray()) {
101 if (ptr && ptr.get() == n_ptr.get()) {
102 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
103 ent_data.getBBDiffNSharedPtr(field_name).reset();
104 n_ptr.reset();
105 return;
106 }
107 }
108 };
109
110 // Entity without base functions for this field: no alpha indices and base
111 // matrices with zero columns, consistent with the hierarchical bases.
112 auto set_empty = [&](auto &ent_data) {
113 make_own(ent_data);
114 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
115 get_base(ent_data).resize(nb_gauss_pts, 0, false);
116 get_diff_base(ent_data).resize(nb_gauss_pts, 0, false);
117 };
118
119 // The BB base is not hierarchical, so mixing degrees between the entities
120 // of one element loses completeness. H1 requires one order on all entities
121 // which carry DOFs and vertex degrees between one and that order. L2 is
122 // element-local and has no such restriction. See the tetrahedron version
123 // for the full argument.
124 auto check_uniform_order = [&]() {
126 auto &node_order = data.dataOnEntities[MBVERTEX][0].getBBNodeOrder();
127 if (node_order.size() != 3)
128 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
129 "Wrong number of vertex orders for BB base: %d",
130 static_cast<int>(node_order.size()));
131 int order = 0;
132 for (int n = 0; n != 3; ++n)
133 order = std::max(order, node_order[n]);
134 auto max_order_on = [&](const EntityType type) {
135 if (data.spacesOnEntities[type].test(H1))
136 for (auto &ent_data : data.dataOnEntities[type])
137 order = std::max(order, ent_data.getOrder());
138 };
139 max_order_on(MBEDGE);
140 max_order_on(MBTRI);
141 if (order < 1)
142 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
143 "Bernstein-Bezier H1 base requires approximation order >= 1");
144 if (static_cast<size_t>(order) >=
146 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
147 "Bernstein-Bezier order %d exceeds the supported maximum %d",
148 order,
149 static_cast<int>(
151 1);
152 for (int n = 0; n != 3; ++n)
153 if (node_order[n] < 1)
154 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
155 "Bernstein-Bezier H1 base requires vertex order between 1 "
156 "and the element order %d; vertex %d has order %d",
157 order, n, node_order[n]);
158 auto check_type = [&](const EntityType type, const int nb_dofs_at_order) {
160 if (!nb_dofs_at_order || !data.spacesOnEntities[type].test(H1))
162 int side = 0;
163 for (auto &ent_data : data.dataOnEntities[type]) {
164 if (ent_data.getOrder() != order)
165 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
166 "Bernstein-Bezier base in H1 space requires uniform "
167 "approximation order on the element: %s %d has order %d, "
168 "element order is %d. BB functions are not hierarchical, "
169 "so mixed degrees do not span a complete polynomial space. "
170 "Set one order for the whole H1 field (L2 fields are not "
171 "restricted).",
172 moab::CN::EntityTypeName(type), side, ent_data.getOrder(),
173 order);
174 ++side;
175 }
177 };
178 CHKERR check_type(MBEDGE, NBEDGE_H1(order));
179 CHKERR check_type(MBTRI, NBFACETRI_H1(order));
181 };
182 CHKERR check_uniform_order();
183
184 auto &vert_get_n = get_base(data.dataOnEntities[MBVERTEX][0]);
185 auto &vert_get_diff_n = get_diff_base(data.dataOnEntities[MBVERTEX][0]);
186 vert_get_n.resize(nb_gauss_pts, 3, false);
187 vert_get_diff_n.resize(nb_gauss_pts, 6, false);
188
189 if (data.dataOnEntities[MBVERTEX][0].getN(NOBASE).size1() !=
190 (unsigned int)nb_gauss_pts)
191 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
192 "Base functions or nodes has wrong number of integration points "
193 "for base %s",
195 auto &lambda = data.dataOnEntities[MBVERTEX][0].getN(NOBASE);
196
197 auto &vertex_alpha = get_alpha(data.dataOnEntities[MBVERTEX][0]);
198 vertex_alpha.resize(3, 3, false);
199 vertex_alpha.clear();
200 for (int n = 0; n != 3; ++n)
201 vertex_alpha(n, n) = data.dataOnEntities[MBVERTEX][0].getBBNodeOrder()[n];
202
204 1, lambda.size1(), vertex_alpha.size1(), &vertex_alpha(0, 0),
205 &lambda(0, 0), Tools::diffShapeFunMBTRI.data(), &vert_get_n(0, 0),
206 &vert_get_diff_n(0, 0));
207 for (int n = 0; n != 3; ++n) {
208 const int f = boost::math::factorial<double>(
209 data.dataOnEntities[MBVERTEX][0].getBBNodeOrder()[n]);
210 for (int g = 0; g != nb_gauss_pts; ++g) {
211 vert_get_n(g, n) *= f;
212 for (int d = 0; d != 2; ++d)
213 vert_get_diff_n(g, 2 * n + d) *= f;
214 }
215 }
216
217 // edges
218 if (data.spacesOnEntities[MBEDGE].test(H1)) {
219 if (data.dataOnEntities[MBEDGE].size() != 3)
220 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
221 "Wrong size of ent data");
222
223 constexpr int edges_nodes[3][2] = {{0, 1}, {1, 2}, {2, 0}};
224 for (int ee = 0; ee != 3; ++ee) {
225 auto &ent_data = data.dataOnEntities[MBEDGE][ee];
226
227 if (ent_data.getSense() == 0)
228 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
229 "Sense of the edge unknown");
230
231 const int sense = ent_data.getSense();
232 const int order = ent_data.getOrder();
233 const int nb_dofs = NBEDGE_H1(ent_data.getOrder());
234
235 if (nb_dofs) {
236 if (get_alpha_by_order_ptr(ent_data, order)) {
237 get_alpha_by_name_ptr(ent_data, field_name) =
238 get_alpha_by_order_ptr(ent_data, order);
239 get_base_by_name_ptr(ent_data, field_name) =
240 get_base_by_order_ptr(ent_data, order);
241 get_diff_base_by_name_ptr(ent_data, field_name) =
242 get_diff_base_by_order_ptr(ent_data, order);
243 } else {
244 make_own(ent_data);
245 auto &get_n = get_base(ent_data);
246 auto &get_diff_n = get_diff_base(ent_data);
247 get_n.resize(nb_gauss_pts, nb_dofs, false);
248 get_diff_n.resize(nb_gauss_pts, 2 * nb_dofs, false);
249
250 auto &edge_alpha = get_alpha(ent_data);
251 edge_alpha.resize(nb_dofs, 3, false);
253 &edge_alpha(0, 0));
254 if (sense == -1) {
255 for (int i = 0; i != edge_alpha.size1(); ++i) {
256 int a = edge_alpha(i, edges_nodes[ee][0]);
257 edge_alpha(i, edges_nodes[ee][0]) =
258 edge_alpha(i, edges_nodes[ee][1]);
259 edge_alpha(i, edges_nodes[ee][1]) = a;
260 }
261 }
263 order, lambda.size1(), edge_alpha.size1(), &edge_alpha(0, 0),
264 &lambda(0, 0), Tools::diffShapeFunMBTRI.data(), &get_n(0, 0),
265 &get_diff_n(0, 0));
266
267 get_alpha_by_order_ptr(ent_data, order) =
268 get_alpha_by_name_ptr(ent_data, field_name);
269 get_base_by_order_ptr(ent_data, order) =
270 get_base_by_name_ptr(ent_data, field_name);
271 get_diff_base_by_order_ptr(ent_data, order) =
272 get_diff_base_by_name_ptr(ent_data, field_name);
273 }
274 } else {
275 set_empty(ent_data);
276 }
277 }
278 } else {
279 for (int ee = 0; ee != 3; ++ee)
280 set_empty(data.dataOnEntities[MBEDGE][ee]);
281 }
282
283 if (data.spacesOnEntities[MBTRI].test(H1)) {
284 if (data.dataOnEntities[MBTRI].size() != 1)
285 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
286 "Wrong size ent of ent data");
287
288 auto &ent_data = data.dataOnEntities[MBTRI][0];
289 const int order = ent_data.getOrder();
290 const int nb_dofs = NBFACETRI_H1(order);
291 if (get_alpha_by_order_ptr(ent_data, order)) {
292 get_alpha_by_name_ptr(ent_data, field_name) =
293 get_alpha_by_order_ptr(ent_data, order);
294 get_base_by_name_ptr(ent_data, field_name) =
295 get_base_by_order_ptr(ent_data, order);
296 get_diff_base_by_name_ptr(ent_data, field_name) =
297 get_diff_base_by_order_ptr(ent_data, order);
298 } else {
299
300 make_own(ent_data);
301 auto &get_n = get_base(ent_data);
302 auto &get_diff_n = get_diff_base(ent_data);
303 get_n.resize(nb_gauss_pts, nb_dofs, false);
304 get_diff_n.resize(nb_gauss_pts, 2 * nb_dofs, false);
305 if (nb_dofs) {
306 auto &tri_alpha = get_alpha(ent_data);
307 tri_alpha.resize(nb_dofs, 3, false);
308
311 order, lambda.size1(), tri_alpha.size1(), &tri_alpha(0, 0),
312 &lambda(0, 0), Tools::diffShapeFunMBTRI.data(), &get_n(0, 0),
313 &get_diff_n(0, 0));
314
315 get_alpha_by_order_ptr(ent_data, order) =
316 get_alpha_by_name_ptr(ent_data, field_name);
317 get_base_by_order_ptr(ent_data, order) =
318 get_base_by_name_ptr(ent_data, field_name);
319 get_diff_base_by_order_ptr(ent_data, order) =
320 get_diff_base_by_name_ptr(ent_data, field_name);
321 } else {
322 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
323 }
324 }
325 } else {
326 set_empty(data.dataOnEntities[MBTRI][0]);
327 }
328
330}
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 baseFunctionsTri(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 generateIndicesTriTri(const int N, int *alpha)
static MoFEMErrorCode generateIndicesEdgeTri(const int N[], int *alpha[])
static constexpr size_t MaxBernsteinBezierOrder

◆ getValueHcurl()

MoFEMErrorCode TriPolynomialBase::getValueHcurl ( MatrixDouble &  pts)
private

Definition at line 1207 of file TriPolynomialBase.cpp.

1207 {
1209 switch (cTx->spaceContinuity) {
1210 case CONTINUOUS:
1211
1212 switch (cTx->bAse) {
1218 default:
1219 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
1220 }
1221
1222 break;
1223
1224 case DISCONTINUOUS:
1225 switch (cTx->bAse) {
1231 default:
1232 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
1233 }
1234
1235 default:
1236 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown continuity");
1237 }
1238
1240}
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
MoFEMErrorCode getValueHcurlDemkowiczBase(MatrixDouble &pts)
MoFEMErrorCode getValueHcurlAinsworthBase(MatrixDouble &pts)
MoFEMErrorCode getValueHcurlAinsworthBrokenBase(MatrixDouble &pts)
MoFEMErrorCode getValueHcurlDemkowiczBrokenBase(MatrixDouble &pts)

◆ getValueHcurlAinsworthBase()

MoFEMErrorCode TriPolynomialBase::getValueHcurlAinsworthBase ( MatrixDouble &  pts)
private

Definition at line 779 of file TriPolynomialBase.cpp.

779 {
781
782 EntitiesFieldData &data = cTx->dAta;
783 const FieldApproximationBase base = cTx->bAse;
784 if (data.dataOnEntities[MBTRI].size() != 1)
785 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
786
787 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
788 double *diffL, const int dim) =
790
791 int nb_gauss_pts = pts.size2();
792
793 // Calculation H-curl on triangle faces
794 if (data.spacesOnEntities[MBEDGE].test(HCURL)) {
795 if (data.dataOnEntities[MBEDGE].size() != 3) {
796 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
797 }
798 int sense[3], order[3];
799 double *hcurl_edge_n[3];
800 double *diff_hcurl_edge_n[3];
801 for (int ee = 0; ee < 3; ee++) {
802 if (data.dataOnEntities[MBEDGE][ee].getSense() == 0) {
803 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
804 "data inconsistency");
805 }
806 sense[ee] = data.dataOnEntities[MBEDGE][ee].getSense();
807 order[ee] = data.dataOnEntities[MBEDGE][ee].getOrder();
808 int nb_dofs =
809 NBEDGE_AINSWORTH_HCURL(data.dataOnEntities[MBEDGE][ee].getOrder());
810 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts,
811 3 * nb_dofs, false);
812 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(
813 nb_gauss_pts, 2 * 3 * nb_dofs, false);
814 hcurl_edge_n[ee] =
815 &*data.dataOnEntities[MBEDGE][ee].getN(base).data().begin();
816 diff_hcurl_edge_n[ee] =
817 &*data.dataOnEntities[MBEDGE][ee].getDiffN(base).data().begin();
818 }
820 sense, order,
821 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
822 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
823 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts, base_polynomials);
824 } else {
825 for (int ee = 0; ee < 3; ee++) {
826 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, 0, false);
827 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts, 0,
828 false);
829 }
830 }
831
832 if (data.spacesOnEntities[MBTRI].test(HCURL)) {
833
834 // cerr << data.dataOnEntities[MBVERTEX][0].getN(base) << endl;
835 // cerr << data.dataOnEntities[MBVERTEX][0].getDiffN(base) << endl;
836 //
837 // face
838 if (data.dataOnEntities[MBTRI].size() != 1) {
839 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
840 }
841 int order = data.dataOnEntities[MBTRI][0].getOrder();
842 int nb_dofs = NBFACETRI_AINSWORTH_HCURL(order);
843 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
844 false);
845 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts,
846 3 * 2 * nb_dofs, false);
847 // cerr << data.dataOnEntities[MBVERTEX][0].getDiffN(base) << endl;
848 int face_nodes[] = {0, 1, 2};
850 face_nodes, order,
851 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
852 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
853 &*data.dataOnEntities[MBTRI][0].getN(base).data().begin(),
854 &*data.dataOnEntities[MBTRI][0].getDiffN(base).data().begin(),
855 nb_gauss_pts, base_polynomials);
856 // cerr << data.dataOnEntities[MBTRI][0].getN(base) << endl;
857 } else {
858 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, 0, false);
859 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts, 0, false);
860 }
861
863}
#define NBFACETRI_AINSWORTH_HCURL(P)
#define NBEDGE_AINSWORTH_HCURL(P)
MoFEMErrorCode Hcurl_Ainsworth_FaceFunctions_MBTET_ON_FACE(int *faces_nodes, int p, double *N, double *diffN, double *phi_f, double *diff_phi_f, 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:1249
MoFEMErrorCode Hcurl_Ainsworth_EdgeBaseFunctions_MBTET_ON_FACE(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 face.
Definition Hcurl.cpp:237

◆ getValueHcurlAinsworthBrokenBase()

MoFEMErrorCode TriPolynomialBase::getValueHcurlAinsworthBrokenBase ( MatrixDouble &  pts)
private

Definition at line 866 of file TriPolynomialBase.cpp.

866 {
868
869 EntitiesFieldData &data = cTx->dAta;
870 const FieldApproximationBase base = cTx->bAse;
871 if (data.dataOnEntities[MBTRI].size() != 1)
872 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
873
874 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
875 double *diffL, const int dim) =
877
878 int nb_gauss_pts = pts.size2();
879
880 if (data.spacesOnEntities[MBTRI].test(HCURL)) {
881
882 // face
883 if (data.dataOnEntities[MBTRI].size() != 1) {
884 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
885 }
886
887 int order = data.dataOnEntities[MBTRI][0].getOrder();
888 auto nb_edge_dofs = NBEDGE_AINSWORTH_HCURL(order);
889 int nb_dofs_face = NBFACETRI_AINSWORTH_HCURL(order);
890
891 // three faces on triangle
892 int nb_dofs = 3 * nb_edge_dofs + nb_dofs_face;
893 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
894 false);
895 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts,
896 3 * 2 * nb_dofs, false);
897
898 MatrixDouble edge_bases[] = {
899 MatrixDouble(nb_gauss_pts, 3 * nb_edge_dofs, false),
900 MatrixDouble(nb_gauss_pts, 3 * nb_edge_dofs, false),
901 MatrixDouble(nb_gauss_pts, 3 * nb_edge_dofs, false)};
902 MatrixDouble diff_edge_bases[] = {
903 MatrixDouble(nb_gauss_pts, 3 * 2 * nb_edge_dofs, false),
904 MatrixDouble(nb_gauss_pts, 3 * 2 * nb_edge_dofs, false),
905 MatrixDouble(nb_gauss_pts, 3 * 2 * nb_edge_dofs, false)};
906
907 std::array<double *, 3> phi{&*edge_bases[0].data().begin(),
908 &*edge_bases[1].data().begin(),
909 &*edge_bases[2].data().begin()};
910 std::array<double *, 3> diff_phi{&*diff_edge_bases[0].data().begin(),
911 &*diff_edge_bases[1].data().begin(),
912 &*diff_edge_bases[2].data().begin()};
913
914 std::array<int, 3> edge_order{order, order, order};
915 std::array<int, 3> edge_sense{1, 1, 1};
917 edge_sense.data(), edge_order.data(),
918 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
919 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
920 phi.data(), diff_phi.data(), nb_gauss_pts, base_polynomials);
921
922 MatrixDouble face_bases(nb_gauss_pts, 3 * nb_dofs_face, false);
923 MatrixDouble diff_face_bases(nb_gauss_pts, 3 * 2 * nb_dofs_face, false);
924 int face_nodes[] = {0, 1, 2};
926 face_nodes, order,
927 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
928 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
929 &*face_bases.data().begin(), &*diff_face_bases.data().begin(),
930 nb_gauss_pts, base_polynomials);
931
932 // edges
933 using Tensor1Ptr3 =
934 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
935 Tensor1Ptr3 t_edge_base[] = {
936 getFTensor1FromPtr<3>(&*edge_bases[0].data().begin()),
937 getFTensor1FromPtr<3>(&*edge_bases[1].data().begin()),
938 getFTensor1FromPtr<3>(&*edge_bases[2].data().begin())};
939 FTensor::Tensor2<FTensor::PackPtr<double *, 6>, 3, 2> t_edge_diff_base[] = {
940 getFTensor2HVecFromPtr<3, 2>(&*diff_edge_bases[0].data().begin()),
941 getFTensor2HVecFromPtr<3, 2>(&*diff_edge_bases[1].data().begin()),
942 getFTensor2HVecFromPtr<3, 2>(&*diff_edge_bases[2].data().begin())};
943
944 // face
945 auto t_vol_base = getFTensor1FromPtr<3>(&*face_bases.data().begin());
946 auto t_vol_diff_base =
947 getFTensor2HVecFromPtr<3, 2>(&*diff_face_bases.data().begin());
948
949 auto t_base = getFTensor1FromPtr<3>(
950 &*data.dataOnEntities[MBTRI][0].getN(base).data().begin());
951 auto t_diff_base = getFTensor2HVecFromPtr<3, 2>(
952 &*data.dataOnEntities[MBTRI][0].getDiffN(base).data().begin());
953
954 FTENSOR_INDEX(3, i);
955 FTENSOR_INDEX(2, j);
956
957 for (int gg = 0; gg != nb_gauss_pts; gg++) {
958 for (int oo = 0; oo < order; oo++) {
959 // edges
960 for (int dd = NBEDGE_AINSWORTH_HCURL(oo);
961 dd != NBEDGE_AINSWORTH_HCURL(oo + 1); ++dd) {
962 for (int ee = 0; ee != 3; ++ee) {
963 t_base(i) = t_edge_base[ee](i);
964 ++t_base;
965 ++t_edge_base[ee];
966 t_diff_base(i, j) = t_edge_diff_base[ee](i, j);
967 ++t_diff_base;
968 ++t_edge_diff_base[ee];
969 }
970 }
971 // face
972 for (int dd = NBFACETRI_AINSWORTH_HCURL(oo);
973 dd != NBFACETRI_AINSWORTH_HCURL(oo + 1); ++dd) {
974 t_base(i) = t_vol_base(i);
975 ++t_base;
976 ++t_vol_base;
977 t_diff_base(i, j) = t_vol_diff_base(i, j);
978 ++t_diff_base;
979 ++t_vol_diff_base;
980 }
981 }
982 }
983
984 } else {
985 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, 0, false);
986 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts, 0, false);
987 }
988
990}
#define FTENSOR_INDEX(DIM, I)
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, 2 >(double *ptr)
static double phi

◆ getValueHcurlDemkowiczBase()

MoFEMErrorCode TriPolynomialBase::getValueHcurlDemkowiczBase ( MatrixDouble &  pts)
private

Definition at line 993 of file TriPolynomialBase.cpp.

993 {
995
996 EntitiesFieldData &data = cTx->dAta;
997 const FieldApproximationBase base = cTx->bAse;
998
999 int nb_gauss_pts = pts.size2();
1000
1001 // Calculation H-curl on triangle faces
1002 if (data.spacesOnEntities[MBEDGE].test(HCURL)) {
1003
1004 if (data.dataOnEntities[MBEDGE].size() != 3)
1005 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1006 "wrong number of data structures on edges, should be three but "
1007 "is %zu",
1008 data.dataOnEntities[MBEDGE].size());
1009
1010 int sense[3], order[3];
1011 double *hcurl_edge_n[3];
1012 double *diff_hcurl_edge_n[3];
1013
1014 for (int ee = 0; ee != 3; ++ee) {
1015
1016 if (data.dataOnEntities[MBEDGE][ee].getSense() == 0)
1017 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1018 "orientation (sense) of edge is not set");
1019
1020 sense[ee] = data.dataOnEntities[MBEDGE][ee].getSense();
1021 order[ee] = data.dataOnEntities[MBEDGE][ee].getOrder();
1022 int nb_dofs =
1023 NBEDGE_DEMKOWICZ_HCURL(data.dataOnEntities[MBEDGE][ee].getOrder());
1024 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts,
1025 3 * nb_dofs, false);
1026 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(
1027 nb_gauss_pts, 2 * 3 * nb_dofs, false);
1028
1029 hcurl_edge_n[ee] =
1030 &*data.dataOnEntities[MBEDGE][ee].getN(base).data().begin();
1031 diff_hcurl_edge_n[ee] =
1032 &*data.dataOnEntities[MBEDGE][ee].getDiffN(base).data().begin();
1033 }
1034
1036 sense, order,
1037 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1038 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1039 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts);
1040
1041 } else {
1042
1043 // No DOFs on faces, resize base function matrices, indicating that no
1044 // dofs on them.
1045 for (int ee = 0; ee != 3; ++ee) {
1046 data.dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, 0, false);
1047 data.dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts, 0,
1048 false);
1049 }
1050 }
1051
1052 if (data.spacesOnEntities[MBTRI].test(HCURL)) {
1053
1054 // face
1055 if (data.dataOnEntities[MBTRI].size() != 1)
1056 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1057 "No data struture to keep base functions on face");
1058
1059 int order = data.dataOnEntities[MBTRI][0].getOrder();
1060 int nb_dofs = NBFACETRI_DEMKOWICZ_HCURL(order);
1061 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
1062 false);
1063 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts,
1064 3 * 2 * nb_dofs, false);
1065
1066 int face_nodes[] = {0, 1, 2};
1068 face_nodes, order,
1069 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1070 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1071 &*data.dataOnEntities[MBTRI][0].getN(base).data().begin(),
1072 &*data.dataOnEntities[MBTRI][0].getDiffN(base).data().begin(),
1073 nb_gauss_pts);
1074
1075 } else {
1076
1077 // No DOFs on faces, resize base function matrices, indicating that no
1078 // dofs on them.
1079 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, 0, false);
1080 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts, 0, false);
1081 }
1082
1084}
#define NBEDGE_DEMKOWICZ_HCURL(P)
#define NBFACETRI_DEMKOWICZ_HCURL(P)
MoFEMErrorCode Hcurl_Demkowicz_EdgeBaseFunctions_MBTRI(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 teriangle.
Definition Hcurl.cpp:2116
MoFEMErrorCode Hcurl_Demkowicz_FaceBaseFunctions_MBTRI(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:2440

◆ getValueHcurlDemkowiczBrokenBase()

MoFEMErrorCode TriPolynomialBase::getValueHcurlDemkowiczBrokenBase ( MatrixDouble &  pts)
private

Definition at line 1087 of file TriPolynomialBase.cpp.

1087 {
1089
1090 EntitiesFieldData &data = cTx->dAta;
1091 const FieldApproximationBase base = cTx->bAse;
1092
1093 int nb_gauss_pts = pts.size2();
1094
1095 if (data.spacesOnEntities[MBTRI].test(HCURL)) {
1096
1097 // face
1098 if (data.dataOnEntities[MBTRI].size() != 1)
1099 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1100 "No data struture to keep base functions on face");
1101
1102 int order = data.dataOnEntities[MBTRI][0].getOrder();
1103 int nb_edge_dofs = NBEDGE_DEMKOWICZ_HCURL(order);
1104 int nb_volume_dofs = NBFACETRI_DEMKOWICZ_HCURL(order);
1105 int nb_dofs = 3 * nb_edge_dofs + nb_volume_dofs;
1106 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
1107 false);
1108 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts,
1109 3 * 2 * nb_dofs, false);
1110
1111 MatrixDouble edge_bases[] = {
1112 MatrixDouble(nb_gauss_pts, 3 * nb_edge_dofs, false),
1113 MatrixDouble(nb_gauss_pts, 3 * nb_edge_dofs, false),
1114 MatrixDouble(nb_gauss_pts, 3 * nb_edge_dofs, false)};
1115 MatrixDouble diff_edge_bases[] = {
1116 MatrixDouble(nb_gauss_pts, 3 * 2 * nb_edge_dofs, false),
1117 MatrixDouble(nb_gauss_pts, 3 * 2 * nb_edge_dofs, false),
1118 MatrixDouble(nb_gauss_pts, 3 * 2 * nb_edge_dofs, false)};
1119
1120 std::array<int, 3> edge_order{order, order, order};
1121 std::array<int, 3> edge_sense{1, 1, 1};
1122 std::array<double *, 3> phi{&*edge_bases[0].data().begin(),
1123 &*edge_bases[1].data().begin(),
1124 &*edge_bases[2].data().begin()};
1125 std::array<double *, 3> diff_phi{&*diff_edge_bases[0].data().begin(),
1126 &*diff_edge_bases[1].data().begin(),
1127 &*diff_edge_bases[2].data().begin()};
1129 edge_sense.data(), edge_order.data(),
1130 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1131 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1132 phi.data(), diff_phi.data(), nb_gauss_pts);
1133
1134 MatrixDouble face_bases(nb_gauss_pts, 3 * nb_volume_dofs, false);
1135 MatrixDouble diff_face_bases(nb_gauss_pts, 3 * 2 * nb_volume_dofs, false);
1136 int face_nodes[] = {0, 1, 2};
1138 face_nodes, order,
1139 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
1140 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1141 &*face_bases.data().begin(), &*diff_face_bases.data().begin(),
1142 nb_gauss_pts);
1143
1144 // edges
1145 using Tensor1Ptr3 =
1146 decltype(getFTensor1FromPtr<3>(static_cast<double *>(nullptr)));
1147 Tensor1Ptr3 t_edge_base[] = {
1148 getFTensor1FromPtr<3>(&*edge_bases[0].data().begin()),
1149 getFTensor1FromPtr<3>(&*edge_bases[1].data().begin()),
1150 getFTensor1FromPtr<3>(&*edge_bases[2].data().begin())};
1151 FTensor::Tensor2<FTensor::PackPtr<double *, 6>, 3, 2> t_edge_diff_base[] = {
1152 getFTensor2HVecFromPtr<3, 2>(&*diff_edge_bases[0].data().begin()),
1153 getFTensor2HVecFromPtr<3, 2>(&*diff_edge_bases[1].data().begin()),
1154 getFTensor2HVecFromPtr<3, 2>(&*diff_edge_bases[2].data().begin())};
1155 // face
1156 auto t_vol_base = getFTensor1FromPtr<3>(&*face_bases.data().begin());
1157 auto t_vol_diff_base =
1158 getFTensor2HVecFromPtr<3, 2>(&*diff_face_bases.data().begin());
1159
1160 auto t_base = getFTensor1FromPtr<3>(
1161 &*data.dataOnEntities[MBTRI][0].getN(base).data().begin());
1162 auto t_diff_base = getFTensor2HVecFromPtr<3, 2>(
1163 &*data.dataOnEntities[MBTRI][0].getDiffN(base).data().begin());
1164
1165 FTENSOR_INDEX(3, i);
1166 FTENSOR_INDEX(2, j);
1167
1168 // Fill the base functions and their derivatives
1169 for (int gg = 0; gg != nb_gauss_pts; gg++) {
1170 for (int oo = 0; oo < order; oo++) {
1171 // edges
1172 for (int dd = NBEDGE_DEMKOWICZ_HCURL(oo);
1173 dd != NBEDGE_DEMKOWICZ_HCURL(oo + 1); ++dd) {
1174 for (int ee = 0; ee != 3; ++ee) {
1175 t_base(i) = t_edge_base[ee](i);
1176 ++t_base;
1177 ++t_edge_base[ee];
1178 t_diff_base(i, j) = t_edge_diff_base[ee](i, j);
1179 ++t_diff_base;
1180 ++t_edge_diff_base[ee];
1181 }
1182 }
1183 // faces
1184 for (int dd = NBFACETRI_DEMKOWICZ_HCURL(oo);
1185 dd != NBFACETRI_DEMKOWICZ_HCURL(oo + 1); ++dd) {
1186 t_base(i) = t_vol_base(i);
1187 ++t_base;
1188 ++t_vol_base;
1189 t_diff_base(i, j) = t_vol_diff_base(i, j);
1190 ++t_diff_base;
1191 ++t_vol_diff_base;
1192 }
1193 }
1194 }
1195
1196 } else {
1197
1198 // No DOFs on faces, resize base function matrices, indicating that no
1199 // dofs on them.
1200 data.dataOnEntities[MBTRI][0].getN(base).resize(nb_gauss_pts, 0, false);
1201 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(nb_gauss_pts, 0, false);
1202 }
1203
1205}

◆ getValueHdiv()

MoFEMErrorCode TriPolynomialBase::getValueHdiv ( MatrixDouble &  pts)
private

Definition at line 762 of file TriPolynomialBase.cpp.

762 {
764
765 switch (cTx->bAse) {
771 default:
772 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
773 }
774
776}
MoFEMErrorCode getValueHdivAinsworthBase(MatrixDouble &pts)
MoFEMErrorCode getValueHdivDemkowiczBase(MatrixDouble &pts)

◆ getValueHdivAinsworthBase()

MoFEMErrorCode TriPolynomialBase::getValueHdivAinsworthBase ( MatrixDouble &  pts)
private

Definition at line 640 of file TriPolynomialBase.cpp.

640 {
642
643 EntitiesFieldData &data = cTx->dAta;
644 const FieldApproximationBase base = cTx->bAse;
645 if (cTx->basePolynomialsType0 == NULL)
646 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
647 "Polynomial type not set");
648 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
649 double *diffL, const int dim) =
651
652 int nb_gauss_pts = pts.size2();
653
654 double *phi_f_e[3];
655 double *phi_f;
656
657 N_face_edge.resize(1, 3, false);
658 N_face_bubble.resize(1, false);
659 int face_order = data.dataOnEntities[MBTRI][0].getOrder();
660 auto nb_dofs_on_face =
665 if (nb_dofs_on_face) {
666 auto face_edge_dofs = NBFACETRI_AINSWORTH_EDGE_HDIV(
668 // three edges on face
669 for (int ee = 0; ee < 3; ee++) {
670 N_face_edge(0, ee).resize(nb_gauss_pts, 3 * face_edge_dofs, false);
671 phi_f_e[ee] = &((N_face_edge(0, ee))(0, 0));
672 }
673 auto face_bubble_dofs = NBFACETRI_AINSWORTH_FACE_HDIV(
675 N_face_bubble[0].resize(nb_gauss_pts, 3 * face_bubble_dofs, false);
676 phi_f = &*(N_face_bubble[0].data().begin());
677
678 int face_nodes[3] = {0, 1, 2};
679 if (face_edge_dofs)
681 face_nodes,
683 &data.dataOnEntities[MBVERTEX][0].getN(base)(0, 0), NULL, phi_f_e,
684 NULL, nb_gauss_pts, 3, base_polynomials);
685 if (face_bubble_dofs)
687 face_nodes,
689 &data.dataOnEntities[MBVERTEX][0].getN(base)(0, 0), NULL, phi_f, NULL,
690 nb_gauss_pts, 3, base_polynomials);
691
692 // set shape functions into data structure
693 if (data.dataOnEntities[MBTRI].size() != 1) {
694 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
695 }
696 data.dataOnEntities[MBTRI][0].getN(base).resize(
697 nb_gauss_pts, 3 * NBFACETRI_AINSWORTH_HDIV(face_order), false);
698
699 auto max_face_order =
700 std::max(face_order,
702
703 int col = 0;
704 for (int oo = 0; oo < max_face_order; oo++) {
706 for (int ee = 0; ee < 3; ee++) {
707 for (int dd = 3 * NBFACETRI_AINSWORTH_EDGE_HDIV(oo);
708 dd < 3 * NBFACETRI_AINSWORTH_EDGE_HDIV(oo + 1); dd++, col++) {
709 for (int gg = 0; gg < nb_gauss_pts; gg++) {
710 data.dataOnEntities[MBTRI][0].getN(base)(gg, col) =
711 N_face_edge(0, ee)(gg, dd);
712 }
713 }
714 }
715
717 for (int dd = 3 * NBFACETRI_AINSWORTH_FACE_HDIV(oo);
718 dd < 3 * NBFACETRI_AINSWORTH_FACE_HDIV(oo + 1); dd++, col++) {
719 for (int gg = 0; gg < nb_gauss_pts; gg++) {
720 data.dataOnEntities[MBTRI][0].getN(base)(gg, col) =
721 N_face_bubble[0](gg, dd);
722 }
723 }
724 }
725 }
726
728}
#define NBFACETRI_AINSWORTH_FACE_HDIV(P)
#define NBFACETRI_AINSWORTH_EDGE_HDIV(P)
#define NBFACETRI_AINSWORTH_HDIV(P)
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_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
static boost::function< int(int)> broken_nbfacetri_face_hdiv
Definition Hdiv.hpp:26
static boost::function< int(int)> broken_nbfacetri_edge_hdiv
Definition Hdiv.hpp:25
ublas::matrix< MatrixDouble > N_face_edge
ublas::vector< MatrixDouble > N_face_bubble

◆ getValueHdivDemkowiczBase()

MoFEMErrorCode TriPolynomialBase::getValueHdivDemkowiczBase ( MatrixDouble &  pts)
private

Definition at line 730 of file TriPolynomialBase.cpp.

730 {
732
733 EntitiesFieldData &data = cTx->dAta;
734 // set shape functions into data structure
735 if (data.dataOnEntities[MBTRI].size() != 1) {
736 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "data inconsistency");
737 }
738 const FieldApproximationBase base = cTx->bAse;
739 if (base != DEMKOWICZ_JACOBI_BASE) {
740 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
741 "This should be used only with DEMKOWICZ_JACOBI_BASE "
742 "but base is %s",
744 }
745 int order = data.dataOnEntities[MBTRI][0].getOrder();
746 int nb_gauss_pts = pts.size2();
747 data.dataOnEntities[MBTRI][0].getN(base).resize(
748 nb_gauss_pts, 3 * NBFACETRI_DEMKOWICZ_HDIV(order), false);
749 double *phi_f = &*data.dataOnEntities[MBTRI][0].getN(base).data().begin();
752 int face_nodes[3] = {0, 1, 2};
754 face_nodes, order,
755 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
756 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(), phi_f,
757 NULL, nb_gauss_pts, 3);
758
760}
#define NBFACETRI_DEMKOWICZ_HDIV(P)
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

◆ getValueL2()

MoFEMErrorCode TriPolynomialBase::getValueL2 ( MatrixDouble &  pts)
private

Definition at line 405 of file TriPolynomialBase.cpp.

405 {
407
408 switch (cTx->bAse) {
413 break;
416 break;
417 default:
418 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
419 }
420
422}
MoFEMErrorCode getValueL2BernsteinBezierBase(MatrixDouble &pts)
MoFEMErrorCode getValueL2AinsworthBase(MatrixDouble &pts)

◆ getValueL2AinsworthBase()

MoFEMErrorCode TriPolynomialBase::getValueL2AinsworthBase ( MatrixDouble &  pts)
private

Definition at line 424 of file TriPolynomialBase.cpp.

424 {
426
427 EntitiesFieldData &data = cTx->dAta;
428 const FieldApproximationBase base = cTx->bAse;
429 if (cTx->basePolynomialsType0 == NULL)
430 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
431 "Polynomial type not set");
432 PetscErrorCode (*base_polynomials)(int p, double s, double *diff_s, double *L,
433 double *diffL, const int dim) =
435
436 int nb_gauss_pts = pts.size2();
437
438 data.dataOnEntities[MBTRI][0].getN(base).resize(
439 nb_gauss_pts, NBFACETRI_L2(data.dataOnEntities[MBTRI][0].getOrder()),
440 false);
441 data.dataOnEntities[MBTRI][0].getDiffN(base).resize(
442 nb_gauss_pts, 2 * NBFACETRI_L2(data.dataOnEntities[MBTRI][0].getOrder()),
443 false);
444
446 data.dataOnEntities[MBTRI][0].getOrder(),
447 &*data.dataOnEntities[MBVERTEX][0].getN(base).data().begin(),
448 &*data.dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
449 &*data.dataOnEntities[MBTRI][0].getN(base).data().begin(),
450 &*data.dataOnEntities[MBTRI][0].getDiffN(base).data().begin(),
451 nb_gauss_pts, base_polynomials);
452
454}
#define NBFACETRI_L2(P)
Number of base functions on triangle for L2 space.
PetscErrorCode L2_Ainsworth_ShapeFunctions_MBTRI(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 triangle for L2 space.
Definition l2.c:19

◆ getValueL2BernsteinBezierBase()

MoFEMErrorCode TriPolynomialBase::getValueL2BernsteinBezierBase ( MatrixDouble &  pts)
private

Definition at line 457 of file TriPolynomialBase.cpp.

457 {
459
460 EntitiesFieldData &data = cTx->dAta;
461 const std::string &field_name = cTx->fieldName;
462 int nb_gauss_pts = pts.size2();
463
464 auto get_alpha = [field_name](auto &data) -> MatrixInt & {
465 auto &ptr = data.getBBAlphaIndicesSharedPtr(field_name);
466 if (!ptr)
467 ptr.reset(new MatrixInt());
468 return *ptr;
469 };
470
471 auto get_base = [field_name](auto &data) -> MatrixDouble & {
472 auto &ptr = data.getBBNSharedPtr(field_name);
473 if (!ptr)
474 ptr.reset(new MatrixDouble());
475 return *ptr;
476 };
477
478 auto get_diff_base = [field_name](auto &data) -> MatrixDouble & {
479 auto &ptr = data.getBBDiffNSharedPtr(field_name);
480 if (!ptr)
481 ptr.reset(new MatrixDouble());
482 return *ptr;
483 };
484
485 auto get_alpha_by_name_ptr =
486 [](auto &data,
487 const std::string &field_name) -> boost::shared_ptr<MatrixInt> & {
488 return data.getBBAlphaIndicesSharedPtr(field_name);
489 };
490
491 auto get_base_by_name_ptr =
492 [](auto &data,
493 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
494 return data.getBBNSharedPtr(field_name);
495 };
496
497 auto get_diff_base_by_name_ptr =
498 [](auto &data,
499 const std::string &field_name) -> boost::shared_ptr<MatrixDouble> & {
500 return data.getBBDiffNSharedPtr(field_name);
501 };
502
503 auto get_alpha_by_order_ptr =
504 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixInt> & {
505 return data.getBBAlphaIndicesByOrderSharedPtr(o);
506 };
507
508 auto get_base_by_order_ptr =
509 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
510 return data.getBBNByOrderSharedPtr(o);
511 };
512
513 auto get_diff_base_by_order_ptr =
514 [](auto &data, const size_t o) -> boost::shared_ptr<MatrixDouble> & {
515 return data.getBBDiffNByOrderSharedPtr(o);
516 };
517
518 // See make_own in getValueH1BernsteinBezierBase: detach from a by-order
519 // matrix shared with another field before writing into it.
520 auto make_own = [field_name](auto &ent_data) {
521 auto &n_ptr = ent_data.getBBNSharedPtr(field_name);
522 if (!n_ptr)
523 return;
524 for (auto &ptr : ent_data.getBBNByOrderArray()) {
525 if (ptr && ptr.get() == n_ptr.get()) {
526 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
527 ent_data.getBBDiffNSharedPtr(field_name).reset();
528 n_ptr.reset();
529 return;
530 }
531 }
532 };
533
534 if (data.spacesOnEntities[MBTRI].test(L2)) {
535 if (data.dataOnEntities[MBTRI].size() != 1)
536 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
537 "Wrong size ent of ent data");
538
539 if (data.dataOnEntities[MBVERTEX][0].getN(NOBASE).size1() !=
540 (unsigned int)nb_gauss_pts)
541 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
542 "Base functions or nodes has wrong number of integration points "
543 "for base %s",
545 auto &lambda = data.dataOnEntities[MBVERTEX][0].getN(NOBASE);
546
547 auto &ent_data = data.dataOnEntities[MBTRI][0];
548 const int order = ent_data.getOrder();
549 const int nb_dofs = NBFACETRI_L2(order);
550 // L2 is element-local, so the order may differ between elements; only the
551 // storage limit applies.
552 if (order < 0 || static_cast<size_t>(order) >=
554 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
555 "Bernstein-Bezier order %d is outside the supported range "
556 "[0, %d]",
557 order,
558 static_cast<int>(
560 1);
561
562 if (get_alpha_by_order_ptr(ent_data, order)) {
563 get_alpha_by_name_ptr(ent_data, field_name) =
564 get_alpha_by_order_ptr(ent_data, order);
565 get_base_by_name_ptr(ent_data, field_name) =
566 get_base_by_order_ptr(ent_data, order);
567 get_diff_base_by_name_ptr(ent_data, field_name) =
568 get_diff_base_by_order_ptr(ent_data, order);
569 } else {
570
571 make_own(ent_data);
572 auto &get_n = get_base(ent_data);
573 auto &get_diff_n = get_diff_base(ent_data);
574 get_n.resize(nb_gauss_pts, nb_dofs, false);
575 get_diff_n.resize(nb_gauss_pts, 2 * nb_dofs, false);
576 if (nb_dofs) {
577
578 if (order == 0) {
579
580 if (nb_dofs != 1)
581 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
582 "Inconsistent number of DOFs");
583
584 // The single degree-zero function is one at every integration
585 // point, with the zero multi-index.
586 auto &tri_alpha = get_alpha(ent_data);
587 tri_alpha.resize(1, 3, false);
588 tri_alpha.clear();
589 std::fill(get_n.data().begin(), get_n.data().end(), 1.);
590 get_diff_n.clear();
591
592 } else {
593
594 if (nb_dofs != 3 + 3 * NBEDGE_H1(order) + NBFACETRI_H1(order))
595 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
596 "Inconsistent number of DOFs");
597
598 auto &tri_alpha = get_alpha(ent_data);
599 tri_alpha.resize(nb_dofs, 3, false);
600
602 &tri_alpha(0, 0));
603
604 if (order > 1) {
605 std::array<int, 3> face_n{order, order, order};
606 std::array<int *, 3> face_edge_ptr{
607 &tri_alpha(3, 0), &tri_alpha(3 + NBEDGE_H1(order), 0),
608 &tri_alpha(3 + 2 * NBEDGE_H1(order), 0)};
610 face_n.data(), face_edge_ptr.data());
611 if (order > 2)
613 order, &tri_alpha(3 + 3 * NBEDGE_H1(order), 0));
614 }
616 order, lambda.size1(), tri_alpha.size1(), &tri_alpha(0, 0),
617 &lambda(0, 0), Tools::diffShapeFunMBTRI.data(), &get_n(0, 0),
618 &get_diff_n(0, 0));
619 }
620
621 get_alpha_by_order_ptr(ent_data, order) =
622 get_alpha_by_name_ptr(ent_data, field_name);
623 get_base_by_order_ptr(ent_data, order) =
624 get_base_by_name_ptr(ent_data, field_name);
625 get_diff_base_by_order_ptr(ent_data, order) =
626 get_diff_base_by_name_ptr(ent_data, field_name);
627 }
628 }
629 } else {
630 auto &ent_data = data.dataOnEntities[MBTRI][0];
631 make_own(ent_data);
632 ent_data.getBBAlphaIndicesSharedPtr(field_name).reset();
633 get_base(ent_data).resize(nb_gauss_pts, 0, false);
634 get_diff_base(ent_data).resize(nb_gauss_pts, 0, false);
635 }
636
638}
static MoFEMErrorCode generateIndicesVertexTri(const int N, int *alpha)

◆ query_interface()

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

Reimplemented from MoFEM::BaseFunction.

Definition at line 9 of file TriPolynomialBase.cpp.

10 {
12 *iface = const_cast<TriPolynomialBase *>(this);
14}
Calculate base functions on triangle.

◆ setDofsSideMap()

MoFEMErrorCode TriPolynomialBase::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 1334 of file TriPolynomialBase.cpp.

1339 {
1341
1342 switch (continuity) {
1343 case DISCONTINUOUS:
1344
1345 switch (space) {
1346 case HCURL:
1348 setDofsSideMapHcurl(space, continuity, base, dofs_side_map));
1349 default:
1350 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Unknown space %s",
1351 FieldSpaceNames[space]);
1352 }
1353 break;
1354
1355 default:
1356 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1357 "Unknown (or not implemented) continuity");
1358 }
1359
1361}
static const char *const FieldSpaceNames[]
Definition definitions.h:92
static MoFEMErrorCode setDofsSideMapHcurl(const FieldSpace space, const FieldContinuity continuity, const FieldApproximationBase base, DofsSideMap &dofs_side_map)

◆ setDofsSideMapHcurl()

MoFEMErrorCode TriPolynomialBase::setDofsSideMapHcurl ( const FieldSpace  space,
const FieldContinuity  continuity,
const FieldApproximationBase  base,
DofsSideMap &  dofs_side_map 
)
staticprivate

Definition at line 1363 of file TriPolynomialBase.cpp.

1365 {
1367
1368 // That has to be consistent with implementation of getValueHdiv for
1369 // particular base functions.
1370
1371 auto set_ainsworth = [&dofs_side_map]() {
1373
1374 dofs_side_map.clear();
1375
1376 int dof = 0;
1377 for (int oo = 0; oo < Field::maxBrokenDofsOrder; oo++) {
1378
1379 // edges
1380 for (int dd = NBEDGE_AINSWORTH_HCURL(oo);
1381 dd != NBEDGE_AINSWORTH_HCURL(oo + 1); ++dd) {
1382 for (int ee = 0; ee != 3; ++ee) {
1383 dofs_side_map.insert(DofsSideMapData{MBEDGE, ee, dof});
1384 ++dof;
1385 }
1386 }
1387 // face
1388 for (int dd = NBFACETRI_AINSWORTH_HCURL(oo);
1389 dd != NBFACETRI_AINSWORTH_HCURL(oo + 1); ++dd) {
1390 dofs_side_map.insert(DofsSideMapData{MBTRI, 0, dof});
1391 ++dof;
1392 }
1393 }
1394
1396 };
1397
1398 auto set_demkowicz = [&dofs_side_map]() {
1400
1401 dofs_side_map.clear();
1402
1403 int dof = 0;
1404 for (int oo = 0; oo < Field::maxBrokenDofsOrder; oo++) {
1405
1406 // edges
1407 for (int dd = NBEDGE_DEMKOWICZ_HCURL(oo);
1408 dd != NBEDGE_DEMKOWICZ_HCURL(oo + 1); ++dd) {
1409 for (int ee = 0; ee != 3; ++ee) {
1410 dofs_side_map.insert(DofsSideMapData{MBEDGE, ee, dof});
1411 ++dof;
1412 }
1413 }
1414 // faces
1415 for (int dd = NBFACETRI_DEMKOWICZ_HCURL(oo);
1416 dd != NBFACETRI_DEMKOWICZ_HCURL(oo + 1); ++dd) {
1417 dofs_side_map.insert(DofsSideMapData{MBTRI, 0, dof});
1418 ++dof;
1419 }
1420 }
1421
1423 };
1424
1425 switch (continuity) {
1426 case DISCONTINUOUS:
1427 switch (base) {
1430 MoFEMFunctionReturnHot(set_ainsworth());
1432 MoFEMFunctionReturnHot(set_demkowicz());
1433 default:
1434 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED, "Not implemented");
1435 }
1436 break;
1437
1438 default:
1439 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1440 "Unknown (or not implemented) continuity");
1441 }
1442
1444}
static constexpr int maxBrokenDofsOrder
Maximum order for broken space DOFs.

Member Data Documentation

◆ cTx

EntPolynomialBaseCtx* MoFEM::TriPolynomialBase::cTx
private

Definition at line 47 of file TriPolynomialBase.hpp.

◆ diffN_face_bubble

ublas::vector<MatrixDouble> MoFEM::TriPolynomialBase::diffN_face_bubble
private

Definition at line 60 of file TriPolynomialBase.hpp.

◆ diffN_face_edge

ublas::matrix<MatrixDouble> MoFEM::TriPolynomialBase::diffN_face_edge
private

Definition at line 59 of file TriPolynomialBase.hpp.

◆ N_face_bubble

ublas::vector<MatrixDouble> MoFEM::TriPolynomialBase::N_face_bubble
private

Definition at line 58 of file TriPolynomialBase.hpp.

◆ N_face_edge

ublas::matrix<MatrixDouble> MoFEM::TriPolynomialBase::N_face_edge
private

Definition at line 57 of file TriPolynomialBase.hpp.


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