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;
 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) {
 2362            p.cHild = child;
 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 {
 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;
 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