17 #include "GmshConfig.h" 
   43 #if defined(HAVE_DOMHEX) 
   44 #include "pointInsertion.h" 
   49 #if defined(HAVE_OPTHOM) 
   50 #include "HighOrderMeshElasticAnalogy.h" 
   51 #include "HighOrderMeshFastCurving.h" 
   52 #include "HighOrderMeshOptimizer.h" 
   55 #if defined(HAVE_WINSLOWUNTANGLER) 
   56 #include "meshSurfaceUntangling.h" 
   57 #include "meshVolumeUntangling.h" 
   60 #if defined(HAVE_POST) 
   72         if (e.empty() && 
f.empty())
 
   74         std::map<MEdge, GEdge *, MEdgeLessThan> 
edges;
 
   75         std::map<MFace, GFace *, MFaceLessThan> 
faces;
 
   78         for (; it != e.end(); ++it)
 
   80             for (std::size_t i = 0; i < (*it)->lines.size(); ++i)
 
   82                 if (
distance((*it)->lines[i]->getVertex(0), (*it)->lines[i]->getVertex(1)) > 1.e-12)
 
   84                         std::make_pair(
MEdge((*it)->lines[i]->getVertex(0), (*it)->lines[i]->getVertex(1)), *it));
 
   87         for (; itf != 
f.end(); ++itf)
 
   89             for (std::size_t i = 0; i < (*itf)->triangles.size(); ++i)
 
   92                     std::make_pair(
MFace((*itf)->triangles[i]->getVertex(0), (*itf)->triangles[i]->getVertex(1),
 
   93                                          (*itf)->triangles[i]->getVertex(2)),
 
   97         Msg::Info(
"Searching for %d embedded mesh edges and %d embedded mesh faces " 
  113             Msg::Info(
"All embedded edges and faces are present in the final mesh");
 
  118             sprintf(name, 
"missingEdgesOnRegion%d.pos", gr->
tag());
 
  119             Msg::Warning(
"Region %d : %d mesh edges that should be embedded are " 
  120                          "missing in the final mesh",
 
  122             Msg::Info(
"Saving the missing edges in file %s", name);
 
  123             FILE *
f = fopen(name, 
"w");
 
  124             fprintf(
f, 
"View \" \" {\n");
 
  125             for (
auto it = 
edges.begin(); it != 
edges.end(); ++it)
 
  127                 MVertex *v1 = it->first.getVertex(0);
 
  128                 MVertex *v2 = it->first.getVertex(1);
 
  129                 fprintf(
f, 
"SL(%g,%g,%g,%g,%g,%g){%d,%d};\n", v1->
x(), v1->
y(), v1->
z(), v2->
x(), v2->
y(), v2->
z(),
 
  130                         it->second->tag(), it->second->tag());
 
  138             sprintf(name, 
"missingFacesOnRegion%d.pos", gr->
tag());
 
  139             Msg::Warning(
"Volume %d : %d mesh faces that should be embedded are " 
  140                          "missing in the final mesh",
 
  142             Msg::Info(
"Saving the missing faces in file %s", name);
 
  143             FILE *
f = fopen(name, 
"w");
 
  144             fprintf(
f, 
"View \" \" {\n");
 
  145             for (
auto it = 
faces.begin(); it != 
faces.end(); ++it)
 
  147                 MVertex *v1 = it->first.getVertex(0);
 
  148                 MVertex *v2 = it->first.getVertex(1);
 
  149                 MVertex *v3 = it->first.getVertex(2);
 
  150                 fprintf(
f, 
"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%d,%d,%d};\n", v1->
x(), v1->
y(), v1->
z(), v2->
x(), v2->
y(),
 
  151                         v2->
z(), v3->
x(), v3->
y(), v3->
z(), it->second->tag(), it->second->tag(), it->second->tag());
 
  160 static void GetQualityMeasure(std::vector<T *> &ele, 
double &gamma, 
double &gammaMin, 
double &gammaMax, 
double &minSICN,
 
  161                               double &minSICNMin, 
double &minSICNMax, 
double &minSIGE, 
double &minSIGEMin,
 
  162                               double &minSIGEMax, 
double quality[3][100])
 
  164     for (std::size_t i = 0; i < ele.size(); i++)
 
  166         double g = ele[i]->gammaShapeMeasure();
 
  168         gammaMin = std::min(gammaMin, g);
 
  169         gammaMax = std::max(gammaMax, g);
 
  170         double s = ele[i]->minSICNShapeMeasure();
 
  172         minSICNMin = std::min(minSICNMin, s);
 
  173         minSICNMax = std::max(minSICNMax, s);
 
  174         double e = ele[i]->minSIGEShapeMeasure();
 
  176         minSIGEMin = std::min(minSIGEMin, e);
 
  177         minSIGEMax = std::max(minSIGEMax, e);
 
  178         for (
int j = 0; j < 100; j++)
 
  180             if (s > (2 * j - 100) / 100. && s <= (2 * j - 98) / 100.)
 
  182             if (g > j / 100. && g <= (j + 1) / 100.)
 
  184             if (e > (2 * j - 100) / 100. && e <= (2 * j - 98) / 100.)
 
  190 void GetStatistics(
double stat[50], 
double quality[3][100], 
bool visibleOnly)
 
  192     for (
int i = 0; i < 50; i++)
 
  205     std::map<int, std::vector<GEntity *>> physicals[4];
 
  207     stat[45] = physicals[0].size() + physicals[1].size() + physicals[2].size() + physicals[3].size();
 
  211         if (visibleOnly && !(*it)->getVisibility())
 
  213         stat[4] += (*it)->mesh_vertices.size();
 
  214         stat[5] += (*it)->points.size();
 
  219         if (visibleOnly && !(*it)->getVisibility())
 
  221         stat[4] += (*it)->mesh_vertices.size();
 
  222         stat[6] += (*it)->lines.size();
 
  227         if (visibleOnly && !(*it)->getVisibility())
 
  229         stat[4] += (*it)->mesh_vertices.size();
 
  230         stat[7] += (*it)->triangles.size();
 
  231         stat[8] += (*it)->quadrangles.size();
 
  236         if (visibleOnly && !(*it)->getVisibility())
 
  238         stat[4] += (*it)->mesh_vertices.size();
 
  239         stat[9] += (*it)->tetrahedra.size();
 
  240         stat[10] += (*it)->hexahedra.size();
 
  241         stat[11] += (*it)->prisms.size();
 
  242         stat[12] += (*it)->pyramids.size();
 
  243         stat[13] += (*it)->trihedra.size();
 
  252         for (
int i = 0; i < 3; i++)
 
  253             for (
int j = 0; j < 100; j++)
 
  255         double minSICN = 0., minSICNMin = 1., minSICNMax = -1.;
 
  256         double minSIGE = 0., minSIGEMin = 1., minSIGEMax = -1.;
 
  257         double gamma = 0., gammaMin = 1., gammaMax = 0.;
 
  259         double N = stat[9] + stat[10] + stat[11] + stat[12] + stat[13];
 
  264                 if (visibleOnly && !(*it)->getVisibility())
 
  266                 GetQualityMeasure((*it)->tetrahedra, gamma, gammaMin, gammaMax, minSICN, minSICNMin, minSICNMax,
 
  267                                   minSIGE, minSIGEMin, minSIGEMax, quality);
 
  268                 GetQualityMeasure((*it)->hexahedra, gamma, gammaMin, gammaMax, minSICN, minSICNMin, minSICNMax, minSIGE,
 
  269                                   minSIGEMin, minSIGEMax, quality);
 
  270                 GetQualityMeasure((*it)->prisms, gamma, gammaMin, gammaMax, minSICN, minSICNMin, minSICNMax, minSIGE,
 
  271                                   minSIGEMin, minSIGEMax, quality);
 
  272                 GetQualityMeasure((*it)->pyramids, gamma, gammaMin, gammaMax, minSICN, minSICNMin, minSICNMax, minSIGE,
 
  273                                   minSIGEMin, minSIGEMax, quality);
 
  278             N = stat[7] + stat[8];
 
  281                 if (visibleOnly && !(*it)->getVisibility())
 
  283                 GetQualityMeasure((*it)->quadrangles, gamma, gammaMin, gammaMax, minSICN, minSICNMin, minSICNMax,
 
  284                                   minSIGE, minSIGEMin, minSIGEMax, quality);
 
  285                 GetQualityMeasure((*it)->triangles, gamma, gammaMin, gammaMax, minSICN, minSICNMin, minSICNMax, minSIGE,
 
  286                                   minSIGEMin, minSIGEMax, quality);
 
  291             stat[18] = minSICN / N;
 
  292             stat[19] = minSICNMin;
 
  293             stat[20] = minSICNMax;
 
  294             stat[21] = gamma / N;
 
  297             stat[24] = minSIGE / N;
 
  298             stat[25] = minSIGEMin;
 
  299             stat[26] = minSIGEMax;
 
  303 #if defined(HAVE_POST) 
  305     for (std::size_t i = 0; i < 
PView::list.size(); i++)
 
  328     double sumAllLc = 0.;
 
  332     if (!sumAllLc || pow(
CTX::instance()->lc / sumAllLc, dim) > 1.e10)
 
  333         return !
Msg::GetAnswer(
"Your choice of mesh element sizes will likely produce a very\n" 
  334                                "large mesh. Do you really want to continue?\n\n" 
  335                                "(To disable this warning in the future, select `Enable expert mode'\n" 
  336                                "in the option dialog.)",
 
  337                                1, 
"Cancel", 
"Continue");
 
  393         if ((*it)->meshAttributes.extrude && (*it)->meshAttributes.extrude->mesh.ExtrudeMesh)
 
  397     std::vector<GEdge *> temp;
 
  416         bool exceptions = 
false;
 
  417 #pragma omp parallel for schedule(dynamic) num_threads(nthreads) 
  418         for (
size_t K = 0; K < temp.size(); K++)
 
  422             int localPending = 0;
 
  434 #pragma omp atomic capture 
  437                     localPending = nPending;
 
  460     FILE *statreport = 
nullptr;
 
  474     double worst = 1, best = 0, avg = 0;
 
  475     double e_long = 0, e_short = 1.e22, e_avg = 0;
 
  476     int nTotT = 0, nTotE = 0, nTotGoodLength = 0, nTotGoodQuality = 0;
 
  477     int nUnmeshed = 0, numFaces = 0;
 
  481         fprintf(statreport, 
"2D stats\tname\t\t#faces\t\t#fail\t\t" 
  482                             "#t\t\tQavg\t\tQbest\t\tQworst\t\t#Q>90\t\t#Q>90/#t\t" 
  483                             "#e\t\ttau\t\t#Egood\t\t#Egood/#e\tCPU\n");
 
  495             worst = std::min((*it)->meshStatistics.worst_element_shape, worst);
 
  496             best = std::max((*it)->meshStatistics.best_element_shape, best);
 
  497             avg += (*it)->meshStatistics.average_element_shape * (*it)->meshStatistics.nbTriangle;
 
  498             e_avg += (*it)->meshStatistics.efficiency_index;
 
  499             e_long = std::max((*it)->meshStatistics.longest_edge_length, e_long);
 
  500             e_short = std::min((*it)->meshStatistics.smallest_edge_length, e_short);
 
  503             nTotT += (*it)->meshStatistics.nbTriangle;
 
  504             nTotE += (*it)->meshStatistics.nbEdge;
 
  505             nTotGoodLength += (*it)->meshStatistics.nbGoodLength;
 
  506             nTotGoodQuality += (*it)->meshStatistics.nbGoodQuality;
 
  511     Msg::Info(
"Efficiency index for surface mesh tau=%g ", 100 * exp(e_avg / (
double)nTotE));
 
  513     fprintf(statreport, 
"\t%16s\t%d\t\t%d\t\t", m->
getName().c_str(), numFaces, nUnmeshed);
 
  514     fprintf(statreport, 
"%d\t\t%8.7f\t%8.7f\t%8.7f\t%d\t\t%8.7f\t", nTotT, avg / (
double)nTotT, best, worst,
 
  515             nTotGoodQuality, (
double)nTotGoodQuality / nTotT);
 
  516     fprintf(statreport, 
"%d\t\t%8.7f\t%d\t\t%8.7f\t%8.1f\n", nTotE, exp(e_avg / (
double)nTotE), nTotGoodLength,
 
  517             (
double)nTotGoodLength / nTotE, 
CTX::instance()->meshTimer[1]);
 
  551         if ((*it)->getMeshMaster() != *it)
 
  555         if ((*it)->meshAttributes.extrude && (*it)->meshAttributes.extrude->mesh.ExtrudeMesh)
 
  567         std::set<GFace *, GEntityPtrLessThan> 
f;
 
  584             bool exceptions = 
false;
 
  585             std::vector<GFace *> temp;
 
  586             temp.insert(temp.begin(), 
f.begin(), 
f.end());
 
  587 #pragma omp parallel for schedule(dynamic) num_threads(nthreads) 
  588             for (
size_t K = 0; K < temp.size(); K++)
 
  592                 int localPending = 0;
 
  604 #pragma omp atomic capture 
  607                         localPending = nPending;
 
  649 static void FindConnectedRegions(
const std::vector<GRegion *> &del, std::vector<std::vector<GRegion *>> &connected)
 
  651     std::vector<GRegion *> delaunay = del;
 
  654     const std::size_t nbVolumes = delaunay.size();
 
  657     while (delaunay.size())
 
  659         std::set<GRegion *> oneDomain;
 
  660         std::stack<GRegion *> _stack;
 
  663         while (!_stack.empty())
 
  669             for (
auto it = 
faces.begin(); it != 
faces.end(); ++it)
 
  673                 if (other != 
nullptr && oneDomain.find(other) == oneDomain.end())
 
  677         std::vector<GRegion *> temp1, temp2;
 
  678         for (std::size_t i = 0; i < delaunay.size(); i++)
 
  681             if (oneDomain.find(r) == oneDomain.end())
 
  686         connected.push_back(temp2);
 
  689     Msg::Info(
"3D Meshing %d volume%s with %d connected component%s", nbVolumes, nbVolumes > 1 ? 
"s" : 
"",
 
  690               connected.size(), connected.size() > 1 ? 
"s" : 
"");
 
  716             auto it = bnd.find(
f);
 
  729     std::set<MFace, MFaceLessThan> bnd;
 
  737     std::set<MFace, MFaceLessThan> bnd2;
 
  738     for (
auto itf = bnd.begin(); itf != bnd.end(); ++itf)
 
  748     Msg::Info(
"%d hanging faces", bnd2.size());
 
  750     std::set<MFace, MFaceLessThan> ncf;
 
  751     for (
auto itf = bnd2.begin(); itf != bnd2.end(); ++itf)
 
  754         if (
f.getNumVertices() == 4)
 
  756             auto it1 = bnd2.find(
MFace(
f.getVertex(0), 
f.getVertex(1), 
f.getVertex(2)));
 
  757             auto it2 = bnd2.find(
MFace(
f.getVertex(2), 
f.getVertex(3), 
f.getVertex(0)));
 
  758             if (it1 != bnd2.end() && it2 != bnd2.end())
 
  760                 ncf.insert(
MFace(
f.getVertex(1), 
f.getVertex(2), 
f.getVertex(3), 
f.getVertex(0)));
 
  764                 it1 = bnd2.find(
MFace(
f.getVertex(0), 
f.getVertex(1), 
f.getVertex(3)));
 
  765                 it2 = bnd2.find(
MFace(
f.getVertex(3), 
f.getVertex(1), 
f.getVertex(2)));
 
  766                 if (it1 != bnd2.end() && it2 != bnd2.end())
 
  768                     ncf.insert(
MFace(
f.getVertex(0), 
f.getVertex(1), 
f.getVertex(2), 
f.getVertex(3)));
 
  772                     Msg::Error(
"MakeMeshConformal: wrong mesh topology");
 
  783         std::vector<MHexahedron *> remainingHexes;
 
  784         for (std::size_t i = 0; i < gr->
hexahedra.size(); i++)
 
  787             std::vector<MFace> 
faces;
 
  791                 auto it = ncf.find(
f);
 
  798                     faces.push_back(
MFace(it->getVertex(0), it->getVertex(1), it->getVertex(3)));
 
  799                     faces.push_back(
MFace(it->getVertex(1), it->getVertex(2), it->getVertex(3)));
 
  805                 remainingHexes.push_back(e);
 
  812                 for (std::size_t j = 0; j < 
faces.size(); j++)
 
  815                     if (
f.getNumVertices() == 4)
 
  818                             new MPyramid(
f.getVertex(0), 
f.getVertex(1), 
f.getVertex(2), 
f.getVertex(3), newv));
 
  823                             new MTetrahedron(
f.getVertex(0), 
f.getVertex(1), 
f.getVertex(2), newv));
 
  829         remainingHexes.clear();
 
  830         std::vector<MPrism *> remainingPrisms;
 
  831         for (std::size_t i = 0; i < gr->
prisms.size(); i++)
 
  834             std::vector<MFace> 
faces;
 
  838                 auto it = ncf.find(
f);
 
  845                     faces.push_back(
MFace(it->getVertex(0), it->getVertex(1), it->getVertex(3)));
 
  846                     faces.push_back(
MFace(it->getVertex(1), it->getVertex(2), it->getVertex(3)));
 
  852                 remainingPrisms.push_back(e);
 
  859                 for (std::size_t j = 0; j < 
faces.size(); j++)
 
  862                     if (
f.getNumVertices() == 4)
 
  865                             new MPyramid(
f.getVertex(0), 
f.getVertex(1), 
f.getVertex(2), 
f.getVertex(3), newv));
 
  870                             new MTetrahedron(
f.getVertex(0), 
f.getVertex(1), 
f.getVertex(2), newv));
 
  875         gr->
