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>,
60 &HDivBaseCacheItem::nb_gauss_pts>,
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>
77 std::array<std::map<const void *, TetBaseCache::BaseCacheMI>,
LASTBASE>
79 std::array<std::map<const void *, TetBaseCache::BaseCacheMI>,
LASTBASE>
81 std::array<std::map<const void *, TetBaseCache::HDivBaseFaceCacheMI>,
LASTBASE>
83 std::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);
313 auto &vertex_alpha = get_alpha(vert_ent_data);
314 vertex_alpha.resize(4, 4,
false);
315 vertex_alpha.clear();
316 for (
int n = 0;
n != 4; ++
n)
319 auto &vert_get_n = get_base(vert_ent_data);
320 auto &vert_get_diff_n = get_diff_base(vert_ent_data);
321 vert_get_n.resize(nb_gauss_pts, 4,
false);
322 vert_get_diff_n.resize(nb_gauss_pts, 12,
false);
324 1,
lambda.size1(), vertex_alpha.size1(), &vertex_alpha(0, 0),
326 &vert_get_diff_n(0, 0));
327 for (
int n = 0;
n != 4; ++
n) {
328 const double f = boost::math::factorial<double>(
330 for (
int g = 0;
g != nb_gauss_pts; ++
g) {
331 vert_get_n(
g,
n) *=
f;
332 for (
int d = 0;
d != 3; ++
d)
333 vert_get_diff_n(
g, 3 *
n +
d) *=
f;
341 "Wrong size of ent data");
343 constexpr
int edges_nodes[6][2] = {{0, 1}, {1, 2}, {2, 0},
344 {0, 3}, {1, 3}, {2, 3}};
345 for (
int ee = 0; ee != 6; ++ee) {
347 const int sense = ent_data.getSense();
350 "Sense of the edge unknown");
351 const int order = ent_data.getOrder();
355 if (get_alpha_by_order_ptr(ent_data,
order)) {
357 get_alpha_by_order_ptr(ent_data,
order);
359 get_base_by_order_ptr(ent_data,
order);
360 get_diff_base_by_name_ptr(ent_data,
field_name) =
361 get_diff_base_by_order_ptr(ent_data,
order);
363 auto &get_n = get_base(ent_data);
364 auto &get_diff_n = get_diff_base(ent_data);
365 get_n.resize(nb_gauss_pts, nb_dofs,
false);
366 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs,
false);
369 edge_alpha.resize(nb_dofs, 4,
false);
373 for (
int i = 0;
i != edge_alpha.size1(); ++
i) {
374 int a = edge_alpha(
i, edges_nodes[ee][0]);
375 edge_alpha(
i, edges_nodes[ee][0]) =
376 edge_alpha(
i, edges_nodes[ee][1]);
377 edge_alpha(
i, edges_nodes[ee][1]) =
a;
381 order,
lambda.size1(), edge_alpha.size1(), &edge_alpha(0, 0),
385 get_alpha_by_order_ptr(ent_data,
order) =
387 get_base_by_order_ptr(ent_data,
order) =
389 get_diff_base_by_order_ptr(ent_data,
order) =
390 get_diff_base_by_name_ptr(ent_data,
field_name);
395 for (
int ee = 0; ee != 6; ++ee) {
397 ent_data.getBBAlphaIndicesSharedPtr(
field_name).reset();
398 auto &get_n = get_base(ent_data);
399 auto &get_diff_n = get_diff_base(ent_data);
400 get_n.resize(nb_gauss_pts, 0,
false);
401 get_diff_n.resize(nb_gauss_pts, 0,
false);
409 "Wrong size of ent data");
415 for (
int ff = 0; ff != 4; ++ff) {
417 const int order = ent_data.getOrder();
421 if (get_alpha_by_order_ptr(ent_data,
order)) {
423 get_alpha_by_order_ptr(ent_data,
order);
425 get_base_by_order_ptr(ent_data,
order);
426 get_diff_base_by_name_ptr(ent_data,
field_name) =
427 get_diff_base_by_order_ptr(ent_data,
order);
430 auto &get_n = get_base(ent_data);
431 auto &get_diff_n = get_diff_base(ent_data);
432 get_n.resize(nb_gauss_pts, nb_dofs,
false);
433 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs,
false);
435 auto &face_alpha = get_alpha(ent_data);
436 face_alpha.resize(nb_dofs, 4,
false);
440 senseFaceAlpha.resize(face_alpha.size1(), face_alpha.size2(),
false);
442 constexpr
int tri_nodes[4][3] = {
443 {0, 1, 3}, {1, 2, 3}, {0, 2, 3}, {0, 1, 2}};
444 for (
int d = 0;
d != nb_dofs; ++
d)
445 for (
int n = 0;
n != 3; ++
n)
447 face_alpha(
d, tri_nodes[ff][
n]);
450 order,
lambda.size1(), face_alpha.size1(), &face_alpha(0, 0),
454 get_alpha_by_order_ptr(ent_data,
order) =
456 get_base_by_order_ptr(ent_data,
order) =
458 get_diff_base_by_order_ptr(ent_data,
order) =
459 get_diff_base_by_name_ptr(ent_data,
field_name);
464 for (
int ff = 0; ff != 4; ++ff) {
466 ent_data.getBBAlphaIndicesSharedPtr(
field_name).reset();
467 auto &get_n = get_base(ent_data);
468 auto &get_diff_n = get_diff_base(ent_data);
469 get_n.resize(nb_gauss_pts, 0,
false);
470 get_diff_n.resize(nb_gauss_pts, 0,
false);
477 "Wrong size ent of ent data");
480 const int order = ent_data.getOrder();
482 if (get_alpha_by_order_ptr(ent_data,
order)) {
484 get_alpha_by_order_ptr(ent_data,
order);
486 get_base_by_order_ptr(ent_data,
order);
487 get_diff_base_by_name_ptr(ent_data,
field_name) =
488 get_diff_base_by_order_ptr(ent_data,
order);
491 auto &get_n = get_base(ent_data);
492 auto &get_diff_n = get_diff_base(ent_data);
493 get_n.resize(nb_gauss_pts, nb_dofs,
false);
494 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs,
false);
496 auto &tet_alpha = get_alpha(ent_data);
497 tet_alpha.resize(nb_dofs, 4,
false);
501 order,
lambda.size1(), tet_alpha.size1(), &tet_alpha(0, 0),
505 get_alpha_by_order_ptr(ent_data,
order) =
507 get_base_by_order_ptr(ent_data,
order) =
509 get_diff_base_by_order_ptr(ent_data,
order) =
510 get_diff_base_by_name_ptr(ent_data,
field_name);
515 ent_data.getBBAlphaIndicesSharedPtr(
field_name).reset();
516 auto &get_n = get_base(ent_data);
517 auto &get_diff_n = get_diff_base(ent_data);
518 get_n.resize(nb_gauss_pts, 0,
false);
519 get_diff_n.resize(nb_gauss_pts, 0,
false);
549 PetscErrorCode (*base_polynomials)(
int p,
double s,
double *diff_s,
double *
L,
550 double *diffL,
const int dim) =
553 int nb_gauss_pts = pts.size2();
557 data.
dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, nb_dofs,
false);
558 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 3 * nb_dofs,
574 auto interior_cache_ptr = get_interior_cache(base);
576 if (interior_cache_ptr) {
578 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
579 if (it != interior_cache_ptr->end()) {
581 noalias(data.
dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
592 nb_gauss_pts, base_polynomials);
594 if (interior_cache_ptr) {
595 auto p = interior_cache_ptr->emplace(
610 const int nb_gauss_pts = pts.size2();
613 (
unsigned int)nb_gauss_pts)
615 "Base functions or nodes has wrong number of integration points "
621 auto &ptr = data.getBBAlphaIndicesSharedPtr(
field_name);
635 auto &ptr = data.getBBDiffNSharedPtr(
field_name);
641 auto get_alpha_by_name_ptr =
643 const std::string &
field_name) -> boost::shared_ptr<MatrixInt> & {
644 return data.getBBAlphaIndicesSharedPtr(
field_name);
647 auto get_base_by_name_ptr =
649 const std::string &
field_name) -> boost::shared_ptr<MatrixDouble> & {
653 auto get_diff_base_by_name_ptr =
655 const std::string &
field_name) -> boost::shared_ptr<MatrixDouble> & {
659 auto get_alpha_by_order_ptr =
660 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixInt> & {
661 return data.getBBAlphaIndicesByOrderSharedPtr(o);
664 auto get_base_by_order_ptr =
665 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixDouble> & {
666 return data.getBBNByOrderSharedPtr(o);
669 auto get_diff_base_by_order_ptr =
670 [](
auto &data,
const size_t o) -> boost::shared_ptr<MatrixDouble> & {
671 return data.getBBDiffNByOrderSharedPtr(o);
677 "Wrong size ent of ent data");
680 const int order = ent_data.getOrder();
683 if (get_alpha_by_order_ptr(ent_data,
order)) {
685 get_alpha_by_order_ptr(ent_data,
order);
687 get_base_by_order_ptr(ent_data,
order);
688 get_diff_base_by_name_ptr(ent_data,
field_name) =
689 get_diff_base_by_order_ptr(ent_data,
order);
692 auto &get_n = get_base(ent_data);
693 auto &get_diff_n = get_diff_base(ent_data);
694 get_n.resize(nb_gauss_pts, nb_dofs,
false);
695 get_diff_n.resize(nb_gauss_pts, 3 * nb_dofs,
false);
703 "Inconsistent number of DOFs");
705 auto &tri_alpha = get_alpha(ent_data);
716 "Inconsistent number of DOFs");
718 auto &tet_alpha = get_alpha(ent_data);
719 tet_alpha.resize(nb_dofs, 4,
false);
725 std::array<int *, 6> tet_edge_ptr{
733 tet_edge_ptr.data());
736 std::array<int *, 6> tet_face_ptr{
746 face_n.data(), tet_face_ptr.data());
756 order,
lambda.size1(), tet_alpha.size1(), &tet_alpha(0, 0),
760 get_alpha_by_order_ptr(ent_data,
order) =
762 get_base_by_order_ptr(ent_data,
order) =
764 get_diff_base_by_order_ptr(ent_data,
order) =
765 get_diff_base_by_name_ptr(ent_data,
field_name);
771 ent_data.getBBAlphaIndicesSharedPtr(
field_name).reset();
772 auto &get_n = get_base(ent_data);
773 auto &get_diff_n = get_diff_base(ent_data);
774 get_n.resize(nb_gauss_pts, 0,
false);
775 get_diff_n.resize(nb_gauss_pts, 0,
false);
787 int volume_order, std::array<int, 4> &faces_order,
788 std::array<int, 3 * 4> &faces_nodes,
790 boost::function<
int(
int)> broken_nbfacetri_edge_hdiv,
791 boost::function<
int(
int)> broken_nbfacetri_face_hdiv,
792 boost::function<
int(
int)> broken_nbvolumetet_edge_hdiv,
793 boost::function<
int(
int)> broken_nbvolumetet_face_hdiv,
794 boost::function<
int(
int)> broken_nbvolumetet_volume_hdiv
799 PetscErrorCode (*base_polynomials)(
int p,
double s,
double *diff_s,
double *
L,
800 double *diffL,
const int dim) =
803 int nb_gauss_pts = pts.size2();
807 double *phi_f_e[4][3];
809 double *diff_phi_f_e[4][3];
810 double *diff_phi_f[4];
817 for (
int ff = 0; ff != 4; ++ff) {
819 broken_nbfacetri_edge_hdiv(faces_order[ff]));
821 for (
int ee = 0; ee < 3; ee++) {
822 N_face_edge(ff, ee).resize(nb_gauss_pts, 3 * face_edge_dofs,
false);
823 diffN_face_edge(ff, ee).resize(nb_gauss_pts, 9 * face_edge_dofs,
false);
824 phi_f_e[ff][ee] = &*
N_face_edge(ff, ee).data().begin();
828 broken_nbfacetri_face_hdiv(faces_order[ff]));
829 N_face_bubble[ff].resize(nb_gauss_pts, 3 * face_bubble_dofs,
false);
835 constexpr
int nb_nodes_on_tet = 4;
837 for (
int ff = 0; ff < 4; ff++) {
839 &faces_nodes[3 * ff], broken_nbfacetri_edge_hdiv(faces_order[ff]),
840 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
841 phi_f_e[ff], diff_phi_f_e[ff], nb_gauss_pts, nb_nodes_on_tet,
845 for (
int ff = 0; ff < 4; ff++) {
847 &faces_nodes[3 * ff], broken_nbfacetri_face_hdiv(faces_order[ff]),
848 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
849 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, nb_nodes_on_tet,
858 double *diff_phi_v_e[6];
859 double *diff_phi_v_f[4];
863 broken_nbvolumetet_edge_hdiv(volume_order));
866 for (
int ee = 0; ee != 6; ++ee) {
867 N_volume_edge[ee].resize(nb_gauss_pts, 3 * volume_edge_dofs,
false);
872 if (volume_edge_dofs)
874 broken_nbvolumetet_edge_hdiv(volume_order),
875 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
876 phi_v_e, diff_phi_v_e, nb_gauss_pts, base_polynomials);
879 broken_nbvolumetet_face_hdiv(volume_order));
882 for (
int ff = 0; ff != 4; ++ff) {
883 N_volume_face[ff].resize(nb_gauss_pts, 3 * volume_face_dofs,
false);
888 if (volume_face_dofs)
890 broken_nbvolumetet_face_hdiv(volume_order),
891 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
892 phi_v_f, diff_phi_v_f, nb_gauss_pts, base_polynomials);
895 broken_nbvolumetet_volume_hdiv(volume_order));
900 if (volume_bubble_dofs)
902 broken_nbvolumetet_volume_hdiv(volume_order),
903 &*shape_functions.data().begin(), &*diff_shape_functions.data().begin(),
904 phi_v, diff_phi_v, nb_gauss_pts, base_polynomials);
912 std::array<int, 4> faces_order;
913 std::array<int, 4 * 3> faces_nodes;
920 faces_nodes.begin());
921 for (
int ff = 0; ff != 4; ff++) {
928 faces_order, faces_nodes,
946 int nb_gauss_pts = pts.size2();
966 getFTensor1FromPtr<3>(&*(
N_face_edge(0, 0).data().begin())),
967 getFTensor1FromPtr<3>(&*(
N_face_edge(0, 1).data().begin())),
968 getFTensor1FromPtr<3>(&*(
N_face_edge(0, 2).data().begin())),
969 getFTensor1FromPtr<3>(&*(
N_face_edge(1, 0).data().begin())),
970 getFTensor1FromPtr<3>(&*(
N_face_edge(1, 1).data().begin())),
971 getFTensor1FromPtr<3>(&*(
N_face_edge(1, 2).data().begin())),
972 getFTensor1FromPtr<3>(&*(
N_face_edge(2, 0).data().begin())),
973 getFTensor1FromPtr<3>(&*(
N_face_edge(2, 1).data().begin())),
974 getFTensor1FromPtr<3>(&*(
N_face_edge(2, 2).data().begin())),
975 getFTensor1FromPtr<3>(&*(
N_face_edge(3, 0).data().begin())),
976 getFTensor1FromPtr<3>(&*(
N_face_edge(3, 1).data().begin())),
977 getFTensor1FromPtr<3>(&*(
N_face_edge(3, 2).data().begin()))};
992 for (
int ff = 0; ff != 4; ff++) {
993 int face_order = faces_order[ff];
1000 3 * face_dofs,
false);
1001 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1002 9 * face_dofs,
false);
1006 double *diff_base_ptr =
1008 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1011 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1012 for (
int oo = 0; oo != face_order; oo++) {
1021 for (
int ee = 0; ee != 3; ++ee) {
1022 t_base(
i) = t_base_f_e[ff * 3 + ee](
i);
1024 ++t_base_f_e[ff * 3 + ee];
1026 for (
int ee = 0; ee != 3; ++ee) {
1027 t_diff_base(
i,
j) = t_diff_base_f_e[ff * 3 + ee](
i,
j);
1029 ++t_diff_base_f_e[ff * 3 + ee];
1040 t_base(
i) = t_base_f_f[ff](
i);
1043 t_diff_base(
i,
j) = t_diff_base_f_f[ff](
i,
j);
1045 ++t_diff_base_f_f[ff];
1060 data.
dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * volume_dofs,
1062 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
1063 9 * volume_dofs,
false);
1067 double *diff_base_ptr =
1069 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1103 auto t_base_v = getFTensor1FromPtr<3>(base_ptr);
1106 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1107 for (
int oo = 0; oo < volume_order; oo++) {
1116 for (
int ee = 0; ee < 6; ee++) {
1117 t_base(
i) = t_base_v_e[ee](
i);
1120 t_diff_base(
i,
j) = t_diff_base_v_e[ee](
i,
j);
1122 ++t_diff_base_v_e[ee];
1133 for (
int ff = 0; ff < 4; ff++) {
1134 t_base(
i) = t_base_v_f[ff](
i);
1137 t_diff_base(
i,
j) = t_diff_base_v_f[ff](
i,
j);
1139 ++t_diff_base_v_f[ff];
1150 t_base(
i) = t_base_v(
i);
1153 t_diff_base(
i,
j) = t_diff_base_v(
i,
j);
1180 int nb_gauss_pts = pts.size2();
1186 int nb_dofs_volume =
1194 int nb_dofs = 4 * nb_dofs_face + nb_dofs_volume;
1195 data.
dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
1197 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 9 * nb_dofs,
1212 auto interior_cache_ptr = get_interior_cache(base);
1214 if (interior_cache_ptr) {
1216 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
1217 if (it != interior_cache_ptr->end()) {
1219 noalias(data.
dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1224 std::array<int, 4 * 3> faces_nodes = {0, 1, 3, 1, 2, 3, 0, 3, 2, 0, 2, 1};
1225 std::array<int, 4> faces_order{volume_order, volume_order, volume_order,
1230 faces_order, faces_nodes,
1240 auto *base_ptr = &*data.
dataOnEntities[MBTET][0].getN(base).data().begin();
1241 auto *diff_base_ptr =
1243 auto t_base = getFTensor1FromPtr<3>(base_ptr);
1248 getFTensor1FromPtr<3>(&*(
N_face_edge(0, 0).data().begin())),
1249 getFTensor1FromPtr<3>(&*(
N_face_edge(0, 1).data().begin())),
1250 getFTensor1FromPtr<3>(&*(
N_face_edge(0, 2).data().begin())),
1251 getFTensor1FromPtr<3>(&*(
N_face_edge(1, 0).data().begin())),
1252 getFTensor1FromPtr<3>(&*(
N_face_edge(1, 1).data().begin())),
1253 getFTensor1FromPtr<3>(&*(
N_face_edge(1, 2).data().begin())),
1254 getFTensor1FromPtr<3>(&*(
N_face_edge(2, 0).data().begin())),
1255 getFTensor1FromPtr<3>(&*(
N_face_edge(2, 1).data().begin())),
1256 getFTensor1FromPtr<3>(&*(
N_face_edge(2, 2).data().begin())),
1257 getFTensor1FromPtr<3>(&*(
N_face_edge(3, 0).data().begin())),
1258 getFTensor1FromPtr<3>(&*(
N_face_edge(3, 1).data().begin())),
1259 getFTensor1FromPtr<3>(&*(
N_face_edge(3, 2).data().begin()))};
1279 getFTensor1FromPtr<3>(&*(
N_face_bubble[3].data().begin()))};
1317 auto t_base_v = getFTensor1FromPtr<3>(base_vol_ptr);
1322 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1323 for (
int oo = 0; oo < volume_order; oo++) {
1331 for (
auto ff = 0; ff != 4; ++ff) {
1332 for (
int ee = 0; ee != 3; ++ee) {
1333 t_base(
i) = t_base_f_e[ff * 3 + ee](
i);
1335 ++t_base_f_e[ff * 3 + ee];
1338 for (
int ee = 0; ee != 3; ++ee) {
1339 t_diff_base(
i,
j) = t_diff_base_f_e[ff * 3 + ee](
i,
j);
1341 ++t_diff_base_f_e[ff * 3 + ee];
1352 for (
auto ff = 0; ff != 4; ++ff) {
1353 t_base(
i) = t_base_f_f[ff](
i);
1356 t_diff_base(
i,
j) = t_diff_base_f_f[ff](
i,
j);
1358 ++t_diff_base_f_f[ff];
1369 for (
int ee = 0; ee < 6; ee++) {
1370 t_base(
i) = t_base_v_e[ee](
i);
1373 t_diff_base(
i,
j) = t_diff_base_v_e[ee](
i,
j);
1375 ++t_diff_base_v_e[ee];
1385 for (
int ff = 0; ff < 4; ff++) {
1386 t_base(
i) = t_base_v_f[ff](
i);
1389 t_diff_base(
i,
j) = t_diff_base_v_f[ff](
i,
j);
1391 ++t_diff_base_v_f[ff];
1401 t_base(
i) = t_base_v(
i);
1404 t_diff_base(
i,
j) = t_diff_base_v(
i,
j);
1413 if (nb_dofs != count_dofs / nb_gauss_pts)
1415 "Number of dofs %d is different than expected %d", count_dofs,
1419 if (interior_cache_ptr) {
1420 auto p = interior_cache_ptr->emplace(
1436 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1440 int nb_gauss_pts = pts.size2();
1446 double *diff_phi_f[4];
1458 auto face_cache_ptr = get_face_cache_ptr();
1461 for (
int ff = 0; ff != 4; ff++) {
1463 int order = volume_order > face_order ? volume_order : face_order;
1471 if (face_cache_ptr) {
1472 auto it = face_cache_ptr->find(boost::make_tuple(
1474 face_order, nb_gauss_pts,
1479 if (it != face_cache_ptr->end()) {
1481 noalias(data.
dataOnEntities[MBTRI][ff].getDiffN(base)) = it->diffN;
1487 phi_f[ff] = &*data.
dataOnEntities[MBTRI][ff].getN(base).data().begin();
1494 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1495 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, 4);
1496 if (face_cache_ptr) {
1498 face_order, nb_gauss_pts, data.
facesNodes(ff, 0),
1516 auto interior_cache_ptr = get_interior_cache();
1525 for (
int v = 0;
v != 1; ++
v) {
1526 if (interior_cache_ptr) {
1527 auto it = interior_cache_ptr->find(
1528 boost::make_tuple(volume_order, nb_gauss_pts));
1529 if (it != interior_cache_ptr->end()) {
1531 noalias(data.
dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1536 double *phi_v = &*data.
dataOnEntities[MBTET][0].getN(base).data().begin();
1537 double *diff_phi_v =
1541 volume_order, &data.
dataOnEntities[MBVERTEX][0].getN(base)(0, 0),
1542 &data.
dataOnEntities[MBVERTEX][0].getDiffN(base)(0, 0), p_f, phi_f,
1543 diff_phi_f, phi_v, diff_phi_v, nb_gauss_pts);
1544 if (interior_cache_ptr) {
1545 auto p = interior_cache_ptr->emplace(
1554 for (
int ff = 0; ff != 4; ff++) {
1573 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1577 int nb_gauss_pts = pts.size2();
1582 int nb_dofs = 4 * nb_dofs_face + nb_dofs_volume;
1583 data.
dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 3 * nb_dofs,
1585 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 9 * nb_dofs,
1603 auto interior_cache_ptr = get_interior_cache();
1605 if (interior_cache_ptr) {
1607 interior_cache_ptr->find(boost::make_tuple(volume_order, nb_gauss_pts));
1608 if (it != interior_cache_ptr->end()) {
1610 noalias(data.
dataOnEntities[MBTET][0].getDiffN(base)) = it->diffN;
1615 std::array<MatrixDouble, 4> face_base_fun{
1620 std::array<MatrixDouble, 4> face_diff_base{
1626 int faces_nodes[4][3] = {{0, 1, 3}, {1, 2, 3}, {0, 3, 2}, {0, 2, 1}};
1628 std::array<int, 4> p_f{volume_order, volume_order, volume_order,
1630 std::array<double *, 4> phi_f{
1631 &*face_base_fun[0].data().begin(), &*face_base_fun[1].data().begin(),
1632 &*face_base_fun[2].data().begin(), &*face_base_fun[3].data().begin()};
1633 std::array<double *, 4> diff_phi_f{
1634 &*face_diff_base[0].data().begin(), &*face_diff_base[1].data().begin(),
1635 &*face_diff_base[2].data().begin(), &*face_diff_base[3].data().begin()};
1638 for (
int ff = 0; ff != 4; ff++) {
1641 faces_nodes[ff], p_f[ff],
1643 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1644 phi_f[ff], diff_phi_f[ff], nb_gauss_pts, 4);
1647 MatrixDouble vol_bases(nb_gauss_pts, 3 * nb_dofs_volume);
1648 MatrixDouble vol_diff_bases(nb_gauss_pts, 9 * nb_dofs_volume);
1649 auto *phi_v = &*vol_bases.data().begin();
1650 auto *diff_phi_v = &*vol_diff_bases.data().begin();
1652 volume_order, &data.
dataOnEntities[MBVERTEX][0].getN(base)(0, 0),
1653 &data.
dataOnEntities[MBVERTEX][0].getDiffN(base)(0, 0), p_f.data(),
1654 phi_f.data(), diff_phi_f.data(), phi_v, diff_phi_v, nb_gauss_pts);
1658 getFTensor1FromPtr<3>(phi_f[0]), getFTensor1FromPtr<3>(phi_f[1]),
1659 getFTensor1FromPtr<3>(phi_f[2]), getFTensor1FromPtr<3>(phi_f[3])};
1668 getFTensor1FromPtr<3>(&*vol_bases.data().begin());
1672 auto t_base = getFTensor1FromPtr<3>(
1680 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1681 for (
int oo = 0; oo < volume_order; oo++) {
1685 for (
auto ff = 0; ff != 4; ++ff) {
1686 t_base(
i) = t_base_v_f[ff](
i);
1689 t_diff_base(
i,
j) = t_diff_base_v_f[ff](
i,
j);
1691 ++t_diff_base_v_f[ff];
1697 t_base(
i) = t_base_v(
i);
1700 t_diff_base(
i,
j) = t_diff_base_v(
i,
j);
1707 if (interior_cache_ptr) {
1708 auto p = interior_cache_ptr->emplace(
1757 PetscErrorCode (*base_polynomials)(
int p,
double s,
double *diff_s,
double *
L,
1758 double *diffL,
const int dim) =
1761 int nb_gauss_pts = pts.size2();
1765 int sense[6],
order[6];
1769 double *hcurl_edge_n[6], *diff_hcurl_edge_n[6];
1770 for (
int ee = 0; ee != 6; ee++) {
1773 "data inconsistency");
1780 3 * nb_dofs,
false);
1781 data.
dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
1782 9 * nb_dofs,
false);
1785 diff_hcurl_edge_n[ee] =
1791 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1792 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts, base_polynomials);
1794 for (
int ee = 0; ee != 6; ee++) {
1795 data.
dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, 0,
false);
1796 data.
dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts, 0,
1808 double *hcurl_base_n[4], *diff_hcurl_base_n[4];
1809 for (
int ff = 0; ff != 4; ff++) {
1812 "data inconsistency");
1817 3 * nb_dofs,
false);
1818 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1819 9 * nb_dofs,
false);
1822 diff_hcurl_base_n[ff] =
1834 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1835 hcurl_base_n, diff_hcurl_base_n, nb_gauss_pts, base_polynomials);
1837 for (
int ff = 0; ff != 4; ff++) {
1838 data.
dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts, 0,
false);
1839 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts, 0,
1850 3 * nb_vol_dofs,
false);
1851 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
1852 9 * nb_vol_dofs,
false);
1856 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1859 nb_gauss_pts, base_polynomials);
1862 data.
dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 0,
false);
1863 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 0,
false);
1877 "This should be used only with DEMKOWICZ_JACOBI_BASE "
1882 int nb_gauss_pts = pts.size2();
1886 int sense[6],
order[6];
1889 "wrong size of data structure, expected space for six edges "
1893 double *hcurl_edge_n[6], *diff_hcurl_edge_n[6];
1894 for (
int ee = 0; ee != 6; ee++) {
1897 "orintation of edges is not set");
1904 3 * nb_dofs,
false);
1905 data.
dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts,
1906 9 * nb_dofs,
false);
1909 diff_hcurl_edge_n[ee] =
1915 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1916 hcurl_edge_n, diff_hcurl_edge_n, nb_gauss_pts);
1920 for (
int ee = 0; ee != 6; ee++) {
1921 data.
dataOnEntities[MBEDGE][ee].getN(base).resize(nb_gauss_pts, 0,
false);
1922 data.
dataOnEntities[MBEDGE][ee].getDiffN(base).resize(nb_gauss_pts, 0,
1933 "data structure for storing face h-curl base have wrong size "
1934 "should be four but is %d",
1937 double *hcurl_base_n[4], *diff_hcurl_base_n[4];
1938 for (
int ff = 0; ff != 4; ff++) {
1941 "orintation of face is not set");
1946 3 * nb_dofs,
false);
1947 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts,
1948 9 * nb_dofs,
false);
1951 diff_hcurl_base_n[ff] =
1956 "data inconsistency, should be four faces");
1960 "data inconsistency, should be three nodes on face");
1965 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1966 hcurl_base_n, diff_hcurl_base_n, nb_gauss_pts);
1970 for (
int ff = 0; ff != 4; ff++) {
1971 data.
dataOnEntities[MBTRI][ff].getN(base).resize(nb_gauss_pts, 0,
false);
1972 data.
dataOnEntities[MBTRI][ff].getDiffN(base).resize(nb_gauss_pts, 0,
1982 3 * nb_vol_dofs,
false);
1983 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts,
1984 9 * nb_vol_dofs,
false);
1988 &*data.
dataOnEntities[MBVERTEX][0].getDiffN(base).data().begin(),
1995 data.
dataOnEntities[MBTET][0].getN(base).resize(nb_gauss_pts, 0,
false);
1996 data.
dataOnEntities[MBTET][0].getDiffN(base).resize(nb_gauss_pts, 0,
false);
2022 boost::shared_ptr<BaseFunctionCtx> ctx_ptr) {
2027 int nb_gauss_pts = pts.size2();
2031 if (pts.size1() < 3)
2034 "Wrong dimension of pts, should be at least 3 rows with coordinates");
2040 data.
dataOnEntities[MBVERTEX][0].getN(base).resize(nb_gauss_pts, 4,
2044 &pts(0, 0), &pts(1, 0), &pts(2, 0), nb_gauss_pts);
2050 (
unsigned int)nb_gauss_pts) {
2052 "Base functions or nodes has wrong number of integration points "
2056 data.
dataOnEntities[MBVERTEX][0].getDiffN(base).resize(4, 3,
false);
2110 switch (continuity) {
2125 "Unknown (or not implemented) continuity");
2140 auto set_ainsworth = [&dofs_side_map]() {
2143 dofs_side_map.clear();
2154 for (
auto ff = 0; ff != 4; ++ff) {
2155 for (
int ee = 0; ee != 3; ++ee) {
2168 for (
auto ff = 0; ff != 4; ++ff) {
2180 for (
int ee = 0; ee < 6; ee++) {
2191 for (
int ff = 0; ff < 4; ff++) {
2210 auto set_demkowicz = [&dofs_side_map]() {
2213 dofs_side_map.clear();
2221 for (
auto ff = 0; ff != 4; ++ff) {
2237 switch (continuity) {
2242 return set_ainsworth();
2244 return set_demkowicz();
2252 "Unknown (or not implemented) continuity");
2258 template <
typename T>
2260 auto it = cache.find(ptr);
2261 if (it != cache.end()) {
2264 <<
"Cache off " << cache_name <<
": " << it->second.size();
2270 <<
"Cache on " << cache_name;
2280 std::string(
"hDivBaseFace") +
2285 bool TetPolynomialBase::switchCacheBaseInterior<HDIV>(
2288 std::string(
"hdivBaseInterior") +
2293 bool TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(
2296 std::string(
"hdivBrokenBaseInterior") +
2302 std::vector<void *>
v) {
2303 for (
auto fe_ptr :
v) {
2304 if (!TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr)) {
2305 TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr);
2307 if (!TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr)) {
2308 TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr);
2310 if (!TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr)) {
2311 TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr);
2318 std::vector<void *>
v) {
2319 for (
auto fe_ptr :
v) {
2320 if (TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr)) {
2321 TetPolynomialBase::switchCacheBaseFace<HDIV>(base, fe_ptr);
2323 if (TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr)) {
2324 TetPolynomialBase::switchCacheBaseInterior<HDIV>(base, fe_ptr);
2326 if (TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr)) {
2327 TetPolynomialBase::switchCacheBrokenBaseInterior<HDIV>(base, fe_ptr);
2333 void TetPolynomialBase::switchCacheBaseOn<HDIV>(std::vector<void *>
v) {
2334 for (
auto b = 0; b !=
LASTBASE; ++b) {
2340 void TetPolynomialBase::switchCacheBaseOff<HDIV>(std::vector<void *>
v) {
2341 for (
auto b = 0; b !=
LASTBASE; ++b) {
2350 std::string(
"hdivBaseInterior") +
2356 std::vector<void *>
v) {
2357 for (
auto fe_ptr :
v) {
2358 if (!TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr)) {
2359 TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr);
2366 std::vector<void *>
v) {
2367 for (
auto fe_ptr :
v) {
2368 if (TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr)) {
2369 TetPolynomialBase::switchCacheBaseInterior<L2>(base, fe_ptr);
2375 void TetPolynomialBase::switchCacheBaseOn<L2>(std::vector<void *>
v) {
2376 for (
auto b = 0; b !=
LASTBASE; ++b) {
2382 void TetPolynomialBase::switchCacheBaseOff<L2>(std::vector<void *>
v) {
2383 for (
auto b = 0; b !=
LASTBASE; ++b) {