37 boost::multi_index::indexed_by<
39 boost::multi_index::hashed_unique<
44 member<BaseCacheItem, int, &BaseCacheItem::order>,
45 member<BaseCacheItem, int, &BaseCacheItem::nb_gauss_pts>>>>
51 boost::multi_index::indexed_by<
53 boost::multi_index::hashed_unique<
58 member<HDivBaseCacheItem, int, &HDivBaseCacheItem::order>,
61 member<HDivBaseCacheItem, int, &HDivBaseCacheItem::n0>,
62 member<HDivBaseCacheItem, int, &HDivBaseCacheItem::n1>,
63 member<HDivBaseCacheItem, int, &HDivBaseCacheItem::n2>>>>
67 static std::array<std::map<const void *, BaseCacheMI>,
LASTBASE>
69 static std::array<std::map<const void *, BaseCacheMI>,
LASTBASE>
71 static std::array<std::map<const void *, HDivBaseFaceCacheMI>,
LASTBASE>
73 static std::array<std::map<const void *, BaseCacheMI>,
LASTBASE>
77std::array<std::map<const void *, TetBaseCache::BaseCacheMI>,
LASTBASE>
79std::array<std::map<const void *, TetBaseCache::BaseCacheMI>,
LASTBASE>
81std::array<std::map<const void *, TetBaseCache::HDivBaseFaceCacheMI>,
LASTBASE>
83std::array<std::map<const void *, TetBaseCache::BaseCacheMI>,
LASTBASE>
100 auto erase = [&](
auto cache) {
101 if (cache.find(
vPtr) != cache.end())
105 for (
auto b = 0; b !=
LASTBASE; ++b) {
136 PetscErrorCode (*base_polynomials)(
int p,
double s,
double *diff_s,
double *
L,
137 double *diffL,
const int dim) =
140 int nb_gauss_pts = pts.size2();
142 int sense[6],
order[6];
148 double *h1_edge_n[6], *diff_h1_egde_n[6];
149 for (
int ee = 0; ee != 6; ++ee) {
152 "data inconsistency");
157 data.
dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, nb_dofs,
159 data.
dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
170 h1_edge_n, diff_h1_egde_n, nb_gauss_pts, base_polynomials);
172 for (
int ee = 0; ee != 6; ++ee) {
174 data.
dataOnEntities[MBEDGE][ee].getDiffN(base).resize(0, 0,
false);
183 double *h1_face_n[4], *diff_h1_face_n[4];
184 for (
int ff = 0; ff != 4; ++ff) {
187 "data inconsistency");
191 data.
dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts, nb_dofs,
193 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
210 h1_face_n, diff_h1_face_n, nb_gauss_pts, base_polynomials);
213 for (
int ff = 0; ff != 4; ++ff) {
215 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(0, 0,
false);
223 data.
dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, nb_vol_dofs,
226 3 * nb_vol_dofs,
false);
233 nb_gauss_pts, base_polynomials);
248 const int nb_gauss_pts = pts.size2();
251 (
unsigned int)nb_gauss_pts)
253 "Base functions or nodes has wrong number of integration points "
259 auto &ptr = data.getBBAlphaIndicesSharedPtr(
field_name);
273 auto &ptr = data.getBBDiffNSharedPtr(
field_name);
279 auto get_alpha_by_name_ptr =
281 const std::string &
field_name) -> boost::shared_ptr<MatrixInt> & {
282 return data.getBBAlphaIndicesSharedPtr(
field_name);
285 auto get_base_by_name_ptr =
287 const std::string &
field_name) -> boost::shared_ptr<MatrixDouble> & {
291 auto get_diff_base_by_name_ptr =
293 const std::string &
field_name) -> boost::shared_ptr<MatrixDouble> & {
297 auto get_alpha_by_order_ptr =
298 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixInt> & {
299 return data.getBBAlphaIndicesByOrderSharedPtr(o);
302 auto get_base_by_order_ptr =
303 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixDouble> & {
304 return data.getBBNByOrderSharedPtr(o);
307 auto get_diff_base_by_order_ptr =
308 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixDouble> & {
309 return data.getBBDiffNByOrderSharedPtr(o);
315 auto make_own = [
field_name](
auto &ent_data) {
316 auto &n_ptr = ent_data.getBBNSharedPtr(
field_name);
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();
331 auto set_empty = [&](
auto &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);
344 auto check_uniform_order = [&]() {
346 auto &node_order = data.
dataOnEntities[MBVERTEX][0].getBBNodeOrder();
347 if (node_order.size() != 4)
349 "Wrong number of vertex orders for BB base: %d",
350 static_cast<int>(node_order.size()));
352 for (
int n = 0;
n != 4; ++
n)
354 auto max_order_on = [&](
const EntityType
type) {
359 max_order_on(MBEDGE);
364 "Bernstein-Bezier H1 base requires approximation order >= 1");
365 if (
static_cast<size_t>(
order) >=
368 "Bernstein-Bezier order %d exceeds the supported maximum %d",
373 for (
int n = 0;
n != 4; ++
n)
374 if (node_order[
n] < 1)
376 "Bernstein-Bezier H1 base requires vertex order between 1 "
377 "and the element order %d; vertex %d has order %d",
379 auto check_type = [&](
const EntityType
type,
const int nb_dofs_at_order) {
385 if (ent_data.getOrder() !=
order)
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 "
393 moab::CN::EntityTypeName(
type), side, ent_data.getOrder(),
404 CHKERR check_uniform_order();
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)
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),
420 &vert_get_diff_n(0, 0));
421 for (
int n = 0;
n != 4; ++
n) {
422 const double f = boost::math::factorial<double>(
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;
435 "Wrong size of ent data");
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) {
441 const int sense = ent_data.getSense();
444 "Sense of the edge unknown");
445 const int order = ent_data.getOrder();
449 if (get_alpha_by_order_ptr(ent_data,
order)) {
451 get_alpha_by_order_ptr(ent_data,
order);
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);
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);
463 auto &edge_alpha = get_alpha(ent_data);
464 edge_alpha.resize(nb_dofs, 4,
false);
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;
476 order,
lambda.size1(), edge_alpha.size1(), &edge_alpha(0, 0),
480 get_alpha_by_order_ptr(ent_data,
order) =
482 get_base_by_order_ptr(ent_data,
order) =
484 get_diff_base_by_order_ptr(ent_data,
order) =
485 get_diff_base_by_name_ptr(ent_data,
field_name);
492 for (
int ee = 0; ee != 6; ++ee)
500 "Wrong size of ent data");
506 for (
int ff = 0; ff != 4; ++ff) {
508 const int order = ent_data.getOrder();
512 if (get_alpha_by_order_ptr(ent_data,
order)) {
514 get_alpha_by_order_ptr(ent_data,
order);
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);
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);
527 auto &face_alpha = get_alpha(ent_data);
528 face_alpha.resize(nb_dofs, 4,
false);
532 senseFaceAlpha.resize(face_alpha.size1(), face_alpha.size2(),
false);
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)
539 face_alpha(d, tri_nodes[ff][
n]);
542 order,
lambda.size1(), face_alpha.size1(), &face_alpha(0, 0),
546 get_alpha_by_order_ptr(ent_data,
order) =
548 get_base_by_order_ptr(ent_data,
order) =
550 get_diff_base_by_order_ptr(ent_data,
order) =
551 get_diff_base_by_name_ptr(ent_data,
field_name);
558 for (
int ff = 0; ff != 4; ++ff)
565 "Wrong size ent of ent data");
568 const int order = ent_data.getOrder();
570 if (get_alpha_by_order_ptr(ent_data,
order)) {
572 get_alpha_by_order_ptr(ent_data,
order);
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);
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);
585 auto &tet_alpha = get_alpha(ent_data);
586 tet_alpha.resize(nb_dofs, 4,
false);
590 order,
lambda.size1(), tet_alpha.size1(), &tet_alpha(0, 0),
594 get_alpha_by_order_ptr(ent_data,
order) =
596 get_base_by_order_ptr(ent_data,
order) =
598 get_diff_base_by_order_ptr(ent_data,
order) =
599 get_diff_base_by_name_ptr(ent_data,
field_name);
601 ent_data.getBBAlphaIndicesSharedPtr(
field_name).reset();
635 PetscErrorCode (*base_polynomials)(
int p,
double s,
double *diff_s,
double *
L,
636 double *diffL,
const int dim) =
639 int nb_gauss_pts = pts.size2();
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,
660 auto interior_cache_ptr = get_interior_cache(base);
662 if (interior_cache_ptr) {
664 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
665 if (it != interior_cache_ptr->end()) {
667 noalias(data.
dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
678 nb_gauss_pts, base_polynomials);
680 if (interior_cache_ptr) {
681 auto p = interior_cache_ptr->emplace(
696 const int nb_gauss_pts = pts.size2();
699 (
unsigned int)nb_gauss_pts)
701 "Base functions or nodes has wrong number of integration points "
707 auto &ptr = data.getBBAlphaIndicesSharedPtr(
field_name);
721 auto &ptr = data.getBBDiffNSharedPtr(
field_name);
727 auto get_alpha_by_name_ptr =
729 const std::string &
field_name) -> boost::shared_ptr<MatrixInt> & {
730 return data.getBBAlphaIndicesSharedPtr(
field_name);
733 auto get_base_by_name_ptr =
735 const std::string &
field_name) -> boost::shared_ptr<MatrixDouble> & {
739 auto get_diff_base_by_name_ptr =
741 const std::string &
field_name) -> boost::shared_ptr<MatrixDouble> & {
745 auto get_alpha_by_order_ptr =
746 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixInt> & {
747 return data.getBBAlphaIndicesByOrderSharedPtr(o);
750 auto get_base_by_order_ptr =
751 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixDouble> & {
752 return data.getBBNByOrderSharedPtr(o);
755 auto get_diff_base_by_order_ptr =
756 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixDouble> & {
757 return data.getBBDiffNByOrderSharedPtr(o);
762 auto make_own = [
field_name](
auto &ent_data) {
763 auto &n_ptr = ent_data.getBBNSharedPtr(
field_name);
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();
779 "Wrong size ent of ent data");
782 const int order = ent_data.getOrder();
786 if (
order < 0 ||
static_cast<size_t>(
order) >=
789 "Bernstein-Bezier order %d is outside the supported range "
796 if (get_alpha_by_order_ptr(ent_data,
order)) {
798 get_alpha_by_order_ptr(ent_data,
order);
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);
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);
817 "Inconsistent number of DOFs");
821 auto &tet_alpha = get_alpha(ent_data);
822 tet_alpha.resize(1, 4,
false);
824 std::fill(get_n.data().begin(), get_n.data().end(), 1.);
832 "Inconsistent number of DOFs");
834 auto &tet_alpha = get_alpha(ent_data);
835 tet_alpha.resize(nb_dofs, 4,
false);
841 std::array<int *, 6> tet_edge_ptr{
849 tet_edge_ptr.data());
852 std::array<int *, 4> tet_face_ptr{
862 face_n.data(), tet_face_ptr.data());
872 order,
lambda.size1(), tet_alpha.size1(), &tet_alpha(0, 0),
876 get_alpha_by_order_ptr(ent_data,
order) =
878 get_base_by_order_ptr(ent_data,
order) =
880 get_diff_base_by_order_ptr(ent_data,
order) =
881 get_diff_base_by_name_ptr(ent_data,
field_name);
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);
902 int volume_order, std::array<int, 4> &faces_order,
903 std::array<int, 3 * 4> &faces_nodes,
905 boost::function<
int(
int)> broken_nbfacetri_edge_hdiv,
906 boost::function<
int(
int)> broken_nbfacetri_face_hdiv,
907 boost::function<
int(
int)> broken_nbvolumetet_edge_hdiv,
908 boost::function<
int(
int)> broken_nbvolumetet_face_hdiv,
909 boost::function<
int(
int)> broken_nbvolumetet_volume_hdiv
914 PetscErrorCode (*base_polynomials)(
int p,
double s,
double *diff_s,
double *
L,
915 double *diffL,
const int dim) =
918 int nb_gauss_pts = pts.size2();
920 return (
m.size1() &&
m.size2()) ? &*
m.data().begin() :
nullptr;
925 double *phi_f_e[4][3];
927 double *diff_phi_f_e[4][3];
928 double *diff_phi_f[4];
935 for (
int ff = 0; ff != 4; ++ff) {
937 broken_nbfacetri_edge_hdiv(faces_order[ff]));
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));
946 broken_nbfacetri_face_hdiv(faces_order[ff]));
947 N_face_bubble[ff].resize(nb_gauss_pts, 3 * face_bubble_dofs,
false);
953 constexpr int nb_nodes_on_tet = 4;
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,
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,
976 double *diff_phi_v_e[6];
977 double *diff_phi_v_f[4];
981 broken_nbvolumetet_edge_hdiv(volume_order));
984 for (
int ee = 0; ee != 6; ++ee) {
985 N_volume_edge[ee].resize(nb_gauss_pts, 3 * volume_edge_dofs,
false);
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);
997 broken_nbvolumetet_face_hdiv(volume_order));
1000 for (
int ff = 0; ff != 4; ++ff) {
1001 N_volume_face[ff].resize(nb_gauss_pts, 3 * volume_face_dofs,
false);
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);
1013 broken_nbvolumetet_volume_hdiv(volume_order));
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);
1030 std::array<int, 4> faces_order;
1031 std::array<int, 4 * 3> faces_nodes;
1038 faces_nodes.begin());
1039 for (
int ff = 0; ff != 4; ff++) {
1046 faces_order, faces_nodes,
1064 int nb_gauss_pts = pts.size2();
1066 return (
m.size1() &&
m.size2()) ? &*
m.data().begin() :
nullptr;
1076 decltype(getFTensor1FromPtr<3>(
static_cast<double *
>(
nullptr)));
1077 Tensor1Ptr3 t_base_f_f[] = {
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)))};
1115 for (
int ff = 0; ff != 4; ff++) {
1116 int face_order = faces_order[ff];
1123 3 * face_dofs,
false);
1124 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1125 9 * face_dofs,
false);
1129 double *diff_base_ptr =
1131 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1134 auto max_face_order =
1135 std::max(face_order,
1138 std::max(max_face_order,
1141 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1142 for (
int oo = 0; oo != max_face_order; oo++) {
1148 for (
int ee = 0; ee != 3; ++ee) {
1149 t_base(
i) = t_base_f_e[ff * 3 + ee](
i);
1151 ++t_base_f_e[ff * 3 + ee];
1153 for (
int ee = 0; ee != 3; ++ee) {
1154 t_diff_base(
i,
j) = t_diff_base_f_e[ff * 3 + ee](
i,
j);
1156 ++t_diff_base_f_e[ff * 3 + ee];
1164 t_base(
i) = t_base_f_f[ff](
i);
1167 t_diff_base(
i,
j) = t_diff_base_f_f[ff](
i,
j);
1169 ++t_diff_base_f_f[ff];
1184 data.
dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * volume_dofs,
1186 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
1187 9 * volume_dofs,
false);
1191 double *diff_base_ptr =
1193 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1198 decltype(getFTensor1FromPtr<3>(
static_cast<double *
>(
nullptr)));
1199 Tensor1Ptr3 t_base_v_e[] = {
1215 Tensor1Ptr3 t_base_v_f[] = {
1229 auto t_base_v = getFTensor1FromPtr<3>(base_ptr);
1232 auto max_volume_order = std::max(
1235 max_volume_order = std::max(
1238 max_volume_order = std::max(
1242 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1243 for (
int oo = 0; oo < max_volume_order; oo++) {
1250 for (
int ee = 0; ee < 6; ee++) {
1251 t_base(
i) = t_base_v_e[ee](
i);
1254 t_diff_base(
i,
j) = t_diff_base_v_e[ee](
i,
j);
1256 ++t_diff_base_v_e[ee];
1265 for (
int ff = 0; ff < 4; ff++) {
1266 t_base(
i) = t_base_v_f[ff](
i);
1269 t_diff_base(
i,
j) = t_diff_base_v_f[ff](
i,
j);
1271 ++t_diff_base_v_f[ff];
1280 t_base(
i) = t_base_v(
i);
1283 t_diff_base(
i,
j) = t_diff_base_v(
i,
j);
1310 int nb_gauss_pts = pts.size2();
1312 return (
m.size1() &&
m.size2()) ? &*
m.data().begin() :
nullptr;
1319 int nb_dofs_volume =
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,
1330 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 9 * nb_dofs,
1345 auto interior_cache_ptr = get_interior_cache(base);
1347 if (interior_cache_ptr) {
1349 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
1350 if (it != interior_cache_ptr->end()) {
1352 noalias(data.
dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
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,
1363 faces_order, faces_nodes,
1373 auto *base_ptr = &*data.
dataOnEntities[MBTET][0].getN(base).data().begin();
1374 auto *diff_base_ptr =
1376 auto t_base = getFTensor1FromPtr<3>(base_ptr);
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)))};
1410 Tensor1Ptr3 t_base_f_f[] = {
1422 Tensor1Ptr3 t_base_v_e[] = {
1438 Tensor1Ptr3 t_base_v_f[] = {
1452 auto t_base_v = getFTensor1FromPtr<3>(base_vol_ptr);
1456 int count_dofs_face = 0;
1457 int count_dofs_volume = 0;
1459 auto max_volume_order =
1460 std::max(volume_order,
1463 std::max(max_volume_order,
1466 std::max(max_volume_order,
1469 std::max(max_volume_order,
1471 max_volume_order = std::max(
1475 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1476 for (
int oo = 0; oo < max_volume_order; oo++) {
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);
1486 ++t_base_f_e[ff * 3 + ee];
1490 for (
int ee = 0; ee != 3; ++ee) {
1491 t_diff_base(
i,
j) = t_diff_base_f_e[ff * 3 + ee](
i,
j);
1493 ++t_diff_base_f_e[ff * 3 + ee];
1502 for (
auto ff = 0; ff != 4; ++ff) {
1503 t_base(
i) = t_base_f_f[ff](
i);
1506 t_diff_base(
i,
j) = t_diff_base_f_f[ff](
i,
j);
1508 ++t_diff_base_f_f[ff];
1518 for (
int ee = 0; ee < 6; ++ee) {
1519 t_base(
i) = t_base_v_e[ee](
i);
1522 t_diff_base(
i,
j) = t_diff_base_v_e[ee](
i,
j);
1524 ++t_diff_base_v_e[ee];
1526 ++count_dofs_volume;
1534 for (
int ff = 0; ff < 4; ff++) {
1535 t_base(
i) = t_base_v_f[ff](
i);
1538 t_diff_base(
i,
j) = t_diff_base_v_f[ff](
i,
j);
1540 ++t_diff_base_v_f[ff];
1542 ++count_dofs_volume;
1551 t_base(
i) = t_base_v(
i);
1554 t_diff_base(
i,
j) = t_diff_base_v(
i,
j);
1558 ++count_dofs_volume;
1564 if (nb_dofs != count_dofs / nb_gauss_pts) {
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;
1571 "Number of dofs %d is different than expected %d",
1572 count_dofs / nb_gauss_pts, nb_dofs);
1576 if (interior_cache_ptr) {
1577 auto p = interior_cache_ptr->emplace(
1593 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1597 int nb_gauss_pts = pts.size2();
1603 double *diff_phi_f[4];
1615 auto face_cache_ptr = get_face_cache_ptr();
1618 for (
int ff = 0; ff != 4; ff++) {
1620 int order = volume_order > face_order ? volume_order : face_order;
1628 if (face_cache_ptr) {
1629 auto it = face_cache_ptr->find(boost::make_tuple(
1631 face_order, nb_gauss_pts,
1636 if (it != face_cache_ptr->end()) {
1638 noalias(data.
dataOnEntities[MBTRI][ff].getDiffN(base)) = it->diffN;
1644 phi_f[ff] = &*data.
dataOnEntities[MBTRI][ff].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) {
1655 face_order, nb_gauss_pts, data.
facesNodes(ff, 0),
1673 auto interior_cache_ptr = get_interior_cache();
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()) {
1688 noalias(data.
dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1693 double *phi_v = &*data.
dataOnEntities[MBTET][0].getN(base).data().begin();
1694 double *diff_phi_v =
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(
1711 for (
int ff = 0; ff != 4; ff++) {
1730 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1734 int nb_gauss_pts = pts.size2();
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,
1742 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 9 * nb_dofs,
1760 auto interior_cache_ptr = get_interior_cache();
1762 if (interior_cache_ptr) {
1764 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
1765 if (it != interior_cache_ptr->end()) {
1767 noalias(data.
dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1772 std::array<MatrixDouble, 4> face_base_fun{
1777 std::array<MatrixDouble, 4> face_diff_base{
1783 int faces_nodes[4][3] = {{0, 1, 3}, {1, 2, 3}, {0, 3, 2}, {0, 2, 1}};
1785 std::array<int, 4> p_f{volume_order, volume_order, 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()};
1795 for (
int ff = 0; ff != 4; ff++) {
1798 faces_nodes[ff], p_f[ff],
1800 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1801 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, 4);
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);
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])};
1826 auto t_base_v = getFTensor1FromPtr<3>(&*vol_bases.data().begin());
1830 auto t_base = getFTensor1FromPtr<3>(
1838 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1839 for (
int oo = 0; oo < volume_order; oo++) {
1843 for (
auto ff = 0; ff != 4; ++ff) {
1844 t_base(
i) = t_base_v_f[ff](
i);
1847 t_diff_base(
i,
j) = t_diff_base_v_f[ff](
i,
j);
1849 ++t_diff_base_v_f[ff];
1855 t_base(
i) = t_base_v(
i);
1858 t_diff_base(
i,
j) = t_diff_base_v(
i,
j);
1865 if (interior_cache_ptr) {
1866 auto p = interior_cache_ptr->emplace(
1915 PetscErrorCode (*base_polynomials)(
int p,
double s,
double *diff_s,
double *
L,
1916 double *diffL,
const int dim) =
1919 int nb_gauss_pts = pts.size2();
1923 int sense[6],
order[6];
1927 double *hcurl_edge_n[6], *diff_hcurl_edge_n[6];
1928 for (
int ee = 0; ee != 6; ee++) {
1931 "data inconsistency");
1938 3 * nb_dofs,
false);
1939 data.
dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
1940 9 * nb_dofs,
false);
1943 diff_hcurl_edge_n[ee] =
1949 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1950 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts, base_polynomials);
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,
1966 double *hcurl_base_n[4], *diff_hcurl_base_n[4];
1967 for (
int ff = 0; ff != 4; ff++) {
1970 "data inconsistency");
1975 3 * nb_dofs,
false);
1976 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1977 9 * nb_dofs,
false);
1980 diff_hcurl_base_n[ff] =
1992 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1993 hcurl_base_n, diff_hcurl_base_n, nb_gauss_pts, base_polynomials);
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,
2008 3 * nb_vol_dofs,
false);
2009 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
2010 9 * nb_vol_dofs,
false);
2014 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2017 nb_gauss_pts, base_polynomials);
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);
2035 "This should be used only with DEMKOWICZ_JACOBI_BASE "
2040 int nb_gauss_pts = pts.size2();
2044 int sense[6],
order[6];
2047 "wrong size of data structure, expected space for six edges "
2051 double *hcurl_edge_n[6], *diff_hcurl_edge_n[6];
2052 for (
int ee = 0; ee != 6; ee++) {
2055 "orintation of edges is not set");
2062 3 * nb_dofs,
false);
2063 data.
dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
2064 9 * nb_dofs,
false);
2067 diff_hcurl_edge_n[ee] =
2073 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2074 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts);
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,
2091 "data structure for storing face h-curl base have wrong size "
2092 "should be four but is %zu",
2095 double *hcurl_base_n[4], *diff_hcurl_base_n[4];
2096 for (
int ff = 0; ff != 4; ff++) {
2099 "orintation of face is not set");
2104 3 * nb_dofs,
false);
2105 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
2106 9 * nb_dofs,
false);
2109 diff_hcurl_base_n[ff] =
2114 "data inconsistency, should be four faces");
2118 "data inconsistency, should be three nodes on face");
2123 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
2124 hcurl_base_n, diff_hcurl_base_n, nb_gauss_pts);
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,
2140 3 * nb_vol_dofs,
false);
2141 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
2142 9 * nb_vol_dofs,
false);
2146 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
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);
2180 boost::shared_ptr<BaseFunctionCtx> ctx_ptr) {
2185 int nb_gauss_pts = pts.size2();
2189 if (pts.size1() < 3)
2192 "Wrong dimension of pts, should be at least 3 rows with coordinates");
2198 data.
dataOnEntities[MBVERTEX][0].getN(base).resize(nb_gauss_pts, 4,
2202 &pts(0, 0), &pts(1, 0), &pts(2, 0), nb_gauss_pts);
2208 (
unsigned int)nb_gauss_pts) {
2210 "Base functions or nodes has wrong number of integration points "
2214 data.
dataOnEntities[MBVERTEX][0].getDiffN(base).resize(4, 3,
false);
2268 switch (continuity) {
2283 "Unknown (or not implemented) continuity");
2298 auto set_ainsworth = [&dofs_side_map]() {
2301 dofs_side_map.clear();
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 =
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);
2322 for (
int oo = 0; oo < max_order; oo++) {
2325 if (oo < face_edge_order)
2328 for (
auto ff = 0; ff != 4; ++ff) {
2329 for (
int ee = 0; ee != 3; ++ee) {
2337 if (oo < face_face_order)
2340 for (
auto ff = 0; ff != 4; ++ff) {
2347 if (oo < volume_edge_order)
2350 for (
int ee = 0; ee < 6; ee++) {
2357 if (oo < volume_face_order)
2360 for (
int ff = 0; ff < 4; ff++) {
2367 if (oo < volume_bubble_order)
2378 auto set_demkowicz = [&dofs_side_map]() {
2381 dofs_side_map.clear();
2389 for (
auto ff = 0; ff != 4; ++ff) {
2405 switch (continuity) {
2420 "Unknown (or not implemented) continuity");
2426template <
typename T>
2428 auto it = cache.find(ptr);
2429 if (it != cache.end()) {
2432 <<
"Cache off " << cache_name <<
": " << it->second.size();
2438 <<
"Cache on " << cache_name;
2448 std::string(
"hDivBaseFace") +
2453bool TetPolynomialBase::switchCacheBaseInterior<HDIV>(
2456 std::string(
"hdivBaseInterior") +
2461bool TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(
2464 std::string(
"hdivBrokenBaseInterior") +
2470 std::vector<void *>
v) {
2471 for (
auto fe_ptr :
v) {
2472 if (!TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr)) {
2473 TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr);
2475 if (!TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr)) {
2476 TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr);
2478 if (!TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr)) {
2479 TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr);
2486 std::vector<void *>
v) {
2487 for (
auto fe_ptr :
v) {
2488 if (TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr)) {
2489 TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr);
2491 if (TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr)) {
2492 TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr);
2494 if (TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr)) {
2495 TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr);
2501void TetPolynomialBase::switchCacheBaseOn<HDIV>(std::vector<void *>
v) {
2502 for (
auto b = 0; b !=
LASTBASE; ++b) {
2508void TetPolynomialBase::switchCacheBaseOff<HDIV>(std::vector<void *>
v) {
2509 for (
auto b = 0; b !=
LASTBASE; ++b) {
2518 std::string(
"hdivBaseInterior") +
2524 std::vector<void *>
v) {
2525 for (
auto fe_ptr :
v) {
2526 if (!TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr)) {
2527 TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr);
2534 std::vector<void *>
v) {
2535 for (
auto fe_ptr :
v) {
2536 if (TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr)) {
2537 TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr);
2543void TetPolynomialBase::switchCacheBaseOn<L2>(std::vector<void *>
v) {
2544 for (
auto b = 0; b !=
LASTBASE; ++b) {
2550void TetPolynomialBase::switchCacheBaseOff<L2>(std::vector<void *>
v) {
2551 for (
auto b = 0; b !=
LASTBASE; ++b) {
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
auto tetCacheSwitch(const void *ptr, T &cache, std::string cache_name)
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
FieldSpace
approximation spaces
@ L2
field with C-1 continuity
@ HCURL
field with continuous tangents
@ HDIV
field with continuous normal traction
FieldContinuity
Field continuity.
@ CONTINUOUS
Regular field.
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
static const char *const FieldSpaceNames[]
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
static const char *const ApproximationBaseNames[]
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
#define NBVOLUMETET_AINSWORTH_EDGE_HDIV(P)
#define NBEDGE_DEMKOWICZ_HCURL(P)
#define NBVOLUMETET_H1(P)
Number of base functions on tetrahedron for H1 space.
#define NBVOLUMETET_AINSWORTH_HCURL(P)
#define NBFACETRI_AINSWORTH_HCURL(P)
#define NBVOLUMETET_DEMKOWICZ_HDIV(P)
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))
#define NBVOLUMETET_AINSWORTH_FACE_HDIV(P)
#define NBEDGE_H1(P)
Number of base function on edge for H1 space.
#define NBFACETRI_DEMKOWICZ_HDIV(P)
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.
#define NBVOLUMETET_DEMKOWICZ_HCURL(P)
#define NBFACETRI_DEMKOWICZ_HCURL(P)
#define NBFACETRI_AINSWORTH_FACE_HDIV(P)
#define NBVOLUMETET_AINSWORTH_VOLUME_HDIV(P)
#define NBFACETRI_AINSWORTH_EDGE_HDIV(P)
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))
#define NBEDGE_AINSWORTH_HCURL(P)
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))
#define NBFACETRI_H1(P)
Number of base function on triangle for H1 space.
#define NBVOLUMETET_L2(P)
Number of base functions on tetrahedron for L2 space.
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'j', 3 > j
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
UBlasMatrix< int > MatrixInt
implementation of Data Operators for Forces and Sources
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)
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 .
auto getFTensor2HVecFromPtr< 3, 3 >(double *ptr)
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)
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.
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))
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 .
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.
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.
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 .
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.
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.
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.
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 .
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static boost::function< int(int)> broken_nbvolumetet_edge_hdiv
static boost::function< int(int)> broken_nbvolumetet_face_hdiv
static boost::function< int(int)> broken_nbfacetri_face_hdiv
static boost::function< int(int)> broken_nbvolumetet_volume_hdiv
static boost::function< int(int)> broken_nbfacetri_edge_hdiv
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 > > > > DofsSideMap
Map entity stype and side to element/entity dof index.
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 generateIndicesVertexTet(const int N, int *alpha)
static MoFEMErrorCode generateIndicesTetTet(const int N, int *alpha)
Class used to pass element data to calculate base functions on tet,triangle,edge.
const FieldApproximationBase copyNodeBase
const std::string fieldName
PetscErrorCode(* basePolynomialsType0)(int p, double s, double *diff_s, double *L, double *diffL, const int dim)
const FieldContinuity spaceContinuity
const FieldApproximationBase bAse
static constexpr size_t MaxBernsteinBezierOrder
data structure for finite element entity
MatrixInt facesNodes
nodes on finite element faces
std::array< std::bitset< LASTSPACE >, MBMAXTYPE > spacesOnEntities
spaces on entity types
std::array< boost::ptr_vector< EntData >, MBMAXTYPE > dataOnEntities
static constexpr int maxBrokenDofsOrder
Maximum order for broken space DOFs.
Calculate base functions on tetrahedral.
ublas::matrix< MatrixDouble > diffN_face_edge
EntPolynomialBaseCtx * cTx
MatrixDouble N_volume_bubble
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 getValueH1AinsworthBase(MatrixDouble &pts)
MoFEMErrorCode getValueHdivAinsworthBrokenBase(MatrixDouble &pts)
ublas::vector< MatrixDouble > diffN_volume_face
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
MoFEMErrorCode getValueL2BernsteinBezierBase(MatrixDouble &pts)
MoFEMErrorCode getValueHcurlDemkowiczBase(MatrixDouble &pts)
MoFEMErrorCode getValueHcurl(MatrixDouble &pts)
Get base functions for Hcurl space.
virtual ~TetPolynomialBase()
MoFEMErrorCode getValueH1BernsteinBezierBase(MatrixDouble &pts)
static MoFEMErrorCode setDofsSideMap(const FieldSpace space, const FieldContinuity continuity, const FieldApproximationBase base, DofsSideMap &)
Set map of dof to side number.
MoFEMErrorCode getValueH1(MatrixDouble &pts)
Get base functions for H1 space.
ublas::vector< MatrixDouble > diffN_face_bubble
ublas::vector< MatrixDouble > N_volume_edge
ublas::vector< MatrixDouble > N_volume_face
MoFEMErrorCode getValueHdiv(MatrixDouble &pts)
Get base functions for Hdiv space.
MoFEMErrorCode getValueHdivAinsworthBase(MatrixDouble &pts)
MoFEMErrorCode getValueL2AinsworthBase(MatrixDouble &pts)
ublas::vector< MatrixDouble > N_face_bubble
ublas::matrix< MatrixDouble > N_face_edge
MoFEMErrorCode getValueL2(MatrixDouble &pts)
Get base functions for L2 space.
MatrixDouble diffN_volume_bubble
MoFEMErrorCode getValueHdivDemkowiczBase(MatrixDouble &pts)
TetPolynomialBase(const void *ptr=nullptr)
MoFEMErrorCode getValue(MatrixDouble &pts, boost::shared_ptr< BaseFunctionCtx > ctx_ptr)
MoFEMErrorCode getValueHdivDemkowiczBrokenBase(MatrixDouble &pts)
ublas::vector< MatrixDouble > diffN_volume_edge
MoFEMErrorCode getValueHcurlAinsworthBase(MatrixDouble &pts)
static MoFEMErrorCode setDofsSideMapHdiv(const FieldContinuity continuity, const FieldApproximationBase base, DofsSideMap &dofs_side_map)
Set the Dofs Side Map Hdiv object.
base class for all interface classes
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
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
static std::array< std::map< const void *, BaseCacheMI >, LASTBASE > hdivBaseInterior
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
static std::array< std::map< const void *, HDivBaseFaceCacheMI >, LASTBASE > hDivBaseFace
static std::array< std::map< const void *, BaseCacheMI >, LASTBASE > l2BaseInterior
static std::array< std::map< const void *, BaseCacheMI >, LASTBASE > hdivBrokenBaseInterior