Skip to content

Commit

Permalink
Support the mix of Point and PointArray in ProbeOutput and SurfacePro…
Browse files Browse the repository at this point in the history
…beOutput (#640)

* Support the mix of Point and PointArray in ProbeOutput

* Modify class examples and address comments

* Remove _check_unique_probe_type function

* Improve class examples
  • Loading branch information
angranl-flex committed Jan 6, 2025
1 parent f245a2f commit 2df373d
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 151 deletions.
158 changes: 58 additions & 100 deletions flow360/component/simulation/outputs/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
)
from flow360.component.simulation.primitives import GhostSurface, Surface
from flow360.component.simulation.unit_system import LengthType
from flow360.component.simulation.validation.validation_output import (
_check_unique_probe_type,
)


class UserDefinedField(Flow360BaseModel):
Expand Down Expand Up @@ -414,48 +411,39 @@ class ProbeOutput(Flow360BaseModel):
Example
-------
- Define :class:`ProbeOutput` on multiple monitor points.
>>> fl.ProbeOutput(
... name="probe_group_points",
... entities=[
... fl.Point(
... name="Point_1",
... location=(0.0, 1.5, 0.0) * fl.u.m,
... ),
... fl.Point(
... name="Point_2",
... location=(0.0, -1.5, 0.0) * fl.u.m,
... ),
... ],
... output_fields=["primitiveVars"],
... )
- Define :class:`ProbeOutput` on monitor points along the line.
Define :class:`ProbeOutput` on multiple specific monitor points and monitor points along the line.
- :code:`Line_1` is from (1,0,0) * fl.u,m to (1.5,0,0) * fl.u,m and has 6 monitor points.
- :code:`Line_2` is from (-1,0,0) * fl.u,m to (-1.5,0,0) * fl.u,m and has 3 monitor points,
namely, (-1,0,0) * fl.u,m, (-1.25,0,0) * fl.u,m and (-1.5,0,0) * fl.u,m.
- :code:`Point_1` and :code:`Point_2` are two specific points we want to monitor in this probe output group.
- :code:`Line_1` is from (1,0,0) * fl.u,m to (1.5,0,0) * fl.u,m and has 6 monitor points.
- :code:`Line_2` is from (-1,0,0) * fl.u,m to (-1.5,0,0) * fl.u,m and has 3 monitor points,
namely, (-1,0,0) * fl.u,m, (-1.25,0,0) * fl.u,m and (-1.5,0,0) * fl.u,m.
>>> fl.ProbeOutput(
... name="probe_group_lines",
... entities=[
... fl.PointArray(
... name="Line_1",
... start=(1.0, 0.0, 0.0) * fl.u.m,
... end=(1.5, 0.0, 0.0) * fl.u.m,
... number_of_points=6,
... ),
... fl.PointArray(
... name="Line_2",
... start=(-1.0, 0.0, 0.0) * fl.u.m,
... end=(-1.5, 0.0, 0.0) * fl.u.m,
... number_of_points=3,
... ),
... ],
... output_fields=["primitiveVars"],
... )
>>> fl.ProbeOutput(
... name="probe_group_points_and_lines",
... entities=[
... fl.Point(
... name="Point_1",
... location=(0.0, 1.5, 0.0) * fl.u.m,
... ),
... fl.Point(
... name="Point_2",
... location=(0.0, -1.5, 0.0) * fl.u.m,
... ),
... fl.PointArray(
... name="Line_1",
... start=(1.0, 0.0, 0.0) * fl.u.m,
... end=(1.5, 0.0, 0.0) * fl.u.m,
... number_of_points=6,
... ),
... fl.PointArray(
... name="Line_2",
... start=(-1.0, 0.0, 0.0) * fl.u.m,
... end=(-1.5, 0.0, 0.0) * fl.u.m,
... number_of_points=3,
... ),
... ],
... output_fields=["primitiveVars"],
... )
====
"""
Expand All @@ -479,12 +467,6 @@ def load_point_location_from_file(cls, file_path: str):
"""Load probe point locations from a file. (Not implemented yet)"""
raise NotImplementedError("Not implemented yet.")

@pd.field_validator("entities", mode="after")
@classmethod
def check_unique_probe_type(cls, value):
"""Check to ensure every entity has the same type"""
return _check_unique_probe_type(value, "ProbeOutput")


class SurfaceProbeOutput(Flow360BaseModel):
"""
Expand All @@ -495,48 +477,36 @@ class SurfaceProbeOutput(Flow360BaseModel):
Example
-------
- Define :class:`SurfaceProbeOutput` on the :code:`geometry["wall"]` surface
with multiple monitor points.
>>> fl.SurfaceProbeOutput(
... name="surface_probe_group_points",
... entities=[
... fl.Point(
... name="Point_1",
... location=(0.0, 1.5, 0.0) * fl.u.m,
... ),
... fl.Point(
... name="Point_2",
... location=(0.0, -1.5, 0.0) * fl.u.m,
... ),
... ],
... target_surfaces=[
... geometry["wall"],
... ],
... output_fields=["heatFlux", "T"],
... )
Define :class:`SurfaceProbeOutput` on the :code:`geometry["wall"]` surface
with multiple specific monitor points and monitor points along the line.
- Define :class:`SurafceProbeOutput` on the :code:`volume_mesh["fluid/wall"]` surface
with monitor points along the line.
:code:`Line_surface` is from (1,0,0) * fl.u.m to (1,0,-10) * fl.u.m and has 11 monitor points,
- :code:`Point_1` and :code:`Point_2` are two specific points we want to monitor in this probe output group.
- :code:`Line_surface` is from (1,0,0) * fl.u.m to (1,0,-10) * fl.u.m and has 11 monitor points,
including both starting and end points.
>>> fl.SurfaceProbeOutput(
... name="surface_probe_group_lines",
... entities=[
... fl.PointArray(
... name="Line_surface",
... start=(1.0, 0.0, 0.0) * fl.u.m,
... end=(1.0, 0.0, -10.0) * fl.u.m,
... number_of_points=11,
... ),
... ],
... target_surfaces=[
... volume_mesh["fluid/wall"],
... ],
... output_fields=["heatFlux", "T"],
... )
>>> fl.SurfaceProbeOutput(
... name="surface_probe_group_points",
... entities=[
... fl.Point(
... name="Point_1",
... location=(0.0, 1.5, 0.0) * fl.u.m,
... ),
... fl.Point(
... name="Point_2",
... location=(0.0, -1.5, 0.0) * fl.u.m,
... ),
... fl.PointArray(
... name="Line_surface",
... start=(1.0, 0.0, 0.0) * fl.u.m,
... end=(1.0, 0.0, -10.0) * fl.u.m,
... number_of_points=11,
... ),
... ],
... target_surfaces=[
... geometry["wall"],
... ],
... output_fields=["heatFlux", "T"],
... )
====
"""
Expand All @@ -561,12 +531,6 @@ class SurfaceProbeOutput(Flow360BaseModel):
)
output_type: Literal["SurfaceProbeOutput"] = pd.Field("SurfaceProbeOutput", frozen=True)

@pd.field_validator("entities", mode="after")
@classmethod
def check_unique_probe_type(cls, value):
"""Check to ensure every entity has the same type"""
return _check_unique_probe_type(value, "SurfaceProbeOutput")


class SurfaceSliceOutput(_AnimationAndFileFormatSettings):
"""
Expand All @@ -590,12 +554,6 @@ class SurfaceSliceOutput(_AnimationAndFileFormatSettings):
)
output_type: Literal["SurfaceSliceOutput"] = pd.Field("SurfaceSliceOutput", frozen=True)

