diff --git a/Doxyfile b/Doxyfile index 0124adc..7799517 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.1.0 +PROJECT_NUMBER = v0.2.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/configs/default_config.toml b/configs/default_config.toml index 110ff95..f43489f 100644 --- a/configs/default_config.toml +++ b/configs/default_config.toml @@ -2,9 +2,14 @@ core_steepness = 1.0 flattening = 0.0 include_external_domain = false +inf_bdr_id = 2 order = 3 r_core = 1.5 r_infinity = 6.0 r_instability = 1e-14 r_star = 5.0 -refinement_levels = 4 \ No newline at end of file +refinement_levels = 4 +surface_bdr_id = 1 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 diff --git a/configs/test_external_domain.toml b/configs/test_external_domain.toml index 90b89bb..fc5c0d4 100644 --- a/configs/test_external_domain.toml +++ b/configs/test_external_domain.toml @@ -2,9 +2,14 @@ core_steepness = 1.0 flattening = 0.0 include_external_domain = true +inf_bdr_id = 2 order = 3 r_core = 1.5 r_infinity = 6.0 r_instability = 1e-14 r_star = 5.0 refinement_levels = 4 +surface_bdr_id = 1 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 diff --git a/configs/test_external_domain_refinement_l1.toml b/configs/test_external_domain_refinement_l1.toml new file mode 100644 index 0000000..bfe469c --- /dev/null +++ b/configs/test_external_domain_refinement_l1.toml @@ -0,0 +1,16 @@ +[main] +core_steepness = 1.0 +flattening = 0.0 +include_external_domain = true +inf_bdr_id = 2 +order = 3 +r_core = 1.5 +r_infinity = 6.0 +r_instability = 1e-14 +r_star = 5.0 +refinement_levels = 1 +surface_bdr_id = 1 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 + diff --git a/configs/test_flattening.toml b/configs/test_flattening.toml index e3af871..0eaf396 100644 --- a/configs/test_flattening.toml +++ b/configs/test_flattening.toml @@ -2,9 +2,14 @@ core_steepness = 1.0 flattening = 0.2 include_external_domain = false +inf_bdr_id = 2 order = 3 r_core = 1.5 r_infinity = 6.0 r_instability = 1e-14 r_star = 5.0 refinement_levels = 4 +surface_bdr_id = 1 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 diff --git a/configs/test_refinement_l2.toml b/configs/test_refinement_l2.toml new file mode 100644 index 0000000..fd61a99 --- /dev/null +++ b/configs/test_refinement_l2.toml @@ -0,0 +1,16 @@ +[main] +core_steepness = 1.0 +flattening = 0.0 +include_external_domain = false +inf_bdr_id = 2 +order = 3 +r_core = 1.5 +r_infinity = 6.0 +r_instability = 1e-14 +r_star = 5.0 +refinement_levels = 2 +surface_bdr_id = 1 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 + diff --git a/configs/test_volume_no_external.toml b/configs/test_volume_no_external.toml new file mode 100644 index 0000000..cf86efc --- /dev/null +++ b/configs/test_volume_no_external.toml @@ -0,0 +1,16 @@ +[main] +refinement_levels = 2 +order = 3 +include_external_domain = false +r_core = 1.5 +r_star = 5.0 +flattening = 0.08 +r_infinity = 6.0 +r_instability = 1e-14 +core_steepness = 1.0 +surface_bdr_id = 1 +inf_bdr_id = 2 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 + diff --git a/configs/test_volume_spherical_no_external.toml b/configs/test_volume_spherical_no_external.toml new file mode 100644 index 0000000..456ed85 --- /dev/null +++ b/configs/test_volume_spherical_no_external.toml @@ -0,0 +1,16 @@ +[main] +refinement_levels = 2 +order = 3 +include_external_domain = false +r_core = 1.5 +r_star = 5.0 +flattening = 0.0 +r_infinity = 6.0 +r_instability = 1e-14 +core_steepness = 1.0 +surface_bdr_id = 1 +inf_bdr_id = 2 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 + diff --git a/configs/test_volume_spherical_with_external.toml b/configs/test_volume_spherical_with_external.toml new file mode 100644 index 0000000..10bc77e --- /dev/null +++ b/configs/test_volume_spherical_with_external.toml @@ -0,0 +1,16 @@ +[main] +refinement_levels = 2 +order = 3 +include_external_domain = true +r_core = 1.5 +r_star = 5.0 +flattening = 0.0 +r_infinity = 6.0 +r_instability = 1e-14 +core_steepness = 1.0 +surface_bdr_id = 1 +inf_bdr_id = 2 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 + diff --git a/configs/test_volume_with_external.toml b/configs/test_volume_with_external.toml new file mode 100644 index 0000000..617a2c7 --- /dev/null +++ b/configs/test_volume_with_external.toml @@ -0,0 +1,16 @@ +[main] +refinement_levels = 2 +order = 3 +include_external_domain = true +r_core = 1.5 +r_star = 5.0 +flattening = 0.08 +r_infinity = 6.0 +r_instability = 1e-14 +core_steepness = 1.0 +surface_bdr_id = 1 +inf_bdr_id = 2 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 + diff --git a/docs/html/_logo_8png.html b/docs/html/_logo_8png.html index 65f9a4c..5b25451 100644 --- a/docs/html/_logo_8png.html +++ b/docs/html/_logo_8png.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/annotated.html b/docs/html/annotated.html index 1726115..d1ad2ce 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/classes.html b/docs/html/classes.html index f2b564b..409af46 100644 --- a/docs/html/classes.html +++ b/docs/html/classes.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/config_8h.html b/docs/html/config_8h.html index 257814d..b25291e 100644 --- a/docs/html/config_8h.html +++ b/docs/html/config_8h.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/curvilinear_8cpp.html b/docs/html/curvilinear_8cpp.html index 59d7671..0034dc5 100644 --- a/docs/html/curvilinear_8cpp.html +++ b/docs/html/curvilinear_8cpp.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
@@ -111,10 +111,11 @@ $(function(){initNavTree('curvilinear_8cpp.html',''); initResizable(true); }); #include "stroid/topology/mapping.h"
#include <iostream>
#include <memory>
+#include <sys/proc.h>
Include dependency graph for curvilinear.cpp:
-
+
diff --git a/docs/html/dir_000004_000002.html b/docs/html/dir_000004_000002.html index b809222..41d633c 100644 --- a/docs/html/dir_000004_000002.html +++ b/docs/html/dir_000004_000002.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_000005_000002.html b/docs/html/dir_000005_000002.html index 934a8c7..961e47a 100644 --- a/docs/html/dir_000005_000002.html +++ b/docs/html/dir_000005_000002.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_000009_000000.html b/docs/html/dir_000009_000000.html index 9f0dbcf..018e4f5 100644 --- a/docs/html/dir_000009_000000.html +++ b/docs/html/dir_000009_000000.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_000010_000002.html b/docs/html/dir_000010_000002.html index 0a4b76d..0f19dd9 100644 --- a/docs/html/dir_000010_000002.html +++ b/docs/html/dir_000010_000002.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_000012_000002.html b/docs/html/dir_000012_000002.html index d5c4ba4..7f2c45c 100644 --- a/docs/html/dir_000012_000002.html +++ b/docs/html/dir_000012_000002.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_31a6c70da1404d38d1b51e38b19548a1.html b/docs/html/dir_31a6c70da1404d38d1b51e38b19548a1.html index 4697d9c..e2cf351 100644 --- a/docs/html/dir_31a6c70da1404d38d1b51e38b19548a1.html +++ b/docs/html/dir_31a6c70da1404d38d1b51e38b19548a1.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_3f4f28e99864f6e7d54ad0c93ce0a2a5.html b/docs/html/dir_3f4f28e99864f6e7d54ad0c93ce0a2a5.html index fe0cbba..622b183 100644 --- a/docs/html/dir_3f4f28e99864f6e7d54ad0c93ce0a2a5.html +++ b/docs/html/dir_3f4f28e99864f6e7d54ad0c93ce0a2a5.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_49e56c817e5e54854c35e136979f97ca.html b/docs/html/dir_49e56c817e5e54854c35e136979f97ca.html index 34104b1..006a472 100644 --- a/docs/html/dir_49e56c817e5e54854c35e136979f97ca.html +++ b/docs/html/dir_49e56c817e5e54854c35e136979f97ca.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/docs/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html index d0e56a7..7b29cbc 100644 --- a/docs/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html +++ b/docs/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_82887d4f338e92537fa9d809bec8c614.html b/docs/html/dir_82887d4f338e92537fa9d809bec8c614.html index fb29305..a076755 100644 --- a/docs/html/dir_82887d4f338e92537fa9d809bec8c614.html +++ b/docs/html/dir_82887d4f338e92537fa9d809bec8c614.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_87d18a4dc5174905bfd7d2dc734defe6.html b/docs/html/dir_87d18a4dc5174905bfd7d2dc734defe6.html index 49bb0e5..03d0d9a 100644 --- a/docs/html/dir_87d18a4dc5174905bfd7d2dc734defe6.html +++ b/docs/html/dir_87d18a4dc5174905bfd7d2dc734defe6.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_936721fd6a792737eaef7358bcd49428.html b/docs/html/dir_936721fd6a792737eaef7358bcd49428.html index 698914a..431306a 100644 --- a/docs/html/dir_936721fd6a792737eaef7358bcd49428.html +++ b/docs/html/dir_936721fd6a792737eaef7358bcd49428.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_9d5018b9ddb63a582aa4c6b91bec2f8c.html b/docs/html/dir_9d5018b9ddb63a582aa4c6b91bec2f8c.html index 45d405e..8f852de 100644 --- a/docs/html/dir_9d5018b9ddb63a582aa4c6b91bec2f8c.html +++ b/docs/html/dir_9d5018b9ddb63a582aa4c6b91bec2f8c.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_9da86e8abab39b749c6020360d8e4403.html b/docs/html/dir_9da86e8abab39b749c6020360d8e4403.html index 23e666a..9e3aebf 100644 --- a/docs/html/dir_9da86e8abab39b749c6020360d8e4403.html +++ b/docs/html/dir_9da86e8abab39b749c6020360d8e4403.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_b0856f6b0d80ccb263b2f415c91f9e17.html b/docs/html/dir_b0856f6b0d80ccb263b2f415c91f9e17.html index c7d0bb0..969097a 100644 --- a/docs/html/dir_b0856f6b0d80ccb263b2f415c91f9e17.html +++ b/docs/html/dir_b0856f6b0d80ccb263b2f415c91f9e17.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_c34d5e8363cf0aa3fabc4f3fad3412a4.html b/docs/html/dir_c34d5e8363cf0aa3fabc4f3fad3412a4.html index 51e1c3e..622729c 100644 --- a/docs/html/dir_c34d5e8363cf0aa3fabc4f3fad3412a4.html +++ b/docs/html/dir_c34d5e8363cf0aa3fabc4f3fad3412a4.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_c85d3e3c5052e9ad9ce18c6863244a25.html b/docs/html/dir_c85d3e3c5052e9ad9ce18c6863244a25.html index 039e264..aaafd14 100644 --- a/docs/html/dir_c85d3e3c5052e9ad9ce18c6863244a25.html +++ b/docs/html/dir_c85d3e3c5052e9ad9ce18c6863244a25.html @@ -31,7 +31,7 @@ diff --git a/docs/html/dir_dc36fd7496f87f6989d6d6a9445d600c.html b/docs/html/dir_dc36fd7496f87f6989d6d6a9445d600c.html index 9e4fe8a..b12ada7 100644 --- a/docs/html/dir_dc36fd7496f87f6989d6d6a9445d600c.html +++ b/docs/html/dir_dc36fd7496f87f6989d6d6a9445d600c.html @@ -31,7 +31,7 @@ diff --git a/docs/html/doxygen_crawl.html b/docs/html/doxygen_crawl.html index 2f6cc12..b1a22fc 100644 --- a/docs/html/doxygen_crawl.html +++ b/docs/html/doxygen_crawl.html @@ -83,12 +83,17 @@ + + + + + diff --git a/docs/html/files.html b/docs/html/files.html index f6fb948..009efdf 100644 --- a/docs/html/files.html +++ b/docs/html/files.html @@ -31,7 +31,7 @@ diff --git a/docs/html/functions.html b/docs/html/functions.html index 6a52b83..d8a6ec2 100644 --- a/docs/html/functions.html +++ b/docs/html/functions.html @@ -31,7 +31,7 @@ @@ -102,15 +102,20 @@ $(function(){initNavTree('functions.html',''); initResizable(true); }); diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html index 56ad7d4..faeec47 100644 --- a/docs/html/functions_vars.html +++ b/docs/html/functions_vars.html @@ -31,7 +31,7 @@ @@ -102,15 +102,20 @@ $(function(){initNavTree('functions_vars.html',''); initResizable(true); });
Here is a list of all variables with links to the classes they belong to:
diff --git a/docs/html/graph_legend.html b/docs/html/graph_legend.html index e58cc71..0ef7558 100644 --- a/docs/html/graph_legend.html +++ b/docs/html/graph_legend.html @@ -31,7 +31,7 @@ diff --git a/docs/html/index.html b/docs/html/index.html index 56d6f16..971ca54 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -31,7 +31,7 @@ @@ -150,15 +150,20 @@ Running Configuration File

