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