Skip to content
Open
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/sphinx/figs/Topologies/CDN/CDN_regions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/sphinx/figs/Topologies/SF/SF_regions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/sphinx/figs/Topologies/SF/SF_topology.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/sphinx/figs/Topologies/SN/SN_Geometry.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/sphinx/figs/Topologies/SN/SN_regions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added manual/sphinx/figs/Topologies/SN/SN_topology.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified manual/sphinx/figs/topology_cross_section.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions manual/sphinx/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ The documentation is divided into the following sections:
user_docs/preconditioning
user_docs/BOUT_Gradperp_op

.. toctree::
:maxdepth: 1
:caption: Topology Handling
:name: topologies

user_docs/topology
user_docs/supported_topologies

.. toctree::
:maxdepth: 1
:caption: Developer Documentation
Expand Down
2 changes: 1 addition & 1 deletion manual/sphinx/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
breathe>=4.30
#breathe>=4.30
Jinja2>=2.11.3
numpy>=1.21.1
netcdf4>=1.5.6
Expand Down
244 changes: 20 additions & 224 deletions manual/sphinx/user_docs/input_grids.rst
Original file line number Diff line number Diff line change
Expand Up @@ -155,237 +155,27 @@ The only quantities which are required are the sizes of the grid. If
these are the only quantities specified, then the coordinates revert to
Cartesian.

This section describes how to generate inputs for tokamak equilibria. If
you’re not interested in tokamaks then you can skip to the next section.

The directory ``tokamak_grids`` contains code to generate input grid
files for tokamaks. These can be used by, for example, the ``2fluid`` and
``highbeta_reduced`` modules.

.. _sec-bout-topology:

BOUT++ Topology
---------------

Basic
~~~~~

BOUT++ is designed to work in a variety of tokamak and non-tokamak
geometries, from simple slabs to disconnected double-null
configurations. In order to handle tokamak geometry BOUT++ contains an
internal topology which is built from six regions determined by four
branch-cut locations and two separatrix locations (``ixseps1`` and
``ixseps2``). There are some limitations on these regions that we will
discuss below, and some regions may be empty, all of which enables
BOUT++ to describe effectively seven types of topology:

- "core": this type of topology can describe the closed field line
regions inside the separatrix of tokamaks or other devices, or
idealised geometries like periodic slabs;

- "SOL": these can describe the open field line regions of the
scrape-off layer (SOL) outside the separatrix of a tokamak, or linear
devices with a target plate at either end;

- "limiter": these topologies have an open field line region and a
region where field lines hit a boundary, without an X-point;

- "X-point": these topologies have four separate legs with their own
boundaries, and no closed field line region;

- "single null": this type of topology has one X-point with two separate
legs, closed and an open field line regions, and a single separatrix;

- "connected double null": these topologies have two X-points with two
separate legs each, closed and open field line regions and a single
separatrix that connects both X-points;

- "disconnected double null": finally, these are similar to connected
double null geometries except that they have two separatrices that do
not connect the two X-points. These come in "lower" and "upper"
flavours, depending on which X-point is adjacent to the closed field
line region.

The six regions that form the building blocks of these topologies are:

- four separate "leg" regions that have a boundary in the ``y``
direction;

- two "core" regions that do not have boundaries in ``y``.

Each of these regions may have additional boundaries in the ``x``
direction. The separate regions are illustrated in
:numref:`fig-topology-cross-section`: the grey dashed lines show the
region partitions, with the sections labelled 1, 2, and 3 forming one
leg; 4, 5, and 6 forming one core region, and so on. The internal names
for these separate regions use "inner" and "outer" in reference to the
major radius -- that is, "inner" regions correspond to the left-hand
side of :numref:`fig-topology-cross-section` and "outer" regions to the
right-hand side.

Two important limitations for BOUT++ grids are that a single processor
can only belong to one region, and that there must be the same number of
points on each processor. The first limitation means that certain
topologies require a minimum number of processors. For example, a
disconnected double null configuration uses all six regions -- therefore
the minimum number of processors able to describe this in BOUT++ is
six. Having equal numbers of points on each processor can put some
restrictions on the resolution of simulations.