@pd.field_validator("entities", mode="after")
@classmethod
def check_unique_probe_type(cls, value):
"""Check to ensure every entity has the same type"""
return _check_unique_probe_type(value, "SurfaceSliceOutput")


class TimeAverageProbeOutput(ProbeOutput):
"""
Expand Down
56 changes: 35 additions & 21 deletions flow360/component/simulation/translator/solver_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
Rotation,
Solid,
)
from flow360.component.simulation.outputs.output_entities import PointArray
from flow360.component.simulation.outputs.output_entities import Point, PointArray
from flow360.component.simulation.outputs.outputs import (
AeroAcousticOutput,
Isosurface,
Expand Down Expand Up @@ -270,32 +270,46 @@ def inject_isosurface_info(entity: Isosurface):

def inject_probe_info(entity: EntityList):
"""inject entity info"""
if isinstance(entity.stored_entities[0], PointArray):
return {
"start": [item.start.value.tolist() for item in entity.stored_entities],
"end": [item.end.value.tolist() for item in entity.stored_entities],
"numberOfPoints": [item.number_of_points for item in entity.stored_entities],
"type": "lineProbe",
}
return {
"monitorLocations": [item.location.value.tolist() for item in entity.stored_entities],
"type": "probe",

translated_entity_dict = {
"start": [],
"end": [],
"numberOfPoints": [],
"type": "lineProbe",
}
for item in entity.stored_entities:
if isinstance(item, PointArray):
translated_entity_dict["start"].append(item.start.value.tolist())
translated_entity_dict["end"].append(item.end.value.tolist())
translated_entity_dict["numberOfPoints"].append(item.number_of_points)
if isinstance(item, Point):
translated_entity_dict["start"].append(item.location.value.tolist())
translated_entity_dict["end"].append(item.location.value.tolist())
translated_entity_dict["numberOfPoints"].append(1)

return translated_entity_dict


def inject_surface_probe_info(entity: EntityList):
"""inject entity info"""
if isinstance(entity.stored_entities[0], PointArray):
return {
"start": [item.start.value.tolist() for item in entity.stored_entities],
"end": [item.end.value.tolist() for item in entity.stored_entities],
"numberOfPoints": [item.number_of_points for item in entity.stored_entities],
"type": "lineProbe",
}
return {
"monitorLocations": [item.location.value.tolist() for item in entity.stored_entities],
"type": "surfaceProbe",

translated_entity_dict = {
"start": [],
"end": [],
"numberOfPoints": [],
"type": "lineProbe",
}
for item in entity.stored_entities:
if isinstance(item, PointArray):
translated_entity_dict["start"].append(item.start.value.tolist())
translated_entity_dict["end"].append(item.end.value.tolist())
translated_entity_dict["numberOfPoints"].append(item.number_of_points)
if isinstance(item, Point):
translated_entity_dict["start"].append(item.location.value.tolist())
translated_entity_dict["end"].append(item.location.value.tolist())
translated_entity_dict["numberOfPoints"].append(1)

return translated_entity_dict


def inject_surface_list_info(entity: EntityList):
Expand Down
12 changes: 0 additions & 12 deletions flow360/component/simulation/validation/validation_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,6 @@
from typing import List, Literal, Union, get_args, get_origin


def _check_unique_probe_type(value, probe_output_type_str: str):
"""check to ensure every entity has the same type"""
if value is None:
return value
for entity in value.stored_entities:
if type(entity) is not type(value.stored_entities[0]):
raise ValueError(
f"All entities in a single `{probe_output_type_str}` must have the same type: `Point` or `PointArray`."
)
return value


def _check_output_fields(params):
"""Check the specified output fields for each output item is valid."""

Expand Down
Loading

0 comments on commit 2df373d

Please # to comment.