.. _knowledge_base_rotation:

.. currentmodule:: flow360

:class:`Rotation`
=======================================================

:py:attr:`~Rotation.spec`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For convenience, there are three options for specifying the rotation settings in :class:`Rotation`: 

* :class:`AngularVelocity` to set up the angular velocity.
* :class:`AngleExpression` to set up the rotation angle as a function of time.
* :class:`FromUserDefinedDynamics` to set up the user defined dynamics for rotation using a non-dimensional expression.

.. _knowledge_base_volumeZones_parentVolumeName:

:py:attr:`~Rotation.parent_volume`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The :py:attr:`~Rotation.parent_volume` is required for nested rotational volume zones. If zoneA is a rotational zone and zoneB rotates relative to zoneA, zoneB is treated as a nested rotational volume zone. In such a scenario, zoneB's frame of reference is built upon zoneA's frame of reference, so in zoneB's :class:`Rotation` configuration, it is required to set :code:`parent_volume=volume_mesh["zoneA"]`. 

.. caution::
   If a volume zone rotates with respect to the inertial frame of reference, the :py:attr:`~Rotation.parent_volume` should not be specified. An example can be found at :ref:`XV15 rotor tutorial <XV15_tutorial_case_config>`. Any volume zone, assigned as parent of another volume zone, has to be a rotational volume zone, otherwise the validation during case submission will report errors.


In the following configuration, the frame of reference of :code:`FLUID-MIDDLE-BLOCK` rotates with respect to the inertial frame of reference, so the :py:attr:`~Rotation.parent_volume` is not specified. The frame of reference of :code:`FLUID-INNER-BLOCK` rotates with respect to the :code:`FLUID-MIDDLE-BLOCK`'s frame of reference, so its :py:attr:`~Rotation.parent_volume` is required to be specified as :code:`FLUID-MIDDLE-BLOCK`.

.. code-block:: python
    :linenos:

    volume_middle = volume_mesh["FLUID-MIDDLE-BLOCK"]
    volume_middle.axis = [1,0,0]
    volume_middle.center = [1,2,3] * fl.u.m
    volume_inner = volume_mesh["FLUID-INNER-BLOCK"]
    volume_inner.axis = [0,0,-1]
    volume_inner.center = [-4,-5,-0.2] * fl.u.m

    rotation_inner = fl.Rotation(
        name="innerRotation",
        volumes=volume_inner,
        spec= fl.AngularVelocity(0.2 * fl.u.rad / fl.u.s),
        parent_volume=volume_middle
    ),
    rotation_middle = fl.Rotation(
        name="middleRotation",
        volumes=volume_middle,
        spec= fl.AngularVelocity(0.1 * fl.u.rad / fl.u.s),
    ),
