Skip to content
Open
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
2 changes: 2 additions & 0 deletions flow360/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
AutomatedFarfield,
AxisymmetricRefinement,
CustomZones,
MeshSliceOutput,
RotationCylinder,
RotationVolume,
StructuredBoxRefinement,
Expand Down Expand Up @@ -190,6 +191,7 @@
"Accounts",
"Project",
"u",
"MeshSliceOutput",
"SimulationParams",
"SI_unit_system",
"imperial_unit_system",
Expand Down
12 changes: 12 additions & 0 deletions flow360/component/simulation/meshing_param/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
AutomatedFarfield,
AxisymmetricRefinement,
CustomZones,
MeshSliceOutput,
RotationCylinder,
RotationVolume,
StructuredBoxRefinement,
Expand Down Expand Up @@ -60,6 +61,11 @@
pd.Field(discriminator="type"),
]

MeshOutputTypes = Annotated[
Union[MeshSliceOutput,],
pd.Field(discriminator="output_type"),
]


class MeshingDefaults(Flow360BaseModel):
"""
Expand Down Expand Up @@ -292,6 +298,12 @@ class MeshingParams(Flow360BaseModel):
default=None, description="Creation of new volume zones."
)

# Meshing outputs (for now, volume mesh slices)
outputs: List[MeshOutputTypes] = pd.Field(
default=[],
description="Mesh output settings.",
)

@pd.field_validator("volume_zones", mode="after")
@classmethod
def _check_volume_zones_has_farfied(cls, v):
Expand Down
29 changes: 29 additions & 0 deletions flow360/component/simulation/meshing_param/volume_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from flow360.component.simulation.framework.base_model import Flow360BaseModel
from flow360.component.simulation.framework.entity_base import EntityList
from flow360.component.simulation.outputs.output_entities import Slice
from flow360.component.simulation.primitives import (
AxisymmetricBody,
Box,
Expand Down Expand Up @@ -474,6 +475,34 @@ def symmetry_plane(self) -> GhostSurface:
return GhostSurface(name="symmetric")


class MeshSliceOutput(Flow360BaseModel):
"""
:class:`MeshSliceOutput` class for mesh slice output settings.

Example
-------

>>> fl.MeshSliceOutput(
... slices=[
... fl.Slice(
... name="Slice_1",
... normal=(0, 1, 0),
... origin=(0, 0.56, 0)*fl.u.m
... ),
... ],
... )

====
"""

name: str = pd.Field("Mesh slice output", description="Name of the `MeshSliceOutput`.")
entities: EntityList[Slice] = pd.Field(
alias="slices",
description="List of output :class:`~flow360.Slice` entities.",
)
output_type: Literal["MeshSliceOutput"] = pd.Field("MeshSliceOutput", frozen=True)


class CustomZones(Flow360BaseModel):
"""
:class:`CustomZones` class for creating volume zones from custom volumes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
AutomatedFarfield,
AxisymmetricRefinement,
AxisymmetricRefinementBase,
MeshSliceOutput,
RotationCylinder,
RotationVolume,
StructuredBoxRefinement,
Expand All @@ -23,8 +24,10 @@
Surface,
)
from flow360.component.simulation.simulation_params import SimulationParams
from flow360.component.simulation.translator.solver_translator import inject_slice_info
from flow360.component.simulation.translator.utils import (
get_global_setting_from_first_instance,
has_instance_in_list,
preprocess_input,
translate_setting_and_apply_to_all_entities,
)
Expand Down Expand Up @@ -227,6 +230,23 @@ def _get_custom_volumes(volume_zones: list):
return custom_volumes


def translate_mesh_slice_output(
output_params: list,
output_class: Union[MeshSliceOutput],
injection_function,
):
"""Translate slice or isosurface output settings."""
translated_output = {}
translated_output["slices"] = translate_setting_and_apply_to_all_entities(
output_params,
output_class,
translation_func=lambda x: {},
to_list=False,
entity_injection_func=injection_function,
)
return translated_output


@preprocess_input
# pylint: disable=unused-argument,too-many-branches,too-many-statements
def get_volume_meshing_json(input_params: SimulationParams, mesh_units):
Expand Down Expand Up @@ -409,4 +429,16 @@ def get_volume_meshing_json(input_params: SimulationParams, mesh_units):
if custom_volumes:
translated["zones"] = custom_volumes

##:: Step 7: Get meshing output fields
outputs = input_params.meshing.outputs

mesh_slice_output_configs = [
(MeshSliceOutput, "meshSliceOutput"),
]
for output_class, output_key in mesh_slice_output_configs:
if has_instance_in_list(outputs, output_class):
slice_output = translate_mesh_slice_output(outputs, output_class, inject_slice_info)
if slice_output:
translated[output_key] = slice_output

return translated
1 change: 1 addition & 0 deletions tests/ref/simulation/service_init_geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"units": "m"
}
},
"outputs": [],
"refinements": [],
"volume_zones": [
{
Expand Down
1 change: 1 addition & 0 deletions tests/ref/simulation/service_init_surface_mesh.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"units": "m"
}
},
"outputs": [],
"refinements": [],
"volume_zones": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@
"passive1": {"type": "projectAnisoSpacing"},
"passive2": {"type": "none"}
},
"meshSliceOutput": {
"slices": {
"test_slice_y_normal": {
"sliceOrigin": [0.1, 0.2, 0.3],
"sliceNormal": [0.0, 1.0, 0.0]
},
"test_slice_z_normal": {
"sliceOrigin": [0.6, 0.1, 0.4],
"sliceNormal": [0.0, 0.0, 1.0]
}
}
},
"refinement": [
{
"type": "cylinder",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@
"passive1": {"type": "projectAnisoSpacing"},
"passive2": {"type": "none"}
},
"meshSliceOutput": {
"slices": {
"test_slice_y_normal": {
"sliceOrigin": [0.1, 0.2, 0.3],
"sliceNormal": [0.0, 1.0, 0.0]
},
"test_slice_z_normal": {
"sliceOrigin": [0.6, 0.1, 0.4],
"sliceNormal": [0.0, 0.0, 1.0]
}
}
},
"refinement": [
{
"type": "cylinder",
Expand Down
20 changes: 20 additions & 0 deletions tests/simulation/translator/test_volume_meshing_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
AutomatedFarfield,
AxisymmetricRefinement,
CustomZones,
MeshSliceOutput,
RotationCylinder,
RotationVolume,
StructuredBoxRefinement,
UniformRefinement,
UserDefinedFarfield,
)
from flow360.component.simulation.outputs.outputs import Slice
from flow360.component.simulation.primitives import (
AxisymmetricBody,
Box,
Expand Down Expand Up @@ -246,6 +249,23 @@ def get_test_param():
spacing_circumferential=20 * u.cm,
),
],
outputs=[
MeshSliceOutput(
name="slice_output",
entities=[
Slice(
name=f"test_slice_y_normal",
origin=(0.1, 0.2, 0.3),
normal=(0, 1, 0),
),
Slice(
name=f"test_slice_z_normal",
origin=(0.6, 0.1, 0.4),
normal=(0, 0, 1),
),
],
),
],
),
private_attribute_asset_cache=AssetCache(use_inhouse_mesher=True),
)
Expand Down
Loading