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
42 changes: 42 additions & 0 deletions flow360/component/simulation/framework/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,46 @@ def _to_25_9_5(params_as_dict):
return _convert_total_pressure_expression_from_ratio_to_nondim(params_as_dict)


_CUSTOM_VOLUME_RENAME_APPLIED_KEY = "__custom_volume_bounding_entities_applied"


def _rename_custom_volume_boundaries_everywhere(params_as_dict):
"""Rename ``boundaries`` to ``bounding_entities`` on every ``CustomVolume`` dict.

``_to_25_9_2`` only handled ``meshing.volume_zones``/``meshing.zones``, missing
CustomVolume dicts everywhere else (asset cache draft entities, model entities,
``parent_volume``, ``output_target``). This walks the whole params dict instead.

This function is referenced by one milestone per release line. A sentinel key
on the dict itself prevents redundant re-walks within one updater() call;
``updater()`` strips it before returning.
"""
if params_as_dict.get(_CUSTOM_VOLUME_RENAME_APPLIED_KEY):
return params_as_dict
params_as_dict[_CUSTOM_VOLUME_RENAME_APPLIED_KEY] = True

def _walk(node):
if isinstance(node, dict):
if (
node.get("private_attribute_entity_type_name") == "CustomVolume"
and "boundaries" in node
and "bounding_entities" not in node
):
node["bounding_entities"] = node.pop("boundaries")
for value in node.values():
_walk(value)
elif isinstance(node, list):
for item in node:
_walk(item)

_walk(params_as_dict)
return params_as_dict


def _to_25_9_10(params_as_dict):
return _rename_custom_volume_boundaries_everywhere(params_as_dict)


VERSION_MILESTONES = [
(Flow360Version("24.11.1"), _to_24_11_1),
(Flow360Version("24.11.7"), _to_24_11_7),
Expand All @@ -861,6 +901,7 @@ def _to_25_9_5(params_as_dict):
(Flow360Version("25.9.2"), _to_25_9_2),
(Flow360Version("25.9.3"), _to_25_9_3),
(Flow360Version("25.9.5"), _to_25_9_5),
(Flow360Version("25.9.10"), _to_25_9_10),
] # A list of the Python API version tuple with their corresponding updaters.


Expand Down Expand Up @@ -951,5 +992,6 @@ def updater(version_from, version_to, params_as_dict) -> dict:
_to_version = re.search(r"_to_(\d+_\d+_\d+)", fun.__name__).group(1)
log.debug(f"Updating input SimulationParam to {_to_version}...")
params_as_dict = fun(params_as_dict)
params_as_dict.pop(_CUSTOM_VOLUME_RENAME_APPLIED_KEY, None)
params_as_dict["version"] = str(version_to)
return params_as_dict
2 changes: 1 addition & 1 deletion flow360/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
version
"""

__version__ = "25.9.9"
__version__ = "25.9.10"
__solver_version__ = "release-25.9"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "flow360"
version = "v25.9.9"
version = "v25.9.10"
description = "Flow360 Python Client"
authors = ["Flexcompute <support@flexcompute.com>"]

Expand Down
57 changes: 57 additions & 0 deletions tests/simulation/test_updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -2331,3 +2331,60 @@ def test_updater_total_pressure_no_double_conversion_across_branches():

assert params_new["version"] == "25.9.5"
assert params_new["models"][0]["spec"]["value"] == "(1.0 + 0.5 * sin(y)) / 1.4"


def test_updater_to_25_9_10_custom_volume_rename_everywhere():
"""Test 25.9.10 updater renames boundaries -> bounding_entities on CustomVolume
dicts outside meshing.volume_zones, which _to_25_9_2 missed."""

def custom_volume():
return {
"private_attribute_entity_type_name": "CustomVolume",
"name": "cv",
"boundaries": {
"stored_entities": [
{"private_attribute_entity_type_name": "Surface", "name": "face1"}
]
},
}

params_as_dict = {
"version": "25.9.3",
"meshing": {
"volume_zones": [
{"type": "CustomZones", "entities": {"stored_entities": [custom_volume()]}}
],
},
"models": [
{
"type": "Rotation",
"entities": {"stored_entities": [custom_volume()]},
"parent_volume": custom_volume(),
}
],
"user_defined_dynamics": [{"output_target": custom_volume()}],
"private_attribute_asset_cache": {
"project_entity_info": {"draft_entities": [custom_volume()]}
},
}

params_new = updater(
version_from="25.9.3",
version_to="25.9.10",
params_as_dict=params_as_dict,
)

renamed = [
params_new["meshing"]["volume_zones"][0]["entities"]["stored_entities"][0],
params_new["models"][0]["entities"]["stored_entities"][0],
params_new["models"][0]["parent_volume"],
params_new["user_defined_dynamics"][0]["output_target"],
params_new["private_attribute_asset_cache"]["project_entity_info"]["draft_entities"][0],
]
for cv in renamed:
assert "boundaries" not in cv
assert cv["bounding_entities"]["stored_entities"][0]["name"] == "face1"

assert params_new["version"] == "25.9.10"
# The run-once sentinel must not leak into the returned dict.
assert "__custom_volume_bounding_entities_applied" not in params_new
2 changes: 1 addition & 1 deletion tests/test_current_flow360_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


def test_version():
assert __version__ == "25.9.9"
assert __version__ == "25.9.10"
Loading