From 09f6637c215fbe1a2c81ef5b3c6f0e47e27f6ee1 Mon Sep 17 00:00:00 2001 From: NasserFlexCompute Date: Wed, 15 Apr 2026 18:04:51 +0000 Subject: [PATCH 1/3] feat(Inflow): add rotate_velocity_direction_with_mesh option Add `rotate_velocity_direction_with_mesh` bool field to `Inflow` boundary condition (default True). When enabled, the velocity direction vector rotates with the mesh at each physical time step for boundaries inside rotating zones. - Add field to `Inflow` model in surface_models.py - Emit `rotateVelocityDirectionWithMesh: false` in translator only when overridden (solver default is true) - Add unit test verifying translation for both default and disabled cases Made-with: Cursor --- .../simulation/models/surface_models.py | 7 +++ .../translator/solver_translator.py | 2 + .../translator/test_solver_translator.py | 45 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/flow360/component/simulation/models/surface_models.py b/flow360/component/simulation/models/surface_models.py index 7e1dc17c2..559fd6d12 100644 --- a/flow360/component/simulation/models/surface_models.py +++ b/flow360/component/simulation/models/surface_models.py @@ -699,6 +699,13 @@ class Inflow(BoundaryBaseWithTurbulenceQuantities): description="Direction of the incoming flow. Must be a unit vector pointing " + "into the volume. If unspecified, the direction will be normal to the surface.", ) + rotate_velocity_direction_with_mesh: bool = pd.Field( + True, + description="When True, the velocity direction vector rotates with the mesh at each " + + "physical time step. Use this when the inflow boundary is inside a rotating zone and " + + "the velocity direction should be specified relative to the body frame rather than the " + + "inertial frame. Only relevant when `velocity_direction` is set.", + ) entities: EntityList[Surface, MirroredSurface, WindTunnelGhostSurface] = pd.Field( alias="surfaces", description="List of boundaries with the `Inflow` boundary condition imposed.", diff --git a/flow360/component/simulation/translator/solver_translator.py b/flow360/component/simulation/translator/solver_translator.py index 23ed6b5ad..12b0169c8 100644 --- a/flow360/component/simulation/translator/solver_translator.py +++ b/flow360/component/simulation/translator/solver_translator.py @@ -1639,6 +1639,8 @@ def boundary_spec_translator(model: SurfaceModelTypes, op_acoustic_to_static_pre boundary["totalTemperatureRatio"] = model_dict["totalTemperature"] if model.velocity_direction is not None: boundary["velocityDirection"] = list(model_dict["velocityDirection"]) + if not model.rotate_velocity_direction_with_mesh: + boundary["rotateVelocityDirectionWithMesh"] = False if isinstance(model.spec, TotalPressure): boundary["type"] = "SubsonicInflow" total_pressure_ratio = model_dict["spec"]["value"] diff --git a/tests/simulation/translator/test_solver_translator.py b/tests/simulation/translator/test_solver_translator.py index 4c367d0dc..e6813ea6d 100644 --- a/tests/simulation/translator/test_solver_translator.py +++ b/tests/simulation/translator/test_solver_translator.py @@ -945,6 +945,51 @@ def test_boundaries(): translate_and_compare(param, mesh_unit=1 * u.m, ref_json_file="Flow360_boundaries.json") +def test_rotate_velocity_direction_with_mesh(): + """Verify rotateVelocityDirectionWithMesh is emitted only when overridden to False.""" + operating_condition = AerospaceCondition(velocity_magnitude=10 * u.m / u.s) + with SI_unit_system: + param_default = SimulationParams( + operating_condition=operating_condition, + models=[ + Inflow( + name="exhaust", + total_temperature=750 * u.K, + surfaces=Surface(name="engine_face"), + spec=Supersonic( + total_pressure=3e6 * u.Pa, + static_pressure=101325 * u.Pa, + ), + velocity_direction=(0, -1, 0), + ), + ], + ) + param_disabled = SimulationParams( + operating_condition=operating_condition, + models=[ + Inflow( + name="exhaust", + total_temperature=750 * u.K, + surfaces=Surface(name="engine_face"), + spec=Supersonic( + total_pressure=3e6 * u.Pa, + static_pressure=101325 * u.Pa, + ), + velocity_direction=(0, -1, 0), + rotate_velocity_direction_with_mesh=False, + ), + ], + ) + + translated_default = get_solver_json(param_default, mesh_unit=1 * u.m) + bc_default = translated_default["boundaries"]["engine_face"] + assert "rotateVelocityDirectionWithMesh" not in bc_default + + translated_disabled = get_solver_json(param_disabled, mesh_unit=1 * u.m) + bc_disabled = translated_disabled["boundaries"]["engine_face"] + assert bc_disabled["rotateVelocityDirectionWithMesh"] is False + + def test_liquid_simulation_translation(): with SI_unit_system: param = SimulationParams( From 524e31617c93dc668e3885ab888ab65bd6208c24 Mon Sep 17 00:00:00 2001 From: NasserFlexCompute Date: Wed, 15 Apr 2026 21:26:24 +0000 Subject: [PATCH 2/3] changed default --- .../component/simulation/models/surface_models.py | 2 +- .../simulation/translator/solver_translator.py | 4 ++-- .../simulation/translator/test_solver_translator.py | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/flow360/component/simulation/models/surface_models.py b/flow360/component/simulation/models/surface_models.py index 559fd6d12..bfe6340ab 100644 --- a/flow360/component/simulation/models/surface_models.py +++ b/flow360/component/simulation/models/surface_models.py @@ -700,7 +700,7 @@ class Inflow(BoundaryBaseWithTurbulenceQuantities): + "into the volume. If unspecified, the direction will be normal to the surface.", ) rotate_velocity_direction_with_mesh: bool = pd.Field( - True, + False, description="When True, the velocity direction vector rotates with the mesh at each " + "physical time step. Use this when the inflow boundary is inside a rotating zone and " + "the velocity direction should be specified relative to the body frame rather than the " diff --git a/flow360/component/simulation/translator/solver_translator.py b/flow360/component/simulation/translator/solver_translator.py index 12b0169c8..85390490c 100644 --- a/flow360/component/simulation/translator/solver_translator.py +++ b/flow360/component/simulation/translator/solver_translator.py @@ -1639,8 +1639,8 @@ def boundary_spec_translator(model: SurfaceModelTypes, op_acoustic_to_static_pre boundary["totalTemperatureRatio"] = model_dict["totalTemperature"] if model.velocity_direction is not None: boundary["velocityDirection"] = list(model_dict["velocityDirection"]) - if not model.rotate_velocity_direction_with_mesh: - boundary["rotateVelocityDirectionWithMesh"] = False + if model.rotate_velocity_direction_with_mesh: + boundary["rotateVelocityDirectionWithMesh"] = True if isinstance(model.spec, TotalPressure): boundary["type"] = "SubsonicInflow" total_pressure_ratio = model_dict["spec"]["value"] diff --git a/tests/simulation/translator/test_solver_translator.py b/tests/simulation/translator/test_solver_translator.py index e6813ea6d..6b18bd3ab 100644 --- a/tests/simulation/translator/test_solver_translator.py +++ b/tests/simulation/translator/test_solver_translator.py @@ -946,7 +946,7 @@ def test_boundaries(): def test_rotate_velocity_direction_with_mesh(): - """Verify rotateVelocityDirectionWithMesh is emitted only when overridden to False.""" + """Verify rotateVelocityDirectionWithMesh is emitted only when set to True.""" operating_condition = AerospaceCondition(velocity_magnitude=10 * u.m / u.s) with SI_unit_system: param_default = SimulationParams( @@ -964,7 +964,7 @@ def test_rotate_velocity_direction_with_mesh(): ), ], ) - param_disabled = SimulationParams( + param_enabled = SimulationParams( operating_condition=operating_condition, models=[ Inflow( @@ -976,7 +976,7 @@ def test_rotate_velocity_direction_with_mesh(): static_pressure=101325 * u.Pa, ), velocity_direction=(0, -1, 0), - rotate_velocity_direction_with_mesh=False, + rotate_velocity_direction_with_mesh=True, ), ], ) @@ -985,9 +985,9 @@ def test_rotate_velocity_direction_with_mesh(): bc_default = translated_default["boundaries"]["engine_face"] assert "rotateVelocityDirectionWithMesh" not in bc_default - translated_disabled = get_solver_json(param_disabled, mesh_unit=1 * u.m) - bc_disabled = translated_disabled["boundaries"]["engine_face"] - assert bc_disabled["rotateVelocityDirectionWithMesh"] is False + translated_enabled = get_solver_json(param_enabled, mesh_unit=1 * u.m) + bc_enabled = translated_enabled["boundaries"]["engine_face"] + assert bc_enabled["rotateVelocityDirectionWithMesh"] is True def test_liquid_simulation_translation(): From 69ac34eedf7386aebb0b8a75daea4e32533c457f Mon Sep 17 00:00:00 2001 From: NasserFlexCompute Date: Sat, 18 Apr 2026 13:13:50 +0000 Subject: [PATCH 3/3] updated version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a2cd89392..6d2e02a0c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ pydantic = ">=2.8,<2.12" # -- Local dev (editable install, schema changes take effect immediately): # flow360-schema = { path = "../../../../flex/share/flow360-schema", develop = true } # -- CI / release (install from CodeArtifact, swap comments before pushing): -flow360-schema = { version = "~0.1.24", source = "codeartifact" } +flow360-schema = { version = "= 25.10.1b2", source = "codeartifact" } pytest = "^7.1.2" click = "^8.1.3" toml = "^0.10.2"