Surface ODE solver
chombo-discharge
provides a simple solver for ODE equations
where \(\vec{\phi}\) represents \(N\) unknowns on the EB.
Note that the underlying data type for \(\vec{\phi}\) and \(\vec{F}\) is EBAMRIVData
, see Mesh data.
Such a solver is useful, for example, as a surface charge solver where \(\phi\) is the surface charge density and \(F\) is the charge flux onto the EB.
The surface charge solver is implemented as
template <int N = 1>
class SurfaceODESolver;
where \(N\) indicates the number of variables stored in each cut cell.
Instantiation
To instantiate the solver, use the default constructor
template <int N>
SurfaceODESolver<N>::SurfaceODESolver();
The solver also requires a reference to AmrMesh, and the computational geometry such that a full instantiation example is
SurfaceODESolver<1>* solver = new SurfaceODESolver<1>();
solver->setAmr(...);
solver->setComputationalGeometry(...);
Setting \(\vec{\phi}\)
Mesh-based
To set \(\vec{\phi}\) on the mesh, one can fetch the underlying data by calling
template <int N>
EBAMRIVData&
SurfaceODESolver<N>::getPhi() noexcept;
This returns a reference to the underlying data which is defined on all cut-cells. The user can then iterate through this data and set the values accordingly, see Iterating over patches.
Function-based
To set the data directly, SurfaceODESolver
defines a function
template <int N>
void
SurfaceODESolver<N>::setPhi(std::function<std::array<Real, N>(const RealVect pos)>& a_func);
where the input argument represents a function \(\vec{f} = \vec{f}\left(\mathbf{x}\right)\) that returns a value for each component in \(\vec{\phi}\).
Setting \(\vec{F}\)
Mesh-based
To set \(\vec{F}\) on the mesh, one can fetch the underlying data by calling
template <int N>
EBAMRIVData&
SurfaceODESolver<N>::getRHS() noexcept;
This returns a reference to the underlying data which is defined on all cut-cells. The user can then iterate through this data and set the values accordingly, see Iterating over patches.
Function-based
To set the right-hand side directly, SurfaceODESolver
defines a function
template <int N>
void
SurfaceODESolver<N>::setRHS(std::function<std::array<Real, N>(const RealVect pos)>& a_func);
where the input argument represents a function \(\vec{f} = \vec{f}\left(\mathbf{x}\right)\) that returns a value for each component in \(\vec{F}\).
Resetting cells
SurfaceODESolver
has functions for setting values in the subset of the cut-cells representing dielectrics or electrodes.
The function signatures are
template <int N>
void
SurfaceODESolver<N>::resetElectrodeCells(const Real a_value);
template <int N>
void
SurfaceODESolver<N>::resetDielectricCells(const Real a_value);
Calling these functions will set the data value in electrode or dielectric cells to a_value
.
Note that one can always call SurfaceODESolver<N>::getPhi()
to iterate over other types of cell subsets.
Regridding
When regridding the SurfaceODESolver
, one should call
template <int N>
void
SurfaceODESolver<N>::preRegrid(const int a_lbase, const int a_oldFinestLevel) noexcept;
before AmrMesh creates the new grids. This will store \(\vec{\phi}\) on the old mesh. After AmrMesh has generated the new grids, \(\vec{\phi}\) can be interpolated onto the new grids by calling
template <int N>
SurfaceODESolver<N>::regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) noexcept;
Note that when interpolating to the new grids one can choose to initialize data in the new cells using the value in the underlying coarse cells, i.e.
Alternatively one can initialize the fine-grid data such that the area-weighted value of \(\vec{\phi}\) is conserved, i.e.
which gives
where \(\mathbf{i}_{\textrm{fine}}\) is set of cut-cells that occur when refining the coarse-grid cut-cell \(\mathbf{i}_{\textrm{coar}}\) and \(r\) is the refinement factor between the two grid levels. In this case \(\vec{\phi}\) is strictly conserved. Users can switch between these two methods by specifying the regridding type in the input script:
SurfaceODESolver.regridding = arithmetic
or
SurfaceODESolver.regridding = conservative
I/O
The user can add \(\vec{\phi}\) and \(\vec{F}\) to output files by specifying these in the input script. These variables are named
SurfaceODESolver.plt_vars = phi rhs
Only phi
and rhs
are recognized as valid arguments.
If choosing to omit output variables for the solver, one can put e.g. SurfaceODESolver.plt_vars = -1
.
Note
SurfaceODESolver
checkpoint files only contain \(\vec{\phi}\).