prisms = remainingPrisms;
 
  881 #if defined(HAVE_DOMHEX) 
  882 static void TestConformity(
GModel *gm)
 
  890         std::set<MFace, MFaceLessThan> bnd;
 
  899                 auto it = bnd.find(
f);
 
  908         for (
auto itf = bnd.begin(); itf != bnd.end(); ++itf)
 
  920         Msg::Error(
"Mesh is not conforming (%d hanging faces)!", count);
 
  950     std::vector<GRegion *> delaunay;
 
  956     std::vector<std::vector<GRegion *>> connected;
 
  960     for (std::size_t i = 0; i < connected.size(); i++)
 
  962         for (std::size_t j = 0; j < connected[i].size(); j++)
 
  967                 std::vector<GFace *> 
f = gr->
faces();
 
  968                 for (
auto it = 
f.begin(); it != 
f.end(); ++it)
 
  974 #if defined(HAVE_DOMHEX) 
  975     double time_recombination = 0., vol_element_recombination = 0.;
 
  976     double vol_hexa_recombination = 0.;
 
  977     int nb_elements_recombination = 0, nb_hexa_recombination = 0;
 
  980     for (std::size_t i = 0; i < connected.size(); i++)
 
  990 #if defined(HAVE_DOMHEX) 
  993         for (std::size_t j = 0; j < connected[i].size(); j++)
 
  996             bool treat_region_ok = 
