From 37416adb03da86260276acdd6810ddb65148f434 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Tue, 7 Apr 2026 12:58:16 -0400 Subject: [PATCH] feat(stroid): added mesh viewer and tmop toggle --- Doxyfile | 2 +- meson.build | 2 +- readme.md | 39 ++++++++++-------- src/include/stroid/topology/optimize.h | 5 +++ src/lib/topology/optimize.cpp | 6 +++ subprojects/libconfig.wrap | 2 +- tools/stroid.cpp | 57 +++++++++++++++++++++++--- 7 files changed, 88 insertions(+), 25 deletions(-) diff --git a/Doxyfile b/Doxyfile index 5aa5c83..757d19f 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = stroid # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = v0.2.1 +PROJECT_NUMBER = v0.3.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewers a diff --git a/meson.build b/meson.build index 48d8eed..bc13b2c 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('stroid', 'cpp', meson_version : '>= 1.3.0', version : 'v0.2.1', default_options : ['cpp_std=c++23']) +project('stroid', 'cpp', meson_version : '>= 1.3.0', version : 'v0.3.0', default_options : ['cpp_std=c++23']) subdir('build-check') diff --git a/readme.md b/readme.md index 534cb22..ce1545a 100644 --- a/readme.md +++ b/readme.md @@ -92,25 +92,31 @@ inf_bdr_id = 2 core_id = 1 envelope_id = 2 vacuum_id = 3 + +[main.optimization_methods] +tmop = false +smoothstep = true ``` -| Parameter | Description | Default | -|-------------------------|-----------------------------------------------------------------------------------------------------|---------| -| refinement_levels | Number of uniform refinement levels to apply to the mesh after generation | 4 | -| order | The polynomial order of the finite elements in the mesh | 3 | -| include_external_domain | Whether to include an external domain extending to r_infinity | true | -| r_core | The radius of the core region of the star | 1.5 | -| r_star | The radius of the star | 5.0 | -| flattening | The flattening factor of the star (0 for spherical, >0 for oblate) | 0 | -| r_infinity | The outer radius of the external domain (if included) | 6.0 | -| r_instability | The radius at which no transformations are applied to the initial topology (to avoid singularities) | 1e-14 | -| core_steepness | The steepness of the transition between the core and envelope regions of the star | 1.0 | -| surface_bdr_id | The boundary ID to assign to the surface of the star | 1 | -| inf_bdr_id | The boundary ID to assign to the outer boundary of the external domain (if included) | 2 | -| core_id | The material ID to assign to the core region of the star | 1 | -| envelope_id | The material ID to assign to the envelope region of the star | 2 | -| vacuum_id | The material ID to assign to the vacuum region of the star (if included) | 3 | +| Parameter | Description | Default | +|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| +| refinement_levels | Number of uniform refinement levels to apply to the mesh after generation | 4 | +| order | The polynomial order of the finite elements in the mesh | 3 | +| include_external_domain | Whether to include an external domain extending to r_infinity | true | +| r_core | The radius of the core region of the star | 1.5 | +| r_star | The radius of the star | 5.0 | +| flattening | The flattening factor of the star (0 for spherical, >0 for oblate) | 0 | +| r_infinity | The outer radius of the external domain (if included) | 6.0 | +| r_instability | The radius at which no transformations are applied to the initial topology (to avoid singularities) | 1e-14 | +| core_steepness | The steepness of the transition between the core and envelope regions of the star | 1.0 | +| surface_bdr_id | The boundary ID to assign to the surface of the star | 1 | +| inf_bdr_id | The boundary ID to assign to the outer boundary of the external domain (if included) | 2 | +| core_id | The material ID to assign to the core region of the star | 1 | +| envelope_id | The material ID to assign to the envelope region of the star | 2 | +| vacuum_id | The material ID to assign to the vacuum region of the star (if included) | 3 | +| optimization_methods.tmop | The tmop flag enables or disables the use of TMOP ideal shape unit size metric optimization during mesh generation. This can help improve the quality of the generated mesh, but will dramatically increase the time required for mesh generation. | false | +| optimization_methods.smoothstep | The smoothstep flag enables or disables the use of a smoothstep function to transition between the core and envelope regions of the star. This can help improve the quality of the generated mesh | true | If no configuration file is provided, stroid will use the default parameters listed above. Further, configuration files @@ -138,6 +144,7 @@ int main() { stroid::topology::Finalize(*mesh, cfg); stroid::topology::PromoteToHighOrder(*mesh, cfg); stroid::topology::ProjectMesh(*mesh, cfg); + stroid::topology::OptimizeMesh(*mesh, cfg); stroid::IO::ViewMesh(*mesh, "Spheroidal Mesh", stroid::IO::VISUALIZATION_MODE::BOUNDARY_ELEMENT_ID); diff --git a/src/include/stroid/topology/optimize.h b/src/include/stroid/topology/optimize.h index af44e95..85571d5 100644 --- a/src/include/stroid/topology/optimize.h +++ b/src/include/stroid/topology/optimize.h @@ -11,4 +11,9 @@ namespace stroid::topology { * @breif Apply target matrix optimization to improve conditioning of the mesh */ void ApplyTMOP(mfem::Mesh& mesh, const fourdst::config::Config &config); + + /** + *@breif Helper to call TMOP if the correct flags are set + */ + void OptimizeMesh(mfem::Mesh& mesh, const fourdst::config::Config &cfg); } diff --git a/src/lib/topology/optimize.cpp b/src/lib/topology/optimize.cpp index 3e9db8a..8d5a66b 100644 --- a/src/lib/topology/optimize.cpp +++ b/src/lib/topology/optimize.cpp @@ -228,4 +228,10 @@ class TMOPProgressBar : public mfem::IterativeSolverMonitor { delete metric; delete target_c; } + + void OptimizeMesh(mfem::Mesh& mesh, const fourdst::config::Config &cfg) { + if (cfg->optimization_methods.has_value() && cfg->optimization_methods.value().tmop.has_value() && cfg->optimization_methods.value().tmop.value()) { + ApplyTMOP(mesh, cfg); + } + } } diff --git a/subprojects/libconfig.wrap b/subprojects/libconfig.wrap index 154b33d..6965883 100644 --- a/subprojects/libconfig.wrap +++ b/subprojects/libconfig.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://github.com/4D-STAR/libconfig.git -revision = v2.2.1 +revision = v2.2.2 depth = 1 diff --git a/tools/stroid.cpp b/tools/stroid.cpp index 67ad25d..8286e82 100644 --- a/tools/stroid.cpp +++ b/tools/stroid.cpp @@ -66,8 +66,10 @@ int main(int argc, char** argv) { auto* generate = app.add_subcommand("generate", "Generate a multi-block mesh"); auto* info = app.add_subcommand("info", "Access information about stroid"); + auto* view = app.add_subcommand("view", "Display a mesh with glvis"); std::optional config_filename; + std::optional mesh_file; std::string output_filename = "stroid.mesh"; bool view_mesh = false; bool no_save = false; @@ -81,6 +83,39 @@ int main(int argc, char** argv) { generate->add_option("--glvis-port", glvis_port, "GLVis server port")->capture_default_str(); generate->add_option("-o,--output", output_filename, "Output filename base")->capture_default_str(); + view->add_option("--host", glvis_host, "GLVis server host")->capture_default_str(); + view->add_option("--port", glvis_port, "GLVis server port")->capture_default_str(); + view->add_option("-f,--file", mesh_file, "Path to .mesh file")->check(CLI::ExistingFile); + + auto to_lower = [](std::string s) { + std::string out; + out.reserve(s.size()); + std::ranges::transform(s, std::back_inserter(out), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + return out; + }; + + std::map mode_map; + for (auto [value, name] : magic_enum::enum_entries()) { + mode_map[to_lower(std::string(name))] = value; + } + + // 2. Storage variable is now the actual Enum type + stroid::IO::VISUALIZATION_MODE selected_mode; + + // 3. One line to rule them all + view->add_option("-v,--vis-mode", selected_mode, "Select Visualization mode") + ->transform(CLI::CheckedTransformer(mode_map, CLI::ignore_case)) + ->default_val(stroid::IO::VISUALIZATION_MODE::ELEMENT_ID); + view->add_flag_callback("-l,--list", [&]() { + std::println("Available Visualization Modes:"); + for (const auto &name: mode_map | std::views::keys) { + std::println("\t - {}", name); + } + exit(0); + }); + for (auto [value, name_view] : magic_enum::enum_entries()) { std::string name{name_view}; std::ranges::transform(name, name.begin(), ::tolower); @@ -127,6 +162,20 @@ int main(int argc, char** argv) { return app.exit(e); } + if (*view) { + if (!mesh_file.has_value()) { + throw std::runtime_error("Mesh file must be specified"); + } + mfem::Mesh mesh(mesh_file.value().c_str()); + stroid::IO::ViewMesh(mesh, + "Mesh Viewer - Colored by Element ID", + selected_mode, + glvis_host, + glvis_port); + exit(0); + + } + if (*generate) { if (config_filename.has_value()) { cfg.load(config_filename.value()); @@ -137,11 +186,7 @@ int main(int argc, char** argv) { stroid::topology::Finalize(*mesh, cfg); stroid::topology::PromoteToHighOrder(*mesh, cfg); stroid::topology::ProjectMesh(*mesh, cfg); - if (cfg->optimization_methods.has_value() && cfg->optimization_methods.value().tmop.has_value() && cfg->optimization_methods.value().tmop.value()) { - stroid::topology::ApplyTMOP(*mesh, cfg); - } - - + stroid::topology::OptimizeMesh(*mesh, cfg); if (!no_save) { const std::string& final_path = output_filename; @@ -201,7 +246,7 @@ int main(int argc, char** argv) { glvis_port); } } else if (!*info) { - std::println("Usage: {} [generate|info] --help", argv[0]); + std::println("Usage: {} [generate|info|view] --help", argv[0]); } return 0;