18 : cOre(const_cast<
Core &>(core)) {
21 auto core_log = logging::core::get();
28 MOFEM_LOG(
"PRISM_INTERFACE", Sev::noisy) <<
"Prism interface created";
34 Range seed_side,
const bool recursive,
41 CubitMeshSet_multiIndex::index<
45 .find(boost::make_tuple(msId, cubit_bc_type.to_ulong()));
59 const bool recursive,
int verb) {
60 return getSides(msId, cubit_bc_type, mesh_bit_level,
Range(), recursive,
66 Range seed_side,
const bool recursive,
75 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
76 CHKERR moab.add_entities(out_meshset,
r);
77 CHKERR moab.write_file(name.c_str(),
"VTK",
"", &out_meshset, 1);
78 CHKERR moab.delete_entities(&out_meshset, 1);
82 auto get_adj = [&moab](
const Range r,
const int dim) {
85 CHKERR moab.get_adjacencies(
r, dim,
false,
a, moab::Interface::UNION);
87 CHKERR moab.get_connectivity(
r,
a,
true);
91 auto get_skin = [&skin](
const auto r) {
93 CHKERR skin.find_skin(0,
r,
false, s);
100 CHKERR moab.get_entities_by_type(sideset, MBTRI, triangles, recursive);
102 Range mesh_level_ents3d, mesh_level_ents3d_tris;
103 Range mesh_level_tris;
104 Range mesh_level_nodes;
105 Range mesh_level_prisms;
107 if (mesh_bit_level.any()) {
109 mesh_bit_level,
BitRefLevel().set(), MBTET, mesh_level_ents3d);
111 mesh_bit_level,
BitRefLevel().set(), MBTRI, mesh_level_tris);
113 mesh_bit_level,
BitRefLevel().set(), MBVERTEX, mesh_level_nodes);
114 mesh_level_ents3d_tris = get_adj(mesh_level_ents3d, 2);
116 mesh_bit_level,
BitRefLevel().set(), MBPRISM, mesh_level_prisms);
117 mesh_level_ents3d.merge(mesh_level_prisms);
121 if (mesh_bit_level.any())
122 triangles = intersect(triangles, mesh_level_ents3d_tris);
123 if (triangles.empty())
125 "Range of triangles set to split is emtpy. Nothing to split.");
127 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::verbose,
"Nb. of triangles in set %u",
130 auto get_skin_edges_boundary = [&]() {
132 auto ents3d_with_prisms = get_adj(get_adj(triangles, 0), 3);
133 if (mesh_bit_level.any())
134 ents3d_with_prisms = intersect(ents3d_with_prisms, mesh_level_ents3d);
135 auto ents3d = ents3d_with_prisms.subset_by_type(
143 auto skin_edges_boundary =
144 subtract(get_skin(triangles),
145 get_adj(get_skin(ents3d),
149 skin_edges_boundary =
150 subtract(skin_edges_boundary,
151 get_adj(ents3d_with_prisms.subset_by_type(MBPRISM),
155 return skin_edges_boundary;
158 auto skin_edges_boundary = get_skin_edges_boundary();
159 auto skin_nodes_boundary = get_adj(skin_edges_boundary, 0);
161 auto get_edges_without_boundary = [&]() {
163 return subtract(get_adj(triangles, 1), skin_edges_boundary);
166 auto get_nodes_without_front = [&]() {
169 return subtract(get_adj(triangles, 0),
170 skin_nodes_boundary);
175 auto get_ents3d_with_prisms = [&](
auto edges_without_boundary,
176 auto nodes_without_front) {
179 Range ents3d_with_prisms =
180 get_adj(unite(edges_without_boundary, nodes_without_front), 3);
182 auto find_triangles_on_front_and_adjacent_tet = [&]() {
185 auto skin_nodes_boundary_tris = get_adj(skin_nodes_boundary, 2);
190 auto skin_nodes_boundary_tris_nodes =
191 subtract(get_adj(skin_nodes_boundary_tris, 2), skin_nodes_boundary);
194 auto skin_nodes_boundary_tris_nodes_tris =
195 get_adj(skin_nodes_boundary_tris_nodes, 2);
198 skin_nodes_boundary_tris =
199 intersect(triangles, subtract(skin_nodes_boundary_tris,
200 skin_nodes_boundary_tris_nodes_tris));
201 if (!skin_nodes_boundary_tris.empty()) {
203 auto skin_nodes_boundary_tris_edges =
204 get_adj(skin_nodes_boundary_tris, 1);
206 skin_nodes_boundary_tris_edges =
207 subtract(skin_nodes_boundary_tris_edges, skin_edges_boundary);
210 ents3d_with_prisms.merge(get_adj(skin_nodes_boundary_tris_edges, 3));
215 CHKERR find_triangles_on_front_and_adjacent_tet();
218 if (mesh_bit_level.any())
219 ents3d_with_prisms = intersect(ents3d_with_prisms, mesh_level_ents3d);
226 return ents3d_with_prisms;
229 auto nodes_without_front = get_nodes_without_front();
230 auto ents3d_with_prisms =
231 get_ents3d_with_prisms(get_edges_without_boundary(), nodes_without_front);
232 auto ents3d = ents3d_with_prisms.subset_by_type(MBTET);
235 "Number of adjacents 3d entities to front nodes %u",
244 auto find_tetrahedrons_on_the_side = [&]() {
245 auto seed = intersect(get_adj(triangles, 3), ents3d);
246 if(!seed_side.empty())
247 seed = intersect(seed, seed_side);
250 side_ents3d.insert(seed[0]);
251 unsigned int nb_side_ents3d = side_ents3d.size();
252 Range side_ents3d_tris_on_surface;
261 nb_side_ents3d = side_ents3d.size();
263 "Number of entities on side %u", nb_side_ents3d);
267 adj_tris = get_skin(side_ents3d.subset_by_type(MBTET));
268 adj_tris = subtract(adj_tris, triangles);
269 if (mesh_bit_level.any())
270 adj_tris = intersect(adj_tris, mesh_level_tris);
273 CHKERR moab.get_adjacencies(adj_tris, 3,
false, adj_ents3d,
274 moab::Interface::UNION);
276 adj_ents3d = intersect(adj_ents3d, ents3d_with_prisms);
279 side_ents3d.insert(adj_ents3d.begin(), adj_ents3d.end());
283 boost::lexical_cast<std::string>(nb_side_ents3d) +
".vtk",
287 }
while (nb_side_ents3d != side_ents3d.size());
288 Range side_ents3d_tris;
289 CHKERR moab.get_adjacencies(side_ents3d, 2,
false, side_ents3d_tris,
290 moab::Interface::UNION);
291 side_ents3d_tris_on_surface = intersect(side_ents3d_tris, triangles);
294 Range left_triangles = subtract(triangles, side_ents3d_tris_on_surface);
295 if (!left_triangles.empty()) {
298 boost::lexical_cast<std::string>(nb_side_ents3d) +
".vtk",
305 if (side_ents3d_tris_on_surface.size() != triangles.size()) {
306 auto left_triangles = subtract(triangles, side_ents3d_tris_on_surface);
308 CHKERR moab.get_adjacencies(&*left_triangles.begin(), 1, 3,
false,
310 tets = intersect(tets, ents3d_with_prisms);
315 "Not all faces on surface going to be split, see error.vtk for "
316 "problematic triangle. "
317 "It could be a case where triangle on front (part boundary of "
318 "surface in interior) "
319 "has three nodes front.");
321 side_ents3d.insert(*tets.begin());
324 }
while (side_ents3d_tris_on_surface.size() != triangles.size());
329 auto side_ents3d = find_tetrahedrons_on_the_side();
330 if (ents3d_with_prisms.size() == side_ents3d.size())
332 "All tetrahedrons are on one side of split surface and that is "
333 "wrong. Algorithm can not distinguish (find) sides of interface.");
336 auto other_side = subtract(ents3d_with_prisms, side_ents3d);
338 auto side_nodes = get_adj(side_ents3d.subset_by_type(MBTET), 0);
340 nodes_without_front = intersect(nodes_without_front, side_nodes);
341 auto side_edges = get_adj(side_ents3d.subset_by_type(MBTET), 1);
342 skin_edges_boundary = intersect(skin_edges_boundary, side_edges);
345 std::vector<EntityHandle> children;
346 CHKERR moab.get_child_meshsets(sideset, children);
347 if (children.empty()) {
349 CHKERR moab.create_meshset(MESHSET_SET, children[0]);
350 CHKERR moab.create_meshset(MESHSET_SET, children[1]);
351 CHKERR moab.create_meshset(MESHSET_SET, children[2]);
352 CHKERR moab.add_child_meshset(sideset, children[0]);
353 CHKERR moab.add_child_meshset(sideset, children[1]);
354 CHKERR moab.add_child_meshset(sideset, children[2]);
356 if (children.size() != 3) {
358 "this meshset should have 3 children meshsets");
361 CHKERR moab.clear_meshset(&children[0], 3);
367 CHKERR moab.add_entities(child_side, side_ents3d);
368 CHKERR moab.add_entities(child_other_side, other_side);
369 CHKERR moab.add_entities(child_nodes_and_skin_edges, nodes_without_front);
370 CHKERR moab.add_entities(child_nodes_and_skin_edges, skin_edges_boundary);
373 "Nb. of side 3d elements in set %u", side_ents3d.size());
375 "Nb. of other side 3d elements in set %u", other_side.size());
376 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::verbose,
"Nb. of boundary edges %u",
377 skin_edges_boundary.size());
380 CHKERR moab.write_file(
"side.vtk",
"VTK",
"", &children[0], 1);
381 CHKERR moab.write_file(
"other_side.vtk",
"VTK",
"", &children[1], 1);
389 const bool recursive,
int verb) {
390 return getSides(sideset, mesh_bit_level,
Range(), recursive, verb);
395 const bool recursive,
Range &faces_with_three_nodes_on_front,
int verb) {
400 Range mesh_level_ents3d;
401 Range mesh_level_edges, mesh_level_tris;
402 if (mesh_bit_level.any()) {
404 mesh_bit_level,
BitRefLevel().set(), MBTET, mesh_level_ents3d);
407 mesh_bit_level,
BitRefLevel().set(), MBTRI, mesh_level_tris);
410 mesh_bit_level,
BitRefLevel().set(), MBEDGE, mesh_level_edges);
416 CHKERR moab.get_entities_by_type(sideset, MBTRI, triangles, recursive);
418 if (mesh_bit_level.any()) {
419 triangles = intersect(triangles, mesh_level_tris);
422 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::verbose,
"Nb. of triangles in set %u",
427 CHKERR moab.get_connectivity(triangles, nodes,
true);
430 CHKERR moab.get_adjacencies(nodes, 3,
false, ents3d, moab::Interface::UNION);
432 if (mesh_bit_level.any()) {
433 ents3d = intersect(ents3d, mesh_level_ents3d);
437 CHKERR skin.find_skin(0, ents3d.subset_by_type(MBTET),
false, skin_faces);
440 Range skin_edges_boundary;
441 CHKERR skin.find_skin(0, triangles,
false, skin_edges_boundary);
444 Range skin_faces_edges;
445 CHKERR moab.get_adjacencies(skin_faces, 1,
false, skin_faces_edges,
446 moab::Interface::UNION);
448 if (mesh_bit_level.any()) {
449 skin_faces_edges = intersect(skin_faces_edges, mesh_level_edges);
457 skin_edges_boundary =
458 subtract(skin_edges_boundary,
464 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
465 CHKERR moab.add_entities(out_meshset, triangles);
466 CHKERR moab.write_file(
"triangles.vtk",
"VTK",
"", &out_meshset, 1);
467 CHKERR moab.delete_entities(&out_meshset, 1);
468 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
469 CHKERR moab.add_entities(out_meshset, ents3d);
470 CHKERR moab.write_file(
"ents3d.vtk",
"VTK",
"", &out_meshset, 1);
471 CHKERR moab.delete_entities(&out_meshset, 1);
472 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
473 CHKERR moab.add_entities(out_meshset, skin_edges_boundary);
474 CHKERR moab.write_file(
"skin_edges_boundary.vtk",
"VTK",
"", &out_meshset,
476 CHKERR moab.delete_entities(&out_meshset, 1);
480 Range skin_nodes_boundary;
481 CHKERR moab.get_connectivity(skin_edges_boundary, skin_nodes_boundary,
true);
486 moab.get_connectivity(ents3d.subset_by_type(MBPRISM), prisms_nodes,
true);
488 skin_nodes_boundary = subtract(skin_nodes_boundary, prisms_nodes);
492 Range nodes_without_front = subtract(
493 nodes, skin_nodes_boundary);
496 Range skin_nodes_boundary_tris;
497 CHKERR moab.get_adjacencies(skin_nodes_boundary, 2,
false,
498 skin_nodes_boundary_tris, moab::Interface::UNION);
499 Range skin_nodes_boundary_tris_nodes;
500 CHKERR moab.get_connectivity(skin_nodes_boundary_tris,
501 skin_nodes_boundary_tris_nodes,
true);
503 skin_nodes_boundary_tris_nodes =
504 subtract(skin_nodes_boundary_tris_nodes, skin_nodes_boundary);
505 Range skin_nodes_boundary_tris_nodes_tris;
506 CHKERR moab.get_adjacencies(skin_nodes_boundary_tris_nodes, 2,
false,
507 skin_nodes_boundary_tris_nodes_tris,
508 moab::Interface::UNION);
511 skin_nodes_boundary_tris =
512 intersect(triangles, subtract(skin_nodes_boundary_tris,
513 skin_nodes_boundary_tris_nodes_tris));
514 faces_with_three_nodes_on_front.swap(skin_nodes_boundary_tris);
523 const bool add_interface_entities,
524 const bool recursive,
int verb) {
530 CubitMeshSet_multiIndex::index<
534 .find(boost::make_tuple(msId, cubit_bc_type.to_ulong()));
549 const bool add_interface_entities,
550 const bool recursive,
int verb) {
554 add_interface_entities, recursive, verb);
562 const bool add_interface_entities,
const bool recursive,
int verb) {
568 std::vector<EntityHandle> children;
570 CHKERR moab.get_child_meshsets(sideset, children);
571 if (children.size() != 3)
573 "should be 3 child meshsets, each of them contains tets on two "
574 "sides of interface");
578 CHKERR moab.get_entities_by_handle(children[0], side_ents3d,
false);
581 CHKERR moab.get_entities_by_handle(children[1], other_ents3d,
false);
584 CHKERR moab.get_entities_by_type(sideset, MBTRI, triangles, recursive);
585 Range side_ents3d_tris;
586 CHKERR moab.get_adjacencies(side_ents3d, 2,
true, side_ents3d_tris,
587 moab::Interface::UNION);
588 triangles = intersect(triangles, side_ents3d_tris);
591 CHKERR moab.get_entities_by_type(children[2], MBVERTEX, nodes,
false);
592 Range meshset_3d_ents, meshset_2d_ents;
593 CHKERR moab.get_entities_by_dimension(meshset, 3, meshset_3d_ents,
true);
594 Range meshset_tets = meshset_3d_ents.subset_by_type(MBTET);
595 CHKERR moab.get_adjacencies(meshset_tets, 2,
false, meshset_2d_ents,
596 moab::Interface::UNION);
597 side_ents3d = intersect(meshset_3d_ents, side_ents3d);
598 other_ents3d = intersect(meshset_3d_ents, other_ents3d);
599 triangles = intersect(meshset_2d_ents, triangles);
601 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::verbose,
"Split sides triangles %u",
603 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::verbose,
"Split sides 3d entities %u",
605 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::verbose,
"split sides nodes %u",
608 struct PartentAndChild {
613 typedef multi_index_container<
618 member<PartentAndChild, EntityHandle, &PartentAndChild::parent>>,
621 member<PartentAndChild, EntityHandle, &PartentAndChild::child>>
626 ParentChildMI parent_child;
632 MapNodes map_nodes, reverse_map_nodes;
636 struct CreateSideNodes {
639 std::vector<EntityHandle> splitNodes;
640 std::vector<double> splitCoords[3];
644 CreateSideNodes(
MoFEM::Core &core,
int split_size = 0)
645 :
cOre(core), m_field(core) {
646 splitNodes.reserve(split_size);
647 for (
auto dd : {0, 1, 2})
648 splitCoords[
dd].reserve(split_size);
652 splitNodes.emplace_back(
n);
653 for (
auto dd : {0, 1, 2})
654 splitCoords[
dd].emplace_back(coords[
dd]);
659 MapNodes &reverse_map_nodes) {
660 ReadUtilIface *iface;
662 int num_nodes = splitNodes.size();
663 std::vector<double *> arrays_coord;
666 CHKERR iface->get_node_coords(3, num_nodes, 0, startv, arrays_coord);
667 Range verts(startv, startv + num_nodes - 1);
668 for (
int dd = 0;
dd != 3; ++
dd)
669 std::copy(splitCoords[
dd].begin(), splitCoords[
dd].end(),
671 for (
int nn = 0; nn != num_nodes; ++nn) {
672 map_nodes[splitNodes[nn]] = verts[nn];
673 reverse_map_nodes[verts[nn]] = splitNodes[nn];
676 verts, &*splitNodes.begin());
682 CreateSideNodes create_side_nodes(
cOre, nodes.size());
685 struct CreateParentEntView {
690 &ref_parent_ents_view)
const {
695 auto miit = ref_ents.lower_bound(boost::make_tuple(MBVERTEX, MBVERTEX));
697 ref_ents.upper_bound(boost::make_tuple(MBVERTEX, MBVERTEX));
698 for (; miit != hi_miit; miit++) {
699 const auto &ent_bit = (*miit)->getBitRefLevel();
700 if ((ent_bit &
bit).any() && (ent_bit & mask) == ent_bit) {
701 auto p_ref_ent_view = ref_parent_ents_view.insert(*miit);
702 if (!p_ref_ent_view.second)
704 "non unique insertion");
710 if (inhered_from_bit_level.any() && inhered_from_bit_level_mask.any())
711 CHKERR CreateParentEntView()(inhered_from_bit_level,
712 inhered_from_bit_level_mask,
713 refined_ents_ptr, ref_parent_ents_view);
717 for (
auto pnit = nodes.pair_begin(); pnit != nodes.pair_end(); ++pnit) {
718 auto lo = refined_ents_ptr->lower_bound(pnit->first);
719 auto hi = refined_ents_ptr->upper_bound(pnit->second);
720 if (std::distance(lo, hi) != (pnit->second - pnit->first + 1))
723 "Can not find some nodes in database that are split on interface");
724 Range nodes_in_range;
726 std::vector<double> coords_range(nodes_in_range.size() * 3);
727 CHKERR moab.get_coords(nodes_in_range, &*coords_range.begin());
729 for (; lo != hi; ++lo, pos += 3) {
732 auto child_it = ref_parent_ents_view.find(node);
733 if (child_it != ref_parent_ents_view.end())
734 child_entity = (*child_it)->getEnt();
735 if (child_entity == 0) {
736 CHKERR create_side_nodes(&coords_range[pos], node);
738 map_nodes[node] = child_entity;
739 add_bit_nodes.insert(child_entity);
743 add_bit_nodes.merge(nodes);
746 CHKERR create_side_nodes(
bit, map_nodes, reverse_map_nodes);
751 CHKERR moab.create_meshset(MESHSET_SET, meshset_for_bit_level);
755 meshset_3d_ents = subtract(meshset_3d_ents, side_ents3d);
756 CHKERR moab.add_entities(meshset_for_bit_level, meshset_3d_ents);
760 for (Range::iterator eit3d = side_ents3d.begin(); eit3d != side_ents3d.end();
762 auto miit_ref_ent = refined_ents_ptr->find(*eit3d);
763 if (miit_ref_ent == refined_ents_ptr->end())
765 "Tetrahedron not in database");
769 CHKERR moab.get_connectivity(*eit3d, conn, num_nodes,
true);
772 for (
int ii = 0; ii < num_nodes; ii++) {
773 std::map<EntityHandle, EntityHandle>::iterator mit =
774 map_nodes.find(conn[ii]);
775 if (mit != map_nodes.end()) {
776 new_conn[ii] = mit->second;
779 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::noisy,
"nodes %u -> %d",
780 conn[ii], new_conn[ii]);
781 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::noisy,
"nodes %u -> %d",
782 conn[ii], new_conn[ii]);
785 new_conn[ii] = conn[ii];
788 if (nb_new_conn == 0) {
790 CHKERR moab.add_entities(meshset_for_bit_level, &*eit3d, 1);
803 for (; child_iit != hi_child_iit; child_iit++) {
805 CHKERR moab.get_connectivity(child_iit->get()->getEnt(), conn_ref_tet,
808 for (; nn < num_nodes; nn++) {
809 if (conn_ref_tet[nn] != new_conn[nn]) {
813 if (nn == num_nodes) {
814 if (existing_ent != 0)
816 "Should be only one child entity with the same connectivity");
817 existing_ent = child_iit->get()->getEnt();
824 RefEntity_multiIndex::iterator child_it;
826 if (existing_ent == 0) {
828 CHKERR moab.get_adjacencies(new_conn, 4, 3,
false, new_conn_tet);
829 if (new_conn_tet.empty()) {
830 CHKERR moab.create_element(MBTET, new_conn, 4, tet);
836 auto new_rit = refined_ents_ptr->get<
Ent_mi_tag>().equal_range(
837 *new_conn_tet.begin());
839 size_t nb_elems = std::distance(new_rit.first, new_rit.second);
842 "Can't find entity in database, size is %d", nb_elems);
843 tet = *new_conn_tet.begin();
849 CHKERR moab.add_entities(meshset_for_bit_level, &tet, 1);
850 new_3d_ents.insert(tet);
855 if (existing_ent == 0) {
856 Range new_conn_prism;
857 CHKERR moab.get_adjacencies(new_conn, 6, 3,
false, new_conn_prism);
858 if (new_conn_prism.empty()) {
859 CHKERR moab.create_element(MBPRISM, new_conn, 6, prism);
864 "It is prism with such connectivity, that case has to be "
865 "handled but this is not implemented");
868 prism = existing_ent;
870 CHKERR moab.add_entities(meshset_for_bit_level, &prism, 1);
871 new_3d_ents.insert(prism);
875 "Not implemented element");
887 auto it = ref_ents_ptr->find(ent);
888 if (it != ref_ents_ptr->end()) {
889 parentsToChange[ent] = parent;
900 for (
auto &
m : parentsToChange) {
901 auto it = ref_ents_ptr->find(
m.first);
902 if (it != ref_ents_ptr->end()) {
908 "Impossible to set parent");
911 "Entity not in database");
919 map<EntityHandle, EntityHandle> parentsToChange;
922 SetParent set_parent(
cOre);
926 for (
auto d : {1, 2}) {
928 CHKERR moab.get_adjacencies(new_3d_ents.subset_by_type(MBTET),
d, create,
929 adj, moab::Interface::UNION);
937 auto get_conn = [&](
const auto e) {
940 CHKERR moab.get_connectivity(e, conn, num_nodes,
true);
941 return std::make_pair(conn, num_nodes);
944 auto get_new_conn = [&](
auto conn) {
945 std::array<EntityHandle, 8> new_conn;
947 for (
int ii = 0; ii != conn.second; ++ii) {
948 auto mit = map_nodes.find(conn.first[ii]);
949 if (mit != map_nodes.end()) {
950 new_conn[ii] = mit->second;
953 PetscPrintf(m_field.
get_comm(),
"nodes %u -> %d", conn.first[ii],
957 new_conn[ii] = conn.first[ii];
960 return std::make_pair(new_conn, nb_new_conn);
963 auto get_reverse_conn = [&](
auto conn) {
964 std::array<EntityHandle, 8> rev_conn;
966 for (
int ii = 0; ii != conn.second; ++ii) {
967 auto mit = reverse_map_nodes.find(conn.first[ii]);
968 if (mit != reverse_map_nodes.end()) {
969 rev_conn[ii] = mit->second;
972 MOFEM_LOG_C(
"PRISM_INTERFACE", Sev::noisy,
"nodes %u -> %d",
973 conn.first[ii], rev_conn[ii]);
976 rev_conn[ii] = conn.first[ii];
979 return std::make_pair(rev_conn, nb_new_conn);
982 auto get_new_ent = [&](
auto new_conn,
auto nb_nodes,
int dim) {
984 CHKERR moab.get_adjacencies(&(new_conn.first[0]), nb_nodes, dim,
false,
986 if (new_ent.size() != 1)
988 return new_ent.front();
991 auto create_prisms = [&]() {
995 Tag th_interface_side;
996 const int def_side[] = {0};
997 CHKERR moab.tag_get_handle(
"INTERFACE_SIDE", 1, MB_TYPE_INTEGER,
998 th_interface_side, MB_TAG_CREAT | MB_TAG_SPARSE,
1001 for (
auto p = triangles.pair_begin(); p != triangles.pair_end(); ++p) {
1005 auto lo = refined_ents_ptr->lower_bound(
f);
1006 auto hi = refined_ents_ptr->upper_bound(s);
1007 if (std::distance(lo, hi) != (s -
f + 1))
1009 "Some triangles are not in database");
1011 for (;
f <= s; ++
f) {
1013 auto conn = get_conn(
f);
1014 auto new_conn = get_new_conn(conn);
1016 if (new_conn.second) {
1018 auto set_side_tag = [&](
auto new_triangle) {
1020 CHKERR moab.tag_set_data(th_interface_side, &new_triangle, 1,
1024 auto get_ent3d = [&](
auto e) {
1026 CHKERR moab.get_adjacencies(&e, 1, 3,
false, ents_3d);
1027 ents_3d = intersect(ents_3d, side_ents3d);
1029 switch (ents_3d.size()) {
1032 "Did not find adjacent tets on one side of the interface; if "
1033 "this error appears for a contact interface, try creating "
1034 "separate blocksets for each contact surface");
1037 "Found both adjacent tets on one side of the interface, if "
1038 "this error appears for a contact interface, try creating "
1039 "separate blocksets for each contact surface");
1044 return ents_3d.front();
1047 auto get_sense = [&](
auto e,
auto ent3d) {
1048 int sense, side, offset;
1049 CHKERR moab.side_number(ent3d, e, side, sense, offset);
1050 if (sense != 1 && sense != -1) {
1052 "Undefined sense of a triangle; if this error appears for a "
1053 "contact interface, try creating separate blocksets for each "
1059 auto new_triangle = get_new_ent(new_conn, 3, 2);
1060 set_side_tag(new_triangle);
1062 if (add_interface_entities) {
1064 if (inhered_from_bit_level.any())
1066 "not implemented for inhered_from_bit_level");
1070 conn.first[0], conn.first[1], conn.first[2],
1072 new_conn.first[0], new_conn.first[1], new_conn.first[2]};
1073 if (get_sense(
f, get_ent3d(
f)) == -1) {
1075 std::swap(prism_conn[1], prism_conn[2]);
1076 std::swap(prism_conn[4], prism_conn[5]);
1080 CHKERR moab.create_element(MBPRISM, prism_conn, 6, prism);
1081 CHKERR moab.add_entities(meshset_for_bit_level, &prism, 1);
1090 auto set_parnets = [&](
auto side_adj_faces_and_edges) {
1093 for (
auto p = side_adj_faces_and_edges.pair_begin();
1094 p != side_adj_faces_and_edges.pair_end(); ++p) {
1098 for (;
f <= s; ++
f) {
1099 auto conn = get_conn(
f);
1100 auto rev_conn = get_reverse_conn(conn);
1101 if (rev_conn.second) {
1102 auto rev_ent = get_new_ent(rev_conn, conn.second, conn.second - 1);
1103 CHKERR set_parent(
f, rev_ent, refined_ents_ptr);
1111 auto all_new_adj_entities = [&](
const bool create) {
1113 for (
auto d : {1, 2})
1114 CHKERR moab.get_adjacencies(new_3d_ents.subset_by_type(MBTET),
d, create,
1115 adj, moab::Interface::UNION);
1119 auto add_new_prisms_which_parents_are_part_of_other_intefaces = [&]() {
1122 Tag th_interface_side;
1123 CHKERR moab.tag_get_handle(
"INTERFACE_SIDE", th_interface_side);
1125 Range new_3d_prims = new_3d_ents.subset_by_type(MBPRISM);
1126 for (Range::iterator pit = new_3d_prims.begin(); pit != new_3d_prims.end();
1135 "this prism should have parent which is prism as well");
1140 CHKERR moab.get_connectivity(parent_prism, conn_parent, num_nodes,
true);
1141 Range face_side3_parent, face_side4_parent;
1142 CHKERR moab.get_adjacencies(conn_parent, 3, 2,
false, face_side3_parent);
1143 CHKERR moab.get_adjacencies(&conn_parent[3], 3, 2,
false,
1145 if (face_side3_parent.size() != 1)
1147 "parent face3.size() = %u", face_side3_parent.size());
1149 if (face_side4_parent.size() != 1)
1151 "parent face4.size() = %u", face_side4_parent.size());
1155 CHKERR moab.get_connectivity(*pit, conn, num_nodes,
true);
1156 Range face_side3, face_side4;
1157 CHKERR moab.get_adjacencies(conn, 3, 2,
false, face_side3);
1158 CHKERR moab.get_adjacencies(&conn[3], 3, 2,
false, face_side4);
1159 if (face_side3.size() != 1)
1161 "face3 is missing");
1163 if (face_side4.size() != 1)
1165 "face4 is missing");
1167 std::vector<EntityHandle> face(2), parent_face(2);
1168 face[0] = *face_side3.begin();
1169 face[1] = *face_side4.begin();
1170 parent_face[0] = *face_side3_parent.begin();
1171 parent_face[1] = *face_side4_parent.begin();
1172 for (
int ff = 0; ff != 2; ++ff) {
1173 if (parent_face[ff] == face[ff])
1176 CHKERR moab.tag_get_data(th_interface_side, &parent_face[ff], 1,
1178 CHKERR moab.tag_set_data(th_interface_side, &face[ff], 1,
1183 if (parent_tri != parent_face[ff]) {
1185 "Wrong parent %lu", parent_tri);
1194 auto reconstruct_refined_ents = [&]() {
1205 CHKERR reconstruct_refined_ents();
1207 CHKERR set_parnets(all_new_adj_entities(
true));
1208 CHKERR add_new_prisms_which_parents_are_part_of_other_intefaces();
1211 CHKERR set_parent.override_parents(refined_ents_ptr);
1214 meshset_for_bit_level, 3,
bit);
1215 CHKERR moab.delete_entities(&meshset_for_bit_level, 1);
1216 CHKERR moab.clear_meshset(&children[0], 3);