\documentclass{article}

% Use the Cactus ThornGuide style file
% (Automatically used from Cactus distribution, if you have a 
%  thorn without the Cactus Flesh download this from the Cactus
%  homepage at www.cactuscode.org)
\usepackage{../../../../doc/ThornGuide/cactus}

\begin{document}

\title{CartGrid3D}
\author{Gabrielle Allen \\ Gerd Lanfermann \\ Joan Masso \\ Jonathan Thornburg}
\date{$ $Date$ $}

\maketitle

% Do not delete next line
% START CACTUS THORNGUIDE

\begin{abstract}
{\tt CartGrid3D} allows you to set up coordinates on a 3D Cartesian
grid in a flexible manner.  You can choose different grid domains
({\it eg} octant) to allow you to exploit any symmetry in your problem.
{\tt CartGrid3D} also provides routines for registering symmetries
of grid functions and applying symmetry conditions across the
coordinate axes. 
\end{abstract}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Specifying the Grid Symmetry}

You specify the grid symmetry (or lack thereof) with the
\verb|grid::domain| parameter:
\begin{description}
\item[{\tt grid::domain = "full"}]\mbox{}\\
	There are no symmetries.
\item[{\tt grid::domain = "bitant"}]\mbox{}\\
	The grid includes only the $z \ge 0$ half-space
	(plus symmetry zones); there is a reflection symmetry
	across the $z=0$ plane.
\item[{\tt grid::domain = "quadrant"}]\mbox{}\\
	The grid includes only the $\{x \ge 0, y \ge 0\}$ quadrant
	(plus symmetry zones); there is a reflection symmetry
	across both the $x=0$ plane and the $y=0$ plane.
\item[{\tt grid::domain = "octant"}]\mbox{}\\
	The grid includes only the $\{x \ge 0, y \ge 0, z \ge 0\}$
	octant (plus symmetry zones); there is a reflection symmetry
	across each of the $x=0$ plane, the $y=0$ plane, and the $z=0$
	plane.
\end{description}

In each case except \verb|grid::domain = "full"|, symmetry zones are
introduced just on the ``other side'' of each symmetry grid boundary.
Each symmetry zone has a width (perpendicular to the boundary) of
\verb|driver::ghost_size| extra grid points.  For centered 2nd~order
finite differencing, a width of \verb|driver::ghost_size = 1| should be
sufficient, but for (centered) 4th~order finite differencing, or for
upwinded 2nd~order, a width of \verb|driver::ghost_size = 2| is needed.
Making \verb|driver::ghost_size|
too large is fairly harmless (it just slightly reduces performance),
but making it too small will almost certainly result in horribly wrong
finite differencing near the symmetry boundaries, and may also result
in core dumps from out-of-range array accessing.

Note that the symmetry zones must be explicitly included in
\verb|driver::global_nx|, \verb|driver::global_ny|, and
\verb|driver::global_nz|, but should {\em not\/} be included in any
of the \verb|grid::type = "byrange"| parameters \verb|grid::xmin|,
\verb|grid::xmax|, \verb|grid::ymin|, \verb|grid::ymax|, \verb|grid::zmin|,
\verb|grid::zmax|, \verb|grid::xyzmin|, and/or \verb|grid::xyzmax|
described in the next section.

