.. _non_dim_intro:

.. currentmodule:: flow360


Introduction
*********************

Non-dimensionalization is essential for the Flow360 solver to reduce the number of variables and helps to provide better understanding of the underlying physics.
A non-dimensional variable is obtained by dividing its dimensional counterpart by an appropriately selected constant reference value.

In the table below, we show some common dimensional variables used as reference in Flow360 and how to access them through Python API. Note that :code:`project` is the cloud asset where you run the :code:`case`, and :code:`params` is the :py:class:`SimulationParams` object defined before submitting the case. For a completed :code:`case`, its :py:class:`SimulationParams` can be accessed by :code:`case.params`. More details about how to use Python API can be found :ref:`here <python_api>`.

.. _table_ref_value:

.. list-table:: Reference variables for non-dimensionalization in Flow360
   :widths: 10,20,10,40
   :header-rows: 1

   * - Variable
     - Definition
     - SI unit
     - How to access in Python API
   * - :math:`L_{gridUnit}`
     - Physical length represented by unit length in the given mesh file, e.g. If your grid is in feet, :math:`L_{gridUnit}=1 \text{ feet}`:math:`=0.3048 \text{ meter}`; If your grid is in millimeters, :math:`L_{gridUnit}=1 \text{ millimeter}`:math:`=0.001 \text{ meter}`. 
     - :math:`\text{m}` 
     - .. code-block:: python
  
        project.length_unit
   * - :math:`C_\infty`
     - Freestream speed of sound
     - :math:`\text{m}/\text{s}`
     - .. code-block:: python
  
        case.params.operating_condition \
        .thermal_state.speed_of_sound
   * - :math:`\rho_\infty`
     - Density of freestream
     - :math:`\text{kg}/\text{m}^3`
     - .. code-block:: python
  
        case.params.operating_condition \
        .thermal_state.density
   * - :math:`\mu_\infty`
     - Dynamic viscosity of freestream
     - :math:`\text{N} \cdot \text{s}/\text{m}^2` 
     - .. code-block:: python
  
        case.params.operating_condition \
        .thermal_state.dynamic_viscosity
   * - :math:`p_\infty`
     - Static pressure of freestream.

       .. note:: :math:`p_\infty` is used only for the pressure coefficient :math:`C_p`, not for general pressure non-dimensionalization (see :ref:`tab_non_dim_input`).
     - :math:`\text{N}/\text{m}^2`
     - .. code-block:: python
  
        case.params.operating_condition \
        .thermal_state.pressure
   * - :math:`T_\infty`
     - Temperature of freestream
     - :math:`\text{K}`
     - .. code-block:: python
  
        case.params.operating_condition \
        .thermal_state.temperature
   * - :math:`U_\text{ref}`
     - Reference velocity (used for force and moment coefficients)
     - :math:`\text{m}/\text{s}`
     - .. code-block:: python
  
        case.params.reference_velocity
   * - :math:`A_\text{ref}`
     - Reference area
     - :math:`\text{m}^2`
     - .. code-block:: python
  
        case.params.reference_geometry \
        .area
   * - :math:`L_\text{ref}`
     - Moment length
     - :math:`\text{m}`
     - .. code-block:: python
  
        case.params.reference_geometry \
        .moment_length

.. _reference_velocity_scaling:

Reference Velocity Scaling
--------------------------

We introduce the **reference velocity scaling** :math:`U_\text{scale}`, which is the reference velocity used for velocity nondimensionalization in many Flow360 variables (such as velocity fields, heat flux, volumetric heat sources, and angular speeds). It also sets the pressure reference: pressure is non-dimensionalized by :math:`\rho_\infty U_\text{scale}^2`.

- For :py:class:`AerospaceCondition`: :math:`U_\text{scale} = C_\infty` (speed of sound)
- For :py:class:`LiquidOperatingCondition`: :math:`U_\text{scale}` is :py:attr:`~LiquidOperatingCondition.reference_velocity` (which corresponds to :py:attr:`~LiquidOperatingCondition.reference_velocity_magnitude` if set, otherwise :py:attr:`~LiquidOperatingCondition.velocity_magnitude`)

