Skip to content

Commit 99eab68

Browse files
Merge pull request #1740 from flexcompute/develop
Merge develop into main, starting next release cycle
2 parents c3e9976 + 756e9ab commit 99eab68

File tree

8 files changed

+145
-3
lines changed

8 files changed

+145
-3
lines changed

flow360/component/simulation/meshing_param/meshing_specs.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,21 @@ class MeshingDefaults(Flow360BaseModel):
161161

162162
remove_non_manifold_faces: bool = pd.Field(
163163
False,
164-
description="Flag to remove non-manifold and interior faces.",
164+
description="Flag to remove non-manifold and interior faces. "
165+
+ "This option is only supported when using geometry AI.",
166+
)
167+
168+
remove_hidden_geometry: bool = pd.Field(
169+
False,
170+
description="Flag to remove hidden geometry that is not visible to flow. "
171+
+ "This option is only supported when using geometry AI.",
172+
)
173+
174+
flooding_cell_size: Optional[LengthType.Positive] = pd.Field(
175+
None,
176+
description="Minimum cell size used for flood-fill exterior classification. "
177+
+ "If not specified, the value is derived from geometry_accuracy and sealing_size. "
178+
+ "This option is only supported when using geometry AI.",
165179
)
166180

167181
@contextual_field_validator("number_of_boundary_layers", mode="after")
@@ -190,13 +204,34 @@ def invalid_geometry_accuracy(cls, value, param_info: ParamsValidationInfo):
190204
"preserve_thin_geometry",
191205
"sealing_size",
192206
"remove_non_manifold_faces",
207+
"remove_hidden_geometry",
208+
"flooding_cell_size",
193209
mode="after",
194210
)
195211
@classmethod
196212
def ensure_geometry_ai_features(cls, value, info, param_info: ParamsValidationInfo):
197213
"""Validate that the feature is only used when Geometry AI is enabled."""
198214
return check_geometry_ai_features(cls, value, info, param_info)
199215

216+
@pd.model_validator(mode="after")
217+
def validate_mutual_exclusion(self):
218+
"""Ensure remove_non_manifold_faces and remove_hidden_geometry are not both True."""
219+
if self.remove_non_manifold_faces and self.remove_hidden_geometry:
220+
raise ValueError(
221+
"'remove_non_manifold_faces' and 'remove_hidden_geometry' cannot both be True. "
222+
"Please enable only one of these options."
223+
)
224+
return self
225+
226+
@pd.model_validator(mode="after")
227+
def validate_flooding_cell_size_requires_remove_hidden_geometry(self):
228+
"""Ensure flooding_cell_size is only specified when remove_hidden_geometry is True."""
229+
if self.flooding_cell_size is not None and not self.remove_hidden_geometry:
230+
raise ValueError(
231+
"'flooding_cell_size' can only be specified when 'remove_hidden_geometry' is True."
232+
)
233+
return self
234+
200235