false;
 
 1003                     treat_region_ok = 
true;
 
 1008                     treat_region_ok = 
f.treat_region(gr);
 
 1038                 nb_elements_recombination += post.get_nb_elements();
 
 1039                 nb_hexa_recombination += post.get_nb_hexahedra();
 
 1040                 vol_element_recombination += post.get_vol_elements();
 
 1041                 vol_hexa_recombination += post.get_vol_hexahedra();
 
 1042                 time_recombination += (
TimeOfDay() - a);
 
 1048 #if defined(HAVE_DOMHEX) 
 1052         Msg::Info(
" - Cumulative time recombination: %g s", time_recombination);
 
 1053         Msg::Info(
"Recombination cumulative statistics:");
 
 1054         Msg::Info(
" - Percentage of hexahedra (#)  : %g", nb_hexa_recombination * 100. / nb_elements_recombination);
 
 1055         Msg::Info(
" - Percentage of hexahedra (Vol): %g", vol_hexa_recombination * 100. / vol_element_recombination);
 
 1067     std::stringstream debugInfo;
 
 1068     debugInfo << 
"No elements in volume ";
 
 1069     bool emptyRegionFound = 
false;
 
 1079             debugInfo << gr->
tag() << 
" ";
 
 1080             emptyRegionFound = 
