.. _knowledge_base_BETDisks:

.. currentmodule:: flow360

:class:`BETDisk`
==========================================

Steady blade disk solver
    To use the steady blade disk solver, the :py:attr:`~BETDisk.blade_line_chord` needs to be set as 0, which is its default value if omitted.

Unsteady blade line solver
    To use the unsteady blade line solver, :py:attr:`~BETDisk.blade_line_chord` has to be a positive value and :py:attr:`~BETDisk.initial_blade_direction` also needs to be set.

In the :class:`BETDisk` volume model, except the :py:attr:`~BETDisk.blade_line_chord` and :py:attr:`~BETDisk.initial_blade_direction`, other parameters are necessary for both solvers. A validation study on the XV-15 rotor using blade element theory can be found at :ref:`XV15 BET Disk <XV15BETDiskValidationStudy>`.

.. note::
   
   #. For users of XROTOR and DFDC, we have a translator script that will convert the XROTOR/DFDC inputs in Flow360 BET inputs.

Some input parameters related to BET solver in Flow360 are explained:

.. _rot_dir_rule:

:py:attr:`~BETDisk.rotation_direction_rule`
-----------------------------------------------------

:code:`leftHand` or :code:`rightHand`. It depends on the design of the rotor blades: whether the blades follow curl left hand rule or the curl right hand rule to generate positive thrust. The following 2 figures show the curl left hand rule and curl right hand rule. The fingers follow the spinning of the blades and the thumb points to the thrust direction. By default, it is :code:`rightHand`.

.. grid:: 2

    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/left_hand_rule.svg
            :width: 80%
            :align: center

    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/right_hand_rule.svg
            :width: 80%
            :align: center

.. _bet_omega:


:py:attr:`~BETDisk.omega`
---------------------------

The nondimensional rotating speed. It should be positive in most cases, which means the leading edge moves in front and the rotation direction of the blades in BET simulations is consistent with the curling fingers described in "rotationDirectionRule" to generate positive thrust. A negative "omega" means the blades rotate in a reverse direction, hence in an opposite direction to the curling fingers, where the trailing edge moves in front. 

The following 4 pictures give some examples of different rotationDirectionRule and axisOfRotation with **positive omega**. The curved arrow follows the same direction in which rotor spins. The straight arrow points to the direction of thrust.

.. grid:: 2

    .. grid-item::
        :columns: 6
        :margin: auto

        .. code-block:: python

            volume_entity.axis = (0,0,1)
            fl.BETDisk(
                rotation_direction_rule="leftHand",
                omega=0.3 * fl.u.deg / fl.u.s,
                entities=[volume_entity]
            )


    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/leftHand_thrust_z+.svg
            :width: 80%
            :align: center

-------------------------------------------------------------

.. grid:: 2

    .. grid-item::
        :columns: 6
        :margin: auto

        .. code-block:: python

            volume_entity.axis = (0,0,-1)
            fl.BETDisk(
                rotation_direction_rule="leftHand",
                omega=0.5 * fl.u.deg / fl.u.s,
                entities=[volume_entity]
            )

    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/leftHand_thrust_z-.svg
            :width: 80%
            :align: center

-------------------------------------------------------------

.. grid:: 2

    .. grid-item::
        :columns: 6
        :margin: auto

        .. code-block:: python

            volume_entity.axis = (0,0,1)
            fl.BETDisk(
                rotation_direction_rule="rightHand",
                omega=0.5 * fl.u.deg / fl.u.s,
                entities=[volume_entity]
            )

    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/rightHand_thrust_z+.svg
            :width: 80%
            :align: center

-------------------------------------------------------------

.. grid:: 2

    .. grid-item::
        :columns: 6
        :margin: auto

        .. code-block:: python

            volume_entity.axis = (0,0,-1)
            fl.BETDisk(
                rotation_direction_rule="rightHand",
                omega=0.5 * fl.u.deg / fl.u.s,
                entities=[volume_entity]
            )

    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/rightHand_thrust_z-.svg
            :width: 80%
            :align: center

-----------------------------------------------------------------

.. _chords_and_twists_bet:

:py:attr:`~BETDisk.chords` and :py:attr:`~BETDisk.twists`
------------------------------------------------------------

