.. _InputsGeometry:

Specifying a geometry
=====================

The following inputs are defined using the ``mfix`` prefix.

+------------------------+-------------------------------------------------------------------+----------+---------------------+
|                        | Description                                                       |   Type   | Default             |
+========================+===================================================================+==========+=====================+
| geometry               | Select a basic ``box`` or ``cylinder`` predefined EB geometry, or |   String | ''                  |
|                        | the user-programed ``generic`` geometry. Details about these      |          |                     |
|                        | geometry options and associated additional inputs are provided    |          |                     |
|                        | in the following sections.                                        |          |                     |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| geometry_filename      | The CSG file that defines the EB geometry                         |   String | ''                  |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| levelset__refinement   | Refinement factor of levelset resolution relative to level 0      |   Int    | 1                   |
|                        | resolution                                                        |          |                     |
+------------------------+-------------------------------------------------------------------+----------+---------------------+

Most simulations require a user to specify some kind of geometry. For example, the geometry could be a basic cylinder used to
model flow inside a pipe, or it may be an irregularly shaped solid to study external flow around a bluff body, or the geometry
may be the proposed design of a complex, multi-stage chemical reactor undergoing performance assessment. In the following sections, several options for specifying a geometry are described.

.. caution::

   Any domain extent that is not periodic or defined as a Dirichlet or Neumann
   :ref:`boundary condition<InputsBoundaryConditions>` must be fully covered.
   To state this another way, if a domain extent is not periodic or an inflow
   or outflow boundary condition, then it should be excluded from (outside of)
   the domain by the embedded boundary geometry.

.. _InputsGeometry_PredefinedEBs:

Predefined geometries
----------------------

The ``mfix.geometry`` input is used to choose one of the basic predefined geometries, or to
select the option to use a user-defined geometry constructed from native AMReX implicit functions.


``box`` geometry
^^^^^^^^^^^^^^^^

The following inputs are defined using the ``box`` prefix.

+------------------------+-------------------------------------------------------------------+----------+---------------------+
|                        | Description                                                       |   Type   | Default             |
+========================+===================================================================+==========+=====================+
| Lo                     | Low corner of the embedded boundary box                           | Reals    | ``prob_lo``         |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| Hi                     | High corner of the embedded boundary box                          | Reals    | ``prob_hi``         |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| internal_flow          | Flag to indicate that flow is *inside* the box.                   | Bool     | true                |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| offset                 | Shift low side box walls by ``+offset`` and high side walls by    | Real     | 1.0e-15             |
|                        | ``-offset``. An example use of this input would be to define a    |          |                     |
|                        | a box with ``Lo`` and ``Hi`` equal to ``prob_lo`` and ``prob_hi``.|          |                     |
|                        | The offset slightly shrinks the ``box`` so the walls do not       |          |                     |
|                        | coincide with the domain extents.                                 |          |                     |
+------------------------+-------------------------------------------------------------------+----------+---------------------+

``box`` limitations
"""""""""""""""""""

The predefined EB ``box`` geometry has several limitations:

* The sides of the box should not coincide with the domain extents.
* A ``box`` is aligned with the coordinate axes and cannot be rotated in any direction.
* There can only be one ``box``. Multiple boxes cannot be defined and combined.