true;
 
 1083     if (emptyRegionFound)
 
 1085         debugInfo << std::endl;
 
 1106     if (how != 
"" && how != 
"Gmsh" && how != 
"Optimize" && how != 
"Netgen" && how != 
"HighOrder" &&
 
 1107         how != 
"HighOrderElastic" && how != 
"HighOrderFastCurving" && how != 
"Laplace2D" && how != 
"Relocate2D" &&
 
 1108         how != 
"Relocate3D" && how != 
"DiskQuadrangulation" && how != 
"QuadCavityRemeshing" &&
 
 1109         how != 
"QuadQuasiStructured" && how != 
"UntangleMeshGeometry")
 
 1111         Msg::Error(
"Unknown mesh optimization method '%s'", how.c_str());
 
 1115     if (how == 
"" || how == 
"Gmsh" || how == 
"Optimize")
 
 1121     if (how == 
"" || how == 
"Gmsh" || how == 
"Optimize")
 
 1130     else if (how == 
"Netgen")
 
 1139     else if (how == 
"HighOrder")
 
 1141 #if defined(HAVE_OPTHOM) 
 1152         HighOrderMeshOptimizer(m, p);
 
 1154         Msg::Error(
"High-order mesh optimization requires the OPTHOM module");
 
 1157     else if (how == 
"HighOrderElastic")
 
 1159 #if defined(HAVE_OPTHOM) 
 1160         HighOrderMeshElasticAnalogy(m, 
false);
 
 1162         Msg::Error(
"High-order mesh optimization requires the OPTHOM module");
 
 1165     else if (how == 
"HighOrderFastCurving")
 
 1167 #if defined(HAVE_OPTHOM) 
 1168         FastCurvingParameters p;
 
 1170         p.thickness = 