The two separatrix locations are ``ixseps1`` and ``ixseps2``, these are
the global indices in the ``x`` domain where the first and second
separatrices are located. These values are set either in the grid file
or in ``BOUT.inp``. :numref:`fig-topology-cross-section` shows
schematically how ``ixseps`` is used.

If ``ixseps1 == ixseps2`` then there is a single separatrix representing
the boundary between the core region and the SOL region and the grid is
a connected double null configuration. If ``ixseps1 > ixseps2`` then
there are two separatrices and the inner separatrix is ``ixseps2`` so
the tokamak is an upper double null. If ``ixseps1 < ixseps2`` then there
are two separatrices and the inner separatrix is ``ixseps1`` so the
tokamak is a lower double null.

In other words: Let us for illustrative purposes say that ``ixseps1 >
ixseps2`` (see :numref:`fig-topology-cross-section`). Let us say that we
have a field ``f(x,y,z)`` with a global ``x``-index which includes ghost
points. ``f(x <= ixseps1, y, z)``) will then be periodic in the
``y``-direction, ``f(ixspes1 < x <= ixseps2, y, z)``) will have boundary
condition in the ``y``-direction set by the lowermost ``ydown`` and
``yup``. If ``f(ixspes2 < x, y, z)``) the boundary condition in the
``y``-direction will be set by the uppermost ``ydown`` and ``yup``. As
for now, there is no difference between the two sets of upper and lower
``ydown`` and ``yup`` boundary conditions (unless manually specified,
see :ref:`sec-custom-BC`).

The four branch cut locations, ``jyseps1_1``, ``jyseps1_2``,
``jyseps2_1``, and ``jyseps2_2``, split the ``y`` domain into logical
regions defining the SOL, the PFR (private flux region) and the core of
the tokamak. This is illustrated also in
:numref:`fig-topology-cross-section`. If ``jyseps1_2 == jyseps2_1`` then
the grid is a single null configuration, otherwise the grid is a double
null configuration.

.. _fig-topology-cross-section:
.. figure:: ../figs/topology_cross_section.*
:alt: Cross-section of the tokamak topology used in BOUT++

Deconstruction of a poloidal tokamak cross-section into logical
domains using the parameters ``ixseps1``, ``ixseps2``,
``jyseps1_1``, ``jyseps1_2``, ``jyseps2_1``, and ``jyseps2_2``. This
configuration is a "disconnected double null" and shows all the
possible regions used in the BOUT++ topology.

Advanced
~~~~~~~~

The internal domain in BOUT++ is deconstructed into a series of
logically rectangular sub-domains with boundaries determined by the
``ixseps`` and ``jyseps`` parameters. The boundaries coincide with
processor boundaries so the number of grid points within each sub-domain
must be an integer multiple of ``ny/nypes`` where ``ny`` is the number
of grid points in ``y`` and ``nypes`` is the number of processors used
to split the y domain. Processor communication across the domain
boundaries is then handled internally. :numref:`fig-topology-schematic`
shows schematically how the different regions of a double null tokamak
with ``ixseps1 = ixseps2`` are connected together via communications.

.. note::
To ensure that each subdomain follows logically, the
``jyseps`` indices must adhere to the following conditions:

- ``jyseps1_1 > -1``
- ``jyseps2_1 >= jyseps1_1 + 1``
- ``jyseps1_2 >= jyseps2_1``
- ``jyseps2_2 >= jyseps1_2``
- ``jyseps2_2 <= ny - 1``

To ensure that communications work branch cuts must align with
processor boundaries.

.. _fig-topology-schematic:
.. figure:: ../figs/topology_schematic.*

Schematic illustration of domain decomposition and communication in
BOUT++ with ``ixseps1 = ixseps2``

Periodic X domains
~~~~~~~~~~~~~~~~~~

