66                                        Range seed_side, 
const bool recursive,
 
   69  moab::Interface &moab = m_field.
get_moab();
 
   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);
 
 
  395    const bool recursive, 
Range &faces_with_three_nodes_on_front, 
int verb) {
 
  397  moab::Interface &moab = m_field.
get_moab();
 
  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);
 
 
  562    const bool add_interface_entities, 
const bool recursive, 
int verb) {
 
  564  moab::Interface &moab = m_field.
get_moab();
 
  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 %ld", 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");
 
  881    SetParent(
MoFEM::Core &core) : cOre(core), mField(core) {}
 
  887        auto it = ref_ents_ptr->find(ent);
 
  888        if (it != ref_ents_ptr->end()) {
 
  889          parentsToChange[ent] = parent;
 
  891          CHKERR mField.get_moab().tag_set_data(cOre.get_th_RefParentHandle(),
 
  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);
 
  924  auto get_adj_ents = [&](
const bool create) {
 
  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 %ld -> %ld", 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 %ld -> %ld",
 
  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() = %ld", face_side3_parent.size());
 
 1149      if (face_side4_parent.size() != 1)
 
 1151                "parent face4.size() = %ld", 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);