Source code for flow360.component.simulation.outputs.output_entities

"""Output for simulation."""

from abc import ABCMeta
from typing import Literal, Union

import pydantic as pd

from flow360.component.simulation.framework.base_model import Flow360BaseModel
from flow360.component.simulation.framework.entity_base import EntityBase, generate_uuid
from flow360.component.simulation.outputs.output_fields import IsoSurfaceFieldNames
from flow360.component.simulation.unit_system import LengthType
from flow360.component.types import Axis


class _OutputItemBase(Flow360BaseModel):
    name: str = pd.Field()

    def __hash__(self):
        return hash(self.name + "-" + self.__class__.__name__)

    def __eq__(self, other):
        if isinstance(other, _OutputItemBase):
            return (self.name + "-" + self.__class__.__name__) == (
                other.name + "-" + other.__class__.__name__
            )
        return False

    def __str__(self):
        return f"{self.__class__.__name__} with name: {self.name}"


class _SliceEntityBase(EntityBase, metaclass=ABCMeta):
    private_attribute_registry_bucket_name: Literal["SliceEntityType"] = "SliceEntityType"


class _PointEntityBase(EntityBase, metaclass=ABCMeta):
    private_attribute_registry_bucket_name: Literal["PointEntityType"] = "PointEntityType"


[docs] class Slice(_SliceEntityBase): """ :class:`Slice` class for defining a slice for :class:`~flow360.SliceOutput`. Example ------- Define a :class:`Slice` along (0,1,0) direction with the origin of (0,2,0) fl.u.m. >>> fl.Slice( ... name="Slice", ... normal=(0, 1, 0), ... origin=(0, 2, 0)*fl.u.m ... ) ==== """ private_attribute_entity_type_name: Literal["Slice"] = pd.Field("Slice", frozen=True) private_attribute_id: str = pd.Field(default_factory=generate_uuid, frozen=True) normal: Axis = pd.Field(description="Normal direction of the slice.") # pylint: disable=no-member origin: LengthType.Point = pd.Field(description="A single point on the slice.")
[docs] class Isosurface(_OutputItemBase): """ :class:`Isosurface` class for defining an isosurface for :class:`~flow360.IsosurfaceOutput`. Example ------- Define a :class:`Isosurface` of temperature equal to 1.5 non-dimensional temperature. >>> fl.Isosurface( ... name="Isosurface_T_1.5", ... iso_value=1.5, ... field="T", ... ) ==== """ field: Union[IsoSurfaceFieldNames, str] = pd.Field( description="Isosurface field variable. One of :code:`p`, :code:`rho`, " ":code:`Mach`, :code:`qcriterion`, :code:`s`, :code:`T`, :code:`Cp`, :code:`mut`," " :code:`nuHat` or one of scalar field defined in :class:`UserDefinedField`." ) # pylint: disable=fixme # TODO: Maybe we need some unit helper function to help user figure out what is the value to use here? iso_value: float = pd.Field(description="Expect non-dimensional value.")
[docs] class Point(_PointEntityBase): """ :class:`Point` class for defining a single point for :class:`~flow360.ProbeOutput`/:class:`~flow360.SurfaceProbeOutput`. Example ------- >>> fl.Point( ... name="Point", ... location=(1.0, 2.0, 3.0) * fl.u.m, ... ) ==== """ private_attribute_entity_type_name: Literal["Point"] = pd.Field("Point", frozen=True) private_attribute_id: str = pd.Field(default_factory=generate_uuid, frozen=True) # pylint: disable=no-member location: LengthType.Point = pd.Field(description="The coordinate of the point.")
[docs] class PointArray(_PointEntityBase): """ :class:`PointArray` class for defining multiple equally spaced monitor points along a line for :class:`~flow360.ProbeOutput`/:class:`~flow360.SurfaceProbeOutput`. Example ------- Define :class:`PointArray` with 6 equally spaced points along a line starting from (0,0,0) * fl.u.m to (1,2,3) * fl.u.m. Both the starting and end points are included in the :class:`PointArray`. >>> fl.PointArray( ... name="Line_1", ... start=(0.0, 0.0, 0.0) * fl.u.m, ... end=(1.0, 2.0, 3.0) * fl.u.m, ... number_of_points=6, ... ) ==== """ private_attribute_entity_type_name: Literal["PointArray"] = pd.Field("PointArray", frozen=True) private_attribute_id: str = pd.Field(default_factory=generate_uuid, frozen=True) # pylint: disable=no-member start: LengthType.Point = pd.Field(description="The starting point of the line.") end: LengthType.Point = pd.Field(description="The end point of the line.") number_of_points: int = pd.Field(gt=2, description="Number of points along the line.")