The :math:`x` coordinate is usually a radial flux coordinate. In some
simulations it is useful to make this direction periodic, for example
flux tube simulations or the Hasegawa-Wakatani example in
``examples/hasegawa-wakatani/hw.cxx``. In that example the :math:`x`
coordinate is made periodic with the top-level ``periodicX`` option:
You can read additional quantities from the grid and make them available in
expressions in the input file by listing them in the ``input:grid_variables``
section, with the key being the name in the grid file (``mesh:file``) and the
value being the type (one of ``field3d``, ``field2d``, ``boutreal``):

.. code-block:: cfg

periodicX = true # Domain is periodic in X
[input:grid_variables]
rho = field2d
theta = field2d
scale = boutreal

[mesh]
B = (scale / rho) * cos(theta)

nx = 260 # Note 4 guard cells in X
ny = 1
nz = 256 # Periodic, so no guard cells in Z

Note that some care is now needed if the model uses Laplacian
inversions, for example to calculate electrostatic potential from
vorticity: If both :math:`x` and :math:`z` coordinates are both
periodic then the inversion has no boundary conditions. In that case
the laplacian has a null space and so is singular; an arbitrary
constant offset can be added to the potential without changing the
vorticity.

The default ``cyclic`` solver treats the :math:`k_z =
0` (DC) mode as a special case, setting the average of the potential
over the :math:`x-z` domain to zero. Other solvers may not
handle the ``periodicX`` case in the same way.

Implementations
~~~~~~~~~~~~~~~

In BOUT++ each processor has a logically rectangular domain, so any
branch cuts needed for X-point geometry (see
:numref:`fig-topology-schematic`) must be at processor boundaries.

In the standard “bout” mesh (``src/mesh/impls/bout/``), the
communication is controlled by the variables

.. code-block:: cpp

int UDATA_INDEST, UDATA_OUTDEST, UDATA_XSPLIT;
int DDATA_INDEST, DDATA_OUTDEST, DDATA_XSPLIT;
int IDATA_DEST, ODATA_DEST;

These control the behavior of the communications as shown in
:numref:`fig-boutmesh-comms`.

.. _fig-boutmesh-comms:
.. figure:: ../figs/boutmesh-comms.*
:alt: Communication of guard cells in BOUT++

Communication of guard cells in BOUT++. Boundaries in X have only
one neighbour each, but boundaries in Y can be split into two,
allowing branch cuts

In the Y direction, each boundary region (**U**\ p and **D**\ own in Y)
can be split into two, with ``0 <= x < UDATA_XSPLIT`` going to the
processor index ``UDATA_INDEST``, and ``UDATA_INDEST <= x < LocalNx`` going
to ``UDATA_OUTDEST``. Similarly for the Down boundary. Since there are
no branch-cuts in the X direction, there is just one destination for the
**I**\ nner and **O**\ uter boundaries. In all cases a negative
processor number means that there’s a domain boundary so no
communication is needed.

The communication control variables are set in the
`BoutMesh::topology()` function, in
``src/mesh/impls/bout/boutmesh.cxx``. First the function
`default_connections()` sets the topology to be a rectangle.
This section describes how to generate inputs for tokamak equilibria. If
you’re not interested in tokamaks then you can skip to the next section.

To change the topology, the function `BoutMesh::set_connection` checks
that the requested branch cut is on a processor boundary, and changes
the communications consistently so that communications are two-way and
there are no “dangling” communications.
The directory ``tokamak_grids`` contains code to generate input grid
files for tokamaks. These can be used by, for example, the ``2fluid`` and
``highbeta_reduced`` modules.

3D variables
------------
Expand Down Expand Up @@ -431,6 +221,12 @@ has been developed to create BOUT++ input files from R-Z equilibria. This can re
(geqdsk) files, find flux surfaces, and calculate metric
coefficients.

From GRIDUE files
--------------

A separate tool (in python) called `INGRID <https://github.com/llnl/INGRID>`_ has been modified to be able to output BOUT++ input files too. It can read EFIT ’g’ (geqdsk) files, find flux surfaces, and calculate metric coefficients
to create grids for complex topologies such as the snowflake configurations.

From ELITE and GATO files
-------------------------

Expand Down
Loading
Loading