false;
 
 1176         HighOrderMeshFastCurving(m, p, 
false);
 
 1178         Msg::Error(
"High-order mesh optimization requires the OPTHOM module");
 
 1181     else if (how == 
"Laplace2D")
 
 1189     else if (how == 
"Relocate2D")
 
 1197     else if (how == 
"Relocate3D")
 
 1205     else if (how == 
"DiskQuadrangulation")
 
 1224     else if (how == 
"QuadCavityRemeshing")
 
 1243     else if (how == 
"QuadQuasiStructured")
 
 1265     else if (how == 
"UntangleMeshGeometry")
 
 1267 #if defined(HAVE_WINSLOWUNTANGLER) 
 1268         int nIterWinslow = 10;
 
 1271             if (
CTX::instance()->mesh.meshOnlyVisible && !gf->getVisibility())
 
 1275                 double timeMax = 100.;
 
 1276                 untangleGFaceMeshConstrained(gf, nIterWinslow, timeMax);
 
 1280                 Msg::Debug(
"- Surface %i: not planar, do not apply Winslow untangling", gf->tag());
 
 1287             double timeMax = 100.;
 
 1288             untangleGRegionMeshConstrained(gr, nIterWinslow, timeMax);
 
 1291         Msg::Error(
"Untangle mesh geometry optimization requires the " 
 1292                    "WinslowUntangler module");
 
 1300     Msg::StatusBar(
true, 
"Done optimizing mesh (Wall %gs, CPU %gs)", w2 - 
w1, t2 - t1);
 
 1311     for (
int i = 0; i < 10; i++)
 
 1315     Msg::StatusBar(
true, 
"Done adaptating 3D mesh (Wall %gs, CPU %gs)", w2 - 
w1, t2 - t1);
 
 1344     Msg::StatusBar(
true, 
"Done recombining 2D mesh (Wall %gs, CPU %gs)", w2 - 
w1, t2 - t1);
 
 1349     double ps[4] = {vsource->
x(), vsource->
y(), vsource->
z(), 1.};
 
 1350     double res[4] = {0., 0., 0., 0.};
 
 1352     for (
int i = 0; i < 4; i++)
 
 1353         for (
int j = 0; j < 4; j++)
 
 1354             res[i] += tfo[idx++] * ps[j];
 
 1356     return SPoint3(res[0], res[1], res[2]);
 
 1361     for (
auto vit = vertS2M.begin(); vit != vertS2M.end(); ++vit)
 
 1364         if (v && v->
onWhat() == slave)
 
 1368             if (useClosestPoint)
 
 1390     for (
auto vit = vertS2M.begin(); vit != vertS2M.end(); ++vit)
 
 1393         if (v && v->
onWhat() == slave)
 
 1397             if (useClosestPoint)
 
 1416     std::multimap<GEntity *, GEntity *> master2slave;
 
 1417     for (std::size_t i = 0; i < entities.size(); ++i)
 
 1419         if (entities[i]->dim() == 0)
 
 1422         if (master != entities[i])
 
 1424             master2slave.insert(std::make_pair(master, entities[i]));
 
 1428     for (
auto it = master2slave.begin(); it != master2slave.end(); ++it)
 
 1430         if (it->first->dim() == 2)
 
 1432             GFace *master = 
