CellTagger
The CellTagger
class is responsible for flagging grid cells for refinement or coarsening.
If the user wants to implement a new refinement or coarsening routine, he will do so by writing a new derived class from CellTagger
.
The CellTagger
parent class is a stand-alone class - it does not have a view of AmrMesh
, Driver
, or TimeStepper
.
Since refinement is intended to be quite general, the user is responsible for providing CellTagger
with the appropriate depedencies.
Refinement flags live in a data holder called EBAMRTags
inside of Driver
.
This data is typedef’ed as
typedef Vector<RefCountedPtr<LayoutData<DenseIntVectSet> > > EBAMRTags;
For performance reasons, DenseIntVectSet
onlys store refinement cells on a per-patch basis.
It is not possible to add a grid cell to a DenseIntVectSet
if it falls outside the grid patch.
Furthermore, the EBAMRTags
structure is a distributed data structure which makes sure that each MPI rank is aware of the refinement flags on the corresponding grid patches.
The flags themselves are owned by Driver, and they are copied onto the new grids in the regrid step.
User interface
To implement a new CellTagger
, the following functions must be implemented:
virtual void regrid() = 0;
virtual void parseOptions() = 0;
virtual void parseRuntimeOptions();
virtual bool tagCells(EBAMRTags& a_tags) = 0;
Users can also parse run-time options and even have CellTagger
write to plot files, by implementing
virtual int getNumberOfPlotVariables();
virtual void writePlotData(EBAMRCellData& a_output, Vector<std::string>& a_plotvar_names, int& a_icomp);
This is primarily useful for debugging the tracer fields that are used for flagging cells for refinement.
tagCells
When the regrid routine enters, the CellTagger
will be asked to generate the refinement flags through a function
bool tagCells(EBAMRTags& a_tags) = 0;
This routine should add cells that will be refined, and remove cells that will be coarsened.
regrid
regrid
is called by Driver during regrids.
The existence of this routine is due to the common usage pattern where CellTagger
holds some auxiliary mesh data that is used when evaluating refinement and coarsening criteria.
This routine should reallocate such temporary storage during regrids.
parseOptions
parseOptions
is called by Driver when setting the CellTagger
.
This routine should parse options into the CellTagger
instance.
parseRuntimeOptions
parseRuntimeOptions
is called by Driver after each grid step.
This routine will re-read class options into the CellTagger
instance.
See Run-time configurations for further details.
getNumberOfPlotVariables
getNumberOfPlotVariables
will return the number of plot variables that CellTagger
will write to plot files.
writePlotData
writePlotData
will write the plot data to the provided data holder.
The functionality is the same as for TimeStepper.
Restrict tagging
It is possible to prevent CellTagger
from adding refinement flags in specified regions.
The default behavior is to add a number of boxes where refinement and coarsening is allowed:
MyCellTagger.num_boxes = 0 # Number of allowed tag boxes (0 = tags allowe everywhere)
MyCellTagger.box1_lo = 0.0 0.0 0.0 # Only allow tags that fall between
MyCellTagger.box1_hi = 1.0 1.0 1.0 # these two corners
Here, MyCellTagger
is a placeholder for the name of the class that is used.
By adding restrictive boxes, tagging will only be allowed inside the specified box corners box1_lo
and box1_hi
.
More boxes can be specified by following the same convention, e.g. box2_lo
and box2_hi
etc.
Adding a buffer
By default, each MPI rank can only tag grid cells where it owns data.
This has been done for performance and communication reasons.
Under the hood, the DenseIntVectSet
is an array of boolean values on a patch which is very fast and simple to communicate with MPI.
Adding a grid cell for refinement which lies outside the patch will lead to memory corruptions.
It is nonetheless still possible to do this by growing the final generated tags like so:
MyCellTagger.buffer = 4 # Add a buffer region around the tagged cells
Just before passing the flags into AmrMesh
grid generation routines, the tagged cells are put in a different data holder (IntVectSet
) and this data holder can contain cells that are outside the patch boundaries.
Manual refinement
The user can add manual refinement by specifying Cartesian spatial regions to be refined down to some grid level, by specifying the physical corners and the refinement level. For example:
MyCellTagger.num_ref_boxes = 2
MyCellTagger.ref_box1_lo = 0 0 0
MyCellTagger.ref_box1_hi = 1 1 1
MyCellTagger.ref_box1_lvl = 2
MyCellTagger.ref_box2_lo = 1 1 1
MyCellTagger.ref_box2_hi = 2 2 2
MyCellTagger.ref_box2_lvl = 3
Any number of boxes can be specified using this format.