The sampled radial distribution of chord length and geometric twist angle. The "twist" affects the local pitch angle. The "chords" affects the amount of lift and drag imposed on the blade (or fluid). For a radial location where chord=0, there is no lift or drag imposed. It should be noted that for any radial location within the given sampling range, the chord or twist is linearly interpolated between its two neighboring sampled data points. For any radial location beyond the given sampling range, the chord or twist is set to be the nearest sampled chord or twist, i.e. constant extrapolation. In the Flow360 python client, the :py:attr:`~BETDisk.chords` and :py:attr:`~BETDisk.twists` can be set up using :class:`BETDiskChord` and :class:`BETDiskTwist`, respectively. Here are 3 examples of the given "chords" and the corresponding radial distribution of chord length:

**Example 1.** The root of blade starts at r=20 with chord length=15. The chord shrinks to 10 linearly up to r=60. The chord keeps as 10 for the rest of blade. In this setting, the chord=0 for r in [0,20], there is no aerodynamic lift and drag imposed no matter what the twist angle it has, so this setting fits the rotor without hub.

.. grid:: 2

    .. grid-item::
        :columns: 6
        :margin: auto

        .. code-block:: python

            chords = []
            radial_loc_value_for_chord =[19.9999, 20, 60, 150]
            radial_chords_value = [0, 15, 10, 10]
            for radius, chord in zip(radial_loc_value_for_chord, radial_chords_value):
                betDiskChord = fl.BETDiskChord(radius=radius * fl.u.inch, chord=chord * fl.u.inch)
                chords.append(betDiskChord)

    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/chords_distribution_1.svg
           :align: center

**Example 2.** The root of blade starts at r=0 with chord=0. The chord expands to 15 linearly up to r=20, then shrinks to 10 linearly up to r=60. The chord keeps as 10 for the rest of blade. This setting could be used for a mesh with the geometry of hub. Because the chord length changes gradually near the root region, there won't be tip vortices in root region.

.. grid:: 2

    .. grid-item::
        :columns: 6
        :margin: auto

        .. code-block:: python

            chords = []
            radial_loc_value_for_chord =[0, 20, 60, 150]
            radial_chords_value = [0, 15, 10, 10]
            for radius, chord in zip(radial_loc_value_for_chord, radial_chords_value):
                betDiskChord = fl.BETDiskChord(radius=radius * fl.u.inch, chord=chord * fl.u.inch)
                chords.append(betDiskChord)

    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/chords_distribution_2.svg
           :align: center

**Example 3.** This is an example of a **wrong** setting of chords, because the chord length at r=0 is not 0, so the local solidity is infinity, which is not realistic.

.. grid:: 2

    .. grid-item::
        :columns: 6
        :margin: auto

        .. code-block:: python
            
            chords = []
            radial_loc_value_for_chord =[20, 60, 150]
            radial_chords_value = [15, 10, 10]
            for radius, chord in zip(radial_loc_value_for_chord, radial_chords_value):
                betDiskChord = fl.BETDiskChord(radius=radius * fl.u.inch, chord=chord * fl.u.inch)
                chords.append(betDiskChord)

    .. grid-item::
        :columns: 6
        :margin: auto

        .. figure:: Figures/chords_distribution_3.svg
           :align: center

.. note::

   The number of sampling data points in :py:attr:`~BETDisk.chords` and :py:attr:`~BETDisk.twists` doesn't have to be the same. They are served as sampled data for interpolation of chord length and twist angle respectively and separately. 

:py:attr:`~BETDisk.n_loading_nodes`
--------------------------------------------

This parameter defines the number of loading nodes used to compute the sectional thrust and torque coefficients :math:`C_t` and :math:`C_q`, defined in :ref:`betDiskLoadingNote`. The recommended value is 20 to ensure sufficient resolution of the sectional loading distributions.

:py:attr:`~BETDisk.blade_line_chord`
------------------------------------------

When the value of :py:attr:`~BETDisk.blade_line_chord` is zero, a steady-state BET Disk simulation is performed. If non-zero, this value defines the nondimensional chord for unsteady BET Line simulations. The recommended value is 1-2x the physical mean aerodynamic chord (MAC) of the blade for an unsteady BET Line simulation.

.. _TipGap:

:py:attr:`~BETDisk.tip_gap`
----------------------------------

The :py:attr:`~BETDisk.tip_gap` is the nondimensional distance between blade tips and peripheral geometry (e.g., duct, shroud, cowling, nacelle, etc.). The peripheral structures must be effective at reducing blade tip vortices as this parameter affects the tip loss effect. Being close to a fuselage or to another blade is not a cause to enable this parameter, because they won't effectively reduce the tip loss. :py:attr:`~BETDisk.tip_gap` = 0 means there is no tip loss effect in the solver. It is :math:`\infty` (default) for open propellers.
