Skip to content
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
36 changes: 33 additions & 3 deletions flow360/component/simulation/conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,15 +362,45 @@ def get_base_thermal_conductivity():
return flow360_conversion_unit_system.conversion_system


def get_flow360_unit_system_liquid(params) -> u.UnitSystem:
def get_flow360_unit_system_liquid(params, to_flow360_unit: bool = False) -> u.UnitSystem:
"""
Returns the flow360 unit system when liquid operating condition is used
Returns the flow360 unit system when liquid operating condition is used.

Parameters
----------
params : SimulationParams
The parameters needed for unit conversion.
to_flow360_unit : bool, optional
If True, return the flow360 unit system.

Returns
-------
u.UnitSystem
The flow360 unit system.

##-- When to_flow360_unit is True,
##-- time unit should be changed such that it takes into consideration
##-- the fact that solver output already multiplied by "velocityScale"
"""

if to_flow360_unit:
base_velocity = params.base_velocity
else:
# For dimensionalization of Flow360 output
# The solver output is already re-normalized by `reference velocity` due to "velocityScale"
# So we need to find the `reference velocity`.
# `reference_velocity_magnitude` takes precedence, consistent with how "velocityScale" is computed.
if params.operating_condition.reference_velocity_magnitude is not None:
base_velocity = (params.operating_condition.reference_velocity_magnitude).to("m/s")
else:
base_velocity = params.base_velocity.to("m/s") * LIQUID_IMAGINARY_FREESTREAM_MACH

time_unit = params.base_length / base_velocity
return u.UnitSystem(
name="flow360_liquid",
length_unit=params.base_length,
mass_unit=params.base_mass,
time_unit=params.base_time / LIQUID_IMAGINARY_FREESTREAM_MACH,
time_unit=time_unit,
temperature_unit=params.base_temperature,
)

