diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp index 506ddd80c79fa2282a85019e18108e8f94ad677b..830661872b89e05343ce86a55e215ced649f8a94 100644 --- a/Common/CommandLine.cpp +++ b/Common/CommandLine.cpp @@ -78,6 +78,7 @@ std::vector<std::pair<std::string, std::string> > GetUsage() s.push_back(mp("-order int", "Set mesh order (1, ..., 5)")); s.push_back(mp("-optimize[_netgen]", "Optimize quality of tetrahedral elements")); s.push_back(mp("-optimize_ho", "Optimize high order meshes")); + s.push_back(mp("-ho_[min,max,nlayers]", "High-order optimization parameters")); s.push_back(mp("-optimize_lloyd", "Optimize 2D meshes using Lloyd algorithm")); s.push_back(mp("-microstructure", "Generate polycrystal Voronoi geometry")); s.push_back(mp("-clscale float", "Set global mesh element size scaling factor")); @@ -445,13 +446,6 @@ void GetOptions(int argc, char *argv[]) CTX::instance()->mesh.optimize = 1; i++; } - else if(!strcmp(argv[i] + 1, "bunin")) { - i++; - if(argv[i]) - CTX::instance()->mesh.bunin = atoi(argv[i++]); - else - Msg::Fatal("Missing cavity size in bunin optimization"); - } else if(!strcmp(argv[i] + 1, "optimize_netgen")) { CTX::instance()->mesh.optimizeNetgen = 1; i++; @@ -461,24 +455,21 @@ void GetOptions(int argc, char *argv[]) i++; opt_mesh_ho_optimize(0, GMSH_SET, 1); } - else if(!strcmp(argv[i] + 1, "ho_mindisto") || - !strcmp(argv[i] + 1, "hoMindisto")) { + else if(!strcmp(argv[i] + 1, "ho_min")) { i++; if(argv[i]) - opt_mesh_ho_mindisto(0, GMSH_SET, atof(argv[i++])); + opt_mesh_ho_threshold_min(0, GMSH_SET, atof(argv[i++])); else Msg::Fatal("Missing number"); } - else if(!strcmp(argv[i] + 1, "ho_poisson") || - !strcmp(argv[i] + 1, "hoElasticity")) { + else if(!strcmp(argv[i] + 1, "ho_max")) { i++; if(argv[i]) - opt_mesh_ho_poisson(0, GMSH_SET, atof(argv[i++])); + opt_mesh_ho_threshold_max(0, GMSH_SET, atof(argv[i++])); else Msg::Fatal("Missing number"); } - else if(!strcmp(argv[i] + 1, "ho_nlayers") || - !strcmp(argv[i] + 1, "hoNlayers")) { + else if(!strcmp(argv[i] + 1, "ho_nlayers")) { i++; if(argv[i]) opt_mesh_ho_nlayers(0, GMSH_SET, atoi(argv[i++])); @@ -492,7 +483,14 @@ void GetOptions(int argc, char *argv[]) else Msg::Fatal("Missing number of lloyd iterations"); } - #if defined(HAVE_MESH) + else if(!strcmp(argv[i] + 1, "bunin")) { + i++; + if(argv[i]) + CTX::instance()->mesh.bunin = atoi(argv[i++]); + else + Msg::Fatal("Missing cavity size in bunin optimization"); + } +#if defined(HAVE_MESH) else if(!strcmp(argv[i] + 1, "microstructure")) { i++; int j; @@ -518,7 +516,7 @@ void GetOptions(int argc, char *argv[]) vm2.correspondance(0.00001); } } - #endif +#endif else if(!strcmp(argv[i] + 1, "nopopup")) { CTX::instance()->noPopup = 1; i++; diff --git a/Common/Context.h b/Common/Context.h index c41cdc3907c46e545ed4587ca004bab5de8821df..d1758cd94d3685744251431d64574c5810a9d480 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -41,9 +41,9 @@ struct contextMeshOptions { int remeshParam, remeshAlgo; int order, secondOrderLinear, secondOrderIncomplete; int secondOrderExperimental, meshOnlyVisible; - int hoOptimize, minCircPoints, minCurvPoints; - int smoothNLayers; - double smoothDistoThreshold, smoothPoissonRatio; + int minCircPoints, minCurvPoints; + int hoOptimize, hoNLayers; + double hoThresholdMin, hoThresholdMax, hoPoissonRatio; int saveAll, saveTri, saveGroupsOfNodes, binary, bdfFieldFormat, saveParametric; int smoothNormals, reverseAllNormals, zoneDefinition, clip; int saveElementTagType; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 744de7d00cd0cadc914686d46e8fc11bbe1dd7ad..59bbfc296b5dfd795022f0d1531487826b9d88d7 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -757,7 +757,7 @@ StringXNumber GeometryOptions_Number[] = { "Display width of lines (in pixels)" }, { F|O, "MatchGeomAndMesh" , opt_geometry_match_geom_and_mesh, 0 , - "Matches geometries and meshes." }, + "Matches geometries and meshes" }, { F|O, "Normals" , opt_geometry_normals , 0. , "Display size of normal vectors (in pixels)" }, @@ -879,7 +879,7 @@ StringXNumber MeshOptions_Number[] = { "Apply n barycentric smoothing passes to the cross field" }, { F|O, "CgnsImportOrder" , opt_mesh_cgns_import_order , 1. , - "Enable the creation of high-order mesh from CGNS structured meshes." + "Enable the creation of high-order mesh from CGNS structured meshes" "(1, 2, 4, 8, ...)" }, { F|O, "ChacoArchitecture" , opt_mesh_partition_chaco_architecture, 1. , "(Adv. Chaco): Parallel architecture topology (0=hypercube, 1-3=mesh " @@ -964,10 +964,12 @@ StringXNumber MeshOptions_Number[] = { { F|O, "HighOrderOptimize" , opt_mesh_ho_optimize , 0., "Optimize high order meshes?" }, { F|0, "HighOrderPoissonRatio", opt_mesh_ho_poisson, 0.33, - "Poisson ratio of the material used in the elastic smoother for high order meshes." + "Poisson ratio of the material used in the elastic smoother for high order meshes" "Must be between -1.0 and 0.5, excluded"}, - { F|O, "HighOrderSmoothingThreshold", opt_mesh_ho_mindisto, 0.5, - "Distorition threshold when choosing which high order element to optimize."}, + { F|O, "HighOrderThresholdMin", opt_mesh_ho_threshold_min, 0.2, + "Minimum threshold for high order element optimization"}, + { F|O, "HighOrderThresholdMax", opt_mesh_ho_threshold_max, 2.0, + "Maximum threshold for high order element optimization"}, { F|O, "LabelSampling" , opt_mesh_label_sampling , 1. , "Label sampling rate (display one label every `LabelSampling' elements)" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index 5e6e48f817c5dab0cb12097bb6417cceb3e39833..851da3d11f2c6b89cbe7bafb0ad8123e247178be 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -5605,15 +5605,22 @@ double opt_mesh_ho_optimize(OPT_ARGS_NUM) double opt_mesh_ho_nlayers(OPT_ARGS_NUM) { if(action & GMSH_SET) - CTX::instance()->mesh.smoothNLayers = (int)val; - return CTX::instance()->mesh.smoothNLayers; + CTX::instance()->mesh.hoNLayers = (int)val; + return CTX::instance()->mesh.hoNLayers; } -double opt_mesh_ho_mindisto(OPT_ARGS_NUM) +double opt_mesh_ho_threshold_min(OPT_ARGS_NUM) { if(action & GMSH_SET) - CTX::instance()->mesh.smoothDistoThreshold = val; - return CTX::instance()->mesh.smoothDistoThreshold; + CTX::instance()->mesh.hoThresholdMin = val; + return CTX::instance()->mesh.hoThresholdMin; +} + +double opt_mesh_ho_threshold_max(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + CTX::instance()->mesh.hoThresholdMax = val; + return CTX::instance()->mesh.hoThresholdMax; } double opt_mesh_ho_poisson(OPT_ARGS_NUM) @@ -5624,9 +5631,9 @@ double opt_mesh_ho_poisson(OPT_ARGS_NUM) ratio = -0.999; else if (ratio >= 0.5) ratio = 0.499; - CTX::instance()->mesh.smoothPoissonRatio = ratio; + CTX::instance()->mesh.hoPoissonRatio = ratio; } - return CTX::instance()->mesh.smoothPoissonRatio; + return CTX::instance()->mesh.hoPoissonRatio; } double opt_mesh_second_order_experimental(OPT_ARGS_NUM) diff --git a/Common/Options.h b/Common/Options.h index 3b156db98d78e7731e394de90d454ac1a2e80a4f..c4f8e3246e0df4f3f52ebba53e4bf11d4cfc9c55 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -448,7 +448,8 @@ double opt_mesh_multiple_passes(OPT_ARGS_NUM); double opt_mesh_order(OPT_ARGS_NUM); double opt_mesh_ho_optimize(OPT_ARGS_NUM); double opt_mesh_ho_nlayers(OPT_ARGS_NUM); -double opt_mesh_ho_mindisto(OPT_ARGS_NUM); +double opt_mesh_ho_threshold_min(OPT_ARGS_NUM); +double opt_mesh_ho_threshold_max(OPT_ARGS_NUM); double opt_mesh_ho_poisson(OPT_ARGS_NUM); double opt_mesh_second_order_experimental(OPT_ARGS_NUM); double opt_mesh_second_order_linear(OPT_ARGS_NUM); diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp index 45bc5e09e7773aa68ebe959e887c766a9fac4adf..1e2410e235862b468baa6476ec7b5feee4db3399 100644 --- a/Mesh/Generator.cpp +++ b/Mesh/Generator.cpp @@ -35,6 +35,11 @@ #include "simple3D.h" #include "yamakawa.h" +#if defined(HAVE_OPTHOM) +#include "OptHomRun.h" +#include "OptHomElastic.h" +#endif + #if defined(HAVE_POST) #include "PView.h" #include "PViewData.h" @@ -746,6 +751,25 @@ void GenerateMesh(GModel *m, int ask) SetOrderN(m, CTX::instance()->mesh.order, CTX::instance()->mesh.secondOrderLinear, CTX::instance()->mesh.secondOrderIncomplete); + // Optimize high order elements + if(CTX::instance()->mesh.hoOptimize){ +#if defined(HAVE_OPTHOM) + if(CTX::instance()->mesh.hoOptimize < 0){ + ElasticAnalogy(GModel::current(), CTX::instance()->mesh.hoThresholdMin, false); + } + else{ + OptHomParameters p; + p.nbLayers = CTX::instance()->mesh.hoNLayers; + p.BARRIER_MIN = CTX::instance()->mesh.hoThresholdMin; + p.BARRIER_MAX = CTX::instance()->mesh.hoThresholdMax; + p.dim = GModel::current()->getDim(); + HighOrderMeshOptimizer(GModel::current(), p); + } +#else + Msg::Error("High-order mesh optimization requires the OPTHOM module"); +#endif + } + Msg::Info("%d vertices %d elements", m->getNumMeshVertices(), m->getNumMeshElements()); diff --git a/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp b/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp index 42fdd93daf32a1073a1759faeaf369d60addb76a..bac2a7a4020524881001358f36d782cf067e44cd 100644 --- a/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp +++ b/contrib/HighOrderMeshOptimizer/OptHomElastic.cpp @@ -69,7 +69,7 @@ void ElasticAnalogy(GModel *m, double threshold, bool onlyVisible) v.insert(v.begin(), (*it)->tetrahedra.begin(), (*it)->tetrahedra.end()); v.insert(v.end(), (*it)->hexahedra.begin(), (*it)->hexahedra.end()); v.insert(v.end(), (*it)->prisms.begin(), (*it)->prisms.end()); - hot.applySmoothingTo(v,1.e32,false); + hot.applySmoothingTo(v, 1.e32, false); } } checkHighOrderTetrahedron("File volume Mesh", m, bad, worst); @@ -190,8 +190,7 @@ double highOrderTools::applySmoothingTo(GFace *gf, double tres, bool mixed) std::vector<MElement*> v; v.insert(v.begin(), gf->triangles.begin(),gf->triangles.end()); v.insert(v.begin(), gf->quadrangles.begin(),gf->quadrangles.end()); - // applySmoothingTo(v,gf); - return applySmoothingTo(v,tres, mixed); + return applySmoothingTo(v, tres, mixed); } void highOrderTools::ensureMinimumDistorsion (double threshold) @@ -256,7 +255,7 @@ void highOrderTools::computeMetricInfo(GFace *gf, } } -void highOrderTools::applySmoothingTo(std::vector<MElement*> & all, GFace *gf) +void highOrderTools::applySmoothingTo(std::vector<MElement*> &all, GFace *gf) { #ifdef HAVE_TAUCS linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>; @@ -266,12 +265,12 @@ void highOrderTools::applySmoothingTo(std::vector<MElement*> & all, GFace *gf) // compute the straight sided positions of high order nodes that are // on the edges of the face in the UV plane dofManager<double> myAssembler(lsys); - elasticityTerm El(0, 1.0, CTX::instance()->mesh.smoothPoissonRatio, _tag); + elasticityTerm El(0, 1.0, CTX::instance()->mesh.hoPoissonRatio, _tag); std::vector<MElement*> layer, v; double minD; - getDistordedElements(all, CTX::instance()->mesh.smoothDistoThreshold, v, minD); + getDistordedElements(all, CTX::instance()->mesh.hoThresholdMin, v, minD); int numBad = v.size(); - const int nbLayers = CTX::instance()->mesh.smoothNLayers; + const int nbLayers = CTX::instance()->mesh.hoNLayers; for (int i = 0; i < nbLayers; i++){ addOneLayer(all, v, layer); v.insert(v.end(), layer.begin(), layer.end()); diff --git a/doc/texinfo/commandline.texi b/doc/texinfo/commandline.texi index a39f2892468030962b13dd0d19b423b6925fcdca..89b2a301c15f37934a6ae0f8896a2d606d4fe02f 100644 --- a/doc/texinfo/commandline.texi +++ b/doc/texinfo/commandline.texi @@ -46,16 +46,12 @@ Select mesh algorithm (meshadapt, del2d, front2d, delquad, del3d, front3d, mmg3d Set number of mesh smoothing steps @item -order int Set mesh order (1, ..., 5) -@item -hoOptimize -Optimize high order meshes -@item -hoMindisto float -Min high-order element quality before optim (0.0->1.0) -@item -hoNLayers int -Number of high order element layers to optimize -@item -hoElasticity float -Poisson ration for elasticity analogy (nu in [-1.0,0.5]) @item -optimize[_netgen] Optimize quality of tetrahedral elements +@item -optimize_ho +Optimize high order meshes +@item -ho_[min,max,nlayers] +High-order optimization parameters @item -optimize_lloyd Optimize 2D meshes using Lloyd algorithm @item -microstructure diff --git a/doc/texinfo/opt_general.texi b/doc/texinfo/opt_general.texi index 199508f4df741e62ea416f24bd88ce6b6a6b71db..396fbd4717b5ef6796f4eedde5bab727711f6653 100644 --- a/doc/texinfo/opt_general.texi +++ b/doc/texinfo/opt_general.texi @@ -569,6 +569,16 @@ Width (in pixels) of the graphic window@* Default value: @code{800}@* Saved in: @code{General.SessionFileName} +@item General.HighOrderToolsPositionX +Horizontal position (in pixels) of the upper left corner of the high order tools window@* +Default value: @code{650}@* +Saved in: @code{General.SessionFileName} + +@item General.HighOrderToolsPositionY +Vertical position (in pixels) of the upper left corner of the high order tools window@* +Default value: @code{150}@* +Saved in: @code{General.SessionFileName} + @item General.InitialModule Module launched on startup (0=automatic, 1=geometry, 2=mesh, 3=solver, 4=post-processing) @* Default value: @code{0}@* diff --git a/doc/texinfo/opt_geometry.texi b/doc/texinfo/opt_geometry.texi index 5cb2df48d7b2170d1b8fc2a7994a332c43f75100..8d8eb3b344b7e11453a79b2255d0ad90d3841474 100644 --- a/doc/texinfo/opt_geometry.texi +++ b/doc/texinfo/opt_geometry.texi @@ -85,7 +85,7 @@ Default value: @code{2}@* Saved in: @code{General.OptionsFileName} @item Geometry.MatchGeomAndMesh -Matches geometries and meshes.@* +Matches geometries and meshes@* Default value: @code{0}@* Saved in: @code{General.OptionsFileName} diff --git a/doc/texinfo/opt_mesh.texi b/doc/texinfo/opt_mesh.texi index af58d735fc65dcf0360a8ef2165ff7743e2e06c8..a493a99033335577f26e963477c4c80f8f08c0c6 100644 --- a/doc/texinfo/opt_mesh.texi +++ b/doc/texinfo/opt_mesh.texi @@ -55,7 +55,7 @@ Default value: @code{0}@* Saved in: @code{General.OptionsFileName} @item Mesh.CgnsImportOrder -Enable the creation of high-order mesh from CGNS structured meshes.(1, 2, 4, 8, ...)@* +Enable the creation of high-order mesh from CGNS structured meshes(1, 2, 4, 8, ...)@* Default value: @code{1}@* Saved in: @code{General.OptionsFileName} @@ -215,23 +215,28 @@ Default value: @code{1}@* Saved in: @code{General.OptionsFileName} @item Mesh.HighOrderNumLayers -Number of high order mesh elements to consider for optimization.@* +Number of high order mesh elements to consider for optimization@* Default value: @code{3}@* Saved in: @code{-} @item Mesh.HighOrderOptimize -Number of smoothing steps of internal edges for high order meshes@* +Optimize high order meshes?@* Default value: @code{0}@* Saved in: @code{General.OptionsFileName} @item Mesh.HighOrderPoissonRatio -Poisson ratio of the material used in the elastic smoother for high order meshes.Must be between -1.0 and 0.5, excluded.@* +Poisson ratio of the material used in the elastic smoother for high order meshesMust be between -1.0 and 0.5, excluded@* Default value: @code{0.33}@* Saved in: @code{-} -@item Mesh.HighOrderSmoothingThreshold -Distorition threshold when choosing which high order element to optimize.@* -Default value: @code{0.5}@* +@item Mesh.HighOrderThresholdMin +Minimum threshold for high order element optimization@* +Default value: @code{0.2}@* +Saved in: @code{General.OptionsFileName} + +@item Mesh.HighOrderThresholdMax +Maximum threshold for high order element optimization@* +Default value: @code{2}@* Saved in: @code{General.OptionsFileName} @item Mesh.LabelSampling