Note also that \verb|driver::global_nx|, \verb|driver::global_ny|,
and \verb|driver::global_nz| do {\em not\/} include any ghost zones
introduced for multiprocessor synchronization.  (For more information
on ghost zones, see the section ``Ghost Size'' in the ``Cactus Variables''
chapter of the Cactus Users' Guide.)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Specifying the Grid Size, Range, and Spacing}

\verb|CartGrid3D| provides several different methods for setting
up the integer {\em grid size\/} ({\it eg} 128), floating-point
{\em grid spacing\/} ({\it eg} 0.1), and floating-point {\em grid range\/}
({\it eg} 12.8).%%%
\footnote{%%%
	 If you're AMR-ing, this all refers to the
	 coarsest or base grid.%%%
	 }%%%
{}  You specify which method to use, with the \verb|grid::type| parameter:
\begin{description}
\item[{\tt grid::type = "byrange"}]\mbox{}\\
	You specify the $x$, $y$, and $z$ grid ranges, either with
	separate \verb|grid::xmin|, \verb|grid::xmax|, \verb|grid::ymin|,
	\verb|grid::ymax|, \verb|grid::zmin|, and \verb|grid::zmax|
	parameters, or with the \verb|grid::xyzmin| and
	\verb|grid::xyzmax| parameters.  The grid spacings are then
	determined automagically from this information and the
	\verb|driver::global_nx|, \verb|driver::global_ny|, and
	\verb|driver::global_nz| grid-size parameters.  You should
	also choose the \verb|grid::domain| parameter consistent with
	all these other parameters.  (It's not clear whether or not
	the code ever explicitly checks this.)
\item[{\tt grid::type = "box"}]\mbox{}\\
	This is a special case of \verb|grid::type = "byrange"|
	with the grid ranges hard-wired to
	\verb|grid::xyzmin = -0.5| and \verb|grid::xyzmax = +0.5|.
\item[{\tt grid::type = "byspacing"}]\mbox{}\\
	You specify the $x$, $y$, and $z$ grid spacings, either with
	separate \verb|grid::dx|, \verb|grid::dy|, and \verb|grid::dz|
	parameters, or with the \verb|grid::dxyz| parameter.  You also
	specify the grid symmetry with the \verb|grid::domain| parameter.
	The $x$, $y$, and $z$ grid ranges are then determined automagically
	from this information and the \verb|driver::global_nx|,
	\verb|driver::global_ny|, and \verb|driver::global_nz|
	grid-size parameters:  Each coordinate's range is chosen
	to be either symmetric about zero, or to extend from 0 up
	to a maximum value.
\end{description}

There are also a number of optional parameters which can be used
to specify whether or not it's ok to have a grid point with an $x$,
$y$, and/or $z$ coordinate exactly equal to 0:
\begin{description}
\item[{\tt grid::no\_originx}, {\tt grid::no\_originy}, {\tt
grid::no\_originz}, {\tt grid::no\_origin}]\mbox{}\\
	These parameters are all deprecated --- don't use them!
\item[{\tt grid::avoid\_originx}]\mbox{}\\
	This is a Boolean parameter; if set to true
	(\verb|grid::avoid_originx = "true"| or
	\verb|grid::avoid_originx = "yes"| or
	\verb|grid::avoid_originx = 1|) then the grid will be
	``half-centered'' across $x=0$, {\it ie} there will be
	grid points at
	\dots,
	$x = - \frac{3}{2} \Delta x$,
	$x = - \frac{1}{2} \Delta x$,
	$x = + \frac{1}{2} \Delta x$,
	$x = + \frac{3}{2} \Delta x$,
	\dots,
	but not at $x=0$.
\item[{\tt grid::avoid\_originy}]\mbox{}\\
	Same thing for $y$.
\item[{\tt grid::avoid\_originz}]\mbox{}\\
	Same thing for $z$.
\item[{\tt grid::avoid\_origin}]\mbox{}\\
	Same thing for all 3 axes $x$ and $y$ and $z$, {\it ie}
	no grid point will have $x=0$ or $y=0$ or $z=0$.
\end{description}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{An Example}

Here is an example of setting up a grid using the {\tt PUGH} unigrid
driver.  The relevant parts of the parameter file are as follows:
\begin{verbatim}
# PUGH
driver::ghost_size = 2
driver::global_nx = 61
driver::global_ny = 61
driver::global_nz = 33

# CartGrid3D
grid::avoid_origin = "no"
grid::domain = "bitant"
grid::type = "byrange"
grid::xmin = -3.0
grid::xmax = +3.0
grid::ymin = -3.0
grid::ymax = +3.0
grid::zmin =  0.0
grid::zmax = +3.0
\end{verbatim}

The resulting Cactus output (describing the grid) is as follows:
\begin{verbatim}
INFO (CartGrid3D): Grid Spacings:
INFO (CartGrid3D):  dx=>1.0000000e-01  dy=>1.0000000e-01  dz=>1.0000000e-01  
INFO (CartGrid3D): Computational Coordinates:
INFO (CartGrid3D):  x=>[-3.000, 3.000]  y=>[-3.000, 3.000]  z=>[-0.200, 3.000]  
INFO (CartGrid3D): Indices of Physical Coordinates:
INFO (CartGrid3D):  x=>[0,60]  y=>[0,60]  z=>[2,32]  
INFO (PUGH): Single processor evolution
INFO (PUGH): 3-dimensional grid functions
INFO (PUGH):   Size: 61 61 33
\end{verbatim}

Since there's no symmetry in the $x$ and $y$ directions, the grid
is set up just as specified, with floating-point coordinates running
from $-3.0$ to $3.0$ inclusive, and 61~grid points with integer grid
indices $[0,60]$ (C) or $[1,61]$ (Fortran).

However, in the $z$ direction there's a reflection symmetry across the
$z=0$ plane, so the specified range of the grid, $z \in [0.0,3.0]$,
is automagically widened to include the symmetry zone of
\verb|driver::ghost_size = 2| grid points.  The grid thus actually
includes the range of floating-point coordinates $z \in [-0.2,3.0]$.
The original specification of 33~grid points is left alone, however,
so the grid points have integer array indices $[0,32]$ (C) or
$[1,33]$ (Fortran).
The ``physical'' ({\it ie} non-symmetry-zone) part of the grid is
precisely the originally-specified range, $z \in [0.0,3.0]$, and
has the integer array indices $[2,32]$ (C) or $[3,33]$ (Fortran).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Coordinates}