``box`` example
"""""""""""""""

The domain is a :math:`2 \times 2 \times 8` cuboid where *X* and *Y* span :math:`[-1,1]`,
and *Z* spans :math:`[0,8]`.  A :math:`10` meter long embedded boundary ``box`` with a
:math:`1 \times 1` cross-section runs lengthwise through the domain, centered about the
*Z* axis. The EB is shifted down the *Z* axis so that there is a :math:`-1` meter
overhang on the low and high *Z* domain faces.

.. _inputs_box_geometry_ex:

.. code-block:: bash
   :caption: Snippet of intpus for predefined EB ``box`` geometry example. This is not a complete input file.

   # Define periodicity and domain extents
   # -------------------------------------------------------------
   geometry.coord_sys   =  0            # Cartesian coordinates
   geometry.is_periodic =  0    0   1   # periodicity for each direction
   geometry.prob_lo     = -1.  -1.  0   # lo corner of physical domain.
   geometry.prob_hi     =  1.   1.  8.  # hi corner of physical domain

   # Select box geometry and specify settings
   # -------------------------------------------------------------
   mfix.geometry = box

   box.Lo = -0.5  -0.5  -1.0
   box.Hi =  0.5   0.5   9.0

   box.offset = 0.

   box.internal_flow = true


:numref:`fig_box_geometry_ex` illustrates the (grey) domain and (blue) embedded
boundary ``box`` geometry. The left image is a 3D rendering of the setup, and
the center and right images are 2D slices along the *XZ* and *XY* planes, respectively.


.. _fig_box_geometry_ex:

.. figure:: ./images/geometry/EB_box_ex.png
   :width: 100%
   :align: center
   :alt: domain used with box embedded boundary

   Example of predefined embedded boundary ``box`` geometry with the EB colored blue and the domain colored grey.
   Left: the domain and EB are rendered in 3D.
   Center: a 2D slice showing the XZ plane.
   Right: a 2D slice showing the XY plane.


This is an internal flow setup, therefore the sections of the domain that do not intersect
the EB ``box`` are *covered* and thereby excluded from run-time calculations.

* No :ref:`boundary conditions<InputsBoundaryConditions>` are needed for the low and high
  domain faces in *X* and *Y* because they are fully covered.

* The low and high *Z* domain faces remain uncovered, however no boundary conditions are
  needed because the domain is periodic in *Z*
  (*see* the :ref:`inputs snippet<inputs_box_geometry_ex>` for this example ).


----


``cylinder`` geometry
^^^^^^^^^^^^^^^^^^^^^

The following inputs are defined using the ``cylinder`` prefix.

+------------------------+-------------------------------------------------------------------+----------+---------------------+
|                        | Description                                                       |   Type   | Default             |
+========================+===================================================================+==========+=====================+
| radius                 | Cylinder radius                                                   | Real     | 0.0002              |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| height                 | Height (length) of cylinder. If the height is not defined (-1),   | Real     | -1                  |
|                        | then the cylinder is made infinitely long to overhang the domain  |          |                     |
|                        | extents.                                                          |          |                     |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| direction              | Axis the cylinder runs along.                                     | int      |  0                  |
|                        | (``0``: *X*, ``1``: *Y*, ``2``: *Z*)                              |          |                     |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| center                 | Center of cylinder. For a cylinder with an undefined ``height``,  | Reals    |  0. 0. 0.           |
|                        | the center value in the height ``direction`` can be any value.    |          |                     |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| rotation               | Rotation angle in degrees of cylinder.                            | Real     |  0.                 |
|                        |                                                                   |          |                     |
|                        | * Only cylinders with an undefined ``height`` (i.e., infinitely   |          |                     |
|                        |   long) can be rotated.                                           |          |                     |
|                        | * Rotation is applied about the ``center`` of the cylinder.       |          |                     |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| rotation_axe           | Axis to rotate the cylinder about.                                | int      |  0                  |
|                        | (``0``: *X*, ``1``: *Y*, ``2``: *Z*)                              |          |                     |
+------------------------+-------------------------------------------------------------------+----------+---------------------+
| internal_flow          | Flag to indicate that flow is *inside* the box.                   | Bool     | true                |
+------------------------+-------------------------------------------------------------------+----------+---------------------+

The inputs for the predefined ``cylinder`` embedded boundary geometry are illustrated in :numref:`fig_cylinder_geometry_inputs`.

.. _fig_cylinder_geometry_inputs:

.. figure:: ./images/geometry/cylinder_geometry_inputs.png
   :width: 80%
   :align: center
   :alt: domain used with box embedded boundary

   Illustration of predefined embedded boundary ``cylinder`` geometry inputs where the cylinder geometry is
   blue and the domain is grey.


``cylinder`` limitations
""""""""""""""""""""""""

The predefined EB ``cylinder`` geometry has several limitations:

* The ends of the ``cylinder`` should not coincide with the domain extents. The ``cylinder`` should be shorter than the domain,
  or sufficiently long that it overhangs the ends of the domain.
* Rotations are about a single axis.
* There can only be one ``cylinder``. Multiple cylinders cannot be defined and combined.


``cylinder`` example
""""""""""""""""""""

The domain is a :math:`4 \times 1 \times 1` cuboid where *Y* and *Z* span :math:`[0,1]`,
and *X* spans :math:`[0,4]`.  An embedded boundary ``cylinder`` with :math:`0.45` radius
runs lengthwise through the domain, offset by :math:`[0.5]` in the *Y* and *Z*, respectively.
The cylinder is not assigned a length, therefore it runs past the low and high *X* domain faces.

.. _inputs_cylinder_geometry_ex:

.. code-block:: bash
   :caption: Snippet of intpus for predefined EB ``cylinder`` geometry example. This is not a complete input file.

   # Define periodicity and domain extents
   # -------------------------------------------------------------
   geometry.coord_sys   =  0           # Cartesian coordinates
   geometry.is_periodic =  0   0   0   # periodicity for each direction
   geometry.prob_lo     =  0.  0.  0   # lo corner of physical domain.
   geometry.prob_hi     =  4.  1.  1.  # hi corner of physical domain

   # Select cylinder geometry and specify settings
   # -------------------------------------------------------------
   mfix.geometry = cylinder

   cylinder.internal_flow = true

   cylinder.radius = 0.45

   cylinder.direction = 0
   cylinder.center    =  0.0  0.5   0.5


:numref:`fig_cylinder_geometry_ex` illustrates the (grey) domain and (blue) embedded
boundary ``cylinder`` geometry. The left image is a 3D rendering of the setup, and
the center and right images are 2D slices along the *XZ* and *YZ* planes, respectively.

.. _fig_cylinder_geometry_ex:

.. figure:: ./images/geometry/EB_cylinder_ex.png
   :width: 100%
   :align: center
   :alt: domain used with box embedded boundary

   Example of predefined embedded boundary ``cylinder`` geometry with the EB colored blue and the domain colored grey.
   Left: the domain and EB are rendered in 3D.
   Center: a 2D slice showing the XZ plane.
   Right: a 2D slice showing the YZ plane.


This is an internal flow setup, therefore the sections of the domain that do not intersect
the EB ``cylinder`` are *covered* and thereby excluded from calculations.

* No :ref:`boundary conditions<InputsBoundaryConditions>` are needed for the low and high
  domain faces in *Y* and *Z* because they are fully covered.

* The low and high *X* domain faces remain uncovered, therefore boundary conditions are
  needed to fully specify the problem. Example boundary conditions include a mass inflow
  on the low *X* face and a pressure outflow on the *X* high face.


----


``generic`` geometry
^^^^^^^^^^^^^^^^^^^^

The ``generic`` geometry option is used to select the user-programed embedded boundary geometry.

* A custom embedded boundary geometry is programed by the user in ``src/eb/mfixeb_generic.cpp``
  using ``AMReX`` native implicit functions and operations.
* An executable containing the geometry modifications is compiled.
* The geometry is accessed using the ``generic`` input.

.. note::
   A full description of this feature is beyond the scope of this section. A future update to
   the documentation may include a tutorial to better demonstrate this capability.


.. _InputsGeometry_Regions_and_BCs:

Regions and boundary conditions
-------------------------------

Simple geometries can be created by combining planar :ref:`regions<InputsRegions>` and no-slip wall
:ref:`boundary conditions<InputsBoundaryConditions>`. The ``mfix.geometry`` and ``mfix.geometry_file``
inputs should remain undefined when using this method.

In the following example, the domain is periodic in the *x-* and *z-* directions; therefore,
walls only need to cover the low and high *xz* faces. First, ``wall1`` and ``wall2`` are defined
in the ``regions`` section, then they are used to specify two no-slip wall boundary conditions.

.. code-block:: bash
   :caption: Example geometry created using regions and boundary conditions.
   :name: define_geometry_with_regions

   # Define periodicity and domain extents
   # -------------------------------------------------------------
   geometry.coord_sys   = 0
   geometry.is_periodic = 1      0      1
   geometry.prob_lo     = 0.     0.     0.
   geometry.prob_hi     = 0.01   0.01   0.005

   # Define two planar regions
   # -------------------------------------------------------------
   mfix.regions = wall1  wall2

   regions.wall1.lo       = 0.000  1.25e-6  0.000
   regions.wall1.hi       = 0.010  1.25e-6  0.005

   regions.wall2.lo       = 0.000  9.99875e-3  0.000
   regions.wall2.hi       = 0.010  9.99875e-3  0.005

   # Use the regions to define no-slip wall boundaries
   # -------------------------------------------------------------
   bc.regions = wall1  wall2

   bc.wall1 = nsw
   bc.wall1.normal = 0.0  1.0  0.0

   bc.wall2 = nsw
   bc.wall2.normal = 0.0 -1.0  0.0

.. caution::

  It is highly recommended that planar regions not be defined coincident to domain
  boundaries. It is better to specify planes slightly offset from the domain as
  demonstrated in the :ref:`above example<define_geometry_with_regions>`.


.. _InputsGeometry_CSG:

Constructive solid geometry
---------------------------

Use the ``mfix.geometry_filename`` input to select a *constructive solid geometry (CSG)* that defines
the system geometry.

* A constructive solid geometry can be created using OpenSCAD.
* This option requires that the executable be built with CSG support.
  See the build documentation for for details.

.. note::
   A full description of this feature is beyond the scope of this section. A future update to
   the documentation may include a tutorial to better demonstrate this feature.
