Merge edges.
Sort all edges, where sorting is by quality calculated as edge length times quality of tets adjacent to the edge. Edge is merged if quality if the mesh is improved.
2318 {
2319 CoreInterface &m_field =
cOre;
2320 moab::Interface &moab = m_field.
get_moab();
2322
2323
2324
2325
2326 struct MergeNodes {
2327 CoreInterface &mField;
2328 const bool onlyIfImproveQuality;
2329 Tag tH;
2330 bool updateMehsets;
2331
2332 MergeNodes(CoreInterface &m_field, const bool only_if_improve_quality,
2333 Tag th, bool update_mehsets)
2334 : mField(m_field), onlyIfImproveQuality(only_if_improve_quality),
2335 tH(
th), updateMehsets(update_mehsets) {
2336 mField.getInterface(nodeMergerPtr);
2337 }
2338 NodeMergerInterface *nodeMergerPtr;
2341 bool add_child = true) {
2342 moab::Interface &moab = mField.get_moab();
2346 CHKERR moab.get_adjacencies(conn, 2, 3,
false, vert_tets,
2347 moab::Interface::UNION);
2348 vert_tets = intersect(vert_tets, proc_tets);
2350 CHKERR nodeMergerPtr->mergeNodes(father, mother, out_tets, &vert_tets,
2351 onlyIfImproveQuality, 0, line_search,
2352 tH);
2353
2354 if (add_child && nodeMergerPtr->getSuccessMerge()) {
2355
2356 Range::iterator lo, hi = proc_tets.begin();
2357 for (auto pt = vert_tets.pair_begin(); pt != vert_tets.pair_end();
2358 ++pt) {
2359 lo = proc_tets.lower_bound(hi, proc_tets.end(), pt->first);
2360 if (lo != proc_tets.end()) {
2361 hi = proc_tets.upper_bound(lo, proc_tets.end(), pt->second);
2362 proc_tets.erase(lo, hi);
2363 } else
2364 break;
2365 }
2366 proc_tets.merge(out_tets);
2367
2368 auto &parent_child_map = nodeMergerPtr->getParentChildMap();
2369
2370 struct ChangeChild {
2372 ChangeChild(
const EntityHandle child) : child(child) {}
2373 void operator()(NodeMergerInterface::ParentChild &
p) {
2375 }
2376 };
2377
2378 std::vector<decltype(parentsChildMap.get<0>().begin())> it_vec;
2379 it_vec.reserve(parentsChildMap.size());
2380
2381 for (
auto &
p : parent_child_map) {
2382
2383 it_vec.clear();
2384 for (
auto it = parentsChildMap.get<0>().equal_range(
p.pArent);
2385 it.first != it.second; ++it.first)
2386 it_vec.emplace_back(it.first);
2387
2388 for (
auto it = parentsChildMap.get<1>().equal_range(
p.pArent);
2389 it.first != it.second; ++it.first)
2390 it_vec.emplace_back(parentsChildMap.project<0>(it.first));
2391
2392 for (auto &it : it_vec)
2393 parentsChildMap.modify(it, ChangeChild(
p.cHild));
2394 }
2395
2396 parentsChildMap.insert(parent_child_map.begin(),
2397 parent_child_map.end());
2398 }
2400 }
2401
2403 Range ¬_merged_edges,
2404 bool add_child) {
2405 moab::Interface &moab = mField.get_moab();
2407 if (add_child) {
2408
2409 std::vector<EntityHandle> parents_ents_vec(parentsChildMap.size());
2410 for (auto &it : parentsChildMap)
2411 parents_ents_vec.emplace_back(it.pArent);
2413 parent_ents.insert_list(parents_ents_vec.begin(),
2414 parents_ents_vec.end());
2415
2416 Range surf_parent_ents = intersect(new_surf, parent_ents);
2417 new_surf = subtract(new_surf, surf_parent_ents);
2418 Range child_surf_ents;
2419 CHKERR updateRangeByChilds(parentsChildMap, surf_parent_ents,
2420 child_surf_ents);
2421 new_surf.merge(child_surf_ents);
2422
2423 Range edges_to_merge_parent_ents =
2424 intersect(edges_to_merge, parent_ents);
2425 edges_to_merge = subtract(edges_to_merge, edges_to_merge_parent_ents);
2426 Range merged_child_edge_ents;
2427 CHKERR updateRangeByChilds(parentsChildMap, edges_to_merge_parent_ents,
2428 merged_child_edge_ents);
2429
2430 Range not_merged_edges_child_ents =
2431 intersect(not_merged_edges, parent_ents);
2432 not_merged_edges =
2433 subtract(not_merged_edges, not_merged_edges_child_ents);
2434 Range not_merged_child_edge_ents;
2435 CHKERR updateRangeByChilds(parentsChildMap, not_merged_edges_child_ents,
2436 not_merged_child_edge_ents);
2437
2438 merged_child_edge_ents =
2439 subtract(merged_child_edge_ents, not_merged_child_edge_ents);
2440 edges_to_merge.merge(merged_child_edge_ents);
2441 not_merged_edges.merge(not_merged_child_edge_ents);
2442
2443 if (updateMehsets) {
2445 (*mField.getInterface<MeshsetsManager>()), cubit_it)) {
2448 CHKERR moab.get_entities_by_handle(cubit_meshset, meshset_ents,
2449 true);
2451 CHKERR updateRangeByChilds(parentsChildMap, meshset_ents,
2452 child_ents);
2453 CHKERR moab.add_entities(cubit_meshset, child_ents);
2454 }
2455 }
2456 }
2457
2459 };
2460
2461 private:
2462 NodeMergerInterface::ParentChildMap parentsChildMap;
2463 std::vector<EntityHandle> childsVec;
2464
2466 const NodeMergerInterface::ParentChildMap &parent_child_map,
2469 childsVec.clear();
2470 childsVec.reserve(parents.size());
2471 for (auto pit = parents.pair_begin(); pit != parents.pair_end(); pit++) {
2472 auto it = parent_child_map.lower_bound(pit->first);
2473 if (it != parent_child_map.end()) {
2474 for (auto hi_it = parent_child_map.upper_bound(pit->second);
2475 it != hi_it; ++it)
2476 childsVec.emplace_back(it->cHild);
2477 }
2478 }
2479 childs.insert_list(childsVec.begin(), childsVec.end());
2481 }
2482 };
2483
2484
2485
2486
2487 struct LengthMap {
2488 Tag tH;
2489 CoreInterface &mField;
2490 moab::Interface &moab;
2491 const double maxLength;
2492 LengthMap(CoreInterface &m_field, Tag th, double max_length)
2493 : tH(
th), mField(m_field), moab(m_field.get_moab()),
2494 maxLength(max_length) {
2495 gammaL = 1.;
2496 gammaQ = 3.;
2497 acceptedThrasholdMergeQuality = 0.5;
2498 }
2499
2500 double
2501 gammaL;
2502 double
2503 gammaQ;
2504 double acceptedThrasholdMergeQuality;
2505
2506
2508 LengthMapData_multi_index &length_map,
2509 double &ave) const {
2510 int num_nodes;
2512 std::array<double, 12> coords;
2514 VectorAdaptor s0(3, ublas::shallow_array_adaptor<double>(3, &coords[0]));
2515 VectorAdaptor s1(3, ublas::shallow_array_adaptor<double>(3, &coords[3]));
2517
2518 struct NodeQuality {
2520 double quality;
2521 NodeQuality(
const EntityHandle node) : node(node), quality(1) {}
2522 };
2523
2524 typedef multi_index_container<
2525 NodeQuality, indexed_by<
2526
2527 sequenced<>,
2528
2529 hashed_non_unique<tag<Ent_mi_tag>,
2531 &NodeQuality::node>>
2532
2533 >>
2534 NodeQuality_sequence;
2535
2536 NodeQuality_sequence node_quality_sequence;
2537
2539 CHKERR moab.get_connectivity(tets, edges_nodes,
false);
2541 CHKERR moab.get_adjacencies(edges, 3,
false, edges_tets,
2542 moab::Interface::UNION);
2543 edges_tets = intersect(edges_tets, tets);
2544
2545 for (auto node : edges_nodes)
2546 node_quality_sequence.emplace_back(node);
2547
2548 for (auto tet : edges_tets) {
2549
2550 CHKERR moab.get_connectivity(tet, conn, num_nodes,
true);
2551 if (tH)
2552 CHKERR moab.tag_get_data(tH, conn, num_nodes, coords.data());
2553 else
2554 CHKERR moab.get_coords(conn, num_nodes, coords.data());
2555
2556 const double q = Tools::volumeLengthQuality(coords.data());
2557
2558 for (
auto n : {0, 1, 2, 3}) {
2559 auto it = node_quality_sequence.get<1>().find(conn[
n]);
2560 if (it != node_quality_sequence.get<1>().end())
2561 const_cast<double &>(it->quality) = std::min(q, it->quality);
2562 }
2563 }
2564
2565 for (auto edge : edges) {
2566
2567 CHKERR moab.get_connectivity(edge, conn, num_nodes,
true);
2568
2569 if (tH)
2570 CHKERR moab.tag_get_data(tH, conn, num_nodes, coords.data());
2571 else
2572 CHKERR moab.get_coords(conn, num_nodes, coords.data());
2573
2574 double q = 1;
2575 for (
auto n : {0, 1}) {
2576 auto it = node_quality_sequence.get<1>().find(conn[
n]);
2577 if (it != node_quality_sequence.get<1>().end())
2578 q = std::min(q, it->quality);
2579 }
2580
2581 if (q < acceptedThrasholdMergeQuality) {
2582 noalias(
delta) = (s0 - s1) / maxLength;
2584 double val = pow(q, gammaQ) * pow(dot, 0.5 * gammaL);
2585 length_map.insert(LengthMapData(val, q, edge));
2586 }
2587 }
2588
2589 ave = 0;
2590 for (LengthMapData_multi_index::nth_index<0>::type::iterator mit =
2591 length_map.get<0>().begin();
2592 mit != length_map.get<0>().end(); mit++) {
2593 ave += mit->qUality;
2594 }
2595 ave /= length_map.size();
2597 }
2598 };
2599
2600
2601
2602
2603 struct Toplogy {
2604
2605 CoreInterface &mField;
2606 Tag tH;
2607 Toplogy(CoreInterface &m_field, Tag th) : mField(m_field), tH(
th) {}
2608
2609 enum TYPE {
2610 FREE = 0,
2611 SKIN = 1 << 0,
2612 SURFACE = 1 << 1,
2613 SURFACE_SKIN = 1 << 2,
2614 FRONT_ENDS = 1 << 3,
2615 FIX_EDGES = 1 << 4,
2616 FIX_CORNERS = 1 << 5
2617 };
2618
2619 typedef map<int, Range> SetsMap;
2620
2622 const Range &fixed_edges,
2623 const Range &corner_nodes,
2624 const Range &constrain_surface,
2625 SetsMap &sets_map) const {
2626 moab::Interface &moab(mField.get_moab());
2627 Skinner skin(&moab);
2629
2630 sets_map[FIX_CORNERS].merge(corner_nodes);
2632 CHKERR moab.get_connectivity(fixed_edges, fixed_verts,
true);
2633 sets_map[FIX_EDGES].swap(fixed_verts);
2634
2636 CHKERR skin.find_skin(0, tets,
false, tets_skin);
2637 Range tets_skin_edges;
2638 CHKERR moab.get_adjacencies(tets_skin, 1,
false, tets_skin_edges,
2639 moab::Interface::UNION);
2640
2641
2642 Range constrain_surface_verts;
2643 CHKERR moab.get_connectivity(constrain_surface, constrain_surface_verts,
2644 true);
2645 Range constrain_surface_edges;
2646 CHKERR moab.get_adjacencies(constrain_surface, 1,
false,
2647 constrain_surface_edges,
2648 moab::Interface::UNION);
2649
2650
2652 CHKERR skin.find_skin(0, surface,
false, surface_skin);
2653 Range front_in_the_body;
2654 front_in_the_body = subtract(surface_skin, tets_skin_edges);
2655 Range front_in_the_body_verts;
2656 CHKERR moab.get_connectivity(front_in_the_body, front_in_the_body_verts,
2657 true);
2659 CHKERR skin.find_skin(0, front_in_the_body,
false, front_ends);
2660 front_ends.merge(
2661 intersect(front_in_the_body_verts, constrain_surface_verts));
2662 sets_map[FRONT_ENDS].swap(front_ends);
2663
2664 Range surface_skin_verts;
2665 CHKERR moab.get_connectivity(surface_skin, surface_skin_verts,
true);
2666 sets_map[SURFACE_SKIN].swap(surface_skin_verts);
2667
2668
2669 Range surface_verts;
2670 CHKERR moab.get_connectivity(surface, surface_verts,
true);
2671 sets_map[SURFACE_SKIN].merge(
2672 intersect(constrain_surface_verts, surface_verts));
2673 sets_map[SURFACE].swap(surface_verts);
2674
2675
2676 Range tets_skin_verts;
2677 CHKERR moab.get_connectivity(tets_skin, tets_skin_verts,
true);
2678 sets_map[SKIN].swap(tets_skin_verts);
2679 sets_map[SKIN].merge(constrain_surface_verts);
2680
2682 CHKERR moab.get_connectivity(tets, tets_verts,
true);
2683 sets_map[FREE].swap(tets_verts);
2684
2686 }
2687
2689 Range &proc_tets)
const {
2690 moab::Interface &moab(mField.get_moab());
2692 Range edges_to_merge_verts;
2693 CHKERR moab.get_connectivity(edges_to_merge, edges_to_merge_verts,
true);
2694 Range edges_to_merge_verts_tets;
2695 CHKERR moab.get_adjacencies(edges_to_merge_verts, 3,
false,
2696 edges_to_merge_verts_tets,
2697 moab::Interface::UNION);
2698 edges_to_merge_verts_tets = intersect(edges_to_merge_verts_tets, tets);
2699 proc_tets.swap(edges_to_merge_verts_tets);
2701 }
2702
2704 const Range &fixed_edges,
2705 const Range &corner_nodes,
2706 const Range &constrain_surface,
2707 Range &edges_to_merge,
2708 Range ¬_merged_edges) {
2709 moab::Interface &moab(mField.get_moab());
2711
2712
2713 Skinner skin(&moab);
2715 CHKERR skin.find_skin(0, tets,
false, tets_skin);
2717 CHKERR skin.find_skin(0, surface,
false, surface_skin);
2718
2719
2720 Range constrain_surface_verts;
2721 CHKERR moab.get_connectivity(constrain_surface, constrain_surface_verts,
2722 true);
2723 Range constrain_surface_edges;
2724 CHKERR moab.get_adjacencies(constrain_surface, 1,
false,
2725 constrain_surface_edges,
2726 moab::Interface::UNION);
2727
2728
2729 Range tets_skin_edges;
2730 CHKERR moab.get_adjacencies(tets_skin, 1,
false, tets_skin_edges,
2731 moab::Interface::UNION);
2732
2733 Range surface_front;
2734 surface_front = subtract(surface_skin, tets_skin_edges);
2735 Range surface_front_nodes;
2736 CHKERR moab.get_connectivity(surface_front, surface_front_nodes,
true);
2737
2739 CHKERR skin.find_skin(0, surface_front,
false, ends_nodes);
2740 ends_nodes.merge(intersect(surface_front_nodes, constrain_surface_verts));
2741
2742
2743 surface_skin.merge(constrain_surface);
2744 tets_skin_edges.merge(constrain_surface_edges);
2745
2746
2747 Range surface_edges;
2748 CHKERR moab.get_adjacencies(surface, 1,
false, surface_edges,
2749 moab::Interface::UNION);
2750
2751 Range surface_edges_verts;
2752 CHKERR moab.get_connectivity(surface_edges, surface_edges_verts,
true);
2753
2754 Range tets_skin_edges_verts;
2755 CHKERR moab.get_connectivity(tets_skin_edges, tets_skin_edges_verts,
2756 true);
2757
2758 Range edges_to_remove;
2759
2760
2761 {
2762 Range ents_nodes_and_edges;
2763 ents_nodes_and_edges.merge(tets_skin_edges_verts);
2764 ents_nodes_and_edges.merge(tets_skin_edges);
2765 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2766 false);
2767 }
2768 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2769 not_merged_edges.merge(edges_to_remove);
2770
2771
2772 {
2773 Range ents_nodes_and_edges;
2774 ents_nodes_and_edges.merge(surface_edges_verts);
2775 ents_nodes_and_edges.merge(surface_edges);
2776 ents_nodes_and_edges.merge(tets_skin_edges_verts);
2777 ents_nodes_and_edges.merge(tets_skin_edges);
2778 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2779 false);
2780 }
2781 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2782 not_merged_edges.merge(edges_to_remove);
2783
2784
2785 Range fixed_edges_nodes;
2786 CHKERR moab.get_connectivity(fixed_edges, fixed_edges_nodes,
true);
2787 {
2788 Range ents_nodes_and_edges;
2789 ents_nodes_and_edges.merge(fixed_edges_nodes);
2790 ents_nodes_and_edges.merge(ends_nodes);
2791 ents_nodes_and_edges.merge(corner_nodes);
2792 ents_nodes_and_edges.merge(fixed_edges);
2793 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2794 false);
2795 }
2796 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2797 not_merged_edges.merge(edges_to_remove);
2798
2799
2800 CHKERR removeSelfConectingEdges(surface_edges, edges_to_remove,
false);
2801 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2802 not_merged_edges.merge(edges_to_remove);
2803
2804
2805 {
2806 Range ents_nodes_and_edges;
2807 ents_nodes_and_edges.merge(surface_skin);
2808 ents_nodes_and_edges.merge(fixed_edges_nodes);
2809 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2810 false);
2811 }
2812 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2813 not_merged_edges.merge(edges_to_remove);
2814
2815
2816 {
2817 Range ents_nodes_and_edges;
2818 ents_nodes_and_edges.merge(surface_skin.subset_by_type(MBEDGE));
2819 ents_nodes_and_edges.merge(fixed_edges.subset_by_type(MBEDGE));
2820 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2821 false);
2822 }
2823 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2824 not_merged_edges.merge(edges_to_remove);
2825
2826
2827 {
2828 Range ents_nodes_and_edges;
2829 ents_nodes_and_edges.merge(surface_front_nodes);
2830 ents_nodes_and_edges.merge(surface_front);
2831 ents_nodes_and_edges.merge(tets_skin_edges_verts);
2832 ents_nodes_and_edges.merge(tets_skin_edges);
2833 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2834 false);
2835 }
2836 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2837 not_merged_edges.merge(edges_to_remove);
2838
2840 }
2841
2842 private:
2844 Range &edges_to_remove,
2846 moab::Interface &moab(mField.get_moab());
2848
2849 Range ents_nodes = ents.subset_by_type(MBVERTEX);
2850 if (ents_nodes.empty()) {
2851 CHKERR moab.get_connectivity(ents, ents_nodes,
true);
2852 }
2853
2854 Range ents_nodes_edges;
2855 CHKERR moab.get_adjacencies(ents_nodes, 1,
false, ents_nodes_edges,
2856 moab::Interface::UNION);
2857
2858 Range ents_nodes_edges_nodes;
2859 CHKERR moab.get_connectivity(ents_nodes_edges, ents_nodes_edges_nodes,
2860 true);
2861
2862 ents_nodes_edges_nodes = subtract(ents_nodes_edges_nodes, ents_nodes);
2863 Range ents_nodes_edges_nodes_edges;
2864 CHKERR moab.get_adjacencies(ents_nodes_edges_nodes, 1,
false,
2865 ents_nodes_edges_nodes_edges,
2866 moab::Interface::UNION);
2867
2868 ents_nodes_edges =
2869 subtract(ents_nodes_edges, ents_nodes_edges_nodes_edges);
2870 ents_nodes_edges =
2871 subtract(ents_nodes_edges, ents.subset_by_type(MBEDGE));
2872
2873 edges_to_remove.swap(ents_nodes_edges);
2875 CHKERR SaveData(moab)(
"edges_to_remove.vtk", edges_to_remove);
2876 }
2878 }
2879 };
2880
2881 Range not_merged_edges;
2883 .removeBadEdges(surface, tets, fixed_edges, corner_nodes,
2885 Toplogy::SetsMap sets_map;
2888 sets_map);
2890 for (Toplogy::SetsMap::reverse_iterator sit = sets_map.rbegin();
2891 sit != sets_map.rend(); sit++) {
2892 std::string name = "classification_verts_" +
2893 boost::lexical_cast<std::string>(sit->first) + ".vtk";
2894 if (!sit->second.empty())
2895 CHKERR SaveData(moab)(name, sit->second);
2896 }
2897 }
2899 CHKERR Toplogy(m_field,
th).getProcTets(tets, edges_to_merge, proc_tets);
2900 out_tets = subtract(tets, proc_tets);
2901
2902 if (bit_ptr) {
2903 Range all_out_ents = out_tets;
2904 for (
int dd = 2;
dd >= 0;
dd--) {
2905 CHKERR moab.get_adjacencies(out_tets, dd,
false, all_out_ents,
2906 moab::Interface::UNION);
2907 }
2908 CHKERR m_field.getInterface<BitRefManager>()->addBitRefLevel(all_out_ents,
2909 *bit_ptr);
2910 }
2911
2912 int nb_nodes_merged = 0;
2914 new_surf = surface;
2915
2916 auto save_merge_step = [&](
const int pp,
const Range collapsed_edges) {
2919 CHKERR moab.get_adjacencies(proc_tets, 2,
false, adj_faces,
2920 moab::Interface::UNION);
2921 std::string name;
2922 name = "node_merge_step_" + boost::lexical_cast<std::string>(pp) + ".vtk";
2924 name, unite(intersect(new_surf, adj_faces), collapsed_edges));
2925 name =
2926 "edges_to_merge_step_" + boost::lexical_cast<std::string>(pp) + ".vtk";
2928 name, unite(intersect(new_surf, adj_faces), edges_to_merge));
2930 };
2931
2934
2935 double ave0 = 0, ave = 0, min = 0, min_p = 0, min_pp;
2937
2938 int nb_nodes_merged_p = nb_nodes_merged;
2939 length_map.clear();
2940 min_pp = min_p;
2941 min_p = min;
2943 length_map, ave);
2944
2945 if(!length_map.empty())
2946 min = length_map.get<2>().begin()->qUality;
2947 if (pp == 0) {
2948 ave0 = ave;
2949 }
2950
2951 int nn = 0;
2952 Range collapsed_edges;
2953 MergeNodes merge_nodes(m_field,
true,
th, update_meshsets);
2954
2955 for (auto mit = length_map.get<0>().begin();
2956 mit != length_map.get<0>().end(); mit++, nn++) {
2957
2958 if (!mit->skip) {
2959
2960 auto get_father_and_mother =
2963 int num_nodes;
2965 CHKERR moab.get_connectivity(mit->eDge, conn, num_nodes,
true);
2966 std::array<int, 2> conn_type = {0, 0};
2967 for (int nn = 0; nn != 2; nn++) {
2968 for (Toplogy::SetsMap::reverse_iterator sit = sets_map.rbegin();
2969 sit != sets_map.rend(); sit++) {
2970 if (sit->second.find(conn[nn]) != sit->second.end()) {
2971 conn_type[nn] |= sit->first;
2972 }
2973 }
2974 }
2975 int type_father, type_mother;
2976 if (conn_type[0] > conn_type[1]) {
2977 father = conn[0];
2978 mother = conn[1];
2979 type_father = conn_type[0];
2980 type_mother = conn_type[1];
2981 } else {
2982 father = conn[1];
2983 mother = conn[0];
2984 type_father = conn_type[1];
2985 type_mother = conn_type[0];
2986 }
2987 if (type_father == type_mother) {
2989 }
2991 };
2992
2993 int line_search = 0;
2995 CHKERR get_father_and_mother(father, mother, line_search);
2996 CHKERR merge_nodes.mergeNodes(line_search, father, mother, proc_tets);
2997 if (m_field.getInterface<NodeMergerInterface>()->getSuccessMerge()) {
2998 const EntityHandle father_and_mother[] = {father, mother};
3000 CHKERR moab.get_adjacencies(father_and_mother, 1, 3,
false, adj_tets);
3001 Range adj_tets_nodes;
3002 CHKERR moab.get_connectivity(adj_tets, adj_tets_nodes,
true);
3004 CHKERR moab.get_adjacencies(adj_tets_nodes, 1,
false, adj_edges,
3005 moab::Interface::UNION);
3006 for (auto ait : adj_edges) {
3007 auto miit = length_map.get<1>().find(ait);
3008 if (miit != length_map.get<1>().end())
3009 (const_cast<LengthMapData &>(*miit)).skip = true;
3010 }
3011 nb_nodes_merged++;
3012 collapsed_edges.insert(mit->eDge);
3013 }
3014
3015 if (nn > static_cast<int>(length_map.size() / fraction_level))
3016 break;
3017 if (mit->qUality > ave)
3018 break;
3019 }
3020 }
3021
3022 CHKERR merge_nodes.updateRangeByChilds(new_surf, edges_to_merge,
3023 not_merged_edges, true);
3024
3026 "(%d) Number of nodes merged %d ave q %3.4e min q %3.4e", pp,
3027 nb_nodes_merged, ave, min);
3028
3030 CHKERR save_merge_step(pp + 1, collapsed_edges);
3031
3032 if (nb_nodes_merged == nb_nodes_merged_p)
3033 break;
3034 if (min > 1e-2 && min == min_pp)
3035 break;
3036 if (min > ave0)
3037 break;
3038
3040 CHKERR moab.get_adjacencies(proc_tets, 1,
false, adj_edges,
3041 moab::Interface::UNION);
3042 edges_to_merge = intersect(edges_to_merge, adj_edges);
3044 .removeBadEdges(new_surf, proc_tets, fixed_edges, corner_nodes,
3046 }
3047
3048 auto reconstruct_refined_ents = [&]() {
3052 };
3053
3054
3055
3056
3057
3058
3059 CHKERR reconstruct_refined_ents();
3060
3061 if (bit_ptr)
3062 CHKERR m_field.getInterface<BitRefManager>()->setBitRefLevel(proc_tets,
3063 *bit_ptr);
3064
3065 out_tets.merge(proc_tets);
3067 CHKERR moab.get_adjacencies(out_tets, 2,
false, adj_faces,
3068 moab::Interface::UNION);
3069 new_surf = intersect(new_surf, adj_faces);
3070
3072}
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define _IT_CUBITMESHSETS_FOR_LOOP_(MESHSET_MANAGER, IT)
Iterator that loops over all the Cubit MeshSets in a moFEM field.
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
MoFEMErrorCode reconstructMultiIndex(const MI &mi, MO &&mo=Modify_change_nothing())
Template used to reconstruct multi-index.
multi_index_container< LengthMapData, indexed_by< ordered_non_unique< member< LengthMapData, double, &LengthMapData::lEngth > >, hashed_unique< member< LengthMapData, EntityHandle, &LengthMapData::eDge > >, ordered_non_unique< member< LengthMapData, double, &LengthMapData::qUality > > > > LengthMapData_multi_index