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.
2311 {
2312 CoreInterface &m_field =
cOre;
2313 moab::Interface &moab = m_field.
get_moab();
2315
2316
2317
2318
2319 struct MergeNodes {
2320 CoreInterface &mField;
2321 const bool onlyIfImproveQuality;
2323 bool updateMehsets;
2324
2325 MergeNodes(CoreInterface &m_field, const bool only_if_improve_quality,
2326 Tag th,
bool update_mehsets)
2327 : mField(m_field), onlyIfImproveQuality(only_if_improve_quality),
2328 tH(
th), updateMehsets(update_mehsets) {
2329 mField.getInterface(nodeMergerPtr);
2330 }
2331 NodeMergerInterface *nodeMergerPtr;
2334 bool add_child = true) {
2335 moab::Interface &moab = mField.get_moab();
2339 CHKERR moab.get_adjacencies(conn, 2, 3,
false, vert_tets,
2340 moab::Interface::UNION);
2341 vert_tets = intersect(vert_tets, proc_tets);
2343 CHKERR nodeMergerPtr->mergeNodes(father, mother, out_tets, &vert_tets,
2344 onlyIfImproveQuality, 0, line_search,
2345 tH);
2346
2347 if (add_child && nodeMergerPtr->getSuccessMerge()) {
2348
2349 Range::iterator lo, hi = proc_tets.begin();
2350 for (auto pt = vert_tets.pair_begin(); pt != vert_tets.pair_end();
2351 ++pt) {
2352 lo = proc_tets.lower_bound(hi, proc_tets.end(), pt->first);
2353 if (lo != proc_tets.end()) {
2354 hi = proc_tets.upper_bound(lo, proc_tets.end(), pt->second);
2355 proc_tets.erase(lo, hi);
2356 } else
2357 break;
2358 }
2359 proc_tets.merge(out_tets);
2360
2361 auto &parent_child_map = nodeMergerPtr->getParentChildMap();
2362
2363 struct ChangeChild {
2365 ChangeChild(
const EntityHandle child) : child(child) {}
2366 void operator()(NodeMergerInterface::ParentChild &p) {
2367 p.cHild = child;
2368 }
2369 };
2370
2371 std::vector<decltype(parentsChildMap.get<0>().begin())> it_vec;
2372 it_vec.reserve(parentsChildMap.size());
2373
2374 for (auto &p : parent_child_map) {
2375
2376 it_vec.clear();
2377 for (auto it = parentsChildMap.get<0>().equal_range(p.pArent);
2378 it.first != it.second; ++it.first)
2379 it_vec.emplace_back(it.first);
2380
2381 for (auto it = parentsChildMap.get<1>().equal_range(p.pArent);
2382 it.first != it.second; ++it.first)
2383 it_vec.emplace_back(parentsChildMap.project<0>(it.first));
2384
2385 for (auto &it : it_vec)
2386 parentsChildMap.modify(it, ChangeChild(p.cHild));
2387 }
2388
2389 parentsChildMap.insert(parent_child_map.begin(),
2390 parent_child_map.end());
2391 }
2393 }
2394
2396 Range ¬_merged_edges,
2397 bool add_child) {
2398 moab::Interface &moab = mField.get_moab();
2400 if (add_child) {
2401
2402 std::vector<EntityHandle> parents_ents_vec(parentsChildMap.size());
2403 for (auto &it : parentsChildMap)
2404 parents_ents_vec.emplace_back(it.pArent);
2406 parent_ents.insert_list(parents_ents_vec.begin(),
2407 parents_ents_vec.end());
2408
2409 Range surf_parent_ents = intersect(new_surf, parent_ents);
2410 new_surf = subtract(new_surf, surf_parent_ents);
2411 Range child_surf_ents;
2412 CHKERR updateRangeByChilds(parentsChildMap, surf_parent_ents,
2413 child_surf_ents);
2414 new_surf.merge(child_surf_ents);
2415
2416 Range edges_to_merge_parent_ents =
2417 intersect(edges_to_merge, parent_ents);
2418 edges_to_merge = subtract(edges_to_merge, edges_to_merge_parent_ents);
2419 Range merged_child_edge_ents;
2420 CHKERR updateRangeByChilds(parentsChildMap, edges_to_merge_parent_ents,
2421 merged_child_edge_ents);
2422
2423 Range not_merged_edges_child_ents =
2424 intersect(not_merged_edges, parent_ents);
2425 not_merged_edges =
2426 subtract(not_merged_edges, not_merged_edges_child_ents);
2427 Range not_merged_child_edge_ents;
2428 CHKERR updateRangeByChilds(parentsChildMap, not_merged_edges_child_ents,
2429 not_merged_child_edge_ents);
2430
2431 merged_child_edge_ents =
2432 subtract(merged_child_edge_ents, not_merged_child_edge_ents);
2433 edges_to_merge.merge(merged_child_edge_ents);
2434 not_merged_edges.merge(not_merged_child_edge_ents);
2435
2436 if (updateMehsets) {
2438 (*mField.getInterface<MeshsetsManager>()), cubit_it)) {
2441 CHKERR moab.get_entities_by_handle(cubit_meshset, meshset_ents,
2442 true);
2444 CHKERR updateRangeByChilds(parentsChildMap, meshset_ents,
2445 child_ents);
2446 CHKERR moab.add_entities(cubit_meshset, child_ents);
2447 }
2448 }
2449 }
2450
2452 };
2453
2454 private:
2455 NodeMergerInterface::ParentChildMap parentsChildMap;
2456 std::vector<EntityHandle> childsVec;
2457
2459 const NodeMergerInterface::ParentChildMap &parent_child_map,
2462 childsVec.clear();
2463 childsVec.reserve(parents.size());
2464 for (auto pit = parents.pair_begin(); pit != parents.pair_end(); pit++) {
2465 auto it = parent_child_map.lower_bound(pit->first);
2466 if (it != parent_child_map.end()) {
2467 for (auto hi_it = parent_child_map.upper_bound(pit->second);
2468 it != hi_it; ++it)
2469 childsVec.emplace_back(it->cHild);
2470 }
2471 }
2472 childs.insert_list(childsVec.begin(), childsVec.end());
2474 }
2475 };
2476
2477
2478
2479
2480 struct LengthMap {
2482 CoreInterface &mField;
2483 moab::Interface &moab;
2484 const double maxLength;
2485 LengthMap(CoreInterface &m_field,
Tag th,
double max_length)
2486 : tH(
th), mField(m_field), moab(m_field.get_moab()),
2487 maxLength(max_length) {
2488 gammaL = 1.;
2489 gammaQ = 3.;
2490 acceptedThrasholdMergeQuality = 0.5;
2491 }
2492
2493 double
2494 gammaL;
2495 double
2496 gammaQ;
2497 double acceptedThrasholdMergeQuality;
2498
2499
2501 LengthMapData_multi_index &length_map,
2502 double &ave) const {
2503 int num_nodes;
2505 std::array<double, 12> coords;
2507 VectorAdaptor s0(3, ublas::shallow_array_adaptor<double>(3, &coords[0]));
2508 VectorAdaptor s1(3, ublas::shallow_array_adaptor<double>(3, &coords[3]));
2510
2511 struct NodeQuality {
2513 double quality;
2514 NodeQuality(
const EntityHandle node) : node(node), quality(1) {}
2515 };
2516
2517 typedef multi_index_container<
2518 NodeQuality, indexed_by<
2519
2520 sequenced<>,
2521
2522 hashed_non_unique<tag<Ent_mi_tag>,
2524 &NodeQuality::node>>
2525
2526 >>
2527 NodeQuality_sequence;
2528
2529 NodeQuality_sequence node_quality_sequence;
2530
2532 CHKERR moab.get_connectivity(tets, edges_nodes,
false);
2534 CHKERR moab.get_adjacencies(edges, 3,
false, edges_tets,
2535 moab::Interface::UNION);
2536 edges_tets = intersect(edges_tets, tets);
2537
2538 for (auto node : edges_nodes)
2539 node_quality_sequence.emplace_back(node);
2540
2541 for (auto tet : edges_tets) {
2542
2543 CHKERR moab.get_connectivity(tet, conn, num_nodes,
true);
2544 if (tH)
2545 CHKERR moab.tag_get_data(tH, conn, num_nodes, coords.data());
2546 else
2547 CHKERR moab.get_coords(conn, num_nodes, coords.data());
2548
2549 const double q = Tools::volumeLengthQuality(coords.data());
2550
2551 for (
auto n : {0, 1, 2, 3}) {
2552 auto it = node_quality_sequence.get<1>().find(conn[
n]);
2553 if (it != node_quality_sequence.get<1>().end())
2554 const_cast<double &>(it->quality) = std::min(q, it->quality);
2555 }
2556 }
2557
2558 for (auto edge : edges) {
2559
2560 CHKERR moab.get_connectivity(edge, conn, num_nodes,
true);
2561
2562 if (tH)
2563 CHKERR moab.tag_get_data(tH, conn, num_nodes, coords.data());
2564 else
2565 CHKERR moab.get_coords(conn, num_nodes, coords.data());
2566
2567 double q = 1;
2568 for (
auto n : {0, 1}) {
2569 auto it = node_quality_sequence.get<1>().find(conn[
n]);
2570 if (it != node_quality_sequence.get<1>().end())
2571 q = std::min(q, it->quality);
2572 }
2573
2574 if (q < acceptedThrasholdMergeQuality) {
2575 noalias(
delta) = (s0 - s1) / maxLength;
2577 double val = pow(q, gammaQ) * pow(dot, 0.5 * gammaL);
2578 length_map.insert(LengthMapData(val, q, edge));
2579 }
2580 }
2581
2582 ave = 0;
2583 for (LengthMapData_multi_index::nth_index<0>::type::iterator mit =
2584 length_map.get<0>().begin();
2585 mit != length_map.get<0>().end(); mit++) {
2586 ave += mit->qUality;
2587 }
2588 ave /= length_map.size();
2590 }
2591 };
2592
2593
2594
2595
2596 struct Toplogy {
2597
2598 CoreInterface &mField;
2600 Toplogy(CoreInterface &m_field,
Tag th) : mField(m_field), tH(
th) {}
2601
2602 enum TYPE {
2603 FREE = 0,
2604 SKIN = 1 << 0,
2605 SURFACE = 1 << 1,
2606 SURFACE_SKIN = 1 << 2,
2607 FRONT_ENDS = 1 << 3,
2608 FIX_EDGES = 1 << 4,
2609 FIX_CORNERS = 1 << 5
2610 };
2611
2612 typedef map<int, Range> SetsMap;
2613
2615 const Range &fixed_edges,
2616 const Range &corner_nodes,
2617 const Range &constrain_surface,
2618 SetsMap &sets_map) const {
2619 moab::Interface &moab(mField.get_moab());
2620 Skinner skin(&moab);
2622
2623 sets_map[FIX_CORNERS].merge(corner_nodes);
2625 CHKERR moab.get_connectivity(fixed_edges, fixed_verts,
true);
2626 sets_map[FIX_EDGES].swap(fixed_verts);
2627
2629 CHKERR skin.find_skin(0, tets,
false, tets_skin);
2630 Range tets_skin_edges;
2631 CHKERR moab.get_adjacencies(tets_skin, 1,
false, tets_skin_edges,
2632 moab::Interface::UNION);
2633
2634
2635 Range constrain_surface_verts;
2636 CHKERR moab.get_connectivity(constrain_surface, constrain_surface_verts,
2637 true);
2638 Range constrain_surface_edges;
2639 CHKERR moab.get_adjacencies(constrain_surface, 1,
false,
2640 constrain_surface_edges,
2641 moab::Interface::UNION);
2642
2643
2646 Range front_in_the_body;
2647 front_in_the_body = subtract(surface_skin, tets_skin_edges);
2648 Range front_in_the_body_verts;
2649 CHKERR moab.get_connectivity(front_in_the_body, front_in_the_body_verts,
2650 true);
2652 CHKERR skin.find_skin(0, front_in_the_body,
false, front_ends);
2653 front_ends.merge(
2654 intersect(front_in_the_body_verts, constrain_surface_verts));
2655 sets_map[FRONT_ENDS].swap(front_ends);
2656
2657 Range surface_skin_verts;
2658 CHKERR moab.get_connectivity(surface_skin, surface_skin_verts,
true);
2659 sets_map[SURFACE_SKIN].swap(surface_skin_verts);
2660
2661
2662 Range surface_verts;
2664 sets_map[SURFACE_SKIN].merge(
2665 intersect(constrain_surface_verts, surface_verts));
2666 sets_map[SURFACE].swap(surface_verts);
2667
2668
2669 Range tets_skin_verts;
2670 CHKERR moab.get_connectivity(tets_skin, tets_skin_verts,
true);
2671 sets_map[SKIN].swap(tets_skin_verts);
2672 sets_map[SKIN].merge(constrain_surface_verts);
2673
2675 CHKERR moab.get_connectivity(tets, tets_verts,
true);
2676 sets_map[FREE].swap(tets_verts);
2677
2679 }
2680
2682 Range &proc_tets)
const {
2683 moab::Interface &moab(mField.get_moab());
2685 Range edges_to_merge_verts;
2686 CHKERR moab.get_connectivity(edges_to_merge, edges_to_merge_verts,
true);
2687 Range edges_to_merge_verts_tets;
2688 CHKERR moab.get_adjacencies(edges_to_merge_verts, 3,
false,
2689 edges_to_merge_verts_tets,
2690 moab::Interface::UNION);
2691 edges_to_merge_verts_tets = intersect(edges_to_merge_verts_tets, tets);
2692 proc_tets.swap(edges_to_merge_verts_tets);
2694 }
2695
2697 const Range &fixed_edges,
2698 const Range &corner_nodes,
2699 const Range &constrain_surface,
2700 Range &edges_to_merge,
2701 Range ¬_merged_edges) {
2702 moab::Interface &moab(mField.get_moab());
2704
2705
2706 Skinner skin(&moab);
2708 CHKERR skin.find_skin(0, tets,
false, tets_skin);
2711
2712
2713 Range constrain_surface_verts;
2714 CHKERR moab.get_connectivity(constrain_surface, constrain_surface_verts,
2715 true);
2716 Range constrain_surface_edges;
2717 CHKERR moab.get_adjacencies(constrain_surface, 1,
false,
2718 constrain_surface_edges,
2719 moab::Interface::UNION);
2720
2721
2722 Range tets_skin_edges;
2723 CHKERR moab.get_adjacencies(tets_skin, 1,
false, tets_skin_edges,
2724 moab::Interface::UNION);
2725
2726 Range surface_front;
2727 surface_front = subtract(surface_skin, tets_skin_edges);
2728 Range surface_front_nodes;
2729 CHKERR moab.get_connectivity(surface_front, surface_front_nodes,
true);
2730
2732 CHKERR skin.find_skin(0, surface_front,
false, ends_nodes);
2733 ends_nodes.merge(intersect(surface_front_nodes, constrain_surface_verts));
2734
2735
2736 surface_skin.merge(constrain_surface);
2737 tets_skin_edges.merge(constrain_surface_edges);
2738
2739
2740 Range surface_edges;
2741 CHKERR moab.get_adjacencies(
surface, 1,
false, surface_edges,
2742 moab::Interface::UNION);
2743
2744 Range surface_edges_verts;
2745 CHKERR moab.get_connectivity(surface_edges, surface_edges_verts,
true);
2746
2747 Range tets_skin_edges_verts;
2748 CHKERR moab.get_connectivity(tets_skin_edges, tets_skin_edges_verts,
2749 true);
2750
2751 Range edges_to_remove;
2752
2753
2754 {
2755 Range ents_nodes_and_edges;
2756 ents_nodes_and_edges.merge(tets_skin_edges_verts);
2757 ents_nodes_and_edges.merge(tets_skin_edges);
2758 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2759 false);
2760 }
2761 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2762 not_merged_edges.merge(edges_to_remove);
2763
2764
2765 {
2766 Range ents_nodes_and_edges;
2767 ents_nodes_and_edges.merge(surface_edges_verts);
2768 ents_nodes_and_edges.merge(surface_edges);
2769 ents_nodes_and_edges.merge(tets_skin_edges_verts);
2770 ents_nodes_and_edges.merge(tets_skin_edges);
2771 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2772 false);
2773 }
2774 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2775 not_merged_edges.merge(edges_to_remove);
2776
2777
2778 Range fixed_edges_nodes;
2779 CHKERR moab.get_connectivity(fixed_edges, fixed_edges_nodes,
true);
2780 {
2781 Range ents_nodes_and_edges;
2782 ents_nodes_and_edges.merge(fixed_edges_nodes);
2783 ents_nodes_and_edges.merge(ends_nodes);
2784 ents_nodes_and_edges.merge(corner_nodes);
2785 ents_nodes_and_edges.merge(fixed_edges);
2786 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2787 false);
2788 }
2789 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2790 not_merged_edges.merge(edges_to_remove);
2791
2792
2793 CHKERR removeSelfConectingEdges(surface_edges, edges_to_remove,
false);
2794 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2795 not_merged_edges.merge(edges_to_remove);
2796
2797
2798 {
2799 Range ents_nodes_and_edges;
2800 ents_nodes_and_edges.merge(surface_skin);
2801 ents_nodes_and_edges.merge(fixed_edges_nodes);
2802 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2803 false);
2804 }
2805 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2806 not_merged_edges.merge(edges_to_remove);
2807
2808
2809 {
2810 Range ents_nodes_and_edges;
2811 ents_nodes_and_edges.merge(surface_skin.subset_by_type(MBEDGE));
2812 ents_nodes_and_edges.merge(fixed_edges.subset_by_type(MBEDGE));
2813 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2814 false);
2815 }
2816 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2817 not_merged_edges.merge(edges_to_remove);
2818
2819
2820 {
2821 Range ents_nodes_and_edges;
2822 ents_nodes_and_edges.merge(surface_front_nodes);
2823 ents_nodes_and_edges.merge(surface_front);
2824 ents_nodes_and_edges.merge(tets_skin_edges_verts);
2825 ents_nodes_and_edges.merge(tets_skin_edges);
2826 CHKERR removeSelfConectingEdges(ents_nodes_and_edges, edges_to_remove,
2827 false);
2828 }
2829 edges_to_merge = subtract(edges_to_merge, edges_to_remove);
2830 not_merged_edges.merge(edges_to_remove);
2831
2833 }
2834
2835 private:
2837 Range &edges_to_remove,
2839 moab::Interface &moab(mField.get_moab());
2841
2842 Range ents_nodes = ents.subset_by_type(MBVERTEX);
2843 if (ents_nodes.empty()) {
2844 CHKERR moab.get_connectivity(ents, ents_nodes,
true);
2845 }
2846
2847 Range ents_nodes_edges;
2848 CHKERR moab.get_adjacencies(ents_nodes, 1,
false, ents_nodes_edges,
2849 moab::Interface::UNION);
2850
2851 Range ents_nodes_edges_nodes;
2852 CHKERR moab.get_connectivity(ents_nodes_edges, ents_nodes_edges_nodes,
2853 true);
2854
2855 ents_nodes_edges_nodes = subtract(ents_nodes_edges_nodes, ents_nodes);
2856 Range ents_nodes_edges_nodes_edges;
2857 CHKERR moab.get_adjacencies(ents_nodes_edges_nodes, 1,
false,
2858 ents_nodes_edges_nodes_edges,
2859 moab::Interface::UNION);
2860
2861 ents_nodes_edges =
2862 subtract(ents_nodes_edges, ents_nodes_edges_nodes_edges);
2863 ents_nodes_edges =
2864 subtract(ents_nodes_edges, ents.subset_by_type(MBEDGE));
2865
2866 edges_to_remove.swap(ents_nodes_edges);
2868 CHKERR SaveData(moab)(
"edges_to_remove.vtk", edges_to_remove);
2869 }
2871 }
2872 };
2873
2874 Range not_merged_edges;
2876 .removeBadEdges(
surface, tets, fixed_edges, corner_nodes,
2878 Toplogy::SetsMap sets_map;
2881 sets_map);
2883 for (Toplogy::SetsMap::reverse_iterator sit = sets_map.rbegin();
2884 sit != sets_map.rend(); sit++) {
2885 std::string name = "classification_verts_" +
2886 boost::lexical_cast<std::string>(sit->first) + ".vtk";
2887 if (!sit->second.empty())
2888 CHKERR SaveData(moab)(name, sit->second);
2889 }
2890 }
2892 CHKERR Toplogy(m_field,
th).getProcTets(tets, edges_to_merge, proc_tets);
2893 out_tets = subtract(tets, proc_tets);
2894
2895 if (bit_ptr) {
2896 Range all_out_ents = out_tets;
2897 for (
int dd = 2;
dd >= 0;
dd--) {
2898 CHKERR moab.get_adjacencies(out_tets, dd,
false, all_out_ents,
2899 moab::Interface::UNION);
2900 }
2901 CHKERR m_field.getInterface<BitRefManager>()->addBitRefLevel(all_out_ents,
2902 *bit_ptr);
2903 }
2904
2905 int nb_nodes_merged = 0;
2908
2909 auto save_merge_step = [&](
const int pp,
const Range collapsed_edges) {
2912 CHKERR moab.get_adjacencies(proc_tets, 2,
false, adj_faces,
2913 moab::Interface::UNION);
2914 std::string name;
2915 name = "node_merge_step_" + boost::lexical_cast<std::string>(pp) + ".vtk";
2917 name, unite(intersect(new_surf, adj_faces), collapsed_edges));
2918 name =
2919 "edges_to_merge_step_" + boost::lexical_cast<std::string>(pp) + ".vtk";
2921 name, unite(intersect(new_surf, adj_faces), edges_to_merge));
2923 };
2924
2927
2928 double ave0 = 0, ave = 0, min = 0, min_p = 0, min_pp;
2930
2931 int nb_nodes_merged_p = nb_nodes_merged;
2932 length_map.clear();
2933 min_pp = min_p;
2934 min_p = min;
2936 length_map, ave);
2937
2938 if(!length_map.empty())
2939 min = length_map.get<2>().begin()->qUality;
2940 if (pp == 0) {
2941 ave0 = ave;
2942 }
2943
2944 int nn = 0;
2945 Range collapsed_edges;
2946 MergeNodes merge_nodes(m_field,
true,
th, update_meshsets);
2947
2948 for (auto mit = length_map.get<0>().begin();
2949 mit != length_map.get<0>().end(); mit++, nn++) {
2950
2951 if (!mit->skip) {
2952
2953 auto get_father_and_mother =
2956 int num_nodes;
2958 CHKERR moab.get_connectivity(mit->eDge, conn, num_nodes,
true);
2959 std::array<int, 2> conn_type = {0, 0};
2960 for (int nn = 0; nn != 2; nn++) {
2961 for (Toplogy::SetsMap::reverse_iterator sit = sets_map.rbegin();
2962 sit != sets_map.rend(); sit++) {
2963 if (sit->second.find(conn[nn]) != sit->second.end()) {
2964 conn_type[nn] |= sit->first;
2965 }
2966 }
2967 }
2968 int type_father, type_mother;
2969 if (conn_type[0] > conn_type[1]) {
2970 father = conn[0];
2971 mother = conn[1];
2972 type_father = conn_type[0];
2973 type_mother = conn_type[1];
2974 } else {
2975 father = conn[1];
2976 mother = conn[0];
2977 type_father = conn_type[1];
2978 type_mother = conn_type[0];
2979 }
2980 if (type_father == type_mother) {
2982 }
2984 };
2985
2986 int line_search = 0;
2988 CHKERR get_father_and_mother(father, mother, line_search);
2989 CHKERR merge_nodes.mergeNodes(line_search, father, mother, proc_tets);
2990 if (m_field.getInterface<NodeMergerInterface>()->getSuccessMerge()) {
2991 const EntityHandle father_and_mother[] = {father, mother};
2993 CHKERR moab.get_adjacencies(father_and_mother, 1, 3,
false, adj_tets);
2994 Range adj_tets_nodes;
2995 CHKERR moab.get_connectivity(adj_tets, adj_tets_nodes,
true);
2997 CHKERR moab.get_adjacencies(adj_tets_nodes, 1,
false, adj_edges,
2998 moab::Interface::UNION);
2999 for (auto ait : adj_edges) {
3000 auto miit = length_map.get<1>().find(ait);
3001 if (miit != length_map.get<1>().end())
3002 (const_cast<LengthMapData &>(*miit)).skip = true;
3003 }
3004 nb_nodes_merged++;
3005 collapsed_edges.insert(mit->eDge);
3006 }
3007
3008 if (nn > static_cast<int>(length_map.size() / fraction_level))
3009 break;
3010 if (mit->qUality > ave)
3011 break;
3012 }
3013 }
3014
3015 CHKERR merge_nodes.updateRangeByChilds(new_surf, edges_to_merge,
3016 not_merged_edges, true);
3017
3019 "(%d) Number of nodes merged %d ave q %3.4e min q %3.4e", pp,
3020 nb_nodes_merged, ave, min);
3021
3023 CHKERR save_merge_step(pp + 1, collapsed_edges);
3024
3025 if (nb_nodes_merged == nb_nodes_merged_p)
3026 break;
3027 if (min > 1e-2 && min == min_pp)
3028 break;
3029 if (min > ave0)
3030 break;
3031
3033 CHKERR moab.get_adjacencies(proc_tets, 1,
false, adj_edges,
3034 moab::Interface::UNION);
3035 edges_to_merge = intersect(edges_to_merge, adj_edges);
3037 .removeBadEdges(new_surf, proc_tets, fixed_edges, corner_nodes,
3039 }
3040
3041 auto reconstruct_refined_ents = [&]() {
3045 };
3046
3047
3048
3049
3050
3051
3052 CHKERR reconstruct_refined_ents();
3053
3054 if (bit_ptr)
3055 CHKERR m_field.getInterface<BitRefManager>()->setBitRefLevel(proc_tets,
3056 *bit_ptr);
3057
3058 out_tets.merge(proc_tets);
3060 CHKERR moab.get_adjacencies(out_tets, 2,
false, adj_faces,
3061 moab::Interface::UNION);
3062 new_surf = intersect(new_surf, adj_faces);
3063
3065}
#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