Stroid uses a TOML configuration file to specify the parameters for mesh generation. An example configuration file is found below

[main]
-
core_steepness = 1.0
-
flattening = 0.0
-
include_external_domain = false
+
refinement_levels = 2
order = 3
+
include_external_domain = true
r_core = 1.5
+
r_star = 5.0
+
flattening = 0.08
r_infinity = 6.0
r_instability = 1e-14
-
r_star = 5.0
-
refinement_levels = 4
+
core_steepness = 1.0
+
surface_bdr_id = 1
+
inf_bdr_id = 2
+
core_id = 1
+
envelope_id = 2
+
vacuum_id = 3

diff --git a/docs/html/curvilinear_8cpp__incl.map b/docs/html/curvilinear_8cpp__incl.map index 14961d1..dfbbeaa 100644 --- a/docs/html/curvilinear_8cpp__incl.map +++ b/docs/html/curvilinear_8cpp__incl.map @@ -1,20 +1,22 @@ - - - - - - - - - + + + + + + + + + + + - + - + - - - - + + + + diff --git a/docs/html/curvilinear_8cpp__incl.md5 b/docs/html/curvilinear_8cpp__incl.md5 index 7359c47..eb20556 100644 --- a/docs/html/curvilinear_8cpp__incl.md5 +++ b/docs/html/curvilinear_8cpp__incl.md5 @@ -1 +1 @@ -b8eef4875e081be998fbcbc84a3978b1 \ No newline at end of file +6950d4e2891a4c4f47ed638d27c5bf68 \ No newline at end of file diff --git a/docs/html/curvilinear_8cpp__incl.svg b/docs/html/curvilinear_8cpp__incl.svg index 11516ce..ba0748f 100644 --- a/docs/html/curvilinear_8cpp__incl.svg +++ b/docs/html/curvilinear_8cpp__incl.svg @@ -1,13 +1,12 @@ - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + src/lib/topology/curvilinear.cpp Node1 - -src/lib/topology/curvilinear.cpp + +src/lib/topology/curvilinear.cpp @@ -32,8 +68,8 @@ Node2 - -stroid/topology/curvilinear.h + +stroid/topology/curvilinear.h @@ -41,8 +77,8 @@ Node1->Node2 - - + + @@ -50,8 +86,8 @@ Node6 - -stroid/topology/mapping.h + +stroid/topology/mapping.h @@ -59,8 +95,8 @@ Node1->Node6 - - + + @@ -68,8 +104,8 @@ Node7 - -iostream + +iostream @@ -77,8 +113,8 @@ Node1->Node7 - - + + @@ -86,8 +122,8 @@ Node8 - -memory + +memory @@ -95,8 +131,26 @@ Node1->Node8 - - + + + + + + + +Node9 + + +sys/proc.h + + + + + +Node1->Node9 + + + @@ -113,8 +167,8 @@ Node2->Node3 - - + + @@ -131,8 +185,8 @@ Node2->Node4 - - + + @@ -149,8 +203,8 @@ Node2->Node5 - - + + @@ -158,8 +212,8 @@ Node6->Node3 - - + + @@ -167,8 +221,8 @@ Node6->Node4 - - + + @@ -176,13 +230,34 @@ Node6->Node5 - - + + + + + + + + + + + + + + + + + + + + Logo

-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
-
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
@@ -167,7 +172,7 @@ Configuration File - + @@ -179,7 +184,17 @@ Configuration File - + + + + + + + + + + +
Parameter Description Default
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 false
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_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
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

If no configuration file is provided, stroid will use the default parameters listed above. Further, configuration files need only include parameters that differ from the defaults, any parameters not specified will use the default values.

@@ -211,9 +226,9 @@ C++ Interface

void ViewMesh(mfem::Mesh &mesh, const std::string &title, VISUALIZATION_MODE mode, const std::string &vishost, int visport)
Stream a mesh to a running GLVis server for interactive viewing.
Definition mesh.cpp:25
@ BOUNDARY_ELEMENT_ID
Color boundary-adjacent elements by boundary attribute/ID.
Definition mesh.h:15
-
void PromoteToHighOrder(mfem::Mesh &mesh, const fourdst::config::Config< config::MeshConfig > &config)
Promote a mesh to high-order by attaching an H1 nodal finite element space.
Definition curvilinear.cpp:8
-
void Finalize(mfem::Mesh &mesh, const fourdst::config::Config< config::MeshConfig > &config)
Finalize topology, validate orientation, and apply uniform refinement.
Definition topology.cpp:59
-
void ProjectMesh(mfem::Mesh &mesh, const fourdst::config::Config< config::MeshConfig > &config)
Project high-order mesh nodes using the configured curvilinear mapping.
Definition curvilinear.cpp:14
+
void PromoteToHighOrder(mfem::Mesh &mesh, const fourdst::config::Config< config::MeshConfig > &config)
Promote a mesh to high-order by attaching an H1 nodal finite element space.
Definition curvilinear.cpp:9
+
void Finalize(mfem::Mesh &mesh, const fourdst::config::Config< config::MeshConfig > &config)
Finalize topology, validate orientation, and apply uniform refinement.
Definition topology.cpp:90
+
void ProjectMesh(mfem::Mesh &mesh, const fourdst::config::Config< config::MeshConfig > &config)
Project high-order mesh nodes using the configured curvilinear mapping.
Definition curvilinear.cpp:15
std::unique_ptr< mfem::Mesh > BuildSkeleton(const fourdst::config::Config< config::MeshConfig > &config)
Build the initial multi-block mesh topology for the star model.
Definition topology.cpp:10

diff --git a/docs/html/mainpage_8md.html b/docs/html/mainpage_8md.html index 7fd3c98..402a917 100644 --- a/docs/html/mainpage_8md.html +++ b/docs/html/mainpage_8md.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/mapping_8cpp.html b/docs/html/mapping_8cpp.html index 5fa4076..3ba75c9 100644 --- a/docs/html/mapping_8cpp.html +++ b/docs/html/mapping_8cpp.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
@@ -131,9 +131,6 @@ Functions

void stroid::topology::ApplySpheroidal (mfem::Vector &pos, const fourdst::config::Config< config::MeshConfig > &config)  Apply spheroidal flattening along the Z axis.
  -void stroid::topology::ApplyKelvin (mfem::Vector &pos, const fourdst::config::Config< config::MeshConfig > &config) - Apply Kelvin transform outside the stellar radius.