dynamic_cast<GFace *
>(it->first);
 
 1433             GFace *slave = 
dynamic_cast<GFace *
>(it->second);
 
 1436             Msg::Info(
"Relocating nodes of slave surface %i using master %i%s", slave->
tag(), master->
tag(),
 
 1437                       useClosestPoint ? 
" (using closest point)" : 
"");
 
 1441         else if (it->first->dim() == 1)
 
 1443             GEdge *master = 
dynamic_cast<GEdge *
>(it->first);
 
 1444             GEdge *slave = 
dynamic_cast<GEdge *
>(it->second);
 
 1447             Msg::Info(
"Relocating nodes of slave curve %i using master %i%s", slave->
tag(), master->
tag(),
 
 1448                       useClosestPoint ? 
" (using closest point)" : 
"");
 
 1470         if (src != 
nullptr && src != tgt)
 
 1476             Msg::Info(
"Reconstructing periodicity for curve connection %d - %d", tgt->
tag(), src->
tag());
 
 1478             std::map<MEdge, MLine *, MEdgeLessThan> srcEdges;
 
 1499                 for (
int iVtx = 0; iVtx < 2; iVtx++)
 
 1502                     auto tIter = v2v.find(vtx);
 
 1503                     if (tIter == v2v.end())
 
 1505                         Msg::Error(
"Cannot find periodic counterpart of node %d" 
 1506                                    " of curve %d on curve %d",
 
 1511                         vtcs[iVtx] = tIter->second;
 
 1514                 auto srcIter = srcEdges.find(
MEdge(vtcs[0], vtcs[1]));
 
 1515                 if (srcIter == srcEdges.end())
 
 1517                     Msg::Error(
"Can't find periodic counterpart of mesh edge %d-%d " 
 1518                                "on curve %d, connected to mesh edge %d-%d on curve %d",
 
 1525                     MLine *srcLine = srcIter->second;
 
 1548         if (src != 
nullptr && src != tgt)
 
 1550             Msg::Info(
"Reconstructing periodicity for surface connection %d - %d", tgt->
tag(), src->
tag());
 
 1558                 Msg::Info(
"No periodic vertices in surface %d (maybe due to a " 
 1559                           "structured mesh constraint on the target surface)",
 
 1564             std::map<MFace, MElement *, MFaceLessThan> srcFaces;
 
 1574                 std::vector<MVertex *> vtcs;
 
 1575                 vtcs.reserve(nbVtcs);
 
 1576                 for (
int iVtx = 0; iVtx < nbVtcs; iVtx++)
 
 1578                     vtcs.push_back(srcElmt->
getVertex(iVtx));
 
 1580                 srcFaces[
MFace(vtcs)] = srcElmt;
 
 1591                 std::vector<MVertex *> vtcs;
 
 1592                 for (
int iVtx = 0; iVtx < nbVtcs; iVtx++)
 
 1596                     auto tIter = v2v.find(vtx);
 
 1597                     if (tIter == v2v.end())
 
 1599                         Msg::Error(
"Cannot find periodic counterpart of node %d " 
 1600                                    "of surface %d on surface %d",
 
 1605                         vtcs.push_back(tIter->second);
 
 1608                 MFace tgtFace(vtcs);
 
 1609                 auto srcIter = srcFaces.find(tgtFace);
 
 1610                 if (srcIter == srcFaces.end())
 
 1612                     std::ostringstream faceDef;
 
 1613                     for (
int iVtx = 0; iVtx < nbVtcs; iVtx++)
 
 1614                         faceDef << vtcs[iVtx]->getNum() << 
" ";
 
 1615                     Msg::Error(
"Cannot find periodic counterpart of mesh face %s in " 
 1616                                "surface %d on surface %d",
 
 1617                                faceDef.str().c_str(), tgt->
tag(), src->
tag());
 
 1622                     MElement *srcElmt = srcIter->second;
 
 1626                     bool revert = 
dot(tgtFace.
normal(), srcIter->first.normal()) < 0;
 
 1654         Msg::Info(
"I'm busy! Ask me that later...");
 
 1679         bool doIt = (ask >= 1 && ask <= 3);
 
 1681         bool overwriteGModelMesh = 
false; 
 
 1682         bool overwriteField = 
false;
 
 1683         if (old == 1 && ask == 1 && exists)
 
 1685         if (old == 1 && ask == 2 && exists)
 
 1687         if (old == 2 && exists && (ask == 1 || ask == 2))
 
 1691             overwriteField = 
true;
 
 1692             overwriteGModelMesh = 
true;
 
 1694         if (old == 2 && ask == 1 && exists)
 
 1696         if (old == 2 && ask == 2 && exists)
 
 1700             bool deleteGModelMeshAfter = 
true; 
 
 1722             std::set<GFace *> 
faces;
 
 1724                 if (gf->edges().size() == 4)
 
 1728             double maxDiffRel = 0.34; 
 
 1737     if (ask == 1 || (ask > 1 && old < 1))
 
 1746     if (ask == 2 || (ask > 2 && old < 2))