\verb|CartGrid3D| defines (registers) two coordinate systems:
\verb|cart3d| and \verb|spher3d|.

The Cartesian coordinates supplied by this thorn are grid functions
with the standard names \verb|x|, \verb|y|, and \verb|z|.  To use
these coordinates you need to inherit from \verb|grid|, {\it ie} you
need to have an
\begin{verbatim}
inherits: grid
\end{verbatim}
line in your \verb|interface.ccl| file.
In addition a grid function \verb|r| is provided, containing the
radial coordinate from the origin where
$$
r = \sqrt{x^2+y^2+z^2}
$$

\verb|CartGrid3D| registers the lower and upper range of each coordinate
with the flesh.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Symmetries for Grid Functions}

If your problem and initial data allow it, \verb|CartGrid3D|
allows you to enforce even or odd parity for any grid function%%%
\footnote{%%%
	 Alas, with the present implementation only
	 {\tt CCTK\_REAL} grid functions work correctly;
	 all others give garbage results.  This is a
	 bug, which should get fixed sometime or other\dots{}
	 Indeed, we haven't yet decided how complex grid
	 functions should be handled here.  Contact
	 Peter Diener and/or Jonathan Thornburg if you
	 have ideas and/or want to help with this.
	 }%%%
{} at (across) each coordinate axis.  For a function $\phi(x,y,z)$,
even parity symmetry on the $x$-axis means
$$
\phi(-x,y,z) = \phi(x,y,z)
$$
while odd parity symmetry means
$$
\phi(-x,y,z) = -\phi(x,y,z)
$$

Note that the symmetries will only be enforced if a symmetry domain
is chosen (that is, if \verb|grid::domain| is set to something other than
\verb|grid::domain = "full"|.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Registering Symmetry Behaviour}

Each grid function can register how it behaves under a coordinate
change using function calls in {\tt CartGrid3D}. These symmetry
properties can then be used by other thorns, for example
{\tt CactusBase/Boundary} uses them to enforce symmetry boundary
conditions across coordinate axes. Symmetries should obviously be
registered before they are used, but since they can be different
for different grids, they must be registered {\it after} the
{\tt CCTK\_STARTUP} timebin. The usual place to register symmetries
is in the {\tt CCTK\_BASEGRID} timebin.

For example, to register the symmetries of the {\it xy} component of the
metric tensor from C, you first need to get access to the include file
by putting the line
\begin{verbatim}
uses include: Symmetry.h
\end{verbatim}
in your \verb|interface.ccl| file.  Then in your thorn you can write (C)
\begin{verbatim}
#include "Symmetry.h"
static int one=1;
int sym[3];
sym[0] = -one;
sym[1] = -one;
sym[2] =  one;
SetCartSymVN(cctkGH, sym,"ADMBase::gxy");
\end{verbatim}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Calling Symmetry Boundary Conditions}

\verb|CartGrid3D| provides the following two routines to apply symmetry
boundary conditions to a variable group:

\begin{verbatim}
CartSymGI(cGH *GH, int *gi)
CartSymGN(cGH *GH, const char *gn)
\end{verbatim}

and for a specific variable it provides:

\begin{verbatim}
CartSymVI(cGH *GH, int *vi)
CartSymVN(cGH *GH, const char *gn)
\end{verbatim}

A group or variable can
be specified by its index value or name (use the 'I' or 'N' version
respectively).  The Fortran versions of these functions take an
additional first argument, which is an integer which will hold the
return value.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Do not delete next line
% END CACTUS THORNGUIDE

\end{document}