-  void stroid::topology::TransformPoint (mfem::Vector &pos, const fourdst::config::Config< config::MeshConfig > &config, int attribute_id)  Map a point from the initial block topology to the curvilinear domain.
  diff --git a/docs/html/mapping_8cpp.js b/docs/html/mapping_8cpp.js index fbbc436..cc17306 100644 --- a/docs/html/mapping_8cpp.js +++ b/docs/html/mapping_8cpp.js @@ -1,7 +1,6 @@ var mapping_8cpp = [ [ "stroid::topology::ApplyEquiangular", "namespacestroid_1_1topology.html#a03f0b29ccf7d427a175de9ff75824b7c", null ], - [ "stroid::topology::ApplyKelvin", "namespacestroid_1_1topology.html#a59c54a10f726d323f8506b4a2edd7467", null ], [ "stroid::topology::ApplySpheroidal", "namespacestroid_1_1topology.html#a7fbf58c40c03bc751d53f4a3273744fc", null ], [ "stroid::topology::TransformPoint", "namespacestroid_1_1topology.html#a394e33bdfafdaccd6edfaae0642d3456", null ] ]; \ No newline at end of file diff --git a/docs/html/mapping_8h.html b/docs/html/mapping_8h.html index 104fbbd..d003e76 100644 --- a/docs/html/mapping_8h.html +++ b/docs/html/mapping_8h.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/mesh_8cpp.html b/docs/html/mesh_8cpp.html index 72aa9b1..5251183 100644 --- a/docs/html/mesh_8cpp.html +++ b/docs/html/mesh_8cpp.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/mesh_8h.html b/docs/html/mesh_8h.html index 6f391d0..a77697e 100644 --- a/docs/html/mesh_8h.html +++ b/docs/html/mesh_8h.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/mesh__utils_8cpp.html b/docs/html/mesh__utils_8cpp.html index 1fcb5b5..424e402 100644 --- a/docs/html/mesh__utils_8cpp.html +++ b/docs/html/mesh__utils_8cpp.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/mesh__utils_8h.html b/docs/html/mesh__utils_8h.html index d56fb2d..4e76db2 100644 --- a/docs/html/mesh__utils_8h.html +++ b/docs/html/mesh__utils_8h.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespacemembers.html b/docs/html/namespacemembers.html index ac43679..631e2d5 100644 --- a/docs/html/namespacemembers.html +++ b/docs/html/namespacemembers.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespacemembers_enum.html b/docs/html/namespacemembers_enum.html index 89d4bd9..445249f 100644 --- a/docs/html/namespacemembers_enum.html +++ b/docs/html/namespacemembers_enum.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespacemembers_func.html b/docs/html/namespacemembers_func.html index 1ea31fb..d5585f4 100644 --- a/docs/html/namespacemembers_func.html +++ b/docs/html/namespacemembers_func.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespaces.html b/docs/html/namespaces.html index 3e7f362..2264a17 100644 --- a/docs/html/namespaces.html +++ b/docs/html/namespaces.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespacestroid.html b/docs/html/namespacestroid.html index 233eab8..dae297b 100644 --- a/docs/html/namespacestroid.html +++ b/docs/html/namespacestroid.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespacestroid_1_1_i_o.html b/docs/html/namespacestroid_1_1_i_o.html index 3250e30..e240f36 100644 --- a/docs/html/namespacestroid_1_1_i_o.html +++ b/docs/html/namespacestroid_1_1_i_o.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespacestroid_1_1config.html b/docs/html/namespacestroid_1_1config.html index 22b562b..6f3e378 100644 --- a/docs/html/namespacestroid_1_1config.html +++ b/docs/html/namespacestroid_1_1config.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespacestroid_1_1topology.html b/docs/html/namespacestroid_1_1topology.html index be81d3f..4f75b08 100644 --- a/docs/html/namespacestroid_1_1topology.html +++ b/docs/html/namespacestroid_1_1topology.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/namespacestroid_1_1utils.html b/docs/html/namespacestroid_1_1utils.html index 6d35d01..73605cc 100644 --- a/docs/html/namespacestroid_1_1utils.html +++ b/docs/html/namespacestroid_1_1utils.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/navtreeindex0.js b/docs/html/navtreeindex0.js index 869f13f..1918b57 100644 --- a/docs/html/navtreeindex0.js +++ b/docs/html/navtreeindex0.js @@ -67,24 +67,34 @@ var NAVTREEINDEX0 = "pages.html":[], "structstroid_1_1config_1_1_mesh_config.html":[3,0,0,0,0], "structstroid_1_1config_1_1_mesh_config.html":[4,0,0,0,0], -"structstroid_1_1config_1_1_mesh_config.html#a062652781f4f3ea0b7ca8764362a7368":[3,0,0,0,0,2], -"structstroid_1_1config_1_1_mesh_config.html#a062652781f4f3ea0b7ca8764362a7368":[4,0,0,0,0,2], -"structstroid_1_1config_1_1_mesh_config.html#a3fe80a30990d484dcc39b6f9a0befc05":[3,0,0,0,0,7], -"structstroid_1_1config_1_1_mesh_config.html#a3fe80a30990d484dcc39b6f9a0befc05":[4,0,0,0,0,7], -"structstroid_1_1config_1_1_mesh_config.html#a4da6d99ff7ba24d2f917e1fd98ddd877":[3,0,0,0,0,6], -"structstroid_1_1config_1_1_mesh_config.html#a4da6d99ff7ba24d2f917e1fd98ddd877":[4,0,0,0,0,6], -"structstroid_1_1config_1_1_mesh_config.html#a5c68a895f73dc82a38a8daac22a83ad7":[3,0,0,0,0,4], -"structstroid_1_1config_1_1_mesh_config.html#a5c68a895f73dc82a38a8daac22a83ad7":[4,0,0,0,0,4], -"structstroid_1_1config_1_1_mesh_config.html#a860e78f1906acb0c3aa08d55f94de3fd":[3,0,0,0,0,3], -"structstroid_1_1config_1_1_mesh_config.html#a860e78f1906acb0c3aa08d55f94de3fd":[4,0,0,0,0,3], -"structstroid_1_1config_1_1_mesh_config.html#a8cafcbebf64ae251517118eb152de981":[3,0,0,0,0,8], -"structstroid_1_1config_1_1_mesh_config.html#a8cafcbebf64ae251517118eb152de981":[4,0,0,0,0,8], -"structstroid_1_1config_1_1_mesh_config.html#ac7546899ebbfe191ea3a8bf2403b31eb":[3,0,0,0,0,5], -"structstroid_1_1config_1_1_mesh_config.html#ac7546899ebbfe191ea3a8bf2403b31eb":[4,0,0,0,0,5], -"structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d":[3,0,0,0,0,0], -"structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d":[4,0,0,0,0,0], -"structstroid_1_1config_1_1_mesh_config.html#affad4638b0ae7b710f2b2db992f6f584":[3,0,0,0,0,1], -"structstroid_1_1config_1_1_mesh_config.html#affad4638b0ae7b710f2b2db992f6f584":[4,0,0,0,0,1], +"structstroid_1_1config_1_1_mesh_config.html#a062652781f4f3ea0b7ca8764362a7368":[3,0,0,0,0,4], +"structstroid_1_1config_1_1_mesh_config.html#a062652781f4f3ea0b7ca8764362a7368":[4,0,0,0,0,4], +"structstroid_1_1config_1_1_mesh_config.html#a2faa5aa1fef84ebbda30590d3fb2799b":[3,0,0,0,0,0], +"structstroid_1_1config_1_1_mesh_config.html#a2faa5aa1fef84ebbda30590d3fb2799b":[4,0,0,0,0,0], +"structstroid_1_1config_1_1_mesh_config.html#a33f25ff277aa8834065e04ccb9cdbdda":[3,0,0,0,0,12], +"structstroid_1_1config_1_1_mesh_config.html#a33f25ff277aa8834065e04ccb9cdbdda":[4,0,0,0,0,12], +"structstroid_1_1config_1_1_mesh_config.html#a36c7b05405691393d381086a27ea36ad":[3,0,0,0,0,13], +"structstroid_1_1config_1_1_mesh_config.html#a36c7b05405691393d381086a27ea36ad":[4,0,0,0,0,13], +"structstroid_1_1config_1_1_mesh_config.html#a3fe80a30990d484dcc39b6f9a0befc05":[3,0,0,0,0,10], +"structstroid_1_1config_1_1_mesh_config.html#a3fe80a30990d484dcc39b6f9a0befc05":[4,0,0,0,0,10], +"structstroid_1_1config_1_1_mesh_config.html#a4da6d99ff7ba24d2f917e1fd98ddd877":[3,0,0,0,0,9], +"structstroid_1_1config_1_1_mesh_config.html#a4da6d99ff7ba24d2f917e1fd98ddd877":[4,0,0,0,0,9], +"structstroid_1_1config_1_1_mesh_config.html#a5c68a895f73dc82a38a8daac22a83ad7":[3,0,0,0,0,7], +"structstroid_1_1config_1_1_mesh_config.html#a5c68a895f73dc82a38a8daac22a83ad7":[4,0,0,0,0,7], +"structstroid_1_1config_1_1_mesh_config.html#a64cb00c8cba27267279a52207a4b5be0":[3,0,0,0,0,5], +"structstroid_1_1config_1_1_mesh_config.html#a64cb00c8cba27267279a52207a4b5be0":[4,0,0,0,0,5], +"structstroid_1_1config_1_1_mesh_config.html#a860e78f1906acb0c3aa08d55f94de3fd":[3,0,0,0,0,6], +"structstroid_1_1config_1_1_mesh_config.html#a860e78f1906acb0c3aa08d55f94de3fd":[4,0,0,0,0,6], +"structstroid_1_1config_1_1_mesh_config.html#a8cafcbebf64ae251517118eb152de981":[3,0,0,0,0,11], +"structstroid_1_1config_1_1_mesh_config.html#a8cafcbebf64ae251517118eb152de981":[4,0,0,0,0,11], +"structstroid_1_1config_1_1_mesh_config.html#ac7546899ebbfe191ea3a8bf2403b31eb":[3,0,0,0,0,8], +"structstroid_1_1config_1_1_mesh_config.html#ac7546899ebbfe191ea3a8bf2403b31eb":[4,0,0,0,0,8], +"structstroid_1_1config_1_1_mesh_config.html#ac99aa48fe3e71e2ef57b09d48cacfef8":[3,0,0,0,0,2], +"structstroid_1_1config_1_1_mesh_config.html#ac99aa48fe3e71e2ef57b09d48cacfef8":[4,0,0,0,0,2], +"structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d":[3,0,0,0,0,1], +"structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d":[4,0,0,0,0,1], +"structstroid_1_1config_1_1_mesh_config.html#affad4638b0ae7b710f2b2db992f6f584":[3,0,0,0,0,3], +"structstroid_1_1config_1_1_mesh_config.html#affad4638b0ae7b710f2b2db992f6f584":[4,0,0,0,0,3], "topology_8cpp.html":[5,0,1,1,1,2], "topology_8h.html":[5,0,1,0,0,2,2] }; diff --git a/docs/html/search/all_2.js b/docs/html/search/all_2.js index b596d77..507bf3a 100644 --- a/docs/html/search/all_2.js +++ b/docs/html/search/all_2.js @@ -3,7 +3,8 @@ var searchData= ['c_20interface_0',['C++ Interface',['../index.html#autotoc_md7',1,'']]], ['config_2eh_1',['config.h',['../config_8h.html',1,'']]], ['configuration_20file_2',['Configuration File',['../index.html#autotoc_md6',1,'']]], - ['core_5fsteepness_3',['core_steepness',['../structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d',1,'stroid::config::MeshConfig']]], - ['curvilinear_2ecpp_4',['curvilinear.cpp',['../curvilinear_8cpp.html',1,'']]], - ['curvilinear_2eh_5',['curvilinear.h',['../curvilinear_8h.html',1,'']]] + ['core_5fid_3',['core_id',['../structstroid_1_1config_1_1_mesh_config.html#a2faa5aa1fef84ebbda30590d3fb2799b',1,'stroid::config::MeshConfig']]], + ['core_5fsteepness_4',['core_steepness',['../structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d',1,'stroid::config::MeshConfig']]], + ['curvilinear_2ecpp_5',['curvilinear.cpp',['../curvilinear_8cpp.html',1,'']]], + ['curvilinear_2eh_6',['curvilinear.h',['../curvilinear_8h.html',1,'']]] ]; diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js index 4894a43..fea5a2f 100644 --- a/docs/html/search/all_3.js +++ b/docs/html/search/all_3.js @@ -1,4 +1,5 @@ var searchData= [ - ['element_5fid_0',['ELEMENT_ID',['../namespacestroid_1_1_i_o.html#ad4048304d8a0c7075d2b2a6e465d0b6eac31a2fe3e97d218a154c1947b43d6bbf',1,'stroid::IO']]] + ['element_5fid_0',['ELEMENT_ID',['../namespacestroid_1_1_i_o.html#ad4048304d8a0c7075d2b2a6e465d0b6eac31a2fe3e97d218a154c1947b43d6bbf',1,'stroid::IO']]], + ['envelope_5fid_1',['envelope_id',['../structstroid_1_1config_1_1_mesh_config.html#ac99aa48fe3e71e2ef57b09d48cacfef8',1,'stroid::config::MeshConfig']]] ]; diff --git a/docs/html/search/all_6.js b/docs/html/search/all_6.js index db440e8..1d61dde 100644 --- a/docs/html/search/all_6.js +++ b/docs/html/search/all_6.js @@ -1,6 +1,7 @@ var searchData= [ ['include_5fexternal_5fdomain_0',['include_external_domain',['../structstroid_1_1config_1_1_mesh_config.html#a062652781f4f3ea0b7ca8764362a7368',1,'stroid::config::MeshConfig']]], - ['installing_1',['Building and Installing',['../index.html#autotoc_md2',1,'']]], - ['interface_2',['C++ Interface',['../index.html#autotoc_md7',1,'']]] + ['inf_5fbdr_5fid_1',['inf_bdr_id',['../structstroid_1_1config_1_1_mesh_config.html#a64cb00c8cba27267279a52207a4b5be0',1,'stroid::config::MeshConfig']]], + ['installing_2',['Building and Installing',['../index.html#autotoc_md2',1,'']]], + ['interface_3',['C++ Interface',['../index.html#autotoc_md7',1,'']]] ]; diff --git a/docs/html/search/all_d.js b/docs/html/search/all_d.js index 4d9b9c4..727423c 100644 --- a/docs/html/search/all_d.js +++ b/docs/html/search/all_d.js @@ -8,5 +8,6 @@ var searchData= ['stroid_3a_3aconfig_5',['config',['../namespacestroid_1_1config.html',1,'stroid']]], ['stroid_3a_3aio_6',['IO',['../namespacestroid_1_1_i_o.html',1,'stroid']]], ['stroid_3a_3atopology_7',['topology',['../namespacestroid_1_1topology.html',1,'stroid']]], - ['stroid_3a_3autils_8',['utils',['../namespacestroid_1_1utils.html',1,'stroid']]] + ['stroid_3a_3autils_8',['utils',['../namespacestroid_1_1utils.html',1,'stroid']]], + ['surface_5fbdr_5fid_9',['surface_bdr_id',['../structstroid_1_1config_1_1_mesh_config.html#a33f25ff277aa8834065e04ccb9cdbdda',1,'stroid::config::MeshConfig']]] ]; diff --git a/docs/html/search/searchdata.js b/docs/html/search/searchdata.js index bdf9aa5..f3fcd0b 100644 --- a/docs/html/search/searchdata.js +++ b/docs/html/search/searchdata.js @@ -5,7 +5,7 @@ var indexSectionsWithContent = 2: "s", 3: "clmt", 4: "abfmpstv", - 5: "cfior", + 5: "cefiorsv", 6: "v", 7: "ben", 8: "s" diff --git a/docs/html/search/variables_0.js b/docs/html/search/variables_0.js index d55962b..fe8dc5f 100644 --- a/docs/html/search/variables_0.js +++ b/docs/html/search/variables_0.js @@ -1,4 +1,5 @@ var searchData= [ - ['core_5fsteepness_0',['core_steepness',['../structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d',1,'stroid::config::MeshConfig']]] + ['core_5fid_0',['core_id',['../structstroid_1_1config_1_1_mesh_config.html#a2faa5aa1fef84ebbda30590d3fb2799b',1,'stroid::config::MeshConfig']]], + ['core_5fsteepness_1',['core_steepness',['../structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d',1,'stroid::config::MeshConfig']]] ]; diff --git a/docs/html/search/variables_1.js b/docs/html/search/variables_1.js index 13cb414..3eb6c41 100644 --- a/docs/html/search/variables_1.js +++ b/docs/html/search/variables_1.js @@ -1,4 +1,4 @@ var searchData= [ - ['flattening_0',['flattening',['../structstroid_1_1config_1_1_mesh_config.html#affad4638b0ae7b710f2b2db992f6f584',1,'stroid::config::MeshConfig']]] + ['envelope_5fid_0',['envelope_id',['../structstroid_1_1config_1_1_mesh_config.html#ac99aa48fe3e71e2ef57b09d48cacfef8',1,'stroid::config::MeshConfig']]] ]; diff --git a/docs/html/search/variables_2.js b/docs/html/search/variables_2.js index 0f72429..13cb414 100644 --- a/docs/html/search/variables_2.js +++ b/docs/html/search/variables_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['include_5fexternal_5fdomain_0',['include_external_domain',['../structstroid_1_1config_1_1_mesh_config.html#a062652781f4f3ea0b7ca8764362a7368',1,'stroid::config::MeshConfig']]] + ['flattening_0',['flattening',['../structstroid_1_1config_1_1_mesh_config.html#affad4638b0ae7b710f2b2db992f6f584',1,'stroid::config::MeshConfig']]] ]; diff --git a/docs/html/search/variables_3.js b/docs/html/search/variables_3.js index 54e4e33..ea892bd 100644 --- a/docs/html/search/variables_3.js +++ b/docs/html/search/variables_3.js @@ -1,4 +1,5 @@ var searchData= [ - ['order_0',['order',['../structstroid_1_1config_1_1_mesh_config.html#a860e78f1906acb0c3aa08d55f94de3fd',1,'stroid::config::MeshConfig']]] + ['include_5fexternal_5fdomain_0',['include_external_domain',['../structstroid_1_1config_1_1_mesh_config.html#a062652781f4f3ea0b7ca8764362a7368',1,'stroid::config::MeshConfig']]], + ['inf_5fbdr_5fid_1',['inf_bdr_id',['../structstroid_1_1config_1_1_mesh_config.html#a64cb00c8cba27267279a52207a4b5be0',1,'stroid::config::MeshConfig']]] ]; diff --git a/docs/html/search/variables_4.js b/docs/html/search/variables_4.js index ca9c138..54e4e33 100644 --- a/docs/html/search/variables_4.js +++ b/docs/html/search/variables_4.js @@ -1,8 +1,4 @@ var searchData= [ - ['r_5fcore_0',['r_core',['../structstroid_1_1config_1_1_mesh_config.html#a5c68a895f73dc82a38a8daac22a83ad7',1,'stroid::config::MeshConfig']]], - ['r_5finfinity_1',['r_infinity',['../structstroid_1_1config_1_1_mesh_config.html#ac7546899ebbfe191ea3a8bf2403b31eb',1,'stroid::config::MeshConfig']]], - ['r_5finstability_2',['r_instability',['../structstroid_1_1config_1_1_mesh_config.html#a4da6d99ff7ba24d2f917e1fd98ddd877',1,'stroid::config::MeshConfig']]], - ['r_5fstar_3',['r_star',['../structstroid_1_1config_1_1_mesh_config.html#a3fe80a30990d484dcc39b6f9a0befc05',1,'stroid::config::MeshConfig']]], - ['refinement_5flevels_4',['refinement_levels',['../structstroid_1_1config_1_1_mesh_config.html#a8cafcbebf64ae251517118eb152de981',1,'stroid::config::MeshConfig']]] + ['order_0',['order',['../structstroid_1_1config_1_1_mesh_config.html#a860e78f1906acb0c3aa08d55f94de3fd',1,'stroid::config::MeshConfig']]] ]; diff --git a/docs/html/structstroid_1_1config_1_1_mesh_config-members.html b/docs/html/structstroid_1_1config_1_1_mesh_config-members.html index 75f2464..0ba8dc0 100644 --- a/docs/html/structstroid_1_1config_1_1_mesh_config-members.html +++ b/docs/html/structstroid_1_1config_1_1_mesh_config-members.html @@ -31,7 +31,7 @@ Logo -
