Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,12 @@ class QualityMetrics(Flow360BaseModel):
alias="max_concave",
description="Maximum cell concavity. Set to False to disable this metric.",
)
min_pyramid_cell_volume: Union[float, Literal[False]] = pd.Field(
default=1e-15,
min_pyramid_cell_volume: Optional[Union[float, Literal[False]]] = pd.Field(
default=None,
alias="min_vol",
description="Minimum cell pyramid volume [mesh_unit³]. "
+ "Set to False to disable this metric (uses -1e30 internally).",
+ "Set to False to disable this metric (uses -1e30 internally). "
+ "Defaults to (effective_min_spacing³) * 1e-10 when not specified.",
)
min_tetrahedron_quality: Union[float, Literal[False]] = pd.Field(
default=1e-9,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,55 @@ def apply_UniformRefinement_w_snappy(
translated["geometry"]["refinementVolumes"].append(volume_body)


def _none_tolerant_min(current, candidate):
"""Return the smaller of two spacing quantities, comparing by raw value."""
if candidate is not None and candidate < current:
return candidate
return current


def _get_effective_min_spacing(input_params, spacing_system: OctreeSpacing):
"""
Get the effective minimum spacing across all refinements,
taking proximity_spacing (gap spacing reduction), edge spacings, and
projected volume refinements into account.
The result is cast to the nearest lower spacing in the octree series.
"""
surface_meshing_params = input_params.meshing.surface_meshing
min_spacing = surface_meshing_params.defaults.min_spacing

for refinement in surface_meshing_params.refinements or []:
if isinstance(refinement, (snappy.BodyRefinement, snappy.RegionRefinement)):
min_spacing = _none_tolerant_min(min_spacing, refinement.min_spacing)
min_spacing = _none_tolerant_min(min_spacing, refinement.proximity_spacing)
elif (
isinstance(refinement, snappy.SurfaceEdgeRefinement) and refinement.spacing is not None
):
edge_spacing = (
refinement.spacing[0]
if isinstance(refinement.spacing, unyt_array)
and isinstance(refinement.distances, unyt_array)
and len(refinement.spacing) > 0
else refinement.spacing
)
min_spacing = _none_tolerant_min(min_spacing, edge_spacing)
elif isinstance(refinement, UniformRefinement):
min_spacing = _none_tolerant_min(min_spacing, refinement.spacing)

# Also consider projected volume meshing refinements
if input_params.meshing.volume_meshing is not None:
for refinement in input_params.meshing.volume_meshing.refinements:
if isinstance(refinement, UniformRefinement) and refinement.project_to_surface in [
True,
None,
]:
min_spacing = _none_tolerant_min(min_spacing, refinement.spacing)

# Cast to the nearest lower spacing in the octree series
level = spacing_system.to_level(min_spacing)[0]
return spacing_system[level].value.item()


# pylint: disable=too-many-branches,too-many-statements,too-many-locals
def snappy_mesher_json(input_params: SimulationParams):
"""
Expand Down Expand Up @@ -412,9 +461,13 @@ def snappy_mesher_json(input_params: SimulationParams):
else 180
),
"minVol": (
quality_settings.min_pyramid_cell_volume
if quality_settings.min_pyramid_cell_volume
else -1e30
-1e30
if quality_settings.min_pyramid_cell_volume is False
else (
quality_settings.min_pyramid_cell_volume
if quality_settings.min_pyramid_cell_volume is not None
else (1e-10 * (_get_effective_min_spacing(input_params, spacing_system) ** 3))
)
),
"minTetQuality": (
quality_settings.min_tetrahedron_quality
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"maxBoundarySkewness": 20,
"maxInternalSkewness": 50,
"maxConcave": 50,
"minVol": 1e-15,
"minVol": 8e-10,
"minTetQuality": 1e-9,
"minArea": 1e-12,
"minTwist": -2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
"maxBoundarySkewness": 20,
"maxInternalSkewness": 50,
"maxConcave": 50,
"minVol": 1e-15,
"minVol": 1.308441162109375e-13,
"minTetQuality": 1e-9,
"minArea": 1e-12,
"minTwist": -2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
"maxBoundarySkewness": 20,
"maxInternalSkewness": 50,
"maxConcave": 50,
"minVol": 1e-15,
"minVol": 1.953125e-10,
"minTetQuality": 1e-9,
"minArea": 1e-12,
"minTwist": -2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"maxBoundarySkewness": 20,
"maxInternalSkewness": 50,
"maxConcave": 50,
"minVol": 1e-15,
"minVol": 1.953125e-13,
"minTetQuality": 1e-9,
"minArea": 1e-12,
"minTwist": -2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
"maxBoundarySkewness": 20,
"maxInternalSkewness": 50,
"maxConcave": 50,
"minVol": 1e-15,
"minVol": 2.7e-09,
"minTetQuality": 1e-9,
"minArea": 1e-12,
"minTwist": -2,
Expand Down
12 changes: 9 additions & 3 deletions tests/simulation/translator/test_surface_meshing_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,7 @@ def test_rotor_surface_mesh(get_rotor_geometry, rotor_surface_mesh):

def test_snappy_default(get_snappy_geometry, snappy_all_defaults):
_translate_and_compare(
snappy_all_defaults, get_snappy_geometry.mesh_unit, "default_snappy.json"
snappy_all_defaults, get_snappy_geometry.mesh_unit, "default_snappy.json", atol=1e-6
)


Expand All @@ -1073,11 +1073,14 @@ def test_snappy_multiple_regions(get_snappy_geometry, snappy_refinements_multipl
snappy_refinements_multiple_regions,
get_snappy_geometry.mesh_unit,
"snappy_refinements_multiple_regions.json",
atol=1e-6,
)


def test_snappy_settings(get_snappy_geometry, snappy_settings):
_translate_and_compare(snappy_settings, get_snappy_geometry.mesh_unit, "snappy_settings.json")
_translate_and_compare(
snappy_settings, get_snappy_geometry.mesh_unit, "snappy_settings.json", atol=1e-6
)


def test_snappy_settings_off_position(get_snappy_geometry, snappy_settings_off_position):
Expand All @@ -1088,7 +1091,10 @@ def test_snappy_settings_off_position(get_snappy_geometry, snappy_settings_off_p

def test_snappy_no_refinements(get_snappy_geometry, snappy_refinements_no_regions):
_translate_and_compare(
snappy_refinements_no_regions, get_snappy_geometry.mesh_unit, "snappy_no_regions.json"
snappy_refinements_no_regions,
get_snappy_geometry.mesh_unit,
"snappy_no_regions.json",
atol=1e-6,
)


Expand Down
Loading