27 using namespace MoFEM;
38 #include <VolumeLengthQuality.hpp>
45 CPMeshCut::query_interface(boost::typeindex::type_index type_index,
53 CHKERRABORT(PETSC_COMM_SELF,
ierr);
58 auto core_log = logging::core::get();
60 LogManager::createSink(LogManager::getStrmSelf(),
"CPMeshCutSelf"));
61 LogManager::setLog(
"CPMeshCutSelf");
63 LogManager::createSink(LogManager::getStrmWorld(),
"CPMeshCutWorld"));
64 LogManager::setLog(
"CPMeshCutWorld");
66 LogManager::createSink(LogManager::getStrmSync(),
"CPMeshCutSync"));
67 LogManager::setLog(
"CPMeshCutSync");
74 MOFEM_LOG(
"CPMeshCutWorld", Sev::noisy) <<
"CPMeshCutSelf interface created";
91 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Mesh cut options",
"none");
94 CHKERR PetscOptionsInt(
"-edges_block_set",
"edges side set",
"",
97 CHKERR PetscOptionsInt(
"-vertex_block_set",
"vertex block set",
"",
101 CHKERR PetscOptionsInt(
"-vertex_node_set",
"vertex node set",
"",
104 CHKERR PetscOptionsInt(
"-fraction_level",
"fraction of merges merged",
"",
107 CHKERR PetscOptionsScalar(
"-tol_cut",
"get tolerance for cut edges",
"",
110 CHKERR PetscOptionsScalar(
"-tol_cut_close",
"get tolerance for cut edges",
"",
113 CHKERR PetscOptionsScalar(
"-tol_trim_close",
"get tolerance for trim edges",
117 CHKERR PetscOptionsBool(
"-cut_debug_cut",
"debug mesh cutting",
"",
debugCut,
122 "-remove_pathological_front_tris",
123 "remove triangles which have three nodes on crack front",
"",
129 "### Input parameter: -tol_cut %6.4e",
tolCut);
131 "### Input parameter: -tol_cut_close %6.4e",
tolCutClose);
133 "### Input parameter: -tol_trim_close %6.4e",
tolTrimClose);
135 PetscBool crack_surf_mesh_flg;
136 char crack_surf_mesh_name[255];
137 CHKERR PetscOptionsString(
138 "-my_cut_surface_file",
"file with crack surface for initial cut",
"",
139 crack_surf_mesh_name, crack_surf_mesh_name, 255, &crack_surf_mesh_flg);
140 if (crack_surf_mesh_flg)
144 CHKERR PetscOptionsRealArray(
"-crack_shift",
"shift surface by vector",
"",
145 sHift, &nmax_shift, &shift_flg);
149 "-cut_surface_side_set",
"sideset id with cutting surface",
"",
153 CHKERR PetscOptionsInt(
"-body_skin",
"body skin sideset id",
"",
156 CHKERR PetscOptionsInt(
"-crack_side_set",
"sideset id with crack surface",
"",
159 CHKERR PetscOptionsInt(
"-front_side_set",
"sideset id with crack front",
"",
163 CHKERR PetscOptionsInt(
"-ref_before_cut",
"number of refinements before cut",
169 PetscBool flg = PETSC_FALSE;
170 CHKERR PetscOptionsInt(
"-ref_before_tim",
"number of refinements before trim",
172 if (flg == PETSC_TRUE) {
174 <<
"### Input parameter: -ref_before_tim is still valid but will be "
175 "made obsolete in the next release, please use -ref_before_trim "
179 CHKERR PetscOptionsInt(
"-ref_before_trim",
180 "number of refinements before trim",
"",
187 "-my_cracked_body_block_set",
"blockset id of the cracked body",
"",
191 "### Input parameter: -my_cracked_body_block_set %d",
196 "-my_contact_prisms_block_set",
"blockset id of contact prisms",
"",
199 ierr = PetscOptionsEnd();
202 if (shift_flg && nmax_shift != 3) {
219 const int verb,
const bool debug) {
236 auto save_entities = [&](
const std::string name,
Range ents) {
254 while (!
bit.test(idx))
259 auto set_last_bit_ref = [&]() {
271 ents = subtract(ents, ents.subset_by_type(MBENTITYSET));
276 CHKERR set_last_bit_ref();
278 auto shift_after_ref = [&]() {
296 BitRefLevel().set(), MBTET,
"all_after_ref_bits.vtk",
"VTK",
"");
316 &meshset_from_file,
"");
329 PetscPrintf(PETSC_COMM_WORLD,
330 "Sideset %d with cutting crack surface not found\n",
345 const std::string save_mesh,
346 const int verb,
bool debug) {
359 Tag th_griffith_force;
360 Tag th_griffith_force_projected;
362 Tag th_front_positions;
364 Tag th_material_force;
366 boost::shared_ptr<OrientedBoxTreeTool> tree_body_skin_ptr;
367 tree_body_skin_ptr = boost::shared_ptr<OrientedBoxTreeTool>(
372 std::map<EntityHandle, EntityHandle> verts_map;
377 struct SetFrontPositionsParameters {
379 double tolRelSnapToFixedEdges;
381 double tolAbsSnapToFixedEdges;
386 double endNodeEdgeDeltaFactor;
388 SetFrontPositionsParameters() {
389 tolRelSnapToFixedEdges = 0.1;
390 tolAbsSnapToFixedEdges = 0.;
393 endNodeEdgeDeltaFactor = 0.2;
395 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
401 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"cutting_",
402 "Set front positions",
"none");
404 CHKERR PetscOptionsScalar(
405 "-surf_corner_factor",
406 "extension of the edge beyond corner when node on corer edge",
"",
407 cornerFactor, &cornerFactor, PETSC_NULL);
408 CHKERR PetscOptionsScalar(
410 "extension of cutting surface when node on the skin",
"", skinFactor,
411 &skinFactor, PETSC_NULL);
412 CHKERR PetscOptionsScalar(
413 "-end_node_edge_delta_factor",
414 "extension of the front edge at the node on the surface",
"",
415 endNodeEdgeDeltaFactor, &endNodeEdgeDeltaFactor, PETSC_NULL);
416 CHKERR PetscOptionsScalar(
"-snap_to_fixed_edge_rtol",
417 "snap to fixed edges (relative tolerances)",
"",
418 tolRelSnapToFixedEdges, &tolRelSnapToFixedEdges,
420 CHKERR PetscOptionsScalar(
"-snap_to_fixed_edge_atol",
421 "snap to fixed edges (absolute tolerances)",
"",
422 tolAbsSnapToFixedEdges, &tolAbsSnapToFixedEdges,
426 "### Input parameter: -cutting_surf_corner_factor %6.4e",
429 "### Input parameter: -cutting_surf_skin_factor %6.4e",
432 "CPMeshCutWorld", Sev::inform,
433 "### Input parameter: -cutting_end_node_edge_delta_factor %6.4e",
434 endNodeEdgeDeltaFactor);
436 "### Input parameter: -cutting_snap_to_fixed_edge_rtol %6.4e",
437 tolRelSnapToFixedEdges);
439 "### Input parameter: -cutting_snap_to_fixed_edge_atol %6.4e",
440 tolAbsSnapToFixedEdges);
442 ierr = PetscOptionsEnd();
449 auto save_entities = [&](
const std::string name,
Range ents) {
462 auto get_tags = [&]() {
467 th_griffith_force_projected);
474 if (
rval == MB_SUCCESS)
477 double def_val[] = {0, 0, 0};
479 "FRONT_POSITIONS", 3, MB_TYPE_DOUBLE, th_front_positions,
480 MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
483 if (
rval == MB_SUCCESS)
487 "AREA_CHANGE", 3, MB_TYPE_DOUBLE, th_area_change,
488 MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
492 auto get_surface = [
this, &
bit]() {
499 return intersect(
surface, bit_faces);
502 auto get_crack_front = [&]() {
509 return intersect(crack_front, bit_edges);
513 auto get_cracked_body_blockset = [&]() {
514 Range cracked_body_tets;
517 return cracked_body_tets;
521 auto build_body_skin_tree =
522 [&](boost::shared_ptr<OrientedBoxTreeTool> &tree_body_skin_ptr,
530 last_bit_tets = intersect(last_bit_tets, get_cracked_body_blockset());
531 Range last_bit_tets_skin;
532 CHKERR skin.find_skin(0, last_bit_tets,
false, last_bit_tets_skin);
533 CHKERR tree_body_skin_ptr->build(last_bit_tets_skin,
534 rootset_tree_body_skin);
539 auto set_positions = [&](
const Range nodes, Tag *
th =
nullptr) {
551 auto get_nodes = [
this](
Range edges) {
557 auto get_surface_skin = [
this, &skin](
auto &
surface) {
563 auto get_crack_front_ends = [
this, &skin](
Range crack_front) {
565 CHKERR skin.find_skin(0, crack_front,
false, end_nodes);
576 if (conn[1] == node) {
587 auto get_node_vec = [](std::vector<double> &
v,
const int nn) {
591 auto check_if_node_is_in_range = [](
const EntityHandle node,
593 return (ents.find(node) != ents.end());
596 auto check_for_nan = [&](
auto &
v, std::string msg =
"") {
599 if (std::isnan(
d) || std::isinf(
d))
602 "(%s) Not number %3.4e", msg.c_str(),
d);
605 "Not number %3.4e",
d);
611 auto set_tag = [&](
const EntityHandle node,
auto coords) {
613 CHKERR check_for_nan(coords,
"set_tag");
619 auto get_str = [](
auto v) {
return boost::lexical_cast<std::string>(
v); };
621 auto get_tag_data = [
this](Tag
th,
const Range &ents) {
622 std::vector<double>
v(3 * ents.size());
627 auto get_coords_vec = [
this](
const Range &ents) {
628 std::vector<double>
v(3 * ents.size());
633 auto get_prisms = [&]() {
636 moab::Interface::UNION);
637 prisms = prisms.subset_by_type(MBPRISM);
641 auto get_prims_surface = [&](
Range prisms) {
642 Range prisms_surface;
643 for (
auto prism : prisms) {
646 prisms_surface.insert(face);
648 return prisms_surface;
651 auto get_random_double = []() {
652 return static_cast<double>(rand()) /
static_cast<double>(RAND_MAX);
656 auto is_point_is_outside = [&](
const auto &coords) {
659 get_random_double() + std::numeric_limits<double>::epsilon();
660 random_ray[1] = get_random_double();
661 random_ray[2] = get_random_double();
662 random_ray /= norm_2(random_ray);
663 std::vector<double> distances_out;
664 std::vector<EntityHandle> facets_out;
665 CHKERR tree_body_skin_ptr->ray_intersect_triangles(
666 distances_out, facets_out, rootset_tree_body_skin, 1e-12, &coords[0],
668 return ((facets_out.size() % 2) == 0);
672 auto is_point_is_outside_with_check = [&](
const auto &coords) {
673 bool is_out = is_point_is_outside(coords);
677 is_out = is_point_is_outside(coords);
678 }
while (test_out != is_out);
682 auto get_proj_front_disp = [&](
auto front_disp,
683 auto griffith_force_projected) {
684 const double mgn_force_projected = norm_2(griffith_force_projected);
687 if (mgn_force_projected > std::numeric_limits<double>::epsilon()) {
688 griffith_force_projected /= mgn_force_projected;
689 noalias(disp) = factor * griffith_force_projected *
690 fmax(0, inner_prod(front_disp, griffith_force_projected));
699 auto get_ave_a_change = [&](
Range &crack_front_nodes,
700 std::vector<double> &area_change) {
701 double ave_a_change = 0;
703 for (
auto node : crack_front_nodes) {
704 auto a_change = get_node_vec(area_change, nn);
705 ave_a_change += norm_2(a_change);
707 ave_a_change /= crack_front_nodes.size();
711 auto get_ray_pout = [&](
const auto coords,
const auto ray) {
712 std::vector<double> distances_out;
713 std::vector<EntityHandle> facets_out;
714 double ray_length = norm_2(ray);
717 CHKERR tree_body_skin_ptr->ray_intersect_triangles(
718 distances_out, facets_out, rootset_tree_body_skin, 1e-12, &coords[0],
719 &unit_ray[0], &ray_length);
720 if (distances_out.empty())
723 return *std::min_element(distances_out.begin(), distances_out.end());
729 SetFrontPositionsParameters front_params;
732 sUrface = get_prims_surface(get_prisms());
735 Range crack_front = intersect(get_crack_front(), surface_skin);
736 Range crack_front_nodes = get_nodes(crack_front);
737 Range end_nodes = get_crack_front_ends(crack_front);
738 Range surface_skin_nodes =
739 subtract(subtract(get_nodes(surface_skin), crack_front_nodes),
740 get_nodes(intersect(
fixedEdges, surface_skin)));
741 surface_skin_nodes.merge(intersect(
cornerNodes, get_nodes(surface_skin)));
745 CHKERR set_positions(get_nodes(get_prisms()),
nullptr);
746 CHKERR build_body_skin_tree(tree_body_skin_ptr, rootset_tree_body_skin);
749 CHKERR save_entities(
"prisms_surface.vtk", get_prims_surface(get_prisms()));
751 CHKERR save_entities(
"surface_skin.vtk", surface_skin);
753 CHKERR save_entities(
"crack_front.vtk", crack_front);
755 CHKERR save_entities(
"crack_front_nodes.vtk", crack_front_nodes);
757 CHKERR save_entities(
"end_nodes.vtk", end_nodes);
759 auto surface_snap = [&]() {
762 surface_skin,
fixedEdges, front_params.tolRelSnapToFixedEdges,
763 front_params.tolAbsSnapToFixedEdges,
nullptr,
debug);
767 auto move_front_nodes = [&]() {
770 auto w = get_tag_data(th_w, crack_front_nodes);
771 auto griffith_forces_projected =
772 get_tag_data(th_griffith_force_projected, crack_front_nodes);
773 auto area_change = get_tag_data(th_area_change, crack_front_nodes);
774 auto mesh_node_positions = get_coords_vec(crack_front_nodes);
776 const double ave_a_change =
777 get_ave_a_change(crack_front_nodes, area_change);
780 for (
auto node : crack_front_nodes) {
782 auto front_disp = get_node_vec(
w, nn);
783 auto force_projected = get_node_vec(griffith_forces_projected, nn);
784 auto a_change = get_node_vec(area_change, nn);
785 auto position = get_node_vec(mesh_node_positions, nn);
787 CHKERR check_for_nan(front_disp,
"front_disp");
788 CHKERR check_for_nan(force_projected,
"force_projected");
789 CHKERR check_for_nan(a_change,
"a_change");
791 VectorDouble3 disp = get_proj_front_disp(front_disp, force_projected);
794 CHKERR check_for_nan(position);
795 CHKERR check_for_nan(disp);
801 Range adj_crack_front_nodes_edges;
803 adj_crack_front_nodes_edges,
804 moab::Interface::UNION);
805 Range adj_crack_front_nodes_on_fixed_edges;
806 adj_crack_front_nodes_on_fixed_edges =
807 intersect(adj_crack_front_nodes_edges,
fixedEdges);
808 adj_crack_front_nodes_on_fixed_edges =
809 intersect(adj_crack_front_nodes_on_fixed_edges, bit_edges);
811 CHKERR check_for_nan(front_disp,
"front_disp");
812 CHKERR check_for_nan(coords,
"coords");
813 CHKERR check_for_nan(disp,
"disp");
819 FIXED_EDGE_KIND0 = 1 << 2,
820 FIXED_EDGE_KIND1 = 1 << 3
823 unsigned int kind = FREE;
824 if (check_if_node_is_in_range(node, get_nodes(
fixedEdges)))
826 if (check_if_node_is_in_range(node, end_nodes))
833 ave_a_change * a_change /
834 (norm_2(a_change) + std::numeric_limits<double>::epsilon());
835 if (is_point_is_outside_with_check(coords)) {
837 coords += front_params.skinFactor * scaled_a_change;
838 CHKERR check_for_nan(coords,
839 "Pushed through surface (out by factor)");
841 MOFEM_LOG(
"CPMeshCutWorld", Sev::verbose)
842 <<
"Pushed through surface (out by factor): ";
847 coords + front_params.skinFactor * scaled_a_change;
848 if (is_point_is_outside_with_check(tmp_coords)) {
850 scaled_a_change / (norm_2(scaled_a_change) +
851 std::numeric_limits<double>::epsilon());
852 const double dist = get_ray_pout(coords, scaled_a_change);
854 coords +=
dist * ray;
856 coords += front_params.skinFactor * scaled_a_change;
858 coords,
"Pushing through surface (out by skin factor)");
860 MOFEM_LOG(
"CPMeshCutWorld", Sev::verbose)
861 <<
"Pushing through surface (out by skin factor): ";
866 if (kind & END_NODE) {
868 double min_dist = front_params.skinFactor * ave_a_change;
870 if (kind & FIXED_EDGE) {
874 &coords[0], 1,
fixedEdges, &min_dist, &pt_out[0]);
875 if (min_dist < front_params.skinFactor * ave_a_change)
878 CHKERR check_for_nan(coords,
"End node on the fixed edge");
880 MOFEM_LOG(
"CPMeshCutWorld", Sev::verbose)
881 <<
"End node on the fixed edge: ";
888 &coords[0], 1,
fixedEdges, &min_dist, &pt_out[0]);
889 if (min_dist < front_params.skinFactor * ave_a_change) {
891 if (inner_prod(a_change, ray) > 0) {
893 front_params.skinFactor * ave_a_change * ray / norm_2(ray);
894 coords += ray + scaled_ray;
896 coords,
"Pushing through surface dist (close to edge)");
897 MOFEM_LOG(
"CPMeshCutWorld", Sev::verbose)
898 <<
"Pushing through surface dist (close to edge): ";
904 if (!adj_crack_front_nodes_on_fixed_edges.empty()) {
906 const int nb_edges_on_fix_edges =
907 adj_crack_front_nodes_on_fixed_edges.size() - 1;
908 adj_crack_front_nodes_on_fixed_edges =
909 intersect(adj_crack_front_nodes_on_fixed_edges, surface_skin);
912 if (!adj_crack_front_nodes_on_fixed_edges.empty()) {
914 const int nb_edges_on_fix_edges_and_surface_skin =
915 adj_crack_front_nodes_on_fixed_edges.size();
916 const int diff_nb_edges =
917 nb_edges_on_fix_edges - nb_edges_on_fix_edges_and_surface_skin;
922 if (diff_nb_edges > 1) {
925 CHKERR get_edge_delta(adj_crack_front_nodes_on_fixed_edges[0], node,
927 coords += front_params.cornerFactor * edge_delta;
928 MOFEM_LOG(
"CPMeshCutWorld", Sev::verbose)
929 <<
"Node on fixed edge (crack meeting fixed edge >|): ";
931 coords,
"Node on fixed edge (crack meeting fixed edge >|)");
933 kind |= FIXED_EDGE_KIND0;
936 }
else if ((kind & END_NODE) && (kind & FIXED_EDGE)) {
941 Range adj_edges_on_skin =
942 intersect(adj_crack_front_nodes_edges, surface_skin);
943 if (!adj_edges_on_skin.empty()) {
946 CHKERR get_edge_delta(adj_edges_on_skin[0], node, edge_delta);
947 coords += front_params.cornerFactor * edge_delta;
949 coords,
"Node on fixed edge (crack crossing fixed edge =|>)");
951 MOFEM_LOG(
"CPMeshCutWorld", Sev::verbose)
952 <<
"Node on fixed edge (crack crossing fixed edge =|>): ";
954 kind |= FIXED_EDGE_KIND1;
963 !(kind & FIXED_EDGE_KIND0) &&
965 !(kind & FIXED_EDGE_KIND1)) {
969 Range adj_edges = intersect(adj_crack_front_nodes_edges, crack_front);
971 CHKERR get_edge_delta(adj_edges[0], node, edge_delta);
972 coords += edge_delta * front_params.endNodeEdgeDeltaFactor;
973 CHKERR check_for_nan(coords,
"End node on the skin");
976 MOFEM_LOG(
"CPMeshCutWorld", Sev::verbose) <<
"End node on the skin: ";
979 MOFEM_LOG_C(
"CPMeshCutWorld", Sev::verbose,
"Disp front %s at node %lu",
980 get_str(front_disp).c_str(), node);
982 CHKERR set_tag(node, coords);
990 auto smooth_front = [&]() {
992 Range smoothed_nodes = subtract(crack_front_nodes, end_nodes);
993 std::vector<double> new_positions(3 * smoothed_nodes.size());
995 for (
auto node : smoothed_nodes) {
998 edges = intersect(edges, crack_front);
1001 edges_nodes.erase(node);
1002 if (edges_nodes.size() != 2)
1004 "Expected two nodes but have %d", edges_nodes.size());
1016 const double l0 = norm_2(delta0);
1017 const double l2 = norm_2(delta2);
1019 if ((l0 / (l0 + l2)) < 0.5)
1020 node1 += 2 * (0.5 - (l0 / (l0 + l2))) * (delta2 / l2) * l0;
1022 node1 += 2 * (0.5 - (l2 / (l0 + l2))) * (delta0 / l0) * l2;
1029 &*new_positions.begin());
1034 auto delete_mofem_meshsets = [&]() {
1045 auto build_surface = [&]() {
1048 Tag th_interface_side;
1063 if (!(conn[0] != conn[1] && conn[0] != conn[2] && conn[1] != conn[2]))
1065 "Imposible trinagle");
1071 CHKERR check_for_nan(coords.data());
1074 for (
auto nn : {0, 1, 2}) {
1075 auto node_map = verts_map.find(conn[nn]);
1076 if (node_map == verts_map.end()) {
1079 verts_map[conn[nn]] = new_node;
1081 new_verts[nn] = verts_map[conn[nn]];
1083 for (
auto nn : {0, 1, 2})
1084 if (new_verts[nn] == 0)
1086 "Imposible trinagle");
1089 new_verts[0] = new_verts[1];
1094 new_surface.insert(ele);
1100 auto build_front = [&]() {
1102 Range new_surface_skin;
1106 for (
auto f : crack_front) {
1111 for (
int nn = 0; nn != 2; nn++) {
1112 auto node_map = verts_map.find(conn[nn]);
1113 if (node_map != verts_map.end())
1114 new_verts[nn] = node_map->second;
1117 "Expected that vertex should be already created");
1121 moab::Interface::INTERSECT);
1122 edges = intersect(edges, new_surface_skin);
1123 new_front.merge(edges);
1125 fRont.swap(new_front);
1129 auto edges_snap = [&]() {
1131 Range new_surface_skin;
1134 new_surface_skin,
fixedEdges, front_params.tolRelSnapToFixedEdges,
1135 front_params.tolAbsSnapToFixedEdges,
nullptr,
debug);
1139 auto delete_meshsets_with_crack_surfaces = [&]() {
1142 for (
int ll = 0; ll != 19; ++ll)
1149 CHKERR move_front_nodes();
1151 CHKERR delete_mofem_meshsets();
1159 CHKERR delete_meshsets_with_crack_surfaces();
1167 if (!save_mesh.empty())
1185 "There are both BLOCKSET and NODESET with ID equal to input "
1186 "parameter -vertex_block_set");
1208 auto save_mesh = [&](
const std::string file,
const Range ents) {
1211 if (!ents.empty()) {
1215 CHKERR m_field.
get_moab().write_file(file.c_str(),
"VTK",
"", &meshset,
1228 if (cit->getName().compare(0, 11,
"INT_CONTACT") == 0) {
1240 auto get_entities_from_constrained_interface = [&](
BitRefLevel &
bit) {
1245 if (cit->getName().compare(0, 15,
"INT_CONSTRAINED") == 0) {
1257 Range all_constrained_faces;
1260 all_constrained_faces.clear();
1263 CHKERR get_entities_from_contact_meshset(
bit);
1267 CHKERR get_entities_from_constrained_interface(
bit);
1274 CHKERR save_mesh(
"crack_surface_before_merge.vtk",
1280 "verts_on_mesh_cut_level.vtk",
"VTK",
"",
false);
1283 "edges_on_mesh_cut_level.vtk",
"VTK",
"",
false);
1286 "triangles_on_mesh_cut_level.vtk",
"VTK",
"",
false);
1289 "tets_on_mesh_cut_level.vtk",
"VTK",
"",
false);
1293 if (!all_constrained_faces.empty()) {
1296 CHKERR save_mesh(
"constrained_surface_before_merge.vtk",
1297 all_constrained_faces);
1313 CHKERR save_mesh(
"crack_surface_after_merge.vtk",
1316 CHKERR get_all_constrained_faces(bit_after_merge);
1317 if (!all_constrained_faces.empty() &&
debug) {
1318 CHKERR save_mesh(
"constrained_surface_after_merge.vtk",
1319 all_constrained_faces);
1322 auto add_entities_to_crack_meshset = [&]() {
1330 "Block set id of the cracked body is required for a simulation "
1331 "with contact and/or constrained interface, use "
1332 "'-my_cracked_body_block_set' parameter");
1335 Range cracked_body_tets, cracked_body_tris;
1338 CHKERR m_field.
get_moab().get_adjacencies(cracked_body_tets, 2,
false,
1340 moab::Interface::UNION);
1341 crack_faces = intersect(crack_faces, cracked_body_tris);
1343 CHKERR save_mesh(
"crack_faces_intersected_with_body_block.vtk",
1352 auto clean_copied_cutting_surface_entities = [&]() {
1354 Range surface_verts;
1357 Range surface_edges;
1359 false, surface_edges,
1360 moab::Interface::UNION);
1363 CHKERR m_field.
get_moab().get_entities_by_type(0, MBENTITYSET, meshsets,
1365 for (Range::iterator mit = meshsets.begin(); mit != meshsets.end(); mit++) {
1377 CHKERR add_entities_to_crack_meshset();
1378 CHKERR clean_copied_cutting_surface_entities();
1385 std::string file_name) {
1390 auto save_mesh = [&](
const std::string file,
const Range ents) {
1394 CHKERR moab.create_meshset(MESHSET_SET, meshset);
1395 CHKERR moab.add_entities(meshset, ents);
1396 CHKERR moab.write_file(file.c_str(),
"VTK",
"", &meshset, 1);
1397 CHKERR moab.delete_entities(&meshset, 1);
1414 for (
auto p : prisms) {
1416 CHKERR moab.side_element(p, 2, 3,
f);
1417 prisms_faces.insert(
f);
1418 CHKERR moab.side_element(p, 2, 4,
f);
1419 prisms_faces.insert(
f);
1423 CHKERR skin.find_skin(0, tets,
false, skin_faces);
1424 skin_faces = subtract(skin_faces, prisms_faces);
1428 CHKERR moab.add_entities(meshset, skin_faces);
1453 auto save_mesh = [&](
const std::string file,
const Range ents) {
1457 CHKERR moab.create_meshset(MESHSET_SET, meshset);
1458 CHKERR moab.add_entities(meshset, ents);
1459 CHKERR moab.write_file(file.c_str(),
"VTK",
"", &meshset, 1);
1460 CHKERR moab.delete_entities(&meshset, 1);
1467 PetscPrintf(PETSC_COMM_WORLD,
"Sideset %d with crack surface not found\n",
1480 Range skin_faces_edges;
1481 Range constrained_faces =
1483 CHKERR moab.get_adjacencies(unite(
cP.
bodySkin, constrained_faces), 1,
false,
1484 skin_faces_edges, moab::Interface::UNION);
1488 crack_front = subtract(crack_front, skin_faces_edges);
1492 CHKERR moab.add_entities(meshset, crack_front);
1498 Range crack_faces_edges;
1500 moab::Interface::UNION);
1520 auto save_mesh = [&](
const std::string file,
const Range ents) {
1524 CHKERR moab.create_meshset(MESHSET_SET, meshset);
1525 CHKERR moab.add_entities(meshset, ents);
1526 CHKERR moab.write_file(file.c_str(),
"VTK",
"", &meshset, 1);
1527 CHKERR moab.delete_entities(&meshset, 1);
1534 MBPRISM, prisms_level);
1540 for (
auto p : prisms_level) {
1566 "Wrong number of faces on both sides of crack %d != %d",
1574 auto create_front_meshset = [&]() {
1576 Range skin_faces_edges;
1578 false, skin_faces_edges,
1579 moab::Interface::UNION);
1583 crack_front = subtract(crack_front, skin_faces_edges);
1589 CHKERR create_front_meshset();
1599 "number of Crack Surfaces Faces = %d\n",
1602 "number of Crack Surfaces Faces On One Side = %d\n",
1605 "number of Crack Surfaces Faces On Other Side = %d\n",
1607 CHKERR PetscPrintf(m_field.
get_comm(),
"number of Crack Front Edges = %d\n",
1611 MBPRISM, prisms_level);
1612 CHKERR PetscPrintf(m_field.
get_comm(),
"number of Prisms = %d\n",
1613 prisms_level.size());
1635 PetscPrintf(PETSC_COMM_WORLD,
"Sideset %d with crack surface not found\n",
1644 Tag th_interface_side;
1646 m_field.
get_moab().tag_get_handle(
"INTERFACE_SIDE", th_interface_side);
1647 if (
rval == MB_SUCCESS)
1648 rval = m_field.
get_moab().tag_delete(th_interface_side);
1652 CHKERR m_field.
get_moab().create_meshset(MESHSET_SET, bit_meshset);
1655 MBTET, bit_meshset);
1657 MBPRISM, bit_meshset);
1659 auto save_mesh = [&](
const std::string file,
const EntityHandle meshset) {
1662 CHKERR moab.write_file(file.c_str(),
"VTK",
"", &meshset, 1);
1669 save_mesh(
"crack_surface_before_split.vtk", meshset_interface);
1673 meshset_interface,
true,
true,
QUIET);
1679 update_meshset, MBMAXTYPE,
true);
1681 CHKERR moab.delete_entities(&bit_meshset, 1);
1684 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
1685 Tag part_tag = pcomm->part_tag();
1688 0, MBENTITYSET, &part_tag, NULL, 1, tagged_sets,
1689 moab::Interface::UNION);
1690 for (Range::iterator mit = tagged_sets.begin(); mit != tagged_sets.end();
1693 CHKERR moab.tag_get_data(part_tag, &*mit, 1, &part);
1695 *mit,
bit,
BitRefLevel().set(), bit_split, bit_split, *mit, MBTET,
1698 CHKERR moab.get_entities_by_dimension(*mit, 3, ents3d,
true);
1699 for (Range::iterator eit = ents3d.begin(); eit != ents3d.end(); eit++) {
1700 CHKERR moab.tag_set_data(part_tag, &*eit, 1, &part);
1702 for (
int dd = 0;
dd != 3;
dd++) {
1704 CHKERR moab.get_adjacencies(ents3d,
dd,
false, ents,
1705 moab::Interface::UNION);
1706 for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
1707 CHKERR moab.tag_set_data(part_tag, &*eit, 1, &part);
1716 bit_split,
BitRefLevel().set(), MBTET, tets_level);
1719 bit_split,
BitRefLevel().set(), MBPRISM, prisms_level);
1721 CHKERR moab.create_meshset(MESHSET_SET, meshset_level);
1722 CHKERR moab.add_entities(meshset_level, tets_level);
1723 CHKERR moab.write_file(
"out_tets_level.vtk",
"VTK",
"", &meshset_level,
1725 CHKERR moab.delete_entities(&meshset_level, 1);
1727 CHKERR moab.create_meshset(MESHSET_SET, meshset_prims_level);
1728 CHKERR moab.add_entities(meshset_prims_level, prisms_level);
1729 CHKERR moab.write_file(
"out_prisms_level.vtk",
"VTK",
"",
1730 &meshset_prims_level, 1);
1731 CHKERR moab.delete_entities(&meshset_prims_level, 1);
1739 CHKERR moab.create_meshset(MESHSET_SET, meshset_level);
1740 CHKERR moab.add_entities(meshset_level, tets_level);
1741 CHKERR moab.write_file(
"out_tets_level_only.vtk",
"VTK",
"", &meshset_level,
1743 CHKERR moab.delete_entities(&meshset_level, 1);
1755 Range integration_triangles;
1760 Range all_masters, all_slaves;
1762 std::vector<std::pair<Range, Range>> contact_surface_pairs;
1765 m_field, contact_surface_pairs);
1768 boost::shared_ptr<ContactSearchKdTree::ContactCommonData_multiIndex>(
1771 for (
auto &contact_surface_pair : contact_surface_pairs) {
1773 Range slave_tris = contact_surface_pair.first;
1774 Range master_tris = contact_surface_pair.second;
1781 all_slaves.merge(slave_tris);
1782 all_masters.merge(master_tris);
1784 if (slave_tris.empty() || master_tris.empty())
1797 if (all_slaves.empty() || all_masters.empty())
1800 Range tris_from_prism;
1804 moab::Interface::UNION);
1806 tris_from_prism = tris_from_prism.subset_by_type(MBTRI);
1811 CHKERR moab.create_meshset(MESHSET_SET, meshset_slave_master_prisms);
1817 meshset_slave_master_prisms, 3,
cP.
mapBitLevel[
"spatial_domain"]);
1819 typedef ContactSearchKdTree::ContactCommonData_multiIndex::index<
1825 ItMultIndexPrism it_mult_index_prism =
1829 Range range_poly_tris;
1830 range_poly_tris.clear();
1831 range_poly_tris = it_mult_index_prism->get()->commonIntegratedTriangle;
1832 integration_triangles.insert(range_poly_tris.begin(),
1833 range_poly_tris.end());
1837 CHKERR moab.create_meshset(MESHSET_SET, ent_integration_vertex);
1840 CHKERR moab.create_meshset(MESHSET_SET, ent_integration_edge);
1843 CHKERR m_field.
get_moab().get_adjacencies(integration_triangles, 1,
true,
1844 edges, moab::Interface::UNION);
1845 CHKERR moab.add_entities(ent_integration_edge, edges);
1847 CHKERR m_field.
get_moab().get_connectivity(integration_triangles, verts,
1849 CHKERR moab.add_entities(ent_integration_vertex, verts);
1852 CHKERR moab.create_meshset(MESHSET_SET, ent_integration_tris);
1853 CHKERR moab.add_entities(ent_integration_tris, integration_triangles);
1856 ent_integration_vertex, 0,
cP.
mapBitLevel[
"spatial_domain"]);
1862 CHKERR moab.delete_entities(&ent_integration_tris, 1);
1864 const std::string output_name =
"slave_master_prisms.vtk";
1865 CHKERR moab.write_mesh(output_name.c_str(), &meshset_slave_master_prisms, 1);
1868 CHKERR moab.delete_entities(&meshset_slave_master_prisms, 1);
1881 std::vector<BitRefLevel> bit_levels;
1884 auto get_cracked_not_in_body_blockset = [&](
auto ref_level_meshset) {
1885 Range ref_level_tet;
1886 CHKERR moab.get_entities_by_type(ref_level_meshset, MBTET, ref_level_tet,
1888 Range cracked_body_tets;
1891 return subtract(ref_level_tet, cracked_body_tets);
1894 std::size_t idx = 0;
1895 while (!bit_levels.back().test(idx))
1897 int contact_lvl = idx + 1;
1904 if (cit->getName().compare(0, 11,
"INT_CONTACT") == 0) {
1905 CHKERR PetscPrintf(PETSC_COMM_WORLD,
"Insert %s (id: %d)\n",
1906 cit->getName().c_str(), cit->getMeshsetId());
1911 CHKERR moab.create_meshset(MESHSET_SET, ref_level_meshset);
1913 bit_levels.back(),
BitRefLevel().set(), MBTET, ref_level_meshset);
1915 bit_levels.back(),
BitRefLevel().set(), MBPRISM, ref_level_meshset);
1919 cubit_meshset, bit_levels.back(),
1920 get_cracked_not_in_body_blockset(ref_level_meshset),
true, verb);
1922 bit_levels.push_back(
BitRefLevel().set(contact_lvl));
1925 cubit_meshset,
true,
true, verb);
1928 CHKERR moab.delete_entities(&ref_level_meshset, 1);
1934 updated_meshset, bit_levels.front(),
BitRefLevel().set(),
1935 bit_levels.back(), bit_levels.back(), updated_meshset, MBMAXTYPE,
1941 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
1942 Tag part_tag = pcomm->part_tag();
1945 0, MBENTITYSET, &part_tag, NULL, 1, tagged_sets,
1946 moab::Interface::UNION);
1947 for (Range::iterator mit = tagged_sets.begin();
1948 mit != tagged_sets.end(); mit++) {
1950 CHKERR moab.tag_get_data(part_tag, &*mit, 1, &part);
1952 *mit, bit_levels.front(),
BitRefLevel().set(), bit_levels.back(),
1953 bit_levels.back(), *mit, MBTET,
true);
1955 CHKERR moab.get_entities_by_dimension(*mit, 3, ents3d,
true);
1956 for (Range::iterator eit = ents3d.begin(); eit != ents3d.end();
1958 CHKERR moab.tag_set_data(part_tag, &*eit, 1, &part);
1960 for (
int dd = 0;
dd != 3;
dd++) {
1962 CHKERR moab.get_adjacencies(ents3d,
dd,
false, ents,
1963 moab::Interface::UNION);
1964 for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
1965 CHKERR moab.tag_set_data(part_tag, &*eit, 1, &part);
1971 if (contact_lvl > 1) {
1973 bit_levels.front(),
true);
1976 for (
int ll = contact_lvl - 1; ll != 19; ++ll) {
1980 1, shift_mask, verb);
1981 bit_levels.pop_back();
1992 bit_levels.back(),
BitRefLevel().set(), MBPRISM, prisms_level);
2022 CHKERR moab.side_element(p, 2, 3, tri);
2024 CHKERR moab.side_element(p, 2, 4, tri);
2029 Range slave_nodes, master_nodes;
2033 if (slave_nodes.size() < master_nodes.size()) {
2054 std::size_t idx = 0;
2055 while (!
bit.test(idx))
2068 MBEDGE, edges_level);
2070 PetscPrintf(PETSC_COMM_WORLD,
"Sideset %d with crack front not found\n",
2077 crack_front = intersect(crack_front, edges_level);
2078 Range crack_front_nodes;
2079 CHKERR moab.get_connectivity(crack_front, crack_front_nodes,
true);
2081 Range crack_front_nodes_tets;
2082 CHKERR m_field.
get_moab().get_adjacencies(crack_front_nodes, 3,
false,
2083 crack_front_nodes_tets,
2084 moab::Interface::UNION);
2085 crack_front_nodes_tets = intersect(crack_front_nodes_tets, tets_level);
2086 Range edges_to_refine;
2087 CHKERR m_field.
get_moab().get_adjacencies(crack_front_nodes_tets, 1,
false,
2089 moab::Interface::UNION);
2090 edges_to_refine = intersect(edges_to_refine, edges_level);
2091 if (edges_to_refine.empty())
2096 edges_to_refine, bit_ref,
VERBOSE);
2107 cubit_meshset, MBMAXTYPE,
true);
2112 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
2113 Tag part_tag = pcomm->part_tag();
2116 0, MBENTITYSET, &part_tag, NULL, 1, tagged_sets,
2117 moab::Interface::UNION);
2118 for (Range::iterator mit = tagged_sets.begin(); mit != tagged_sets.end();
2121 CHKERR moab.tag_get_data(part_tag, &*mit, 1, &part);
2126 CHKERR moab.get_entities_by_dimension(*mit, 3, ents3d,
true);
2127 for (Range::iterator eit = ents3d.begin(); eit != ents3d.end(); eit++) {
2128 CHKERR moab.tag_set_data(part_tag, &*eit, 1, &part);
2130 for (
int dd = 0;
dd != 3;
dd++) {
2132 CHKERR moab.get_adjacencies(ents3d,
dd,
false, ents,
2133 moab::Interface::UNION);
2134 for (Range::iterator eit = ents.begin(); eit != ents.end(); eit++) {
2135 CHKERR moab.tag_set_data(part_tag, &*eit, 1, &part);
2143 for (
int ll = 0; ll != 19; ++ll)
2150 name =
"out_crack_surface_level_" +
2151 boost::lexical_cast<std::string>(ll) +
".vtk";
2158 CHKERR m_field.
get_moab().write_file(name.c_str(),
"VTK",
"", &meshset,
2173 Tag th_interface_side;
2174 rval = m_field.
get_moab().tag_get_handle(
"INTERFACE_SIDE", th_interface_side);
2175 if (
rval == MB_SUCCESS)
2178 auto delete_mofem_meshsets = [&]() {
2190 CHKERR delete_mofem_meshsets();
2201 "Refinement at the crack front after the crack insertion ('my_ref') "
2202 "should not be used when the mesh cutting is on, use "
2203 "'ref_before_cut' or 'ref_before_trim' instead");
2206 CHKERR delete_mofem_meshsets();
2213 "out_mesh_after_refine.vtk",
"VTK",
2223 "crack_surface_before_contact_split.vtk",
"VTK",
"",
2224 &meshset_interface, 1);
2235 "crack_surface_after_contact_split.vtk",
"VTK",
"",
2236 &meshset_interface, 1);
2240 "out_mesh_after_contact_split.vtk",
"VTK",
"");
2243 "out_mesh_contact_prisms.vtk",
"VTK",
"");
2260 "out_mesh_after_split.vtk",
"VTK",
2263 "out_mesh_after_split_prisms.vtk",
2268 CHKERR delete_mofem_meshsets();
2289 Range all_free_ents;
2294 std::size_t idx = 0;
2295 while (!
bit.test(idx))
2297 int first_bit = idx + 1;
2303 for (
int ll = 0; ll != first_bit + 1; ++ll)
2311 "out_mesh_after_cut.vtk",
"VTK",
"");
2318 "out_mesh_after_split_and_refine.vtk",
"VTK",
"");
2322 auto get_entities_to_delete = [&]() {
2323 Range ents_not_in_database;
2324 CHKERR moab.get_entities_by_handle(0, ents_not_in_database,
false);
2325 ents_not_in_database = subtract(
2326 ents_not_in_database, ents_not_in_database.subset_by_type(MBENTITYSET));
2328 return subtract(ents_not_in_database, all_free_ents);
2330 Range ents_to_remove = get_entities_to_delete();
2332 auto remove_entities_from_meshsets = [&]() {
2336 CHKERR moab.get_entities_by_type(0, MBENTITYSET, meshsets,
false);
2337 for (
auto m : meshsets)
2338 CHKERR moab.remove_entities(
m, ents_to_remove);
2342 CHKERR remove_entities_from_meshsets();
2343 CHKERR moab.delete_entities(ents_to_remove);
2357 MBEDGE, level_edges);
2387 cerr <<
"getFrontEdgesAndElements ";
2396 if (verb >=
NOISY) {
2415 MBVERTEX, org_verts);
2420 if (
rval == MB_SUCCESS) {
2426 }
else if (
rval != MB_TAG_NOT_FOUND)
2428 "Can not get tag handle");
2443 MBVERTEX, org_verts);
2448 double def_position[] = {0, 0, 0};
2451 th, MB_TAG_CREAT | MB_TAG_SPARSE,