Expand Down
16 changes: 16 additions & 0 deletions tests/simulation/translator/ref/Flow360_liquid_rotation_dd.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@
}
},
"userDefinedFields": [
{
"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);",
"name": "velocity_SI"
},
{
"expression": "double velocity[3];velocity[0] = primitiveVars[1];velocity[1] = primitiveVars[2];velocity[2] = primitiveVars[3];velocity_magnitude = magnitude(velocity) * velocityScale;",
"name": "velocity_magnitude",
Expand All @@ -99,6 +103,18 @@
"outputRescale": {
"velocityScale": 20.0
},
"volumeOutput": {
"animationFrequency": -1,
"animationFrequencyOffset": 0,
"animationFrequencyTimeAverage": -1,
"animationFrequencyTimeAverageOffset": 0,
"computeTimeAverages": false,
"outputFields": [
"velocity_SI"
],
"outputFormat": "paraview",
"startAverageIntegrationStep": -1
},
"volumeZones": {
"zone_zone_1": {
"referenceFrame": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
{
"freestream": {
"alphaAngle": 5.0,
"betaAngle": 2.0,
"Mach": 0.05,
"Temperature": -1,
"muRef": 4.554545454545455e-09,
"MachRef": 0.1
},
"timeStepping": {
"CFL": {
"type": "adaptive",
"min": 0.1,
"max": 1000000.0,
"maxRelativeChange": 50.0,
"convergenceLimitingFactor": 1.0
},
"physicalSteps": 100,
"orderOfAccuracy": 2,
"maxPseudoSteps": 20,
"timeStepSize": 80.0
},
"navierStokesSolver": {
"absoluteTolerance": 1e-10,
"relativeTolerance": 0.0,
"orderOfAccuracy": 2,
"linearSolver": {
"maxIterations": 30
},
"CFLMultiplier": 1.0,
"kappaMUSCL": -1.0,
"numericalDissipationFactor": 1.0,
"limitVelocity": false,
"limitPressureDensity": false,
"lowMachPreconditioner": true,
"updateJacobianFrequency": 4,
"maxForceJacUpdatePhysicalSteps": 0,
"lowMachPreconditionerThreshold": 0.05,
"modelType": "Compressible",
"equationEvalFrequency": 1
},
"turbulenceModelSolver": {
"absoluteTolerance": 1e-08,
"relativeTolerance": 0.0,
"orderOfAccuracy": 2,
"linearSolver": {
"maxIterations": 20
},
"CFLMultiplier": 2.0,
"reconstructionGradientLimiter": 0.5,
"quadraticConstitutiveRelation": false,
"updateJacobianFrequency": 4,
"maxForceJacUpdatePhysicalSteps": 0,
"rotationCorrection": false,
"equationEvalFrequency": 4,
"modelType": "SpalartAllmaras",
"modelConstants": {
"C_DES": 0.72,
"C_d": 8.0,
"C_cb1": 0.1355,
"C_cb2": 0.622,
"C_sigma": 0.6666666666666666,
"C_v1": 7.1,
"C_vonKarman": 0.41,
"C_w2": 0.3,
"C_t3": 1.2,
"C_t4": 0.5,
"C_min_rd": 10.0
},
"DDES": false,
"ZDES": false,
"gridSizeForLES": "maxEdgeLength"
},
"initialCondition": {
"type": "initialCondition",
"rho": "rho",
"u": "u",
"v": "v",
"w": "w",
"p": "p"
},
"boundaries": {
"fluid/body": {
"type": "NoSlipWall",
"heatFlux": 0.0,
"roughnessHeight": 0.0
},
"fluid/farfield": {
"type": "Freestream"
}
},
"userDefinedFields": [
{
"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);",
"name": "velocity_SI"
},
{
"expression": "double velocity[3];velocity[0] = primitiveVars[1];velocity[1] = primitiveVars[2];velocity[2] = primitiveVars[3];velocity_magnitude = magnitude(velocity) * velocityScale;",
"name": "velocity_magnitude",
"from_user_variables": false
}
],
"usingLiquidAsMaterial": true,
"outputRescale": {
"velocityScale": 10.0
},
"volumeOutput": {
"animationFrequency": -1,
"animationFrequencyOffset": 0,
"animationFrequencyTimeAverage": -1,
"animationFrequencyTimeAverageOffset": 0,
"computeTimeAverages": false,
"outputFields": [
"velocity_SI"
],
"outputFormat": "paraview",
"startAverageIntegrationStep": -1
},
"volumeZones": {
"zone_zone_1": {
"referenceFrame": {
"axisOfRotation": [
0.6,
0.8,
0.0
],
"centerOfRotation": [
0.01,
0.01,
0.01
],
"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))"
},
"modelType": "FluidDynamics",
"isRotatingReferenceFrame": false
}
}
}
16 changes: 8 additions & 8 deletions tests/simulation/translator/test_output_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,7 @@ def test_dimensioned_output_fields_translation(vel_in_km_per_hr):
},
{
"name": "pressure_pa",
"expression": "double pressure;double gamma = 1.4;pressure = (usingLiquidAsMaterial) ? (primitiveVars[4] - 1.0 / gamma) * (velocityScale * velocityScale) : primitiveVars[4];pressure_pa = pressure * 2500000.0;",
"expression": "double pressure;double gamma = 1.4;pressure = (usingLiquidAsMaterial) ? (primitiveVars[4] - 1.0 / gamma) * (velocityScale * velocityScale) : primitiveVars[4];pressure_pa = pressure * 10000000.0;",
"from_user_variables": False,
},
{
Expand All @@ -1361,11 +1361,11 @@ def test_dimensioned_output_fields_translation(vel_in_km_per_hr):
},
{
"name": "velocity_in_km_per_hr",
"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);",
"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);",
},
{
"name": "velocity_m_per_s",
"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;",
"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;",
"from_user_variables": False,
},
{
Expand All @@ -1375,22 +1375,22 @@ def test_dimensioned_output_fields_translation(vel_in_km_per_hr):
},
{
"name": "velocity_magnitude_m_per_s",
"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;",
"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;",
"from_user_variables": False,
},
{
"name": "velocity_x_m_per_s",
"expression": "double velocity_x;velocity_x = primitiveVars[1] * velocityScale;velocity_x_m_per_s = velocity_x * 50.0;",
"expression": "double velocity_x;velocity_x = primitiveVars[1] * velocityScale;velocity_x_m_per_s = velocity_x * 100.0;",
"from_user_variables": False,
},
{
"name": "velocity_y_m_per_s",
"expression": "double velocity_y;velocity_y = primitiveVars[2] * velocityScale;velocity_y_m_per_s = velocity_y * 50.0;",
"expression": "double velocity_y;velocity_y = primitiveVars[2] * velocityScale;velocity_y_m_per_s = velocity_y * 100.0;",
"from_user_variables": False,
},
{
"name": "velocity_z_m_per_s",
"expression": "double velocity_z;velocity_z = primitiveVars[3] * velocityScale;velocity_z_m_per_s = velocity_z * 50.0;",
"expression": "double velocity_z;velocity_z = primitiveVars[3] * velocityScale;velocity_z_m_per_s = velocity_z * 100.0;",
"from_user_variables": False,
},
{
Expand All @@ -1405,7 +1405,7 @@ def test_dimensioned_output_fields_translation(vel_in_km_per_hr):
},
{
"name": "wall_shear_stress_magnitude_pa",
"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;",
"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;",
"from_user_variables": False,
},
]
Expand Down
16 changes: 16 additions & 0 deletions tests/simulation/translator/test_solver_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
from flow360.component.simulation.user_code.core.types import UserVariable
from flow360.component.simulation.user_code.functions import math
from flow360.component.simulation.user_code.variables import solution
from flow360.component.simulation.utils import model_attribute_unlock
from tests.simulation.translator.utils.actuator_disk_param_generator import (
actuator_disk_create_param,
)
Expand Down Expand Up @@ -659,13 +660,28 @@ def test_liquid_simulation_translation():
),
],
time_stepping=Unsteady(steps=100, step_size=0.4),
outputs=[
VolumeOutput(
name="output",
output_fields=[solution.velocity],
)
],
)
# Derivation:
# Solver speed of sound = 10m/s / 0.05 = 200m/s
# Flow360 time to seconds = 1m/(200m/s) = 0.005 s
# t_seconds = (0.005 s * t)
translate_and_compare(param, mesh_unit=1 * u.m, ref_json_file="Flow360_liquid_rotation_dd.json")

with model_attribute_unlock(param.operating_condition, "reference_velocity_magnitude"):
param.operating_condition.reference_velocity_magnitude = 20 * u.m / u.s
translate_and_compare(
param,
mesh_unit=1 * u.m,
ref_json_file="Flow360_liquid_rotation_dd_with_ref_vel.json",
debug=True,
)


def test_param_with_user_variables():
some_dependent_variable_a = UserVariable(
Expand Down
Loading