Skip to content

Commit

Permalink
Merge pull request #247 from lucass-carneiro/lucas/docs
Browse files Browse the repository at this point in the history
Documentation
  • Loading branch information
eschnett authored Nov 16, 2023
2 parents 6b2acc4 + e421aba commit 2db7553
Show file tree
Hide file tree
Showing 25 changed files with 1,873 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*.pyc
.vscode
11 changes: 11 additions & 0 deletions CarpetX/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

doc/*.aux
doc/*.log
doc/*.fdb_latexmk
doc/*.fls
doc/*.out
doc/*.synctex.gz
doc/*.toc
doc/*.pdf

doc/openpmd-plot/venv/*
Binary file removed CarpetX/doc/amr-grids.pdf
Binary file not shown.
5 changes: 4 additions & 1 deletion CarpetX/doc/amr-grids.tex
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
\documentclass{article}
\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
\input{amr-grids.tikz}
\end{document}
100 changes: 57 additions & 43 deletions CarpetX/doc/amr-grids.tikz
Original file line number Diff line number Diff line change
@@ -1,48 +1,62 @@
% Node styles
\tikzstyle{red dot}=[fill=red, draw=black, shape=circle]
\tikzstyle{green dot}=[fill={rgb,255: red,0; green,128; blue,0}, draw=black, shape=circle]

% Edge styles
\tikzstyle{black line}=[-, draw=black]
\tikzstyle{red line}=[-, draw=red]
\tikzstyle{green line}=[-, draw={rgb,255: red,0; green,128; blue,0}]

% Layers
\pgfdeclarelayer{nodelayer}
\pgfdeclarelayer{edgelayer}
\pgfsetlayers{nodelayer,edgelayer}

\begin{tikzpicture}
\begin{pgfonlayer}{nodelayer}
\node [style=none] (0) at (-2, 2) {};
\node [style=none] (1) at (0, 2) {};
\node [style=none] (2) at (0, 0) {};
\node [style=none] (3) at (-2, 0) {};
\node [style=none] (4) at (-2, -2) {};
\node [style=none] (5) at (0, -2) {};
\node [style=none] (6) at (1, -2) {};
\node [style=none] (7) at (2, -2) {};
\node [style=none] (8) at (2, -1) {};
\node [style=none] (9) at (1, -1) {};
\node [style=none] (10) at (1, 0) {};
\node [style=none] (11) at (2, 0) {};
\node [style=none] (12) at (2, 1) {};
\node [style=none] (13) at (1, 1) {};
\node [style=none] (14) at (1, 2) {};
\node [style=none] (15) at (2, 2) {};
\node [style=none] (16) at (0, -1) {};
\node [style=none] (17) at (0, 1) {};
\node [style=none] (18) at (-4, -2) {};
\node [style=none] (19) at (-4, 0) {};
\node [style=none] (20) at (-4, 2) {};
\node [style=none] (21) at (-3, 1) {};
\node [style=none] (22) at (-3, 3) {};
\node [style=none] (23) at (-5, 1) {};
\node [style=none] (24) at (-5, -1) {};
\node [style=none] (25) at (-3, -1) {};
\node [style=none] (26) at (-3, -3) {};
\node [style=none] (27) at (-1, -3) {};
\node [style=none] (28) at (-1, -1) {};
\node [style=none] (29) at (-1, 1) {};
\node [style=none] (30) at (-1, 3) {};
\node [style=none] (31) at (0.5, 2.5) {};
\node [style=none] (32) at (0.5, 1.5) {};
\node [style=none] (33) at (0.5, 0.5) {};
\node [style=none] (34) at (0.5, -0.5) {};
\node [style=none] (35) at (0.5, -1.5) {};
\node [style=none] (36) at (0.5, -2.5) {};
\node [style=none] (37) at (1.5, -2.5) {};
\node [style=none] (38) at (1.5, -1.5) {};
\node [style=none] (39) at (1.5, -0.5) {};
\node [style=none] (40) at (1.5, 0.5) {};
\node [style=none] (41) at (1.5, 1.5) {};
\node [style=none] (42) at (1.5, 2.5) {};
\node (0) at (-2, 2) {};
\node (1) at (0, 2) {};
\node (2) at (0, 0) {};
\node (3) at (-2, 0) {};
\node (4) at (-2, -2) {};
\node (5) at (0, -2) {};
\node (6) at (1, -2) {};
\node (7) at (2, -2) {};
\node (8) at (2, -1) {};
\node (9) at (1, -1) {};
\node (10) at (1, 0) {};
\node (11) at (2, 0) {};
\node (12) at (2, 1) {};
\node (13) at (1, 1) {};
\node (14) at (1, 2) {};
\node (15) at (2, 2) {};
\node (16) at (0, -1) {};
\node (17) at (0, 1) {};
\node (18) at (-4, -2) {};
\node (19) at (-4, 0) {};
\node (20) at (-4, 2) {};
\node (21) at (-3, 1) {};
\node (22) at (-3, 3) {};
\node (23) at (-5, 1) {};
\node (24) at (-5, -1) {};
\node (25) at (-3, -1) {};
\node (26) at (-3, -3) {};
\node (27) at (-1, -3) {};
\node (28) at (-1, -1) {};
\node (29) at (-1, 1) {};
\node (30) at (-1, 3) {};
\node (31) at (0.5, 2.5) {};
\node (32) at (0.5, 1.5) {};
\node (33) at (0.5, 0.5) {};
\node (34) at (0.5, -0.5) {};
\node (35) at (0.5, -1.5) {};
\node (36) at (0.5, -2.5) {};
\node (37) at (1.5, -2.5) {};
\node (38) at (1.5, -1.5) {};
\node (39) at (1.5, -0.5) {};
\node (40) at (1.5, 0.5) {};
\node (41) at (1.5, 1.5) {};
\node (42) at (1.5, 2.5) {};
\end{pgfonlayer}
\begin{pgfonlayer}{edgelayer}
\draw [style=red line] (0.center) to (1.center);
Expand Down
199 changes: 199 additions & 0 deletions CarpetX/doc/amr.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@

\subsection{Box-in-box AMR}
\label{sec:box_in_box_amr}
\CarpetX\space supports fixed mesh refinement via the so called box-in-box paradigm. This capability is provided by the \texttt{BoxInBox} thorn. Using it is very simple and similar to \texttt{Carpet}'s \texttt{CarpetRegrid2} usage.

\begin{table}[ht]
\begin{tabularx}{\textwidth}{cXccX}
Name & Type & Possible Values & Default Value & Description \\\hline\hline
\texttt{shape\_n} & String & \texttt{"sphere"} or \texttt{"cube"} & \texttt{"sphere"} & Shape of refined region \\
\texttt{active\_n} & Boolean & \texttt{"yes"} or \texttt{"no"} & \texttt{"yes"} & Is this box active? \\
\texttt{num\_levels\_n} & Single integer & $[1,30]$ & $1$ & Number of refinement levels for this box \\
\texttt{position\_x\_n} & Single real number & Any real & $0.0$ & x-position of this box \\
\texttt{position\_y\_n} & Single real number & Any real & $0.0$ & y-position of this box \\
\texttt{position\_z\_n} & Single real number & Any real & $0.0$ & z-position of this box \\
\texttt{radius\_n} & 30 element array of reals & $-1.0$ or positive real & $-1.0$ (radius ignored) & Radius of refined region for this level \\
\texttt{radius\_x\_n} & 30 element array of reals & $-1.0$ or positive real & $-1.0$ (radius ignored) & x-radius of refined region for this level \\
\texttt{radius\_y\_n} & 30 element array of reals & $-1.0$ or positive real & $-1.0$ (radius ignored) & y-radius of refined region for this level \\
\texttt{radius\_z\_n} & 30 element array of reals & $-1.0$ or positive real & $-1.0$ (radius ignored) & z-radius of refined region for this level \\\hline\hline
\end{tabularx}
\caption{Configuration parameters for a single (1 out of 3) box that can be defined in parameter files using the \texttt{BoxInBox} thorn.}
\label{tab:box_config}
\end{table}

All configuration of boxes and levels are performed within configuration files. \texttt{BoxInBox} supports adding 3 ``boxes'' or ``centers''. Each box can be configured as summarized in Tab.~\ref{tab:box_config}. The \texttt{n} suffix should be replaced by \texttt{1}, \texttt{2} or \texttt{3} for configuring the corresponding boxes. Each box can be shaped differently as either Cartesian-like cubes or spheres and support configuring up to 30 levels. Level's positions and radii can be set independently for each dimension. Note that for each box the \texttt{active}, \texttt{num\_levels} and \texttt{position\_(xyz)} field are stored as grid scalars. Each of the 30 refinement level radii and \texttt{x, y, z} individual radii for each box are also stored as grid arrays. This allows these parameters to be changed during a simulation run, allowing for moving boxes. This is useful, for example, when implementing a puncture tracker.

These configurations are subjected to (and restricted by) two additional \CarpetX\space configurations, namely \texttt{CarpetX::regrid\_every}, which controls how many iterations should pass before checking if the box grid variables have changed and \texttt{CarpetX::max\_num\_levels} which controls the maximum number of allowed refinement levels.

As an example, we present a configuration file excerpt for creating two refinement boxes with the \texttt{BoxInBox} thorn

\begin{lstlisting}[language=bash]
BoxInBox::num_regions = 2

BoxInBox::num_levels_1 = 2
BoxInBox::position_x_1 = -0.5
BoxInBox::radius_x_1[1] = 0.25
BoxInBox::radius_y_1[1] = 0.25
BoxInBox::radius_z_1[1] = 0.25

BoxInBox::num_levels_2 = 2
BoxInBox::position_x_2 = +0.5
BoxInBox::radius_x_2[1] = 0.25
BoxInBox::radius_y_2[1] = 0.25
BoxInBox::radius_z_2[1] = 0.25
\end{lstlisting}

Let us now suppose that one wishes to make the boxes set up in the above parameter file to move in a circle around the origin. This is not very useful in practice, but it illustrates important concepts that can be later applied to more complex tools, such as puncture trackers. The \texttt{MovingBoxToy} thorn bundled in \CarpetX\space provides an example of how to achieve this. We shall now examine this implementation closely. Let us start by the examining the thorn's \texttt{interface.ccl} file:
%
\begin{lstlisting}[language=bash]
# Interface definition for thorn MovingBoxToy

IMPLEMENTS: MovingBoxToy

INHERITS: BoxInBox
\end{lstlisting}

The \texttt{INHERITS} statement in line 5 states that this thorn will write to grid functions provided in \texttt{BoxInBox} which control the refinement boxes parameters. Next, in the thorn's \texttt{param.ccl} file we have
%
\begin{lstlisting}
# Parameter definitions for thorn MovingBoxToy

shares: BoxInBox
USES CCTK_REAL position_x_1
USES CCTK_REAL position_x_2
\end{lstlisting}

Lines 3-5 declare that \texttt{MovingBoxToy} uses parameters \texttt{position\_x\_1} and \texttt{position\_x\_2} from \texttt{BoxInBox}. These declarations are required in order to access the initial positions of the boxes. Note that similar statements would be used if other parameters from \texttt{BoxInBox} were required.

Finally, in the \texttt{schedule.ccl} file we schedule the routine that will actually update the box positions, called \texttt{MovingBoxToy\_MoveBoxes}:
%
\begin{lstlisting}
# Schedule definitions for thorn MovingBoxToy

SCHEDULE MovingBoxToy_MoveBoxes AT postinitial BEFORE EstimateError
{
LANG: C
READS: BoxInBox::positions
WRITES: BoxInBox::positions
} "Update box positions"

SCHEDULE MovingBoxToy_MoveBoxes AT poststep BEFORE EstimateError
{
LANG: C
READS: BoxInBox::positions
WRITES: BoxInBox::positions
} "Update box positions"
\end{lstlisting}

Note that the routine is scheduled with \texttt{AT poststep BEFORE EstimateError}. This is important, since it is in the \texttt{EstimateError} bin that \CarpetX's AMR error grid function (see Sec.~\ref{sec:advanced_amr}) will be updated thus any changes to box data should be scheduled before that.

Finally, the \texttt{C++} routine \texttt{MovingBoxToy\_MoveBoxes} that will actually update the boxes positions reads
%
\begin{lstlisting}
extern "C" void MovingBoxToy_MoveBoxes(CCTK_ARGUMENTS) {
DECLARE_CCTK_ARGUMENTSX_MovingBoxToy_MoveBoxes;
DECLARE_CCTK_PARAMETERS;

using std::cos;

const CCTK_REAL omega{M_PI/4};

// Initial positions of box 1
const auto x0_1{position_x_1};

// Initial positions of box 2
const auto x0_2{position_x_2};

// Trajectory of box 1
position_x[0] = x0_1 * cos(omega * cctk_time);
position_y[0] = x0_1 * sin(omega * cctk_time);

// Trajectory of box 2
position_x[1] = x0_2 * cos(omega * cctk_time);
position_y[1] = x0_2 * sin(omega * cctk_time);
}
\end{lstlisting}

In lines 10 and 13, we read \texttt{BoxInBox} parameters for the initial positions of the boxes. In line 16-21 those positions are updated in a way that the boxes centers describe a circle around the origin. At each time, the boxes move $\pi/4$ radians around the origin in a counterclockwise fashion. Figure~\ref{fig:boxes_circle} shows 6 still frames of the boxes motions around the origin. All panels are $z=0$ slices of the grid hierarchy and time and iteration values are provided for each panel. These plots were produced with the \texttt{VisIt} visualization software with \CarpetX\space producing \texttt{silo} data files as output (see Sec.~\ref{sec:data} for more details on how to visualize and post-process \CarpetX\space data). The data can be reproduced by running the \texttt{circle.par} parameter file, provided in the \texttt{par} folder of the \texttt{MovingBoxToy} thorn. An animated version of Fig.~\ref{fig:boxes_circle} can be found in the \texttt{doc} folder of the \CarpetX\space thorn under the name {animated\_boxes.gif}.

\begin{figure*}[ht]
\begin{center}
\includegraphics[width=\linewidth]{boxes_frames.png}
\end{center}
\caption{AMR boxes moving around a circle, as implemented in the \texttt{MovingBoxToy} thorn.}
\label{fig:boxes_circle}
\end{figure*}

\subsection{Advanced AMR}
\label{sec:advanced_amr}

\CarpetX\space supports non-fixed (adaptive) mesh refinement. For cell level control of AMR, \CarpetX\space provides user with a cell centered and non-checkpointed grid function called \texttt{regrid\_error}. Users are responsible for filling this grid function with real value however they see fit. Once it is filled, the configuration parameter \texttt{CarpetX::regrid\_error\_threshold} controls regridding: If the values stored in \texttt{regrid\_error} are larger than what is set in \texttt{regrid\_error\_threshold}, the region gets refined. Additionally, the configuration parameter \texttt{CarpetX::regrid\_every} controls how many iterations should pass before checking if the error threshold has been exceeded. The parameter \texttt{CarpetX::max\_num\_levels} controls the maximum number of allowed refinement levels.

Note that \CarpetX\space \textbf{does not} provide a ``standardized'' regrid error routine. This is because refinement criteria are highly specific to the problem being solved via AMR, and thus there is no one size fits all error criteria. This might seem inconvenient, but ultimately it allows for users to have higher degrees of customization in their AMR codes. For demonstration purposes, we shall now provide a routine that estimates the regrinding error as \todo{what? Provide a good starter example}. This implementation could be used as a starting point for codes that wish to use different error criteria in their AMR grids.

\begin{lstlisting}
extern "C" void EstimateError(CCTK_ARGUMENTS) {
DECLARE_CCTK_ARGUMENTSX_EstimateError;
DECLARE_CCTK_PARAMETERS;

// The template indices indicate this a loop over cell centers
// Remember that regrid_error is a cell centered grid function
grid.loop_int_device<1, 1, 1>(
grid.nghostzones,
[=] (const Loop::PointDesc &p) {
// TODO: Give a simple example
regrid_error(p.I) = 0.0;
});
}
\end{lstlisting}

Once defined, \texttt{EstimateError} should be scheduled in both the \texttt{postinitial} and \texttt{poststep} bins. The \texttt{poststep} bin gets called right after a new state vector has been calculated, and is thus the proper place to analyze it. The \texttt{postinitial} scheduling is also necessary for computing the initial refinement after initial conditions have been set up. A thorn making use of the \texttt{regrid\_error} AMR mechanism should then add the following to its \texttt{schedule.ccl} file:

\begin{lstlisting}[language=bash]
SCHEDULE EstimateError AT postinitial
{
LANG: C
READS: state(everywhere)
WRITES: CarpetX::regrid_error(interior)
} "Estimate error for regridding"

SCHEDULE EstimateError AT poststep
{
LANG: C
READS: state(everywhere)
WRITES: CarpetX::regrid_error(interior)
} "Estimate error for regridding"
\end{lstlisting}

\subsection{Controlling prolongation}

Prolongation refers to the interpolation of data on coarse grid into a finer grid. \CarpetX\space allows users to control how this propagation of data will be executed via the parameter \texttt{CarpetX::prolongation\_type}, whose possible values are detailed in Tab.~\ref{tab:prolongation_methods}. Additionally, other aspects of the prolongation operator can be controlled with the parameters detailed in Tab.~\ref{tab:other_prolongation_params}

\begin{table}[ht]
\centering
\begin{tabularx}{\textwidth}{lX}
Method & Description \\\hline\hline
\texttt{"interpolate"} & Interpolate between data points \\
\texttt{"conservative"} & Interpolate cell averages, ensuring conservation \\
\texttt{"ddf"} & Interpolate in vertex centered and conserve in cell centered directions \\
\texttt{"ddf-eno"} & Interpolate in vertex centered and ENO-conserve in cell centered directions \\
\texttt{"ddf-hermite"} & Hermite-interpolate in vertex centered and conserve in cell centered directions \\
\texttt{"natural"} & Interpolate in vertex centered and conserve in cell centered directions, using the same order \\
\texttt{"poly-cons3lfb"} & Interpolate polynomially in vertex centered directions and conserve with 3rd order accuracy and a linear fallback in cell centered directions \\\hline\hline
\end{tabularx}
\caption{Prolongation methods available in \CarpetX.}
\label{tab:prolongation_methods}
\end{table}

\begin{table}[ht]
\centering
\begin{tabularx}{\textwidth}{lccX}
Parameter & Type & Default value & Description \\\hline\hline
\texttt{prolongation\_order} & Integer larger than 0 & 1 & Controls the order of the interpolation in prolongation \\
\texttt{do\_restrict} & Boolean & yes & Automatically restrict fine to coarse grid functions \\
\texttt{restrict\_during\_sync} & Boolean & yes & Restrict fine to coarse grid functions when syncing \\
\end{tabularx}
\caption{Parameters controlling prolongation in \CarpetX.}
\label{tab:other_prolongation_params}
\end{table}

Binary file added CarpetX/doc/animated_boxes.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2db7553

Please sign in to comment.