feat(mesh): non conforming vacuum
stroid can now generate non uniformly refined vacuum meshes. Note we still enforce that the stellar domain is fully conforming.
This commit is contained in:
122
readme.md
122
readme.md
@@ -103,11 +103,11 @@ smoothstep = true
|
||||
<!-- Table of what these parameters do -->
|
||||
| Parameter | Description | Default |
|
||||
|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
|
||||
| refinement_levels | Number of uniform refinement levels to apply to the mesh after generation | 4 |
|
||||
| refinement_levels | Stellar minimum depth, or uniform depth when vacuum overrides are omitted | 4 |
|
||||
| order | The polynomial order of the finite elements in the mesh | 3 |
|
||||
| include_external_domain | Whether to include an external domain extending to r_infinity | true |
|
||||
| r_core | The radius of the core region of the star | 1.5 |
|
||||
| r_star | The radius of the star | 5.0 |
|
||||
| r_core | The radius of the core region of the star | 0.25 |
|
||||
| r_star | The radius of the star | 1.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 |
|
||||
@@ -123,7 +123,11 @@ smoothstep = true
|
||||
|
||||
|
||||
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.
|
||||
need only include parameters that differ from the defaults. For compatibility with older TOML files,
|
||||
an omitted `core_mapping` uses `"spherified"`, and omitted TMOP controls leave optimization disabled.
|
||||
Set `core_mapping = "multi_block"` explicitly to use the conditioned mapping in a TOML file.
|
||||
Default-constructed C++ and Python `MeshConfig` objects select `"multi_block"`; other omitted TOML
|
||||
geometry fields use the defaults from `MeshConfig`.
|
||||
|
||||
### Conditioned core mapping
|
||||
|
||||
@@ -148,32 +152,98 @@ build/tools/geometry_quality_experiment --orders 4 --refinements 2 \
|
||||
--contraction-probe --probe-order 3 --output core_comparison.csv
|
||||
```
|
||||
|
||||
### Nonconforming vacuum refinement
|
||||
|
||||
Stroid can keep the star and both ends of the vacuum well resolved while using
|
||||
coarser elements in the vacuum interior. Refinement is isotropic: each refinement
|
||||
splits a hexahedron into eight children. Note however that only one geometric polynomial `order` applies
|
||||
to every region.
|
||||
|
||||
```toml
|
||||
[main]
|
||||
refinement_levels = 4
|
||||
vacuum_refinement_levels = 2
|
||||
# Optional: omitted outer depth inherits refinement_levels (4 here).
|
||||
# vacuum_outer_refinement_levels = 4
|
||||
order = 3
|
||||
include_external_domain = true
|
||||
core_mapping = "multi_block"
|
||||
|
||||
[main.optimization_methods]
|
||||
tmop = false
|
||||
smoothstep = true
|
||||
```
|
||||
|
||||
`configs/nonconforming_vacuum.toml` provides a complete example. The three depth
|
||||
settings are absolute minimum targets measured from the initial block topology:
|
||||
|
||||
| Setting | Applies to | Default |
|
||||
|----------------------------------|------------------------------------------|-----------------------------|
|
||||
| `refinement_levels` | Core and envelope | `4` |
|
||||
| `vacuum_refinement_levels` | Vacuum interior | Inherit `refinement_levels` |
|
||||
| `vacuum_outer_refinement_levels` | Cells touching the vacuum outer boundary | Inherit `refinement_levels` |
|
||||
|
||||
Omitting both vacuum overrides preserves uniform generation. Supplying either
|
||||
activates the local refinement policy and requires `include_external_domain = true`.
|
||||
All levels must be nonnegative integers.
|
||||
|
||||
Stroid enforces that vacuum cells touching the stellar surface match the stellar face subdivision. That is to say that
|
||||
the inner boundary of the vacuum region is conforming to the outer boundary of the stellar region. Further, the
|
||||
outer-boundary cells receive the outer target, and automatic grading limits neighboring refinement depths to one level.
|
||||
This two layer approach is intended to allow for refinement when using compactification maps.
|
||||
|
||||
```python
|
||||
import stroid
|
||||
|
||||
cfg = stroid.config.MeshConfig(
|
||||
refinement_levels=4,
|
||||
vacuum_refinement_levels=2,
|
||||
vacuum_outer_refinement_levels=None, # Inherit stellar depth.
|
||||
order=3,
|
||||
core_mapping="multi_block",
|
||||
optimization_methods=stroid.config.OptimizationMethods(tmop=False),
|
||||
)
|
||||
mesh = stroid.GenerateMesh(cfg)
|
||||
features = stroid.stats.MESH_STAT_DEFAULT | stroid.stats.MeshStatFeatures.ELEMENT_COUNT
|
||||
stats = stroid.stats.ComputeMeshStats(mesh, features)
|
||||
print(stats.element_counts.vacuum)
|
||||
print(stats.refinement.vacuum.min_depth, stats.refinement.vacuum.max_depth)
|
||||
print(stats.refinement.geometry_dofs, stats.refinement.geometry_true_dofs)
|
||||
print(stats.conformity.conforming, stats.conformity.n_nonconforming_faces)
|
||||
|
||||
stroid.IO.SaveStroidMesh(mesh, "graded.stroid")
|
||||
restored = stroid.IO.LoadStroidMesh("graded.stroid")
|
||||
stroid.refinement.UniformRefinement(restored, 1)
|
||||
```
|
||||
|
||||
|
||||
The `UniformRefinement(mesh, n)` function adds `n` levels to every current leaf while preserving the
|
||||
existing grading, and rebuilds the geometry and exterior coordinate. Note that this means that a non-conforming mesh
|
||||
that has been Uniformly refined will still be non-conforming, but the refinement will be applied to all leaves.
|
||||
|
||||
#### Viewing curved meshes in GLVis
|
||||
|
||||
It is important to note --- and potentially confusing if not understood --- that GLVis approximates curved faces with
|
||||
flat triangles. At a hanging interface, the same subdivision count on a coarse face and its finer neighbors samples the
|
||||
curved surface at different locations. This can produce apparent gaps even when the finite-element face transformations
|
||||
agree. These gaps are not indications that the mesh itself is non-conforming; rather, they are a visualization artifact.
|
||||
|
||||
### C++ Interface
|
||||
Stroid can be used as a library in C++ projects. After installation, include the stroid header and link against the stroid library.
|
||||
|
||||
A basic example of using stroid in C++ is shown below (note that you will need a glvis instance running on localhost:19916 to visualize the mesh):
|
||||
```c++
|
||||
#include <memory>
|
||||
#include "mfem.hpp"
|
||||
|
||||
#include "stroid/config/config.h"
|
||||
#include "stroid/IO/mesh.h"
|
||||
#include "stroid/topology/curvilinear.h"
|
||||
#include "stroid/topology/topology.h"
|
||||
|
||||
#include "fourdst/config/config.h"
|
||||
#include "stroid/stroid.h"
|
||||
|
||||
int main() {
|
||||
const fourdst::config::Config<stroid::config::MeshConfig> cfg;
|
||||
stroid::config::MeshConfig cfg;
|
||||
cfg.refinement_levels = 4;
|
||||
cfg.vacuum_refinement_levels = 2;
|
||||
cfg.optimization_methods = stroid::config::OptimizationMethods{false, true};
|
||||
|
||||
const std::unique_ptr<mfem::Mesh> mesh = stroid::topology::BuildSkeleton(cfg);
|
||||
stroid::topology::Finalize(*mesh, cfg);
|
||||
stroid::topology::PromoteToHighOrder(*mesh, cfg);
|
||||
stroid::topology::ProjectMesh(*mesh, cfg);
|
||||
stroid::topology::OptimizeMesh(*mesh, cfg);
|
||||
|
||||
|
||||
stroid::IO::ViewMesh(*mesh, "Spheroidal Mesh", stroid::IO::VISUALIZATION_MODE::BOUNDARY_ELEMENT_ID);
|
||||
auto mesh = stroid::GenerateMesh(cfg);
|
||||
stroid::IO::SaveStroidMesh(mesh, "graded.stroid");
|
||||
stroid::IO::ViewMesh(mesh, "Spheroidal Mesh", stroid::IO::VISUALIZATION_MODE::ELEMENT_ID, "localhost", 19916);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -184,8 +254,12 @@ An example mesh with the default configuration parameters is shown below (colora
|
||||
The legacy spherified core mapping strategy is shown below as well
|
||||

|
||||
|
||||
Note that both of these meshes are shown with 3 levels of refinement and polynomial order 3. Blue shows the stellar
|
||||
domain while purple shows the vacuum domain.
|
||||
An example of a non-conforming mesh generated with stroid. Note that the gaps between elements are a visualization artifact
|
||||
rather than true gaps within the mesh.
|
||||

|
||||
|
||||
Note that both of these meshes are shown with 3 levels of refinement and polynomial order 3. Blue shows the core
|
||||
domain, yellow shows the envelope domain, while purple shows the vacuum domain.
|
||||
|
||||
|
||||
## Funding
|
||||
|
||||
Reference in New Issue
Block a user