Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(): add update mechanism for input cache #626

Merged
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 @@ -208,7 +208,8 @@ class GenericReferenceCondition(MultiConstructorBaseModel):
velocity_magnitude: Optional[VelocityType.Positive] = ConditionalField(
context=CASE,
description="Freestream velocity magnitude. Used as reference velocity magnitude"
+ " when :py:attr:`reference_velocity_magnitude` is not specified.",
+ " when :py:attr:`reference_velocity_magnitude` is not specified. Cannot change once specified.",
frozen=True,
)
thermal_state: ThermalState = pd.Field(
ThermalState(),
Expand All @@ -233,6 +234,12 @@ def mach(self) -> pd.PositiveFloat:
"""Computes Mach number."""
return self.velocity_magnitude / self.thermal_state.speed_of_sound

@pd.field_validator("thermal_state", mode="after")
@classmethod
def _update_input_cache(cls, value, info: pd.ValidationInfo):
setattr(info.data["private_attribute_input_cache"], info.field_name, value)
return value


class AerospaceConditionCache(Flow360BaseModel):
"""[INTERNAL] Cache for AerospaceCondition inputs"""
Expand Down Expand Up @@ -275,6 +282,7 @@ class AerospaceCondition(MultiConstructorBaseModel):
description="Freestream velocity magnitude. Used as reference velocity magnitude"
+ " when :py:attr:`reference_velocity_magnitude` is not specified.",
context=CASE,
frozen=True,
)
thermal_state: ThermalState = pd.Field(
ThermalState(),
Expand All @@ -284,6 +292,7 @@ class AerospaceCondition(MultiConstructorBaseModel):
reference_velocity_magnitude: Optional[VelocityType.Positive] = CaseField(
None,
description="Reference velocity magnitude. Is required when :py:attr:`velocity_magnitude` is 0.",
frozen=True,
)
private_attribute_input_cache: AerospaceConditionCache = AerospaceConditionCache()

Expand Down Expand Up @@ -381,6 +390,12 @@ def mach(self) -> pd.PositiveFloat:
"""Computes Mach number."""
return self.velocity_magnitude / self.thermal_state.speed_of_sound

@pd.field_validator("alpha", "beta", "thermal_state", mode="after")
@classmethod
def _update_input_cache(cls, value, info: pd.ValidationInfo):
setattr(info.data["private_attribute_input_cache"], info.field_name, value)
return value


# pylint: disable=fixme
# TODO: AutomotiveCondition
Expand Down
22 changes: 18 additions & 4 deletions flow360/component/simulation/primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,16 +264,24 @@ class Box(MultiConstructorBaseModel, _VolumeEntityBase):
"""

type_name: Literal["Box"] = pd.Field("Box", frozen=True)
private_attribute_entity_type_name: Literal["Box"] = pd.Field("Box", frozen=True)
# pylint: disable=no-member
center: LengthType.Point = pd.Field(description="The coordinates of the center of the box.")
size: LengthType.PositiveVector = pd.Field(
description="The dimensions of the box (length, width, height)."
)
axis_of_rotation: Axis = pd.Field(default=(0, 0, 1), description="The rotation axis.")
angle_of_rotation: AngleType = pd.Field(default=0 * u.degree, description="The rotation angle.")
private_attribute_input_cache: BoxCache = pd.Field(BoxCache(), frozen=True)
axis_of_rotation: Axis = pd.Field(
default=(0, 0, 1),
description="The rotation axis. Cannot change once specified.",
frozen=True,
)
angle_of_rotation: AngleType = pd.Field(
default=0 * u.degree,
description="The rotation angle. Cannot change once specified.",
frozen=True,
)
private_attribute_id: str = pd.Field(default_factory=generate_uuid, frozen=True)
private_attribute_input_cache: BoxCache = pd.Field(BoxCache(), frozen=True)
private_attribute_entity_type_name: Literal["Box"] = pd.Field("Box", frozen=True)

# pylint: disable=no-self-argument
@MultiConstructorBaseModel.model_constructor
Expand Down Expand Up @@ -344,6 +352,12 @@ def axes(self):
"""Return the axes that the box is aligned with."""
return self.private_attribute_input_cache.axes

@pd.field_validator("center", "size", mode="after")
@classmethod
def _update_input_cache(cls, value, info: pd.ValidationInfo):
setattr(info.data["private_attribute_input_cache"], info.field_name, value)
return value


@final
class Cylinder(_VolumeEntityBase):
Expand Down
42 changes: 41 additions & 1 deletion tests/ref/simulation/service_init_geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,47 @@
"operating_condition": {
"type_name": "AerospaceCondition",
"private_attribute_constructor": "default",
"private_attribute_input_cache": {},
"private_attribute_input_cache": {
"alpha": {
"value": 0.0,
"units": "degree"
},
"beta": {
"value": 0.0,
"units": "degree"
},
"thermal_state": {
"type_name": "ThermalState",
"private_attribute_constructor": "default",
"private_attribute_input_cache": {},
"temperature": {
"value": 288.15,
"units": "K"
},
"density": {
"value": 1.225,
"units": "kg/m**3"
},
"material": {
"type": "air",
"name": "air",
"dynamic_viscosity": {
"reference_viscosity": {
"value": 1.716e-05,
"units": "Pa*s"
},
"reference_temperature": {
"value": 273.15,
"units": "K"
},
"effective_temperature": {
"value": 110.4,
"units": "K"
}
}
}
}
},
"alpha": {
"value": 0.0,
"units": "degree"
Expand Down
42 changes: 41 additions & 1 deletion tests/ref/simulation/service_init_volume_mesh.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,47 @@
"operating_condition": {
"type_name": "AerospaceCondition",
"private_attribute_constructor": "default",
"private_attribute_input_cache": {},
"private_attribute_input_cache": {
"alpha": {
"value": 0.0,
"units": "degree"
},
"beta": {
"value": 0.0,
"units": "degree"
},
"thermal_state": {
"type_name": "ThermalState",
"private_attribute_constructor": "default",
"private_attribute_input_cache": {},
"temperature": {
"value": 288.15,
"units": "K"
},
"density": {
"value": 1.225,
"units": "kg/m**3"
},
"material": {
"type": "air",
"name": "air",
"dynamic_viscosity": {
"reference_viscosity": {
"value": 1.716e-05,
"units": "Pa*s"
},
"reference_temperature": {
"value": 273.15,
"units": "K"
},
"effective_temperature": {
"value": 110.4,
"units": "K"
}
}
}
}
},
"alpha": {
"value": 0.0,
"units": "degree"
Expand Down
28 changes: 28 additions & 0 deletions tests/simulation/framework/test_multi_constructor_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,31 @@ class ModelWithEntityList(Flow360BaseModel):

data_parsed = parse_model_dict(incomplete_data, globals())
assert sorted(data_parsed.items()) == sorted(full_data.items())


def test_entity_modification(get_aerospace_condition_using_from):

my_box = Box.from_principal_axes(
name="box",
axes=[(0, 1, 0), (0, 0, 1)],
center=(0, 0, 0) * u.m,
size=(0.2, 0.3, 2) * u.m,
)

my_box.center = (1, 2, 3) * u.m
assert all(my_box.private_attribute_input_cache.center == (1, 2, 3) * u.m)

my_box = Box(
name="box2",
axis_of_rotation=(1, 0, 0),
angle_of_rotation=45 * u.deg,
center=(1, 1, 1) * u.m,
size=(0.2, 0.3, 2) * u.m,
)

my_box.size = (1, 2, 32) * u.m
assert all(my_box.private_attribute_input_cache.size == (1, 2, 32) * u.m)

my_op = get_aerospace_condition_using_from
my_op.alpha = -12 * u.rad
assert my_op.private_attribute_input_cache.alpha == -12 * u.rad
Loading