diff --git a/docs/html/structstroid_1_1config_1_1_mesh_config.html b/docs/html/structstroid_1_1config_1_1_mesh_config.html index 83a108d..8cebfc5 100644 --- a/docs/html/structstroid_1_1config_1_1_mesh_config.html +++ b/docs/html/structstroid_1_1config_1_1_mesh_config.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
@@ -116,37 +116,73 @@ $(function(){initNavTree('structstroid_1_1config_1_1_mesh_config.html',''); init

Public Attributes

int refinement_levels = 4 - Number of uniform refinement passes applied after topology creation. @toml [main].refinement_levels.
+ Number of uniform refinement passes applied after topology creation.
  int order = 3 - Polynomial order for high-order elements. @toml [main].order.
+ Polynomial order for high-order elements.
  -bool include_external_domain = false +bool include_external_domain = true  Whether to include an external domain extending to r_infinity.
  double r_core = 1.5 - Radius of the stellar core region. @toml [main].r_core.
+ Radius of the stellar core region.
  double r_star = 5.0 - Radius of the stellar surface. @toml [main].r_star.
+ Radius of the stellar surface.
  double flattening = 0 - Flattening factor for spheroidal shaping (0 = spherical, >0 = oblate). @toml [main].flattening.
+ Flattening factor for spheroidal shaping (0 = spherical, >0 = oblate).
  double r_infinity = 6.0 - Outer radius of the external domain when enabled. @toml [main].r_infinity.
+ Outer radius of the external domain when enabled.
  double r_instability = 1e-14 - Radius inside which transformations are skipped to avoid singularities. @toml [main].r_instability.
+ Radius inside which transformations are skipped to avoid singularities.
  double core_steepness = 1.0 - Controls the smoothness/steepness of the core-to-envelope transition. @toml [main].core_steepness.
+ Controls the smoothness/steepness of the core-to-envelope transition.
  +size_t surface_bdr_id = 1 + Boundary attribute id for stellar surface.
+  +size_t inf_bdr_id = 2 + Boundary attribute id for infinity in kelvin mapping.
+  +size_t core_id = 1 + Material attribute id for the core region.
+  +size_t envelope_id = 2 + Material attribute id for the envelope region.
+  +size_t vacuum_id = 3 + Material attribute id for the external domain (if enabled)

Detailed Description

Configuration parameters for stroid mesh generation.

These values are typically loaded via fourdst::config::Config<stroid::config::MeshConfig> from a TOML file. The README shows the expected TOML layout under the [main] table. Unspecified keys use the defaults defined here.

Member Data Documentation

+ +

◆ core_id

+ +
+
+ + + + +
size_t stroid::config::MeshConfig::core_id = 1
+
+ +

Material attribute id for the core region.

+

+toml

+
    +
  • [main].core_id
  • +
+ +
+

◆ core_steepness

@@ -159,7 +195,33 @@ Public Attributes
-

Controls the smoothness/steepness of the core-to-envelope transition. @toml [main].core_steepness.

+

Controls the smoothness/steepness of the core-to-envelope transition.

+

+toml

+
    +
  • [main].core_steepness
  • +
+ +
+
+ +

◆ envelope_id

+ +
+
+ + + + +
size_t stroid::config::MeshConfig::envelope_id = 2
+
+ +

Material attribute id for the envelope region.

+

+toml

+
    +
  • [main].envelope_id
  • +
@@ -175,7 +237,12 @@ Public Attributes
-

Flattening factor for spheroidal shaping (0 = spherical, >0 = oblate). @toml [main].flattening.

+

Flattening factor for spheroidal shaping (0 = spherical, >0 = oblate).

+

+toml

+
    +
  • [main].flattening
  • +
@@ -186,13 +253,38 @@ Public Attributes
- +
bool stroid::config::MeshConfig::include_external_domain = falsebool stroid::config::MeshConfig::include_external_domain = true

Whether to include an external domain extending to r_infinity.

-

Currently this flag does not affect mesh generation. @toml [main].include_external_domain

+

+toml

+
    +
  • [main].include_external_domain
  • +
+ +
+
+ +

◆ inf_bdr_id

+ +
+
+ + + + +
size_t stroid::config::MeshConfig::inf_bdr_id = 2
+
+ +

Boundary attribute id for infinity in kelvin mapping.

+

+toml

+
    +
  • [main].inf_bdr_id
  • +
@@ -208,7 +300,12 @@ Public Attributes
-

Polynomial order for high-order elements. @toml [main].order.

+

Polynomial order for high-order elements.

+

+toml

+
    +
  • [main].order
  • +
@@ -224,7 +321,12 @@ Public Attributes
-

Radius of the stellar core region. @toml [main].r_core.

+

Radius of the stellar core region.

+

+toml

+
    +
  • [main].r_core
  • +
@@ -240,7 +342,12 @@ Public Attributes
-

Outer radius of the external domain when enabled. @toml [main].r_infinity.

+

Outer radius of the external domain when enabled.

+

+toml

+
    +
  • [main].r_infinity
  • +
@@ -256,7 +363,12 @@ Public Attributes
-

Radius inside which transformations are skipped to avoid singularities. @toml [main].r_instability.

+

Radius inside which transformations are skipped to avoid singularities.

+

+toml

+
    +
  • [main].r_instability
  • +
@@ -272,7 +384,12 @@ Public Attributes
-

Radius of the stellar surface. @toml [main].r_star.

+

Radius of the stellar surface.

+

+toml

+
    +
  • [main].r_star
  • +
@@ -288,7 +405,54 @@ Public Attributes
-

Number of uniform refinement passes applied after topology creation. @toml [main].refinement_levels.

+

Number of uniform refinement passes applied after topology creation.

+

+toml

+ + +
+
+ +

◆ surface_bdr_id

+ +
+
+ + + + +
size_t stroid::config::MeshConfig::surface_bdr_id = 1
+
+ +

Boundary attribute id for stellar surface.

+

+toml

+ + +
+
+ +

◆ vacuum_id

+ +
+
+ + + + +
size_t stroid::config::MeshConfig::vacuum_id = 3
+
+ +

Material attribute id for the external domain (if enabled)

+

+toml

+
diff --git a/docs/html/structstroid_1_1config_1_1_mesh_config.js b/docs/html/structstroid_1_1config_1_1_mesh_config.js index e123f5a..e08ceff 100644 --- a/docs/html/structstroid_1_1config_1_1_mesh_config.js +++ b/docs/html/structstroid_1_1config_1_1_mesh_config.js @@ -1,12 +1,17 @@ var structstroid_1_1config_1_1_mesh_config = [ + [ "core_id", "structstroid_1_1config_1_1_mesh_config.html#a2faa5aa1fef84ebbda30590d3fb2799b", null ], [ "core_steepness", "structstroid_1_1config_1_1_mesh_config.html#aed32864839b149c94842801b6413d94d", null ], + [ "envelope_id", "structstroid_1_1config_1_1_mesh_config.html#ac99aa48fe3e71e2ef57b09d48cacfef8", null ], [ "flattening", "structstroid_1_1config_1_1_mesh_config.html#affad4638b0ae7b710f2b2db992f6f584", null ], [ "include_external_domain", "structstroid_1_1config_1_1_mesh_config.html#a062652781f4f3ea0b7ca8764362a7368", null ], + [ "inf_bdr_id", "structstroid_1_1config_1_1_mesh_config.html#a64cb00c8cba27267279a52207a4b5be0", null ], [ "order", "structstroid_1_1config_1_1_mesh_config.html#a860e78f1906acb0c3aa08d55f94de3fd", null ], [ "r_core", "structstroid_1_1config_1_1_mesh_config.html#a5c68a895f73dc82a38a8daac22a83ad7", null ], [ "r_infinity", "structstroid_1_1config_1_1_mesh_config.html#ac7546899ebbfe191ea3a8bf2403b31eb", null ], [ "r_instability", "structstroid_1_1config_1_1_mesh_config.html#a4da6d99ff7ba24d2f917e1fd98ddd877", null ], [ "r_star", "structstroid_1_1config_1_1_mesh_config.html#a3fe80a30990d484dcc39b6f9a0befc05", null ], - [ "refinement_levels", "structstroid_1_1config_1_1_mesh_config.html#a8cafcbebf64ae251517118eb152de981", null ] + [ "refinement_levels", "structstroid_1_1config_1_1_mesh_config.html#a8cafcbebf64ae251517118eb152de981", null ], + [ "surface_bdr_id", "structstroid_1_1config_1_1_mesh_config.html#a33f25ff277aa8834065e04ccb9cdbdda", null ], + [ "vacuum_id", "structstroid_1_1config_1_1_mesh_config.html#a36c7b05405691393d381086a27ea36ad", null ] ]; \ No newline at end of file diff --git a/docs/html/topology_8cpp.html b/docs/html/topology_8cpp.html index 471e004..f684546 100644 --- a/docs/html/topology_8cpp.html +++ b/docs/html/topology_8cpp.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/html/topology_8h.html b/docs/html/topology_8h.html index 9bfe801..4abe0c0 100644 --- a/docs/html/topology_8h.html +++ b/docs/html/topology_8h.html @@ -31,7 +31,7 @@ Logo -
stroid v0.1.0 +
stroid v0.2.0
Multi-block curvilinear mesh generation
diff --git a/docs/static/mainpage.md b/docs/static/mainpage.md index c1b920e..9f61eaa 100644 --- a/docs/static/mainpage.md +++ b/docs/static/mainpage.md @@ -77,15 +77,20 @@ file is found below ```toml [main] -core_steepness = 1.0 -flattening = 0.0 -include_external_domain = false +refinement_levels = 2 order = 3 +include_external_domain = true r_core = 1.5 +r_star = 5.0 +flattening = 0.08 r_infinity = 6.0 r_instability = 1e-14 -r_star = 5.0 -refinement_levels = 4 +core_steepness = 1.0 +surface_bdr_id = 1 +inf_bdr_id = 2 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 ``` @@ -93,13 +98,18 @@ refinement_levels = 4 |-------------------------|-----------------------------------------------------------------------------------------------------|---------| | 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 | false | +| 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 | If no configuration file is provided, stroid will use the default parameters listed above. Further, configuration files diff --git a/meson.build b/meson.build index fd798b3..3a33757 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('stroid', 'cpp', meson_version : '>= 1.3.0', version : 'v0.1.0', default_options : ['cpp_std=c++23']) +project('stroid', 'cpp', meson_version : '>= 1.3.0', version : 'v0.2.0', default_options : ['cpp_std=c++23']) subdir('build-check') diff --git a/readme.md b/readme.md index 52affca..534cb22 100644 --- a/readme.md +++ b/readme.md @@ -78,15 +78,20 @@ file is found below ```toml [main] -core_steepness = 1.0 -flattening = 0.0 -include_external_domain = false +refinement_levels = 2 order = 3 +include_external_domain = true r_core = 1.5 +r_star = 5.0 +flattening = 0.08 r_infinity = 6.0 r_instability = 1e-14 -r_star = 5.0 -refinement_levels = 4 +core_steepness = 1.0 +surface_bdr_id = 1 +inf_bdr_id = 2 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 ``` @@ -94,13 +99,18 @@ refinement_levels = 4 |-------------------------|-----------------------------------------------------------------------------------------------------|---------| | 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 | false | +| 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 | If no configuration file is provided, stroid will use the default parameters listed above. Further, configuration files diff --git a/src/include/stroid/config/config.h b/src/include/stroid/config/config.h index 083a331..416956a 100644 --- a/src/include/stroid/config/config.h +++ b/src/include/stroid/config/config.h @@ -12,52 +12,95 @@ namespace stroid::config { struct MeshConfig { /** * @brief Number of uniform refinement passes applied after topology creation. - * @toml [main].refinement_levels + * @section toml + * - [main].refinement_levels */ int refinement_levels = 4; /** * @brief Polynomial order for high-order elements. - * @toml [main].order + * @section toml + * - [main].order */ int order = 3; /** * @brief Whether to include an external domain extending to `r_infinity`. - * @details Currently this flag does not affect mesh generation. - * @toml [main].include_external_domain + * @section toml + * - [main].include_external_domain */ - bool include_external_domain = false; + bool include_external_domain = true; /** * @brief Radius of the stellar core region. - * @toml [main].r_core + * @section toml + * - [main].r_core */ double r_core = 1.5; /** * @brief Radius of the stellar surface. - * @toml [main].r_star + * @section toml + * - [main].r_star */ double r_star = 5.0; /** * @brief Flattening factor for spheroidal shaping (0 = spherical, >0 = oblate). - * @toml [main].flattening + * @section toml + * - [main].flattening */ double flattening = 0; /** * @brief Outer radius of the external domain when enabled. - * @toml [main].r_infinity + * @section toml + * - [main].r_infinity */ double r_infinity = 6.0; /** * @brief Radius inside which transformations are skipped to avoid singularities. - * @toml [main].r_instability + * @section toml + * - [main].r_instability */ double r_instability = 1e-14; /** * @brief Controls the smoothness/steepness of the core-to-envelope transition. - * @toml [main].core_steepness + * @section toml + * - [main].core_steepness */ double core_steepness = 1.0; + + /** + * @brief Boundary attribute id for stellar surface + * @section toml + * - [main].surface_bdr_id + */ + size_t surface_bdr_id = 1; + + /** + * @brief Boundary attribute id for infinity in kelvin mapping + * @section toml + * - [main].inf_bdr_id + */ + size_t inf_bdr_id = 2; + + /** + * @brief Material attribute id for the core region + * @section toml + * - [main].core_id + */ + size_t core_id = 1; + + /** + * @brief Material attribute id for the envelope region + * @section toml + * - [main].envelope_id + */ + size_t envelope_id = 2; + + /** + * @brief Material attribute id for the external domain (if enabled) + * @section toml + * - [main].vacuum_id + */ + size_t vacuum_id = 3; }; } diff --git a/src/lib/topology/curvilinear.cpp b/src/lib/topology/curvilinear.cpp index 3a98151..ae0150c 100644 --- a/src/lib/topology/curvilinear.cpp +++ b/src/lib/topology/curvilinear.cpp @@ -3,6 +3,7 @@ #include #include +#include namespace stroid::topology { void PromoteToHighOrder(mfem::Mesh &mesh, const fourdst::config::Config &config) { @@ -22,20 +23,48 @@ namespace stroid::topology { const int vDim = fes->GetVDim(); const int nDofs = fes->GetNDofs(); + const int nElem = mesh.GetNE(); + std::vector processed(nDofs, false); + mfem::Array vdofs; mfem::Vector pos(vDim); - for (int i = 0; i < nDofs; ++i) { - for (int d = 0; d < vDim; ++d) { - pos(d) = nodes(fes->DofToVDof(i, d)); - } + for (int elemID = 0; elemID < nElem; ++elemID) { + const int attrID = mesh.GetAttribute(elemID); + fes->GetElementVDofs(elemID, vdofs); - TransformPoint(pos, config, 0); + for (int dofID = 0; dofID < vdofs.Size(); ++dofID) { + const int vDof = vdofs[dofID]; + const int scalar_dof = (fes->GetOrdering() == mfem::Ordering::byNODES) ? vDof / vDim : vDof % nDofs; - for (int d = 0; d < vDim; ++d) { - nodes(fes->DofToVDof(i, d)) = pos(d); + if (processed[scalar_dof]) { + continue; // Skip already processed dofs. This avoids doing multiple transformations of a node if it was already transformed by a neighbor + } + + for (int d = 0; d < vDim; ++d) { + pos(d) = nodes(fes->DofToVDof(scalar_dof, d)); + } + + TransformPoint(pos, config, attrID); + + for (int d = 0; d < vDim; ++d) { + nodes(fes->DofToVDof(scalar_dof, d)) = pos(d); + } + + processed[scalar_dof] = true; } } + // for (int i = 0; i < nDofs; ++i) { + // for (int d = 0; d < vDim; ++d) { + // pos(d) = nodes(fes->DofToVDof(i, d)); + // } + // + // TransformPoint(pos, config, 0); + // + // for (int d = 0; d < vDim; ++d) { + // nodes(fes->DofToVDof(i, d)) = pos(d); + // } + // } } } diff --git a/src/lib/topology/mapping.cpp b/src/lib/topology/mapping.cpp index fba882a..bbc9105 100644 --- a/src/lib/topology/mapping.cpp +++ b/src/lib/topology/mapping.cpp @@ -32,20 +32,6 @@ namespace stroid::topology { pos(2) *= (1.0 - config->flattening); } - void ApplyKelvin(mfem::Vector &pos, const fourdst::config::Config &config) { - const double r = pos.Norml2(); - if (r <= config->r_star) { - return; - } - - double xi = (r - config->r_star) / (config->r_infinity - config->r_star); - xi = std::min(0.999, std::max(0.0, xi)); // Clamp xi to [0, 0.999] - - const double r_new = config->r_star + xi / (1.0 - xi); - const double scale = r_new / r; - pos *= scale; - } - void TransformPoint(mfem::Vector &pos, const fourdst::config::Config &config, int attribute_id) { double l_inf = 0.0; for (int i = 0; i < pos.Size(); ++i) { @@ -82,9 +68,6 @@ namespace stroid::topology { ApplySpheroidal(pos, config); return; } - - - if (l_inf <= config->r_star) { const double xi = (l_inf - config->r_core) / (config->r_star - config->r_core); const double r_phys = config->r_core + xi * (config->r_star - config->r_core); @@ -97,7 +80,6 @@ namespace stroid::topology { pos = unit_dir; pos *= l_inf; - ApplyKelvin(pos, config); ApplySpheroidal(pos, config); } } diff --git a/src/lib/topology/topology.cpp b/src/lib/topology/topology.cpp index db0cff8..ddc4286 100644 --- a/src/lib/topology/topology.cpp +++ b/src/lib/topology/topology.cpp @@ -10,7 +10,7 @@ namespace stroid::topology { std::unique_ptr BuildSkeleton(const fourdst::config::Config & config) { int nVert = config->include_external_domain ? 24 : 16; int nElem = config->include_external_domain ? 13 : 7; - int nBev = 6; + int nBev = config->include_external_domain ? 12 : 6; auto mesh = std::make_unique(3, nVert, nElem, nBev, 3); @@ -28,9 +28,9 @@ namespace stroid::topology { } const int core_v[8] = {0, 1, 3, 2, 4, 5, 7, 6}; - mesh->AddHex(core_v, 1); + mesh->AddHex(core_v, config->core_id); - int shells[6][8] = { + std::vector> stellar_shells = { {8, 9, 11, 10, 0, 1, 3, 2}, {4, 5, 7, 6, 12, 13, 15, 14}, // +Z face {0, 1, 5, 4, 8, 9, 13, 12}, // -Y face @@ -38,9 +38,25 @@ namespace stroid::topology { {1, 3, 7, 5, 9, 11, 15, 13}, // +X face {0, 4, 6, 2, 8, 12, 14, 10} // -X face }; - for (const auto & shell : shells) mesh->AddHex(shell, 2); + for (const auto & shell : stellar_shells) { + mesh->AddHex(shell.data(), config->envelope_id); + } - const int bdr_quads[6][4] = { + if (config->include_external_domain) { + std::vector> vacuum_shells; + vacuum_shells.push_back({8, 9, 13, 12, 16, 17, 21, 20}); + vacuum_shells.push_back({9, 11, 15, 13, 17, 19, 23, 21}); + vacuum_shells.push_back({11, 10, 14, 15, 19, 18, 22, 23}); + vacuum_shells.push_back({10, 8, 12, 14, 18, 16, 20, 22}); + vacuum_shells.push_back({12, 13, 15, 14, 20, 21, 23, 22}); + vacuum_shells.push_back({10, 11, 9, 8, 18, 19, 17, 16}); + for (const auto & shell : vacuum_shells) { + mesh->AddHex(shell.data(), config->vacuum_id); + } + } + + + const int surface_bdr_quads[6][4] = { {12, 13, 15, 14}, {13, 9, 11, 15}, {9, 8, 10, 11}, @@ -49,8 +65,23 @@ namespace stroid::topology { {14, 15, 11, 10} }; - for (const auto& bdr: bdr_quads) { - mesh->AddBdrQuad(bdr, 1); + for (const auto& bdr: surface_bdr_quads) { + mesh->AddBdrQuad(bdr, config->surface_bdr_id); + } + + if (config->include_external_domain) { + const int inf_bdr_quads[6][4] = { + {16, 17, 21, 20}, + {17, 19, 23, 21}, + {19, 18, 22, 23}, + {18, 16, 20, 22}, + {18, 19, 17, 16}, + {20, 21, 23, 22} + }; + + for (const auto& bdr: inf_bdr_quads) { + mesh->AddBdrQuad(bdr, config->inf_bdr_id); + } } return mesh; diff --git a/src/lib/utils/mesh_utils.cpp b/src/lib/utils/mesh_utils.cpp index 7c94f53..9c691f2 100644 --- a/src/lib/utils/mesh_utils.cpp +++ b/src/lib/utils/mesh_utils.cpp @@ -4,8 +4,6 @@ namespace stroid::utils { void MarkFlippedElements(mfem::Mesh& mesh) { - size_t total_flipped = 0; - size_t total_elements = mesh.GetNE(); for (int i = 0; i < mesh.GetNE(); i++) { mfem::ElementTransformation *T = mesh.GetElementTransformation(i); @@ -22,17 +20,11 @@ namespace stroid::utils { if (is_flipped) { mesh.SetAttribute(i, 999); - total_flipped++; } - - } - std::println("Marked {}/{} elements as flipped.", total_flipped, total_elements); } void MarkFlippedBoundaryElements(mfem::Mesh& mesh) { - size_t total_flipped = 0; - size_t total_boundary_elements = mesh.GetNBE(); for (int i = 0; i < mesh.GetNBE(); i++) { mfem::ElementTransformation *T = mesh.GetBdrElementTransformation(i); const mfem::IntegrationRule &ir = mfem::IntRules.Get(T->GetGeometryType(), 2 * T->Order()); @@ -56,9 +48,7 @@ namespace stroid::utils { if (is_flipped) { mesh.SetBdrAttribute(i, 500); - total_flipped++; } } - std::println("Marked {}/{} boundary elements as flipped.", total_flipped, total_boundary_elements); } } \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build index 4eb5fc6..95ec39b 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -27,3 +27,5 @@ foreach test_file : test_sources test_exe, env: ['MESON_SOURCE_ROOT=' + meson.project_source_root(), 'MESON_BUILD_ROOT=' + meson.project_build_root()]) endforeach + +subdir('sandbox') diff --git a/tests/sandbox/default.toml b/tests/sandbox/default.toml new file mode 100644 index 0000000..8d452c0 --- /dev/null +++ b/tests/sandbox/default.toml @@ -0,0 +1,15 @@ +[main] +core_steepness = 1.0 +flattening = 0.0 +include_external_domain = true +inf_bdr_id = 2 +order = 3 +r_core = 1.5 +r_infinity = 10.0 +r_instability = 1e-14 +r_star = 5.0 +refinement_levels = 2 +surface_bdr_id = 1 +core_id = 1 +envelope_id = 2 +vacuum_id = 3 \ No newline at end of file diff --git a/tests/sandbox/meson.build b/tests/sandbox/meson.build new file mode 100644 index 0000000..2a3c0bd --- /dev/null +++ b/tests/sandbox/meson.build @@ -0,0 +1 @@ +executable('sandbox_test', 'sandbox_test.cpp', dependencies: [stroid_dep]) \ No newline at end of file diff --git a/tests/sandbox/sandbox_test.cpp b/tests/sandbox/sandbox_test.cpp new file mode 100644 index 0000000..bb2359d --- /dev/null +++ b/tests/sandbox/sandbox_test.cpp @@ -0,0 +1,37 @@ +#include "fourdst/config/config.h" +#include "stroid/config/config.h" +#include "stroid/IO/mesh.h" +#include "stroid/topology/curvilinear.h" +#include "stroid/topology/mapping.h" +#include "stroid/topology/topology.h" + +#include "mfem.hpp" + +#include + +struct SandboxConfig { + std::string host = "localhost"; + int port = 19916; + bool visualize = true; +}; + +using MeshConfig = fourdst::config::Config; +using UserConfig = fourdst::config::Config; + +int main() { + MeshConfig mesh_cfg; + mesh_cfg.load("default.toml"); + + UserConfig user_cfg; + + + std::unique_ptr mesh = stroid::topology::BuildSkeleton(mesh_cfg); + stroid::topology::Finalize(*mesh, mesh_cfg); + stroid::topology::PromoteToHighOrder(*mesh, mesh_cfg); + stroid::topology::ProjectMesh(*mesh, mesh_cfg); + stroid::IO::ViewMesh(*mesh, "Sandbox Mesh", stroid::IO::VISUALIZATION_MODE::ELEMENT_ID, user_cfg->host, user_cfg->port); + + return 0; + + +} \ No newline at end of file diff --git a/tests/stroidTest.cpp b/tests/stroidTest.cpp index c0a11f1..845beaf 100644 --- a/tests/stroidTest.cpp +++ b/tests/stroidTest.cpp @@ -6,11 +6,17 @@ #include "stroid/topology/curvilinear.h" #include "stroid/topology/mapping.h" #include "stroid/topology/topology.h" +#include "stroid/utils/mesh_utils.h" #include #include #include #include +#include +#include +#include +#include +#include namespace { @@ -21,7 +27,7 @@ using Config = fourdst::config::Config; std::filesystem::path GetSourceRoot() { if (const char* env = std::getenv("MESON_SOURCE_ROOT")) { - return std::filesystem::path(env); + return {env}; } return std::filesystem::current_path(); } @@ -51,6 +57,182 @@ bool IsFiniteMeshNodes(const mfem::Mesh& mesh) { return true; } +std::map CountVolumeAttributes(const mfem::Mesh& mesh) { + std::map counts; + for (int i = 0; i < mesh.GetNE(); ++i) { + counts[mesh.GetAttribute(i)]++; + } + return counts; +} + +std::map CountBoundaryAttributes(const mfem::Mesh& mesh) { + std::map counts; + for (int i = 0; i < mesh.GetNBE(); ++i) { + counts[mesh.GetBdrAttribute(i)]++; + } + return counts; +} + +mfem::Vector TransformCopy(const mfem::Vector& in, const Config& cfg, int attribute_id = 0) { + mfem::Vector out = in; + stroid::topology::TransformPoint(out, cfg, attribute_id); + return out; +} + +double IntegrateElementVolume(const mfem::Mesh& mesh, int element_id) { + mfem::ElementTransformation* T = const_cast(mesh).GetElementTransformation(element_id); + const int order = std::max(2, 2 * T->Order() + 2); + const mfem::IntegrationRule& ir = mfem::IntRules.Get(T->GetGeometryType(), order); + + double volume = 0.0; + for (int j = 0; j < ir.GetNPoints(); ++j) { + const mfem::IntegrationPoint& ip = ir.IntPoint(j); + T->SetIntPoint(&ip); + volume += ip.weight * std::abs(T->Weight()); + } + return volume; +} + +double ComputeMeshVolume(const mfem::Mesh& mesh) { + double volume = 0.0; + for (int i = 0; i < mesh.GetNE(); ++i) { + volume += IntegrateElementVolume(mesh, i); + } + return volume; +} + +double ComputeMeshVolumeForAttributes(const mfem::Mesh& mesh, const std::set& attributes) { + double volume = 0.0; + for (int i = 0; i < mesh.GetNE(); ++i) { + if (!attributes.contains(mesh.GetAttribute(i))) { + continue; + } + volume += IntegrateElementVolume(mesh, i); + } + return volume; +} + +std::unique_ptr BuildProjectedMesh(const Config& cfg) { + std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + stroid::topology::Finalize(*mesh, cfg); + stroid::topology::PromoteToHighOrder(*mesh, cfg); + stroid::topology::ProjectMesh(*mesh, cfg); + return mesh; +} + +double ComputeStellarVolumeWithDomainLFIntegrator(mfem::Mesh& mesh, const Config& cfg) { + const int mesh_max_attr = mesh.attributes.Size() > 0 ? mesh.attributes.Max() : 0; + const int cfg_max_attr = static_cast(std::max({cfg->core_id, cfg->envelope_id, cfg->vacuum_id})); + const int coeff_size = std::max(1, std::max(mesh_max_attr, cfg_max_attr)); + + mfem::Vector attr_coeff(coeff_size); + attr_coeff = 0.0; + attr_coeff(static_cast(cfg->core_id) - 1) = 1.0; + attr_coeff(static_cast(cfg->envelope_id) - 1) = 1.0; + + mfem::PWConstCoefficient stellar_coeff(attr_coeff); + mfem::L2_FECollection fec(0, mesh.Dimension()); + mfem::FiniteElementSpace fes(&mesh, &fec); + mfem::LinearForm lf(&fes); + lf.AddDomainIntegrator(new mfem::DomainLFIntegrator(stellar_coeff)); + lf.Assemble(); + return lf.Sum(); +} + +double ColumnNorm2(const mfem::DenseMatrix& J, int col) { + double n2 = 0.0; + for (int r = 0; r < J.Height(); ++r) { + n2 += J(r, col) * J(r, col); + } + return std::sqrt(n2); +} + +double ComputeHexEdgeRatio(const mfem::Mesh& mesh, int elem_id) { + static constexpr std::array, 12> edges = {{ + {{0, 1}}, {{1, 2}}, {{2, 3}}, {{3, 0}}, + {{4, 5}}, {{5, 6}}, {{6, 7}}, {{7, 4}}, + {{0, 4}}, {{1, 5}}, {{2, 6}}, {{3, 7}} + }}; + + const mfem::Element* e = mesh.GetElement(elem_id); + if (e->GetNVertices() != 8) { + return 1.0; + } + + const int* v = e->GetVertices(); + double min_edge = std::numeric_limits::infinity(); + double max_edge = 0.0; + + for (const auto& [a, b] : edges) { + const double* pa = mesh.GetVertex(v[a]); + const double* pb = mesh.GetVertex(v[b]); + const double dx = pa[0] - pb[0]; + const double dy = pa[1] - pb[1]; + const double dz = pa[2] - pb[2]; + const double len = std::sqrt(dx * dx + dy * dy + dz * dz); + min_edge = std::min(min_edge, len); + max_edge = std::max(max_edge, len); + } + + if (min_edge <= 0.0 || !std::isfinite(min_edge)) { + return std::numeric_limits::infinity(); + } + return max_edge / min_edge; +} + +struct ConditioningStats { + double min_det = std::numeric_limits::infinity(); + double max_det = 0.0; + double min_scaled_jac = std::numeric_limits::infinity(); + double max_stretch_ratio = 0.0; + double max_edge_ratio = 0.0; + int samples = 0; +}; + +ConditioningStats CollectConditioningStats(const mfem::Mesh& mesh, const std::set& attrs) { + ConditioningStats stats; + + for (int i = 0; i < mesh.GetNE(); ++i) { + if (!attrs.empty() && !attrs.contains(mesh.GetAttribute(i))) { + continue; + } + + stats.max_edge_ratio = std::max(stats.max_edge_ratio, ComputeHexEdgeRatio(mesh, i)); + + mfem::ElementTransformation* T = const_cast(mesh).GetElementTransformation(i); + const int order = std::max(2, 2 * T->Order() + 2); + const mfem::IntegrationRule& ir = mfem::IntRules.Get(T->GetGeometryType(), order); + + for (int j = 0; j < ir.GetNPoints(); ++j) { + const mfem::IntegrationPoint& ip = ir.IntPoint(j); + T->SetIntPoint(&ip); + + const mfem::DenseMatrix& J = T->Jacobian(); + const double det = T->Weight(); + const double abs_det = std::abs(det); + + const double c0 = ColumnNorm2(J, 0); + const double c1 = ColumnNorm2(J, 1); + const double c2 = ColumnNorm2(J, 2); + + const double denom = c0 * c1 * c2; + const double scaled_jac = (denom > 0.0) ? (abs_det / denom) : 0.0; + + const double cmax = std::max({c0, c1, c2}); + const double cmin = std::max(1e-16, std::min({c0, c1, c2})); + const double stretch_ratio = cmax / cmin; + + stats.min_det = std::min(stats.min_det, det); + stats.max_det = std::max(stats.max_det, abs_det); + stats.min_scaled_jac = std::min(stats.min_scaled_jac, scaled_jac); + stats.max_stretch_ratio = std::max(stats.max_stretch_ratio, stretch_ratio); + stats.samples++; + } + } + + return stats; +} + } // namespace /** @@ -58,18 +240,80 @@ bool IsFiniteMeshNodes(const mfem::Mesh& mesh) { */ class stroidTest : public ::testing::Test {}; +/** + * @brief Verifies the baseline block topology cardinalities in the no-vacuum case. + * @details + * Rationale: this is the fastest canary for accidental edits in block construction order, + * vertex indexing, or boundary-face assembly. + * Method: build the default skeleton and assert exact counts (3D, 16 vertices, 7 hexes, 6 bdr quads). + * If this fails: inspect `stroid::topology::BuildSkeleton` in `src/lib/topology/topology.cpp`, + * especially `add_box`, `stellar_shells`, and `surface_bdr_quads`, plus ID defaults in + * `src/include/stroid/config/config.h`. + */ TEST_F(stroidTest, BuildSkeleton_DefaultCounts) { const Config cfg; const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); ASSERT_NE(mesh, nullptr); EXPECT_EQ(mesh->Dimension(), 3); - EXPECT_EQ(mesh->GetNV(), 16); - EXPECT_EQ(mesh->GetNE(), 7); - EXPECT_EQ(mesh->GetNBE(), 6); + EXPECT_EQ(mesh->GetNV(), 24); + EXPECT_EQ(mesh->GetNE(), 13); + EXPECT_EQ(mesh->GetNBE(), 12); +} + +/** + * @brief Verifies topology cardinalities when the external vacuum domain is enabled. + * @details + * Rationale: external-domain regressions usually surface first as wrong element/boundary counts. + * Method: load `configs/test_external_domain.toml`, build skeleton, assert exact counts (24, 13, 12). + * If this fails: inspect vacuum block creation and infinity boundary insertion in + * `src/lib/topology/topology.cpp` (`vacuum_shells`, `inf_bdr_quads`) and config parsing path. + */ +TEST_F(stroidTest, BuildSkeleton_ExternalDomainCounts) { + const Config cfg = LoadConfigFromRepo("configs/test_external_domain.toml"); + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + + ASSERT_NE(mesh, nullptr); + EXPECT_EQ(mesh->Dimension(), 3); + EXPECT_EQ(mesh->GetNV(), 24); + EXPECT_EQ(mesh->GetNE(), 13); + EXPECT_EQ(mesh->GetNBE(), 12); +} + +/** + * @brief Confirms attribute bookkeeping for core/envelope/vacuum and surface/infinity boundaries. + * @details + * Rationale: physics coupling depends on stable material and boundary IDs, not just geometry. + * Method: count attributes immediately after skeleton build and assert expected multiplicities. + * If this fails: inspect element insertion attribute arguments in `BuildSkeleton` and verify + * `core_id`, `envelope_id`, `vacuum_id`, `surface_bdr_id`, `inf_bdr_id` in config fixtures. + */ +TEST_F(stroidTest, BuildSkeleton_ExternalDomainAttributes) { + const Config cfg = LoadConfigFromRepo("configs/test_external_domain.toml"); + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + + ASSERT_NE(mesh, nullptr); + + const auto volume_attr_counts = CountVolumeAttributes(*mesh); + EXPECT_EQ(volume_attr_counts.at(static_cast(cfg->core_id)), 1); + EXPECT_EQ(volume_attr_counts.at(static_cast(cfg->envelope_id)), 6); + EXPECT_EQ(volume_attr_counts.at(static_cast(cfg->vacuum_id)), 6); + + const auto boundary_attr_counts = CountBoundaryAttributes(*mesh); + EXPECT_EQ(boundary_attr_counts.at(static_cast(cfg->surface_bdr_id)), 6); + EXPECT_EQ(boundary_attr_counts.at(static_cast(cfg->inf_bdr_id)), 6); } +/** + * @brief Ensures `Finalize` performs refinement and preserves conforming topology. + * @details + * Rationale: `Finalize` is the topology gate before high-order projection; nonconforming output here + * contaminates every downstream stage. + * Method: compare element count pre/post finalize and assert `mesh.Conforming()`. + * If this fails: inspect `stroid::topology::Finalize` in `src/lib/topology/topology.cpp` + * (`FinalizeTopology`, orientation checks, `UniformRefinement` loop). + */ TEST_F(stroidTest, Finalize_RefinementIncreasesElements) { const Config cfg; const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); @@ -81,6 +325,117 @@ TEST_F(stroidTest, Finalize_RefinementIncreasesElements) { EXPECT_TRUE(mesh->Conforming()); } +/** + * @brief Checks exact 3D uniform-refinement scaling for default topology. + * @details + * Rationale: each hexahedron should split into 8; this catches subtle refine-loop regressions. + * Method: run with fixed `refinement_levels=2` config and assert `NE_final = NE_initial * 8^2`. + * If this fails: inspect refine-loop count and any topology-side early exits in `Finalize`. + */ +TEST_F(stroidTest, Finalize_DefaultRefinementScalesHexCountByEightPowerL) { + const Config cfg = LoadConfigFromRepo("configs/test_refinement_l2.toml"); + + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + const int initial_elements = mesh->GetNE(); + + stroid::topology::Finalize(*mesh, cfg); + + const int expected = initial_elements * 8 * 8; + EXPECT_EQ(mesh->GetNE(), expected); +} + +/** + * @brief Checks exact 3D uniform-refinement scaling for external-domain topology. + * @details + * Rationale: refinement behavior must be independent of whether vacuum blocks are present. + * Method: use fixed `refinement_levels=1` external config and assert `NE_final = NE_initial * 8`. + * If this fails: inspect `Finalize` and verify external-domain elements are not excluded from refinement. + */ +TEST_F(stroidTest, Finalize_ExternalDomainRefinementScalesHexCountByEightPowerL) { + const Config cfg = LoadConfigFromRepo("configs/test_external_domain_refinement_l1.toml"); + + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + const int initial_elements = mesh->GetNE(); + + stroid::topology::Finalize(*mesh, cfg); + + const int expected = initial_elements * 8; + EXPECT_EQ(mesh->GetNE(), expected); +} + +/** + * @brief Validates conformance + attribute presence after refining external-domain meshes. + * @details + * Rationale: refinement must not silently drop regions or boundaries in multi-material meshes. + * Method: finalize external mesh, check conforming status, growth in `NE`, and nonzero counts for expected IDs. + * If this fails: inspect `Finalize` orientation/refinement calls and any attribute mutation side effects. + */ +TEST_F(stroidTest, Finalize_ExternalDomainConformingAndRefined) { + const Config cfg = LoadConfigFromRepo("configs/test_external_domain.toml"); + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + const int initial_elements = mesh->GetNE(); + + stroid::topology::Finalize(*mesh, cfg); + + EXPECT_TRUE(mesh->Conforming()); + EXPECT_GT(mesh->GetNE(), initial_elements); + + const auto volume_attr_counts = CountVolumeAttributes(*mesh); + EXPECT_GT(volume_attr_counts.at(static_cast(cfg->core_id)), 0); + EXPECT_GT(volume_attr_counts.at(static_cast(cfg->envelope_id)), 0); + EXPECT_GT(volume_attr_counts.at(static_cast(cfg->vacuum_id)), 0); + + const auto boundary_attr_counts = CountBoundaryAttributes(*mesh); + EXPECT_GT(boundary_attr_counts.at(static_cast(cfg->surface_bdr_id)), 0); + EXPECT_GT(boundary_attr_counts.at(static_cast(cfg->inf_bdr_id)), 0); +} + +/** + * @brief Enforces strict attribute set invariants after finalize. + * @details + * Rationale: presence checks alone can miss rogue IDs introduced by buggy attribute rewrites. + * Method: assert post-finalize volume/boundary attribute keys exactly match expected sets. + * If this fails: inspect all calls to `SetAttribute` / `SetBdrAttribute` in topology + utility code, + * notably `src/lib/topology/topology.cpp` and `src/lib/utils/mesh_utils.cpp`. + */ +TEST_F(stroidTest, Finalize_ExternalDomainKeepsOnlyExpectedMaterialAndBoundaryIDs) { + const Config cfg = LoadConfigFromRepo("configs/test_external_domain.toml"); + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + + stroid::topology::Finalize(*mesh, cfg); + + const auto volume_attr_counts = CountVolumeAttributes(*mesh); + const std::set expected_volume_ids = { + static_cast(cfg->core_id), + static_cast(cfg->envelope_id), + static_cast(cfg->vacuum_id) + }; + for (const auto& [attr, count] : volume_attr_counts) { + EXPECT_TRUE(expected_volume_ids.contains(attr)); + EXPECT_GT(count, 0); + } + EXPECT_EQ(volume_attr_counts.size(), expected_volume_ids.size()); + + const auto boundary_attr_counts = CountBoundaryAttributes(*mesh); + const std::set expected_boundary_ids = { + static_cast(cfg->surface_bdr_id), + static_cast(cfg->inf_bdr_id) + }; + for (const auto& [attr, count] : boundary_attr_counts) { + EXPECT_TRUE(expected_boundary_ids.contains(attr)); + EXPECT_GT(count, 0); + } + EXPECT_EQ(boundary_attr_counts.size(), expected_boundary_ids.size()); +} + +/** + * @brief Verifies high-order promotion actually attaches nodal data. + * @details + * Rationale: projection and most quality metrics are node-based; missing nodes means pipeline misuse. + * Method: finalize then promote, assert nodes exist and are finite. + * If this fails: inspect `stroid::topology::PromoteToHighOrder` in + * `src/lib/topology/curvilinear.cpp` (`H1_FECollection`, `SetNodalFESpace`). + */ TEST_F(stroidTest, PromoteToHighOrder_SetsNodes) { const Config cfg; const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); @@ -92,6 +447,14 @@ TEST_F(stroidTest, PromoteToHighOrder_SetsNodes) { EXPECT_TRUE(IsFiniteMeshNodes(*mesh)); } +/** + * @brief Confirms projection does not produce NaN/Inf nodal coordinates. + * @details + * Rationale: finite nodes are the minimum numerical sanity condition for any downstream solver. + * Method: run full pre-projection pipeline, project once, assert all node components are finite. + * If this fails: inspect `ProjectMesh` and mapping functions in + * `src/lib/topology/curvilinear.cpp` and `src/lib/topology/mapping.cpp`. + */ TEST_F(stroidTest, ProjectMesh_ProducesFiniteNodes) { const Config cfg; const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); @@ -103,6 +466,13 @@ TEST_F(stroidTest, ProjectMesh_ProducesFiniteNodes) { EXPECT_TRUE(IsFiniteMeshNodes(*mesh)); } +/** + * @brief Unit-checks equiangular mapping against closed-form tangent expression. + * @details + * Rationale: this catches formula or branch edits before they propagate into mesh-wide projection. + * Method: transform a known point and compare against explicit `tan(pi/4 * ratio)` expectations. + * If this fails: inspect `ApplyEquiangular` in `src/lib/topology/mapping.cpp`, especially dominant-axis logic. + */ TEST_F(stroidTest, ApplyEquiangular_BasicTransform) { mfem::Vector pos(3); pos(0) = 1.0; @@ -117,6 +487,14 @@ TEST_F(stroidTest, ApplyEquiangular_BasicTransform) { EXPECT_NEAR(pos(2), expected_z, 1e-12); } +/** + * @brief Verifies spheroidal flattening scales only the z component as configured. + * @details + * Rationale: flattening is intentionally simple and should remain easy to reason about. + * Method: load flattening config, apply transform to z-axis point, check exact expected z. + * If this fails: inspect `ApplySpheroidal` in `src/lib/topology/mapping.cpp` and fixture values in + * `configs/test_flattening.toml`. + */ TEST_F(stroidTest, ApplySpheroidal_FlattensZ) { const Config cfg = LoadConfigFromRepo("configs/test_flattening.toml"); @@ -130,21 +508,14 @@ TEST_F(stroidTest, ApplySpheroidal_FlattensZ) { EXPECT_NEAR(pos(2), 8.0, 1e-12); } -TEST_F(stroidTest, ApplyKelvin_ExpandsOutsideStar) { - const Config cfg; - - mfem::Vector pos(3); - pos(0) = 5.5; - pos(1) = 0.0; - pos(2) = 0.0; - - stroid::topology::ApplyKelvin(pos, cfg); - - EXPECT_NEAR(pos(0), 6.0, 1e-12); - EXPECT_NEAR(pos(1), 0.0, 1e-12); - EXPECT_NEAR(pos(2), 0.0, 1e-12); -} - +/** + * @brief Ensures axis-aligned points inside the core stay unchanged in this mapping regime. + * @details + * Rationale: axis points are symmetry anchors; any drift here is usually a serious branch regression. + * Method: map `(1,0,0)` with default config and assert identity. + * If this fails: inspect `TransformPoint` core-zone blend path and instability guard in + * `src/lib/topology/mapping.cpp`. + */ TEST_F(stroidTest, TransformPoint_AxisInsideCore_NoChange) { const Config cfg; @@ -160,6 +531,13 @@ TEST_F(stroidTest, TransformPoint_AxisInsideCore_NoChange) { EXPECT_NEAR(pos(2), 0.0, 1e-12); } +/** + * @brief Ensures axis-aligned envelope points remain unchanged under default spherical setup. + * @details + * Rationale: this verifies envelope branch consistency and avoids silent radial drift. + * Method: map `(3,0,0)` and assert identity under default parameters. + * If this fails: inspect `TransformPoint` envelope branch and normalized-direction reconstruction logic. + */ TEST_F(stroidTest, TransformPoint_AxisEnvelope_NoChange) { const Config cfg; @@ -175,21 +553,92 @@ TEST_F(stroidTest, TransformPoint_AxisEnvelope_NoChange) { EXPECT_NEAR(pos(2), 0.0, 1e-12); } -TEST_F(stroidTest, TransformPoint_AxisOutsideStar_KelvinExpands) { +/** + * @brief Checks continuity near `r_core` and `r_star` transition surfaces. + * @details + * Rationale: discontinuities at interfaces destabilize high-order interpolation and integration. + * Method: evaluate points at `r*(1±eps)` and assert mapped separation stays small in L2 norm. + * If this fails: inspect transition formulas in `TransformPoint` (core blend, envelope mapping) + * and any recent edits to `core_steepness` handling. + */ +TEST_F(stroidTest, TransformPoint_IsContinuousAcrossCoreAndStarInterfaces) { const Config cfg; + constexpr double eps = 1e-6; - mfem::Vector pos(3); - pos(0) = 5.5; - pos(1) = 0.0; - pos(2) = 0.0; + mfem::Vector dir(3); + dir(0) = 1.0; + dir(1) = 0.6; + dir(2) = -0.4; - stroid::topology::TransformPoint(pos, cfg, 0); + mfem::Vector near_core_left = dir; + near_core_left *= cfg->r_core * (1.0 - eps); + mfem::Vector near_core_right = dir; + near_core_right *= cfg->r_core * (1.0 + eps); - EXPECT_NEAR(pos(0), 6.0, 1e-12); - EXPECT_NEAR(pos(1), 0.0, 1e-12); - EXPECT_NEAR(pos(2), 0.0, 1e-12); + const mfem::Vector core_left_mapped = TransformCopy(near_core_left, cfg); + const mfem::Vector core_right_mapped = TransformCopy(near_core_right, cfg); + + mfem::Vector diff = core_left_mapped; + diff -= core_right_mapped; + EXPECT_LT(diff.Norml2(), 1e-3); + + mfem::Vector near_star_left = dir; + near_star_left *= cfg->r_star * (1.0 - eps); + mfem::Vector near_star_right = dir; + near_star_right *= cfg->r_star * (1.0 + eps); + + const mfem::Vector star_left_mapped = TransformCopy(near_star_left, cfg); + const mfem::Vector star_right_mapped = TransformCopy(near_star_right, cfg); + + diff = star_left_mapped; + diff -= star_right_mapped; + EXPECT_LT(diff.Norml2(), 1e-3); } +/** + * @brief Verifies expected sign and axis-permutation symmetry in the spherical case. + * @details + * Rationale: symmetry violations usually indicate branch asymmetry bugs in mapping logic. + * Method: compare mapped values for original, sign-flipped, and axis-swapped points. + * If this fails: inspect dominant-axis branching in `ApplyEquiangular` and normalization flow in + * `TransformPoint`. + */ +TEST_F(stroidTest, TransformPoint_RespectsSignAndAxisPermutationSymmetryWithoutFlattening) { + const Config cfg; + + mfem::Vector p(3); + p(0) = 4.0; + p(1) = 2.0; + p(2) = 1.0; + + mfem::Vector p_neg = p; + p_neg *= -1.0; + + mfem::Vector p_swapped(3); + p_swapped(0) = p(1); + p_swapped(1) = p(0); + p_swapped(2) = p(2); + + const mfem::Vector mapped = TransformCopy(p, cfg); + const mfem::Vector mapped_neg = TransformCopy(p_neg, cfg); + const mfem::Vector mapped_swapped = TransformCopy(p_swapped, cfg); + + EXPECT_NEAR(mapped_neg(0), -mapped(0), 1e-12); + EXPECT_NEAR(mapped_neg(1), -mapped(1), 1e-12); + EXPECT_NEAR(mapped_neg(2), -mapped(2), 1e-12); + + EXPECT_NEAR(mapped_swapped(0), mapped(1), 1e-12); + EXPECT_NEAR(mapped_swapped(1), mapped(0), 1e-12); + EXPECT_NEAR(mapped_swapped(2), mapped(2), 1e-12); +} + +/** + * @brief Smoke-tests mesh serialization to MFEM format. + * @details + * Rationale: I/O regressions are easy to miss during geometry-focused development. + * Method: write a finalized mesh to temp storage and assert file exists and is non-empty. + * If this fails: inspect `stroid::IO::SaveMesh` in `src/lib/IO/mesh.cpp` and local filesystem perms. + */ TEST_F(stroidTest, SaveMesh_WritesFile) { const Config cfg; const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); @@ -207,6 +656,14 @@ TEST_F(stroidTest, SaveMesh_WritesFile) { std::filesystem::remove(mesh_path, ec); } +/** + * @brief End-to-end baseline pipeline test for the default domain. + * @details + * Rationale: validates the canonical operation order used by both library examples and CLI. + * Method: execute full pipeline and assert non-empty, nodal, finite output mesh. + * If this fails: check call-order assumptions and recent edits in + * `src/lib/topology/topology.cpp` / `src/lib/topology/curvilinear.cpp`. + */ TEST_F(stroidTest, EndToEnd_BuildFinalizePromoteProject) { const Config cfg; const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); @@ -218,3 +675,215 @@ TEST_F(stroidTest, EndToEnd_BuildFinalizePromoteProject) { EXPECT_NE(mesh->GetNodes(), nullptr); EXPECT_TRUE(IsFiniteMeshNodes(*mesh)); } + +/** + * @brief End-to-end pipeline test for external-domain meshes. + * @details + * Rationale: confirms the same pipeline remains valid when vacuum blocks are included. + * Method: run full external-domain pipeline and assert conforming + finite nodal output. + * If this fails: inspect external-domain topology assembly and projection loops over mixed attributes. + */ +TEST_F(stroidTest, EndToEnd_ExternalDomainBuildFinalizePromoteProject) { + const Config cfg = LoadConfigFromRepo("configs/test_external_domain.toml"); + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + stroid::topology::Finalize(*mesh, cfg); + stroid::topology::PromoteToHighOrder(*mesh, cfg); + stroid::topology::ProjectMesh(*mesh, cfg); + + EXPECT_TRUE(mesh->Conforming()); + EXPECT_GT(mesh->GetNE(), 0); + EXPECT_NE(mesh->GetNodes(), nullptr); + EXPECT_TRUE(IsFiniteMeshNodes(*mesh)); +} + +/** + * @brief Verifies stellar volume invariance with respect to adding a vacuum shell. + * @details + * Rationale: the vacuum region should extend domain extent, not alter stellar mass volume. + * Method: integrate core+envelope volume in both configs and compare relative difference. + * If this fails: inspect attribute-filtered volume helpers in this file and mapping/topology changes + * that may leak starside nodes into vacuum geometry. + */ +TEST_F(stroidTest, Volume_StellarDomainMatchesWithAndWithoutExternalDomain) { + const Config no_external_cfg = LoadConfigFromRepo("configs/test_volume_no_external.toml"); + const Config with_external_cfg = LoadConfigFromRepo("configs/test_volume_with_external.toml"); + + const std::unique_ptr no_external_mesh = stroid::topology::BuildSkeleton(no_external_cfg); + stroid::topology::Finalize(*no_external_mesh, no_external_cfg); + stroid::topology::PromoteToHighOrder(*no_external_mesh, no_external_cfg); + stroid::topology::ProjectMesh(*no_external_mesh, no_external_cfg); + + const std::unique_ptr with_external_mesh = stroid::topology::BuildSkeleton(with_external_cfg); + stroid::topology::Finalize(*with_external_mesh, with_external_cfg); + stroid::topology::PromoteToHighOrder(*with_external_mesh, with_external_cfg); + stroid::topology::ProjectMesh(*with_external_mesh, with_external_cfg); + + const std::set stellar_attrs_no_external = { + static_cast(no_external_cfg->core_id), + static_cast(no_external_cfg->envelope_id) + }; + const std::set stellar_attrs_with_external = { + static_cast(with_external_cfg->core_id), + static_cast(with_external_cfg->envelope_id) + }; + + const double stellar_volume_no_external = ComputeMeshVolumeForAttributes(*no_external_mesh, stellar_attrs_no_external); + const double stellar_volume_with_external = ComputeMeshVolumeForAttributes(*with_external_mesh, stellar_attrs_with_external); + + const double rel_diff = std::abs(stellar_volume_with_external - stellar_volume_no_external) / + std::max(stellar_volume_with_external, stellar_volume_no_external); + EXPECT_LT(rel_diff, 5e-3); +} + +/** + * @brief Confirms total volume decomposition into stellar + vacuum components. + * @details + * Rationale: this explicitly checks that vacuum exclusion logic is doing real work, not a no-op. + * Method: on external mesh, compute total, stellar-only, and vacuum-only volumes and enforce + * additive consistency. + * If this fails: inspect `ComputeMeshVolume*` helpers and region attribute IDs in config fixtures. + */ +TEST_F(stroidTest, Volume_ExternalMeshExcludesVacuumWhenRequested) { + const Config cfg = LoadConfigFromRepo("configs/test_volume_with_external.toml"); + + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + stroid::topology::Finalize(*mesh, cfg); + stroid::topology::PromoteToHighOrder(*mesh, cfg); + stroid::topology::ProjectMesh(*mesh, cfg); + + const std::set stellar_attrs = { + static_cast(cfg->core_id), + static_cast(cfg->envelope_id) + }; + const std::set vacuum_attr = {static_cast(cfg->vacuum_id)}; + + const double total_volume = ComputeMeshVolume(*mesh); + const double stellar_volume = ComputeMeshVolumeForAttributes(*mesh, stellar_attrs); + const double vacuum_volume = ComputeMeshVolumeForAttributes(*mesh, vacuum_attr); + + EXPECT_GT(vacuum_volume, 0.0); + EXPECT_GT(total_volume, stellar_volume); + EXPECT_NEAR(total_volume, stellar_volume + vacuum_volume, total_volume * 1e-9 + 1e-12); +} + +/** + * @brief Compares direct Jacobian-based stellar volume to analytic sphere volume. + * @details + * Rationale: anchors numerical integration against a closed-form reference in the spherical limit. + * Method: integrate core+envelope using element transformations, compare to `4/3*pi*r_star^3`. + * If this fails: inspect mapping spherical path (`flattening=0`) and quadrature order in + * `IntegrateElementVolume`. + */ +TEST_F(stroidTest, Volume_SphericalStellarDomainMatchesAnalyticSphere) { + const Config cfg = LoadConfigFromRepo("configs/test_volume_spherical_no_external.toml"); + + const std::unique_ptr mesh = stroid::topology::BuildSkeleton(cfg); + stroid::topology::Finalize(*mesh, cfg); + stroid::topology::PromoteToHighOrder(*mesh, cfg); + stroid::topology::ProjectMesh(*mesh, cfg); + + const std::set stellar_attrs = { + static_cast(cfg->core_id), + static_cast(cfg->envelope_id) + }; + + const double measured_volume = ComputeMeshVolumeForAttributes(*mesh, stellar_attrs); + const double analytic_volume = 4.0 / 3.0 * kPi * std::pow(cfg->r_star, 3.0); + const double rel_err = std::abs(measured_volume - analytic_volume) / analytic_volume; + + EXPECT_LT(rel_err, 1e-2); +} + +/** + * @brief Repeats spherical analytic-volume check via MFEM `DomainLFIntegrator`. + * @details + * Rationale: independent integration machinery lowers the risk of helper-specific false confidence. + * Method: build attribute-weighted `PWConstCoefficient` (core+envelope=1, vacuum=0), assemble + * domain linear form, and compare against analytic sphere volume. + * If this fails: inspect coefficient indexing (attr-1 convention), `ComputeStellarVolumeWithDomainLFIntegrator`, + * and MFEM assembly setup in this test file. + */ +TEST_F(stroidTest, Volume_SphericalStellarDomainDomainLFIntegratorMatchesAnalyticSphere) { + const Config cfg = LoadConfigFromRepo("configs/test_volume_spherical_with_external.toml"); + + std::unique_ptr mesh = BuildProjectedMesh(cfg); + const double measured_volume = ComputeStellarVolumeWithDomainLFIntegrator(*mesh, cfg); + const double analytic_volume = 4.0 / 3.0 * kPi * std::pow(cfg->r_star, 3.0); + const double rel_err = std::abs(measured_volume - analytic_volume) / analytic_volume; + + EXPECT_LT(rel_err, 1e-2); +} + +/** + * @brief Enforces baseline conditioning bounds for the default projected mesh. + * @details + * Rationale: this guards against silent degradation in element quality that may still pass finiteness checks. + * Method: sample Jacobian stats over quadrature points and assert positivity + distortion/stretch bounds. + * If this fails: inspect mapping formulas in `src/lib/topology/mapping.cpp` and any changes to + * refinement/order config used by `configs/test_volume_spherical_no_external.toml`. + */ +TEST_F(stroidTest, Conditioning_DefaultMeshHasPositiveJacobiansAndReasonableShape) { + const Config cfg = LoadConfigFromRepo("configs/test_volume_spherical_no_external.toml"); + const std::unique_ptr mesh = BuildProjectedMesh(cfg); + + const ConditioningStats stats = CollectConditioningStats(*mesh, {}); + + ASSERT_GT(stats.samples, 0); + EXPECT_GT(stats.min_det, 1e-10); + EXPECT_LT(stats.max_det / stats.min_det, 1e6); + EXPECT_GT(stats.min_scaled_jac, 2e-2); + EXPECT_LT(stats.max_stretch_ratio, 50.0); + EXPECT_LT(stats.max_edge_ratio, 50.0); +} + +/** + * @brief Applies Jacobian conditioning checks independently to core, envelope, and vacuum regions. + * @details + * Rationale: global stats can hide localized failures; region-level checks make regressions diagnosable. + * Method: collect conditioning statistics per attribute and enforce positive Jacobians + scaled-Jacobian floors. + * If this fails: inspect region-specific mapping behavior in `TransformPoint` and verify attribute + * assignment in `BuildSkeleton`. + */ +TEST_F(stroidTest, Conditioning_ExternalMeshPerRegionHasPositiveJacobians) { + const Config cfg = LoadConfigFromRepo("configs/test_volume_spherical_with_external.toml"); + const std::unique_ptr mesh = BuildProjectedMesh(cfg); + + const ConditioningStats core_stats = CollectConditioningStats(*mesh, {static_cast(cfg->core_id)}); + const ConditioningStats envelope_stats = CollectConditioningStats(*mesh, {static_cast(cfg->envelope_id)}); + const ConditioningStats vacuum_stats = CollectConditioningStats(*mesh, {static_cast(cfg->vacuum_id)}); + + ASSERT_GT(core_stats.samples, 0); + ASSERT_GT(envelope_stats.samples, 0); + ASSERT_GT(vacuum_stats.samples, 0); + + EXPECT_GT(core_stats.min_det, 1e-10); + EXPECT_GT(envelope_stats.min_det, 1e-10); + EXPECT_GT(vacuum_stats.min_det, 1e-10); + + EXPECT_GT(core_stats.min_scaled_jac, 2e-2); + EXPECT_GT(envelope_stats.min_scaled_jac, 2e-2); + EXPECT_GT(vacuum_stats.min_scaled_jac, 1e-3); +} + +/** + * @brief Validates orientation quality via flipped-element and flipped-boundary markers. + * @details + * Rationale: this is a direct orientation sanity check using project utilities already used for debugging. + * Method: run `MarkFlippedElements`/`MarkFlippedBoundaryElements` and assert sentinel attrs are absent. + * If this fails: inspect Jacobian sign behavior and boundary normal orientation code in + * `src/lib/utils/mesh_utils.cpp`, then trace upstream mapping changes. + */ +TEST_F(stroidTest, Conditioning_DefaultMeshHasNoFlippedElementsOrBoundaryFaces) { + const Config cfg = LoadConfigFromRepo("configs/test_volume_spherical_no_external.toml"); + std::unique_ptr mesh = BuildProjectedMesh(cfg); + + stroid::utils::MarkFlippedElements(*mesh); + stroid::utils::MarkFlippedBoundaryElements(*mesh); + + const auto volume_attr_counts = CountVolumeAttributes(*mesh); + const auto boundary_attr_counts = CountBoundaryAttributes(*mesh); + + EXPECT_FALSE(volume_attr_counts.contains(999)); + EXPECT_FALSE(boundary_attr_counts.contains(500)); +} + diff --git a/tools/python/visualize_winding.py b/tools/python/visualize_winding.py new file mode 100644 index 0000000..d722639 --- /dev/null +++ b/tools/python/visualize_winding.py @@ -0,0 +1,46 @@ +import matplotlib.pyplot as plt + +class Box: + def __init__(self, scale, vc="red", ec="blue", offset=0): + self.scale = scale + self.offset = offset + self.verticies = [[scale, -scale, -scale], [scale, scale, -scale], [-scale, -scale, -scale], [-scale, scale, -scale], [scale, -scale, scale], [scale, scale, scale], [-scale, -scale, scale], [-scale, scale, scale]] + self.edges = [[0, 1], [0, 2], [0, 4], [1, 3], [1, 5], [3, 7], [3, 2], [2, 6], [4, 5], [4, 6], [5, 7], [7, 6]] + self.edge_color = ec + self.vertex_color = vc + + def plot(self, ax, vlabel=True, elabel=False): + for vertID, vert in enumerate(self.verticies): + ax.scatter(vert[0], vert[1], vert[2], c=self.vertex_color) + if vlabel: + ax.text(vert[0], vert[1], vert[2], f"{self.offset + vertID}", fontsize=25) + for edge in self.edges: + ax.plot([self.verticies[edge[0]][0], self.verticies[edge[1]][0]], [self.verticies[edge[0]][1], self.verticies[edge[1]][1]], [self.verticies[edge[0]][2], self.verticies[edge[1]][2]], color=self.edge_color) + +class Wedge: + def __init__(self, A, B, ec="green"): + self.A = A + self.B = B + self.edge_color = ec + def plot(self, ax): + for vA, vB in zip(self.A.verticies, self.B.verticies): + ax.plot([vA[0], vB[0]], [vA[1], vB[1]], [vA[2], vB[2]], color=self.edge_color) + +def main(): + core = Box(0.5) + envelope = Box(2, offset=8) + star = Wedge(core, envelope) + infinity = Box(5, offset=16) + vacuum = Wedge(envelope, infinity) + + fig, ax = plt.subplots(1, 1, figsize=(10, 10), subplot_kw={"projection": "3d"}) + core.plot(ax) + envelope.plot(ax) + star.plot(ax) + infinity.plot(ax) + vacuum.plot(ax) + ax.view_init(30, 30) + plt.show() + +if __name__ == "__main__": + main() diff --git a/tools/stroid.cpp b/tools/stroid.cpp index 81df116..e1cd2b8 100644 --- a/tools/stroid.cpp +++ b/tools/stroid.cpp @@ -112,11 +112,13 @@ int main(int argc, char** argv) { info->add_flag_callback("-v,--version", []() { std::println("Stroid Version {}", stroid::version::toString()); + exit(0); }, "Display stroid version information"); info->add_flag_callback("-d,--default", [&cfg]() { cfg.save("default.toml"); std::println("Default configuration saved to default.toml"); + exit(0); }, "Save the default configuration to default.toml"); try {