12 #ifndef __POSTPROC_ON_REF_MESH_HPP
13 #define __POSTPROC_ON_REF_MESH_HPP
33 std::map<std::string, std::vector<VectorDouble>>
fieldMap;
34 std::map<std::string, std::vector<MatrixDouble>>
gradMap;
59 std::vector<EntityHandle> &map_gauss_pts,
60 const std::string
field_name,
const std::string tag_name,
92 std::vector<EntityHandle> &map_gauss_pts,
94 const std::string tag_name,
131 ParallelComm *pcomm_post_proc_mesh =
133 if (pcomm_post_proc_mesh != NULL)
134 delete pcomm_post_proc_mesh;
154 Vec v = PETSC_NULL) {
156 ELEMENT::getOpPtrVector().push_back(
173 const std::string tag_name,
174 Vec v = PETSC_NULL) {
176 ELEMENT::getOpPtrVector().push_back(
196 Vec v = PETSC_NULL) {
198 ELEMENT::getOpPtrVector().push_back(
215 const std::string tag_name,
216 Vec v = PETSC_NULL) {
218 ELEMENT::getOpPtrVector().push_back(
236 Vec v = PETSC_NULL) {
238 ELEMENT::getOpPtrVector().push_back(
254 const char *file_type =
"MOAB",
255 const char *file_options =
"PARALLEL=WRITE_PART") {
257 ParallelComm *pcomm_post_proc_mesh =
259 if (pcomm_post_proc_mesh == NULL)
261 "ParallelComm not allocated");
267 template <
class VOLUME_ELEMENT>
277 bool ten_nodes_post_proc_tets =
true,
304 auto get_nb_of_ref_levels_from_options = [
this] {
307 PetscBool flg = PETSC_TRUE;
309 "-my_max_post_proc_ref_level", &max_level, &flg);
317 auto generate_for_hex = [&]() {
323 auto create_reference_element = [&moab_ref]() {
325 constexpr
double base_coords[] = {0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0,
326 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1};
328 for (
int nn = 0; nn < 8; nn++)
329 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
331 CHKERR moab_ref.create_element(MBHEX, nodes, 8, hex);
335 auto add_ho_nodes = [&]() {
338 CHKERR moab_ref.get_entities_by_type(0, MBHEX, hexes,
true);
340 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
341 CHKERR moab_ref.add_entities(meshset, hexes);
342 CHKERR moab_ref.convert_entities(meshset,
true,
true,
true);
343 CHKERR moab_ref.delete_entities(&meshset, 1);
347 auto set_gauss_pts = [&](std::map<EntityHandle, int> &little_map) {
350 CHKERR moab_ref.get_entities_by_type(0, MBHEX, hexes,
true);
352 CHKERR moab_ref.get_connectivity(hexes, hexes_nodes,
false);
354 gauss_pts.resize(hexes_nodes.size(), 4,
false);
356 for (
auto node : hexes_nodes) {
357 CHKERR moab_ref.get_coords(&node, 1, &gauss_pts(gg, 0));
358 little_map[node] = gg;
361 gauss_pts = trans(gauss_pts);
365 auto set_ref_hexes = [&](std::map<EntityHandle, int> &little_map) {
368 CHKERR moab_ref.get_entities_by_type(0, MBHEX, hexes,
true);
371 for (
auto hex : hexes) {
374 CHKERR moab_ref.get_connectivity(hex, conn, num_nodes,
false);
375 if (ref_hexes.size2() != num_nodes) {
376 ref_hexes.resize(hexes.size(), num_nodes);
378 for (
int nn = 0; nn != num_nodes; ++nn) {
379 ref_hexes(hh, nn) = little_map[conn[nn]];
386 auto set_shape_functions = [&]() {
390 const auto nb_gauss_pts = gauss_pts.size2();
391 shape_functions.resize(nb_gauss_pts, 8);
392 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
393 const double ksi = gauss_pts(0, gg);
394 const double zeta = gauss_pts(1, gg);
395 const double eta = gauss_pts(2, gg);
412 CHKERR create_reference_element();
415 std::map<EntityHandle, int> little_map;
416 CHKERR set_gauss_pts(little_map);
417 CHKERR set_ref_hexes(little_map);
418 CHKERR set_shape_functions();
423 auto generate_for_tet = [&]() {
426 const int max_level = get_nb_of_ref_levels_from_options();
431 auto create_reference_element = [&moab_ref]() {
433 constexpr
double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
435 for (
int nn = 0; nn < 4; nn++) {
437 moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
440 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
447 auto refine_ref_tetrahedron = [
this, &m_field_ref, max_level]() {
452 m_field_ref.
getInterface<BitRefManager>()->setBitRefLevelByDim(
454 for (
int ll = 0; ll != max_level; ++ll) {
456 "Refine Level %d", ll);
459 ->getEntitiesByTypeAndRefLevel(
463 ->getEntitiesByTypeAndRefLevel(
466 MeshRefinement *m_ref;
468 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
475 auto get_ref_gauss_pts_and_shape_functions = [
this, max_level, &moab_ref,
478 for (
int ll = 0; ll != max_level + 1; ++ll) {
482 ->getEntitiesByTypeAndRefLevel(
486 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
487 CHKERR moab_ref.add_entities(meshset, tets);
488 CHKERR moab_ref.convert_entities(meshset,
true,
false,
false);
489 CHKERR moab_ref.delete_entities(&meshset, 1);
492 CHKERR moab_ref.get_connectivity(tets, elem_nodes,
false);
495 gauss_pts.resize(elem_nodes.size(), 4,
false);
496 std::map<EntityHandle, int> little_map;
497 Range::iterator nit = elem_nodes.begin();
498 for (
int gg = 0; nit != elem_nodes.end(); nit++, gg++) {
499 CHKERR moab_ref.get_coords(&*nit, 1, &gauss_pts(gg, 0));
500 little_map[*nit] = gg;
502 gauss_pts = trans(gauss_pts);
505 Range::iterator tit = tets.begin();
506 for (
int tt = 0; tit != tets.end(); ++tit, ++tt) {
509 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
511 ref_tets.resize(tets.size(), num_nodes);
513 for (
int nn = 0; nn != num_nodes; ++nn) {
514 ref_tets(tt, nn) = little_map[conn[nn]];
519 shape_functions.resize(elem_nodes.size(), 4);
521 &gauss_pts(1, 0), &gauss_pts(2, 0),
531 CHKERR create_reference_element();
532 CHKERR refine_ref_tetrahedron();
533 CHKERR get_ref_gauss_pts_and_shape_functions();
538 CHKERR generate_for_hex();
539 CHKERR generate_for_tet();
545 auto get_element_max_dofs_order = [&]() {
547 auto dofs_vec = this->getDataVectorDofsPtr();
548 for (
auto &dof : *dofs_vec) {
549 const int dof_order = dof->getDofOrder();
550 max_order = (max_order < dof_order) ? dof_order : max_order;
554 const auto dof_max_order = get_element_max_dofs_order();
555 return (dof_max_order > 0) ? (dof_max_order - 1) / 2 : 0;
570 auto set_gauss_pts = [&](
auto &level_gauss_pts_on_ref_mesh,
auto &level_ref,
571 auto &level_shape_functions,
573 auto start_vert_handle,
auto start_ele_handle,
574 auto &verts_array,
auto &conn,
auto &ver_count,
581 std::min(
getMaxLevel(), level_gauss_pts_on_ref_mesh.size() - 1);
583 auto &level_ref_gauss_pts = level_gauss_pts_on_ref_mesh[level];
584 auto &level_ref_ele = level_ref[level];
585 auto &shape_functions = level_shape_functions[level];
586 T::gaussPts.resize(level_ref_gauss_pts.size1(),
587 level_ref_gauss_pts.size2(),
false);
588 noalias(T::gaussPts) = level_ref_gauss_pts;
590 EntityHandle fe_ent = T::numeredEntFiniteElementPtr->getEnt();
594 T::mField.get_moab().get_connectivity(fe_ent, conn, num_nodes,
true);
595 T::coords.resize(3 * num_nodes,
false);
596 CHKERR T::mField.get_moab().get_coords(conn, num_nodes, &T::coords[0]);
599 const int num_nodes = level_ref_gauss_pts.size2();
604 &*shape_functions.data().begin());
606 &verts_array[0][ver_count], &verts_array[1][ver_count],
607 &verts_array[2][ver_count]);
608 for (
int gg = 0; gg != num_nodes; ++gg, ++ver_count) {
612 auto set_float_precision = [](
const double x) {
613 if (std::abs(x) < std::numeric_limits<float>::epsilon())
620 auto t_ele_coords = getFTensor1FromArray<3, 3>(T::coords);
621 for (
int nn = 0; nn != CN::VerticesPerEntity(
type); ++nn) {
622 t_coords(
i) += t_n * t_ele_coords(
i);
627 for (
auto ii : {0, 1, 2})
628 t_coords(ii) = set_float_precision(t_coords(ii));
634 int def_in_the_loop = -1;
636 "NB_IN_THE_LOOP", 1, MB_TYPE_INTEGER,
th,
637 MB_TAG_CREAT | MB_TAG_SPARSE, &def_in_the_loop);
640 const int num_el = level_ref_ele.size1();
641 const int num_nodes_on_ele = level_ref_ele.size2();
642 auto start_e = start_ele_handle + ele_count;
644 for (
auto tt = 0; tt != level_ref_ele.size1(); ++tt, ++ele_count) {
645 for (
int nn = 0; nn != num_nodes_on_ele; ++nn) {
646 conn[num_nodes_on_ele * ele_count + nn] =
651 const int n_in_the_loop = T::nInTheLoop;
677 "Element type not implemented");
692 T::getOpPtrVector().clear();
699 ParallelComm *pcomm_post_proc_mesh =
701 if (pcomm_post_proc_mesh != NULL)
702 delete pcomm_post_proc_mesh;
706 auto alloc_vertices_and_elements_on_post_proc_mesh = [&]() {
709 auto fe_ptr = this->problemPtr->numeredFiniteElementsPtr;
712 fe_ptr->template get<Composite_Name_And_Part_mi_tag>().lower_bound(
713 boost::make_tuple(this->getFEName(), this->getLoFERank()));
715 fe_ptr->template get<Composite_Name_And_Part_mi_tag>().upper_bound(
716 boost::make_tuple(this->getFEName(), this->getHiFERank()));
718 const int number_of_ents_in_the_loop = this->getLoopSize();
719 if (std::distance(miit, hi_miit) != number_of_ents_in_the_loop) {
721 "Wrong size of indicices. Inconsistent size number of iterated "
722 "elements iterated by problem and from range.");
725 int nb_tet_vertices = 0;
727 int nb_hex_vertices = 0;
730 for (; miit != hi_miit; ++miit) {
731 auto type = (*miit)->getEntType();
735 this->numeredEntFiniteElementPtr = *miit;
738 if (this->exeTestHook) {
739 add = this->exeTestHook(
this);
759 "Element type not implemented");
765 ReadUtilIface *iface;
769 CHKERR iface->get_node_coords(
777 CHKERR iface->get_node_coords(
792 CHKERR alloc_vertices_and_elements_on_post_proc_mesh();
800 auto update_elements = [&]() {
802 ReadUtilIface *iface;
824 auto resolve_shared_ents = [&]() {
826 ParallelComm *pcomm_post_proc_mesh =
828 if (pcomm_post_proc_mesh == NULL) {
831 pcomm_post_proc_mesh =
new ParallelComm(
846 int rank = T::mField.get_comm_rank();
850 CHKERR pcomm_post_proc_mesh->resolve_shared_ents(0);
855 CHKERR resolve_shared_ents();
865 T::getOpPtrVector().push_back(
876 std::vector<EntityHandle> &map_gauss_pts,
886 if (data.getIndices().size() == 0)
890 th.resize(data.getFieldData().size());
892 double def_VAL[9] = {0, 0, 0};
896 for (
unsigned int dd = 0;
dd < data.getN().size2() / 3;
dd++) {
897 std::ostringstream ss;
898 ss <<
"HDIV_FACE_" << side <<
"_" <<
dd;
900 ss.str().c_str(), 3, MB_TYPE_DOUBLE,
th[
dd],
901 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
905 for (
unsigned int dd = 0;
dd < data.getN().size2() / 3;
dd++) {
906 std::ostringstream ss;
907 ss <<
"HDIV_TET_" <<
dd;
909 ss.str().c_str(), 3, MB_TYPE_DOUBLE,
th[
dd],
910 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
915 "data inconsistency");
918 for (
unsigned int gg = 0; gg < data.getN().size1(); gg++) {
919 for (
unsigned int dd = 0;
dd < data.getN().size2() / 3;
dd++) {
921 &data.getVectorN<3>(gg)(
dd, 0));
957 MoFEM::VolumeElementForcesAndSourcesCore> {
975 MoFEM::FatPrismElementForcesAndSourcesCore> {
980 bool ten_nodes_post_proc_tets =
true)
997 typedef multi_index_container<
999 indexed_by<ordered_unique<composite_key<
1000 PointsMap3D, member<PointsMap3D, const int, &PointsMap3D::kSi>,
1001 member<PointsMap3D, const int, &PointsMap3D::eTa>,
1002 member<PointsMap3D, const int, &PointsMap3D::zEta>>>>>
1013 std::map<EntityHandle, std::vector<PointsMap3D_multiIndex>>
1033 MoFEM::FaceElementForcesAndSourcesCore> {
1038 bool six_node_post_proc_tris =
true)
1068 boost::shared_ptr<VolumeElementForcesAndSourcesCoreOnSide>
sideOpFe;
1077 std::vector<EntityHandle> &map_gauss_pts,
const std::string
field_name,
1078 const std::string tag_name,
1079 boost::shared_ptr<VolumeElementForcesAndSourcesCoreOnSide> side_fe,
1080 const std::string vol_fe_name, boost::shared_ptr<MatrixDouble> mat_ptr,
1096 const std::string
field_name,
const std::string vol_fe_name =
"dFE",
1097 boost::shared_ptr<MatrixDouble> grad_mat_ptr =
nullptr,
1098 bool save_on_tag =
true);
1101 const std::string
field_name,
const std::string vol_fe_name =
"dFE",
1102 boost::shared_ptr<MatrixDouble> mat_ptr =
nullptr,
1103 bool save_on_tag =
true);
1115 std::vector<double *>
1118 std::vector<double *>
1154 bool six_node_post_proc_tris =
true)
1184 template <
int DIM1,
int DIM2>
1187 using DataMapVec = std::map<std::string, boost::shared_ptr<VectorDouble>>;
1188 using DataMapMat = std::map<std::string, boost::shared_ptr<MatrixDouble>>;
1202 std::vector<EntityHandle> &map_gauss_pts,
1211 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE],
false);
1225 template <
int DIM1,
int DIM2>
1231 std::array<double, 9> def;
1232 std::fill(def.begin(), def.end(), 0);
1234 auto get_tag = [&](
const std::string name,
size_t size) {
1236 CHKERR postProcMesh.tag_get_handle(name.c_str(), size, MB_TYPE_DOUBLE,
th,
1237 MB_TAG_CREAT | MB_TAG_SPARSE,
1246 for (
size_t r = 0;
r !=
DIM1; ++
r)
1253 for (
size_t r = 0;
r !=
DIM1; ++
r)
1254 for (
size_t c = 0;
c !=
DIM2; ++
c)
1255 mat(
r,
c) =
t(
r,
c);
1261 for (
size_t r = 0;
r !=
DIM1; ++
r)
1262 for (
size_t c = 0;
c !=
DIM1; ++
c)
1263 mat(
r,
c) =
t(
r,
c);
1273 auto set_float_precision = [](
const double x) {
1274 if (std::abs(x) < std::numeric_limits<float>::epsilon())
1281 for (
auto &
v : mat.data())
1282 v = set_float_precision(
v);
1283 return postProcMesh.tag_set_data(
th, &mapGaussPts[gg], 1,
1284 &*mat.data().begin());
1287 for (
auto &
m : dataMapScalar) {
1288 auto th = get_tag(
m.first, 1);
1290 auto nb_integration_pts = getGaussPts().size2();
1292 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1293 CHKERR set_tag(
th, gg, set_scalar(t_scl));
1298 for (
auto &
m : dataMapVec) {
1299 auto th = get_tag(
m.first, 3);
1300 auto t_vec = getFTensor1FromMat<DIM1>(*
m.second);
1301 auto nb_integration_pts = getGaussPts().size2();
1303 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1304 CHKERR set_tag(
th, gg, set_vector_3d(t_vec));
1309 for (
auto &
m : dataMapMat) {
1310 auto th = get_tag(
m.first, 9);
1311 auto t_mat = getFTensor2FromMat<DIM1, DIM2>(*
m.second);
1312 auto nb_integration_pts = getGaussPts().size2();
1314 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1315 CHKERR set_tag(
th, gg, set_matrix_3d(t_mat));
1320 for (
auto &
m : dataMapSymmMat) {
1321 auto th = get_tag(
m.first, 9);
1322 auto t_mat = getFTensor2SymmetricFromMat<DIM1>(*
m.second);
1323 auto nb_integration_pts = getGaussPts().size2();
1325 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
1326 CHKERR set_tag(
th, gg, set_matrix_symm_3d(t_mat));
1334 #endif //__POSTPROC_ON_REF_MESH_HPP