Skip to content

Commit f049166

Browse files
NasserFlexComputeflow360-auto-hotfix-bot
authored andcommitted
[BackPort] fix: remove output fields subsumed by primitiveVars to prevent duplic… (#1951)
1 parent 239dfe1 commit f049166

4 files changed

Lines changed: 88 additions & 3 deletions

File tree

flow360/component/simulation/outputs/output_fields.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,3 +486,33 @@ def append_component_to_output_fields(output_fields: List[str]) -> List[str]:
486486
if field == "vorticity" and "vorticityMagnitude" not in output_fields:
487487
output_fields_with_component.append("vorticityMagnitude")
488488
return output_fields_with_component
489+
490+
491+
# In the C++ solver, "primitiveVars" expands to DataArrays named "rho", "velocity", and "p".
492+
# "pressure" and "velocity" individually produce DataArrays with the same names ("p" and
493+
# "velocity"). Having both creates duplicate DataArray names in VTK output, which causes
494+
# ParaView to fail when loading a subset of fields.
495+
_FIELDS_SUBSUMED_BY_PRIMITIVE_VARS = {"pressure", "velocity"}
496+
497+
498+
def remove_fields_subsumed_by_primitive_vars(output_fields: List[str]) -> List[str]:
499+
"""
500+
Remove output fields that are already included as sub-fields of ``primitiveVars``.
501+
502+
Must be called after :func:`append_component_to_output_fields` so that auto-appended
503+
fields like ``velocity_magnitude`` are already in the list before ``velocity`` is removed.
504+
505+
Parameters:
506+
-----------
507+
output_fields : List[str]
508+
The list of output fields to deduplicate.
509+
510+
Returns:
511+
--------
512+
List[str]
513+
The deduplicated list with ``pressure`` and ``velocity`` removed when
514+
``primitiveVars`` is present.
515+
"""
516+
if "primitiveVars" not in output_fields:
517+
return output_fields
518+
return [f for f in output_fields if f not in _FIELDS_SUBSUMED_BY_PRIMITIVE_VARS]

flow360/component/simulation/translator/solver_translator.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
PREDEFINED_UDF_EXPRESSIONS,
6060
append_component_to_output_fields,
6161
generate_predefined_udf,
62+
remove_fields_subsumed_by_primitive_vars,
6263
)
6364
from flow360.component.simulation.outputs.outputs import (
6465
AeroAcousticOutput,
@@ -284,7 +285,12 @@ def translate_output_fields(
284285
output_fields.append(output_field.name)
285286
# Filter out the UserVariable Dicts
286287
output_fields = [item for item in output_fields if isinstance(item, str)]
288+
<<<<<<< HEAD
287289
return {"outputFields": sorted(output_fields)}
290+
=======
291+
output_fields = remove_fields_subsumed_by_primitive_vars(output_fields)
292+
return {"outputFields": output_fields}
293+
>>>>>>> c3af3b35 ([BackPort] fix: remove output fields subsumed by primitiveVars to prevent duplic… (#1951))
288294

289295

290296
def surface_probe_setting_translation_func(entity: Union[SurfaceProbeOutput, SurfaceSliceOutput]):
@@ -462,6 +468,7 @@ def translate_volume_output(
462468
output_fields.append(output_field.name)
463469
# Filter out the UserVariable Dicts
464470
output_fields = [item for item in output_fields if isinstance(item, str)]
471+
output_fields = remove_fields_subsumed_by_primitive_vars(output_fields)
465472
volume_output.update(
466473
{
467474
"outputFields": sorted(output_fields),

tests/simulation/outputs/test_output_fields.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import flow360 as fl
44
from flow360 import SI_unit_system, u
5-
from flow360.component.simulation.outputs.output_fields import generate_predefined_udf
5+
from flow360.component.simulation.outputs.output_fields import (
6+
generate_predefined_udf,
7+
remove_fields_subsumed_by_primitive_vars,
8+
)
69

710

811
@pytest.fixture
@@ -137,3 +140,47 @@ def test_generate_field_udf_no_match(simulation_params):
137140
"""Test behavior when no matching predefined expression is found."""
138141
result = generate_predefined_udf("non_existent_field_for_udf", simulation_params)
139142
assert result is None
143+
144+
145+
class TestRemoveFieldsSubsumedByPrimitiveVars:
146+
def test_removes_pressure_and_velocity_when_primitive_vars_present(self):
147+
fields = ["Cp", "primitiveVars", "pressure", "velocity", "Mach"]
148+
result = remove_fields_subsumed_by_primitive_vars(fields)
149+
assert "primitiveVars" in result
150+
assert "pressure" not in result
151+
assert "velocity" not in result
152+
assert "Cp" in result
153+
assert "Mach" in result
154+
155+
def test_keeps_pressure_and_velocity_when_no_primitive_vars(self):
156+
fields = ["pressure", "velocity", "Cp"]
157+
result = remove_fields_subsumed_by_primitive_vars(fields)
158+
assert result == ["pressure", "velocity", "Cp"]
159+
160+
def test_preserves_velocity_magnitude_when_velocity_removed(self):
161+
fields = ["primitiveVars", "velocity", "velocity_magnitude", "pressure"]
162+
result = remove_fields_subsumed_by_primitive_vars(fields)
163+
assert "velocity" not in result
164+
assert "pressure" not in result
165+
assert "velocity_magnitude" in result
166+
assert "primitiveVars" in result
167+
168+
def test_no_op_on_empty_list(self):
169+
assert remove_fields_subsumed_by_primitive_vars([]) == []
170+
171+
def test_primitive_vars_only(self):
172+
fields = ["primitiveVars"]
173+
result = remove_fields_subsumed_by_primitive_vars(fields)
174+
assert result == ["primitiveVars"]
175+
176+
def test_removes_pressure_only_when_velocity_absent(self):
177+
fields = ["primitiveVars", "pressure", "Cp"]
178+
result = remove_fields_subsumed_by_primitive_vars(fields)
179+
assert "pressure" not in result
180+
assert result == ["primitiveVars", "Cp"]
181+
182+
def test_removes_velocity_only_when_pressure_absent(self):
183+
fields = ["primitiveVars", "velocity", "Mach"]
184+
result = remove_fields_subsumed_by_primitive_vars(fields)
185+
assert "velocity" not in result
186+
assert result == ["primitiveVars", "Mach"]

tests/simulation/translator/test_output_translation.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ def volume_output_config(vel_in_km_per_hr):
7777
"betMetrics",
7878
"primitiveVars",
7979
"qcriterion",
80-
"velocity",
8180
"velocity_in_km_per_hr",
8281
"velocity_magnitude",
8382
"vorticity",
@@ -114,7 +113,6 @@ def avg_volume_output_config(vel_in_km_per_hr):
114113
"betMetrics",
115114
"primitiveVars",
116115
"qcriterion",
117-
"velocity",
118116
"velocity_in_km_per_hr",
119117
"velocity_magnitude",
120118
],
@@ -161,8 +159,11 @@ def test_volume_output(volume_output_config, avg_volume_output_config):
161159
"betMetrics",
162160
"primitiveVars",
163161
"qcriterion",
162+
<<<<<<< HEAD
164163
"velocity",
165164
"velocity_in_km_per_hr",
165+
=======
166+
>>>>>>> c3af3b35 ([BackPort] fix: remove output fields subsumed by primitiveVars to prevent duplic… (#1951))
166167
"velocity_magnitude",
167168
"vorticity",
168169
"vorticityMagnitude",

0 commit comments

Comments
 (0)