The following Python code can be used to obtain :math:`U_\text{scale}`:

.. code-block:: python
   :linenos:
   :name: code_dim_velocity

   if operating_condition.type_name == "LiquidOperatingCondition":
       U_scale = operating_condition.reference_velocity
   else:  # AerospaceCondition
       U_scale = operating_condition.thermal_state.speed_of_sound

.. note::
   It is important to distinguish :math:`U_\text{scale}` from :math:`U_\text{ref}` (see :ref:`table_ref_value`). :math:`U_\text{scale}` non-dimensionalizes solver fields: velocity by :math:`U_\text{scale}`, pressure by :math:`\rho_\infty U_\text{scale}^2`, heat flux by :math:`\rho_\infty U_\text{scale}^3`. :math:`U_\text{ref}` non-dimensionalizes **force and moment coefficients** (:math:`C_L`, :math:`C_D`, :math:`C_F`, :math:`C_M`). Mixing them up produces incorrect conversions.

Grid Unit Length
----------------

In particular, the :math:`L_{gridUnit}` value is used to scale all length inputs. This allows the user to construct a mesh in any desired unit. Typical units are: meters, millimeters, feet, inches or reference chord lengths.  However, care must be taken when calculating input values such as Reynolds number or rotational speed, omega, to ensure that the same solution is obtained across different mesh scales. The :math:`L_{gridUnit}` values for commonly used mesh units are shown in :ref:`tab_Lgridunit`

.. _tab_Lgridunit:
.. list-table:: :math:`L_{gridUnit}` values for commonly used mesh units.
   :widths: 10,50
   :header-rows: 1
   
   * - Mesh Unit Length
     - :math:`L_{gridUnit}`
   * - metres [m]
     - 1.0 m  
   * - millimetres [mm]
     - 1 mm = 0.001 m
   * - feet [ft]
     - 1 ft = 0.3048 m
   * - inches [in]
     - 1 in = 0.0254 m
   * - unit chords [c=1.0]
     - 1 c_ref = (value of c_ref in metres)

For demonstration purpose, we assume grid unit :math:`L_{gridUnit} = 1\;\text{m}`. The operating condition is defined as :math:`T_\infty = 288.15\;\text{K}`, :math:`p_\infty = 1.225\;\text{kg}/\text{m}^3`, :math:`U_\text{ref} = 10\;\text{m}/\text{s}`, the inflow angle of attack :math:`\alpha` = 15 |deg|, and the side slip angle :math:`\beta` = 0 |deg|. The reference geometry is defined with :math:`A_\text{ref} = 1\;\text{m}^2`, :math:`L_\text{ref}=(1,1,1)\;\text{m}`, and moment center at :math:`(0,0,0)\;\text{m}`. The operating condition and reference geometry are set up with :py:class:`AerospaceCondition` and :py:class:`ReferenceGeometry` as follows,

.. _code_ref_value_operating_condition:

.. code-block:: python

   operating_condition = fl.AerospaceCondition(
       thermal_state=fl.ThermalState(
           density=1.225 * fl.u.kg / fl.u.m**3, 
           temperature=288.15 * fl.u.K
       ),
       alpha=15 * fl.u.deg,
       beta=0 * fl.u.deg,
       velocity_magnitude=10 * fl.u.m / fl.u.s,
   )

.. _code_ref_value_reference_geometry:
.. code-block:: python

   reference_geometry = fl.ReferenceGeometry(
       moment_center=(0, 0, 0) * fl.u.m, 
       moment_length=(1, 1, 1) * fl.u.m, 
       area=1.0 * fl.u.m**2
   )


In the following sections, we will present how to use these dimensional values as reference to non-dimensionalize :ref:`input variables <non_dim_input_userGuide>`, postprocess :ref:`output variables <non_dim_output_userGuide>` and :ref:`force & moment coefficients <non_dim_coeff_userGuide>`. 