Skip to content

Commit e025e34

Browse files
Fix bug that dimensionalization used wrong velocity scale (#1361)
* Fix bug that dimensionalization used wrong velocity scale * Fix unit test
1 parent 6183830 commit e025e34

File tree

5 files changed

+211
-11
lines changed

5 files changed

+211
-11
lines changed

flow360/component/simulation/conversion.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,15 +362,45 @@ def get_base_thermal_conductivity():
362362
return flow360_conversion_unit_system.conversion_system
363363

364364

365-
def get_flow360_unit_system_liquid(params) -> u.UnitSystem:
365+
def get_flow360_unit_system_liquid(params, to_flow360_unit: bool = False) -> u.UnitSystem:
366366
"""
367-
Returns the flow360 unit system when liquid operating condition is used
367+
Returns the flow360 unit system when liquid operating condition is used.
368+
369+
Parameters
370+
----------
371+
params : SimulationParams
372+
The parameters needed for unit conversion.
373+
to_flow360_unit : bool, optional
374+
If True, return the flow360 unit system.
375+
376+
Returns
377+
-------
378+
u.UnitSystem
379+
The flow360 unit system.
380+
381+
##-- When to_flow360_unit is True,
382+
##-- time unit should be changed such that it takes into consideration
383+
##-- the fact that solver output already multiplied by "velocityScale"
368384
"""
385+
386+
if to_flow360_unit:
387+
base_velocity = params.base_velocity
388+
else:
389+
# For dimensionalization of Flow360 output
390+
# The solver output is already re-normalized by `reference velocity` due to "velocityScale"
391+
# So we need to find the `reference velocity`.
392+
# `reference_velocity_magnitude` takes precedence, consistent with how "velocityScale" is computed.
393+
if params.operating_condition.reference_velocity_magnitude is not None:
394+
base_velocity = (params.operating_condition.reference_velocity_magnitude).to("m/s")
395+
else:
396+
base_velocity = params.base_velocity.to("m/s") * LIQUID_IMAGINARY_FREESTREAM_MACH
397+
398+
time_unit = params.base_length / base_velocity
369399
return u.UnitSystem(
370400
name="flow360_liquid",
371401
length_unit=params.base_length,
372402
mass_unit=params.base_mass,
373-
time_unit=params.base_time / LIQUID_IMAGINARY_FREESTREAM_MACH,
403+
time_unit=time_unit,
374404
temperature_unit=params.base_temperature,
375405
)
376406

tests/simulation/translator/ref/Flow360_liquid_rotation_dd.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@
8989
}
9090
},
9191
"userDefinedFields": [
92+
{
93+
"expression": "double ___velocity[3];___velocity[0] = primitiveVars[1] * velocityScale;___velocity[1] = primitiveVars[2] * velocityScale;___velocity[2] = primitiveVars[3] * velocityScale;velocity_SI[0] = (___velocity[0] * 10.0); velocity_SI[1] = (___velocity[1] * 10.0); velocity_SI[2] = (___velocity[2] * 10.0);",
94+
"name": "velocity_SI"
95+
},
9296
{
9397
"expression": "double velocity[3];velocity[0] = primitiveVars[1];velocity[1] = primitiveVars[2];velocity[2] = primitiveVars[3];velocity_magnitude = magnitude(velocity) * velocityScale;",
9498
"name": "velocity_magnitude",
@@ -99,6 +103,18 @@
99103
"outputRescale": {
100104
"velocityScale": 20.0
101105
},
106+
"volumeOutput": {
107+
"animationFrequency": -1,
108+
"animationFrequencyOffset": 0,
109+
"animationFrequencyTimeAverage": -1,
110+
"animationFrequencyTimeAverageOffset": 0,
111+
"computeTimeAverages": false,
112+
"outputFields": [
113+
"velocity_SI"
114+
],
115+
"outputFormat": "paraview",
116+
"startAverageIntegrationStep": -1
117+
},
102118
"volumeZones": {
103119
"zone_zone_1": {
104120
"referenceFrame": {
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
{
2+
"freestream": {
3+
"alphaAngle": 5.0,
4+
"betaAngle": 2.0,
5+
"Mach": 0.05,
6+
"Temperature": -1,
7+
"muRef": 4.554545454545455e-09,
8+
"MachRef": 0.1
9+
},
10+
"timeStepping": {
11+
"CFL": {
12+
"type": "adaptive",
13+
"min": 0.1,
14+
"max": 1000000.0,
15+
"maxRelativeChange": 50.0,
16+
"convergenceLimitingFactor": 1.0
17+
},
18+
"physicalSteps": 100,
19+
"orderOfAccuracy": 2,
20+
"maxPseudoSteps": 20,
21+
"timeStepSize": 80.0
22+
},
23+
"navierStokesSolver": {
24+
"absoluteTolerance": 1e-10,
25+
"relativeTolerance": 0.0,
26+
"orderOfAccuracy": 2,
27+
"linearSolver": {
28+
"maxIterations": 30
29+
},
30+
"CFLMultiplier": 1.0,
31+
"kappaMUSCL": -1.0,
32+
"numericalDissipationFactor": 1.0,
33+
"limitVelocity": false,
34+
"limitPressureDensity": false,
35+
"lowMachPreconditioner": true,
36+
"updateJacobianFrequency": 4,
37+
"maxForceJacUpdatePhysicalSteps": 0,
38+
"lowMachPreconditionerThreshold": 0.05,
39+
"modelType": "Compressible",
40+
"equationEvalFrequency": 1
41+
},
42+
"turbulenceModelSolver": {
43+
"absoluteTolerance": 1e-08,
44+
"relativeTolerance": 0.0,
45+
"orderOfAccuracy": 2,
46+
"linearSolver": {
47+
"maxIterations": 20
48+
},
49+
"CFLMultiplier": 2.0,
50+
"reconstructionGradientLimiter": 0.5,
51+
"quadraticConstitutiveRelation": false,
52+
"updateJacobianFrequency": 4,
53+
"maxForceJacUpdatePhysicalSteps": 0,
54+
"rotationCorrection": false,
55+
"equationEvalFrequency": 4,
56+
"modelType": "SpalartAllmaras",
57+
"modelConstants": {
58+
"C_DES": 0.72,
59+
"C_d": 8.0,
60+
"C_cb1": 0.1355,
61+
"C_cb2": 0.622,
62+
"C_sigma": 0.6666666666666666,
63+
"C_v1": 7.1,
64+
"C_vonKarman": 0.41,
65+
"C_w2": 0.3,
66+
"C_t3": 1.2,
67+
"C_t4": 0.5,
68+
"C_min_rd": 10.0
69+
},
70+
"DDES": false,
71+
"ZDES": false,
72+
"gridSizeForLES": "maxEdgeLength"
73+
},
74+
"initialCondition": {
75+
"type": "initialCondition",
76+
"rho": "rho",
77+
"u": "u",
78+
"v": "v",
79+
"w": "w",
80+
"p": "p"
81+
},
82+
"boundaries": {
83+
"fluid/body": {
84+
"type": "NoSlipWall",
85+
"heatFlux": 0.0,
86+
"roughnessHeight": 0.0
87+
},
88+
"fluid/farfield": {
89+
"type": "Freestream"
90+
}
91+
},
92+
"userDefinedFields": [
93+
{
94+
"expression": "double ___velocity[3];___velocity[0] = primitiveVars[1] * velocityScale;___velocity[1] = primitiveVars[2] * velocityScale;___velocity[2] = primitiveVars[3] * velocityScale;velocity_SI[0] = (___velocity[0] * 20.0); velocity_SI[1] = (___velocity[1] * 20.0); velocity_SI[2] = (___velocity[2] * 20.0);",
95+
"name": "velocity_SI"
96+
},
97+
{
98+
"expression": "double velocity[3];velocity[0] = primitiveVars[1];velocity[1] = primitiveVars[2];velocity[2] = primitiveVars[3];velocity_magnitude = magnitude(velocity) * velocityScale;",
99+
"name": "velocity_magnitude",
100+
"from_user_variables": false
101+
}
102+
],
103+
"usingLiquidAsMaterial": true,
104+
"outputRescale": {
105+
"velocityScale": 10.0
106+
},
107+
"volumeOutput": {
108+
"animationFrequency": -1,
109+
"animationFrequencyOffset": 0,
110+
"animationFrequencyTimeAverage": -1,
111+
"animationFrequencyTimeAverageOffset": 0,
112+
"computeTimeAverages": false,
113+
"outputFields": [
114+
"velocity_SI"
115+
],
116+
"outputFormat": "paraview",
117+
"startAverageIntegrationStep": -1
118+
},
119+
"volumeZones": {
120+
"zone_zone_1": {
121+
"referenceFrame": {
122+
"axisOfRotation": [
123+
0.6,
124+
0.8,
125+
0.0
126+
],
127+
"centerOfRotation": [
128+
0.01,
129+
0.01,
130+
0.01
131+
],
132+
"thetaRadians": "-180/pi * atan(2 * 3.00 * 20.00 * 2.00/180*pi * cos(2.00/180*pi * sin(0.05877271 * (0.005 * t))) * cos(0.05877271 * (0.005 * t)) / 200.00) + 2 * 2.00 * sin(0.05877271 * (0.005 * t)) - 2.00 * sin(0.05877271 * (0.005 * t))"
133+
},
134+
"modelType": "FluidDynamics",
135+
"isRotatingReferenceFrame": false
136+
}
137+
}
138+
}

tests/simulation/translator/test_output_translation.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,7 @@ def test_dimensioned_output_fields_translation(vel_in_km_per_hr):
13511351
},
13521352
{
13531353
"name": "pressure_pa",
1354-
"expression": "double pressure;double gamma = 1.4;pressure = (usingLiquidAsMaterial) ? (primitiveVars[4] - 1.0 / gamma) * (velocityScale * velocityScale) : primitiveVars[4];pressure_pa = pressure * 2500000.0;",
1354+
"expression": "double pressure;double gamma = 1.4;pressure = (usingLiquidAsMaterial) ? (primitiveVars[4] - 1.0 / gamma) * (velocityScale * velocityScale) : primitiveVars[4];pressure_pa = pressure * 10000000.0;",
13551355
"from_user_variables": False,
13561356
},
13571357
{
@@ -1361,11 +1361,11 @@ def test_dimensioned_output_fields_translation(vel_in_km_per_hr):
13611361
},
13621362
{
13631363
"name": "velocity_in_km_per_hr",
1364-
"expression": "double ___velocity[3];___velocity[0] = primitiveVars[1] * velocityScale;___velocity[1] = primitiveVars[2] * velocityScale;___velocity[2] = primitiveVars[3] * velocityScale;velocity_in_km_per_hr[0] = (___velocity[0] * 180.0); velocity_in_km_per_hr[1] = (___velocity[1] * 180.0); velocity_in_km_per_hr[2] = (___velocity[2] * 180.0);",
1364+
"expression": "double ___velocity[3];___velocity[0] = primitiveVars[1] * velocityScale;___velocity[1] = primitiveVars[2] * velocityScale;___velocity[2] = primitiveVars[3] * velocityScale;velocity_in_km_per_hr[0] = (___velocity[0] * 360.0); velocity_in_km_per_hr[1] = (___velocity[1] * 360.0); velocity_in_km_per_hr[2] = (___velocity[2] * 360.0);",
13651365
},
13661366
{
13671367
"name": "velocity_m_per_s",
1368-
"expression": "double velocity[3];velocity[0] = primitiveVars[1] * velocityScale;velocity[1] = primitiveVars[2] * velocityScale;velocity[2] = primitiveVars[3] * velocityScale;velocity_m_per_s[0] = velocity[0] * 50.0;velocity_m_per_s[1] = velocity[1] * 50.0;velocity_m_per_s[2] = velocity[2] * 50.0;",
1368+
"expression": "double velocity[3];velocity[0] = primitiveVars[1] * velocityScale;velocity[1] = primitiveVars[2] * velocityScale;velocity[2] = primitiveVars[3] * velocityScale;velocity_m_per_s[0] = velocity[0] * 100.0;velocity_m_per_s[1] = velocity[1] * 100.0;velocity_m_per_s[2] = velocity[2] * 100.0;",
13691369
"from_user_variables": False,
13701370
},
13711371
{
@@ -1375,22 +1375,22 @@ def test_dimensioned_output_fields_translation(vel_in_km_per_hr):
13751375
},
13761376
{
13771377
"name": "velocity_magnitude_m_per_s",
1378-
"expression": "double velocity_magnitude;double velocity[3];velocity[0] = primitiveVars[1];velocity[1] = primitiveVars[2];velocity[2] = primitiveVars[3];velocity_magnitude = magnitude(velocity) * velocityScale;velocity_magnitude_m_per_s = velocity_magnitude * 50.0;",
1378+
"expression": "double velocity_magnitude;double velocity[3];velocity[0] = primitiveVars[1];velocity[1] = primitiveVars[2];velocity[2] = primitiveVars[3];velocity_magnitude = magnitude(velocity) * velocityScale;velocity_magnitude_m_per_s = velocity_magnitude * 100.0;",
13791379
"from_user_variables": False,
13801380
},
13811381
{
13821382
"name": "velocity_x_m_per_s",
1383-
"expression": "double velocity_x;velocity_x = primitiveVars[1] * velocityScale;velocity_x_m_per_s = velocity_x * 50.0;",
1383+
"expression": "double velocity_x;velocity_x = primitiveVars[1] * velocityScale;velocity_x_m_per_s = velocity_x * 100.0;",
13841384
"from_user_variables": False,
13851385
},
13861386
{
13871387
"name": "velocity_y_m_per_s",
1388-
"expression": "double velocity_y;velocity_y = primitiveVars[2] * velocityScale;velocity_y_m_per_s = velocity_y * 50.0;",
1388+
"expression": "double velocity_y;velocity_y = primitiveVars[2] * velocityScale;velocity_y_m_per_s = velocity_y * 100.0;",
13891389
"from_user_variables": False,
13901390
},
13911391
{
13921392
"name": "velocity_z_m_per_s",
1393-
"expression": "double velocity_z;velocity_z = primitiveVars[3] * velocityScale;velocity_z_m_per_s = velocity_z * 50.0;",
1393+
"expression": "double velocity_z;velocity_z = primitiveVars[3] * velocityScale;velocity_z_m_per_s = velocity_z * 100.0;",
13941394
"from_user_variables": False,
13951395
},
13961396
{
@@ -1405,7 +1405,7 @@ def test_dimensioned_output_fields_translation(vel_in_km_per_hr):
14051405
},
14061406
{
14071407
"name": "wall_shear_stress_magnitude_pa",
1408-
"expression": "double wall_shear_stress_magnitude;wall_shear_stress_magnitude = magnitude(wallShearStress) * (velocityScale * velocityScale);wall_shear_stress_magnitude_pa = wall_shear_stress_magnitude * 2500000.0;",
1408+
"expression": "double wall_shear_stress_magnitude;wall_shear_stress_magnitude = magnitude(wallShearStress) * (velocityScale * velocityScale);wall_shear_stress_magnitude_pa = wall_shear_stress_magnitude * 10000000.0;",
14091409
"from_user_variables": False,
14101410
},
14111411
]

tests/simulation/translator/test_solver_translator.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
from flow360.component.simulation.user_code.core.types import UserVariable
6969
from flow360.component.simulation.user_code.functions import math
7070
from flow360.component.simulation.user_code.variables import solution
71+
from flow360.component.simulation.utils import model_attribute_unlock
7172
from tests.simulation.translator.utils.actuator_disk_param_generator import (
7273
actuator_disk_create_param,
7374
)
@@ -659,13 +660,28 @@ def test_liquid_simulation_translation():
659660
),
660661
],
661662
time_stepping=Unsteady(steps=100, step_size=0.4),
663+
outputs=[
664+
VolumeOutput(
665+
name="output",
666+
output_fields=[solution.velocity],
667+
)
668+
],
662669
)
663670
# Derivation:
664671
# Solver speed of sound = 10m/s / 0.05 = 200m/s
665672
# Flow360 time to seconds = 1m/(200m/s) = 0.005 s
666673
# t_seconds = (0.005 s * t)
667674
translate_and_compare(param, mesh_unit=1 * u.m, ref_json_file="Flow360_liquid_rotation_dd.json")
668675

676+
with model_attribute_unlock(param.operating_condition, "reference_velocity_magnitude"):
677+
param.operating_condition.reference_velocity_magnitude = 20 * u.m / u.s
678+
translate_and_compare(
679+
param,
680+
mesh_unit=1 * u.m,
681+
ref_json_file="Flow360_liquid_rotation_dd_with_ref_vel.json",
682+
debug=True,
683+
)
684+
669685

670686
def test_param_with_user_variables():
671687
some_dependent_variable_a = UserVariable(

0 commit comments

Comments
 (0)