201236
class VolumeMeshingDefaults(Flow360BaseModel):
202237
"""

flow360/component/simulation/translator/surface_meshing_translator.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,8 @@ def _get_gai_setting_whitelist(input_params: SimulationParams) -> dict:
727727
"surface_max_adaptation_iterations": None,
728728
"sealing_size": None,
729729
"remove_non_manifold_faces": None,
730+
"remove_hidden_geometry": None,
731+
"flooding_cell_size": None,
730732
"planar_face_tolerance": None,
731733
}
732734

tests/ref/simulation/service_init_geometry.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"units": "m"
2424
},
2525
"sliding_interface_tolerance": 0.01,
26-
"remove_non_manifold_faces": false
26+
"remove_non_manifold_faces": false,
27+
"remove_hidden_geometry": false
2728
},
2829
"outputs": [],
2930
"refinements": [],

tests/ref/simulation/service_init_surface_mesh.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"units": "m"
2424
},
2525
"sliding_interface_tolerance": 0.01,
26-
"remove_non_manifold_faces": false
26+
"remove_non_manifold_faces": false,
27+
"remove_hidden_geometry": false
2728
},
2829
"outputs": [],
2930
"refinements": [],

tests/simulation/params/meshing_validation/test_meshing_param_validation.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,3 +1474,103 @@ def test_wind_tunnel_farfield_requires_geometry_ai():
14741474
with CGS_unit_system:
14751475
farfield = WindTunnelFarfield()
14761476
assert farfield.type == "WindTunnelFarfield"
1477+
1478+
1479+
def test_remove_non_manifold_faces_and_remove_hidden_geometry_mutual_exclusion():
1480+
"""Test that remove_non_manifold_faces and remove_hidden_geometry cannot both be True."""
1481+
gai_context = ParamsValidationInfo({}, [])
1482+
gai_context.use_geometry_AI = True
1483+
1484+
# Test 1: Both True should raise ValueError
1485+
with pytest.raises(
1486+
pd.ValidationError,
1487+
match=r"'remove_non_manifold_faces' and 'remove_hidden_geometry' cannot both be True",
1488+
):
1489+
with ValidationContext(SURFACE_MESH, gai_context):
1490+
with SI_unit_system:
1491+
MeshingDefaults(
1492+
geometry_accuracy=0.01 * u.m,
1493+
surface_max_edge_length=0.1 * u.m,
1494+
remove_non_manifold_faces=True,
1495+
remove_hidden_geometry=True,
1496+
)
1497+
1498+
# Test 2: Only remove_non_manifold_faces=True should work
1499+
with ValidationContext(SURFACE_MESH, gai_context):
1500+
with SI_unit_system:
1501+
defaults = MeshingDefaults(
1502+
geometry_accuracy=0.01 * u.m,
1503+
surface_max_edge_length=0.1 * u.m,
1504+
remove_non_manifold_faces=True,
1505+
remove_hidden_geometry=False,
1506+
)
1507+
assert defaults.remove_non_manifold_faces is True
1508+
assert defaults.remove_hidden_geometry is False
1509+
1510+
# Test 3: Only remove_hidden_geometry=True should work
1511+
with ValidationContext(SURFACE_MESH, gai_context):
1512+
with SI_unit_system:
1513+
defaults = MeshingDefaults(
1514+
geometry_accuracy=0.01 * u.m,
1515+
surface_max_edge_length=0.1 * u.m,
1516+
remove_non_manifold_faces=False,
1517+
remove_hidden_geometry=True,
1518+
)
1519+
assert defaults.remove_non_manifold_faces is False
1520+
assert defaults.remove_hidden_geometry is True
1521+
1522+
# Test 4: Both False should work (default case)
1523+
with ValidationContext(SURFACE_MESH, gai_context):
1524+
with SI_unit_system:
1525+
defaults = MeshingDefaults(
1526+
geometry_accuracy=0.01 * u.m,
1527+
surface_max_edge_length=0.1 * u.m,
1528+
remove_non_manifold_faces=False,
1529+
remove_hidden_geometry=False,
1530+
)
1531+
assert defaults.remove_non_manifold_faces is False
1532+
assert defaults.remove_hidden_geometry is False
1533+
1534+
1535+
def test_flooding_cell_size_requires_remove_hidden_geometry():
1536+
"""Test that flooding_cell_size can only be specified when remove_hidden_geometry is True."""
1537+
gai_context = ParamsValidationInfo({}, [])
1538+
gai_context.use_geometry_AI = True
1539+
1540+
# Test 1: flooding_cell_size with remove_hidden_geometry=False should raise
1541+
with pytest.raises(
1542+
pd.ValidationError,
1543+
match=r"'flooding_cell_size' can only be specified when 'remove_hidden_geometry' is True",
1544+
):
1545+
with ValidationContext(SURFACE_MESH, gai_context):
1546+
with SI_unit_system:
1547+
MeshingDefaults(
1548+
geometry_accuracy=0.01 * u.m,
1549+
surface_max_edge_length=0.1 * u.m,
1550+
remove_hidden_geometry=False,
1551+
flooding_cell_size=0.005 * u.m,
1552+
)
1553+
1554+
# Test 2: flooding_cell_size with remove_hidden_geometry=True should work
1555+
with ValidationContext(SURFACE_MESH, gai_context):
1556+
with SI_unit_system:
1557+
defaults = MeshingDefaults(
1558+
geometry_accuracy=0.01 * u.m,
1559+
surface_max_edge_length=0.1 * u.m,
1560+
remove_hidden_geometry=True,
1561+
flooding_cell_size=0.005 * u.m,
1562+
)
1563+
assert defaults.flooding_cell_size == 0.005 * u.m
1564+
assert defaults.remove_hidden_geometry is True
1565+
1566+
# Test 3: remove_hidden_geometry=True without flooding_cell_size should work (it's optional)
1567+
with ValidationContext(SURFACE_MESH, gai_context):
1568+
with SI_unit_system:
1569+
defaults = MeshingDefaults(
1570+
geometry_accuracy=0.01 * u.m,
1571+
surface_max_edge_length=0.1 * u.m,
1572+
remove_hidden_geometry=True,
1573+
flooding_cell_size=None,
1574+
)
1575+
assert defaults.flooding_cell_size is None
1576+
assert defaults.remove_hidden_geometry is True

tests/simulation/translator/ref/Flow360_mirrored_surface_meshing.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"planar_face_tolerance": 1e-06,
1313
"preserve_thin_geometry": false,
1414
"remove_non_manifold_faces": false,
15+
"remove_hidden_geometry": false,
1516
"resolve_face_boundaries": false,
1617
"sealing_size": {
1718
"units": "1.0*m",

tests/simulation/translator/ref/surface_meshing/gai_surface_mesher.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"units": "1.0*m"
2424
},
2525
"remove_non_manifold_faces": false,
26+
"remove_hidden_geometry": false,
2627
"planar_face_tolerance": 1e-06
2728
},
2829
"refinements": [

tests/simulation/translator/ref/surface_meshing/gai_windtunnel.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"units": "1.0*m"
2424
},
2525
"remove_non_manifold_faces": false,
26+
"remove_hidden_geometry": false,
2627
"planar_face_tolerance": 0.001
2728
},
2829
"refinements": [],

0 commit comments

Comments
 (0)