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
/*!
@brief Surface ODE solver
@details This is a basic solver that acts as an ODE solver on cut-cells.
*/
template <int N = 1>
class SurfaceODESolver
where \(N\) indicates the number of variables stored in each cut cell. This solver is analogous to Mesh ODE solver, with the exception that variables are only stored on cut-cells.
Instantiation
To instantiate the solver, use one of the following constructors:
static_assert(N > 0, "SurfaceODESolver<N> must have N > 0");
/*!
@brief Default constructor. Must subsequently set AmrMesh.
@details Sets realm to primal and phase to phase::gas.
*/
SurfaceODESolver();
/*!
@brief Full constructor.
@details Sets AmrMesh to input and sets realm to primal and phase to phase::gas.
@param[in] a_amr AmrMesh reference
*/
SurfaceODESolver(const RefCountedPtr<AmrMesh>& a_amr);
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
/*!
@brief Get internal state
@return Returns m_phi
*/
virtual EBAMRIVData&
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 the AMR hierarchy.
Constant value
To set the data directly, SurfaceODESolver<N> defines functions
/*!
@brief Convenience function for setting m_phi
@param[in] a_phi Values for all components
*/
virtual void
setPhi(const Real a_phi);
/*!
@brief Convenience function for setting m_phi
@param[in] a_phi Component-wise values.
*/
virtual void
setPhi(const std::array<Real, N>& a_phi);
Setting \(\vec{F}\)
In order to set the right-hand side of the equation, functions exist that are entirely analogous to the function signatures for setting \(\vec{\phi}\):
/*!
@brief Convenience function for setting m_rhs
@param[in] a_rhs Values for all components
*/
virtual void
setRHS(const Real a_rhs);
/*!
@brief Convenience function for setting m_rhs
@param[in] a_rhs Component-wise values.
*/
virtual void
setRHS(const std::array<Real, N>& a_rhs);
/*!
@brief Convenience function for setting m_rhs
@param[in] a_rhs Values per cell and component.
@note a_rhs must have N components.
*/
virtual void
setRHS(const EBAMRIVData& a_rhs);
/*!
@brief Get internal state
@return Returns m_rhs
*/
virtual EBAMRIVData&
getRHS();
Resetting cells
SurfaceODESolver<N> has functions for setting values in the subset of the cut-cells representing dielectrics or electrodes.
The information about whether or not a cut-cell is on the dielectric or electrode is passed in through ComputationalGeometry.
The function signatures are
/*!
@brief Reset m_phi on electrode cells.
@details This will set a_data to the specified value (in electrode cells)
@param[in] a_val Value
@note Does not include ghost cells.
*/
virtual void
resetElectrodes(const Real a_value) noexcept;
/*!
@brief Reset the input data holder on electrode cells.
@details This will set a_data to the specified value (in electrode cells)
@param[in] a_data Input data to be set.
@param[in] a_val Value
@note Does not include ghost cells.
*/
virtual void
resetElectrodes(EBAMRIVData& a_phi, const Real a_value) const noexcept;
/*!
@brief Reset m_phi on dielectric cells.
@details This will set a_data to the specified value (in dielectric cells)
@param[in] a_val Value
@note Does not include ghost cells.
*/
virtual void
resetDielectrics(const Real a_value) noexcept;
/*!
@brief Reset the input data holder on dielectric cells.
@details This will set a_data to the specified value (in dielectric cells)
@param[in] a_data Input data to be set.
@param[in] a_val Value
@note Does not include ghost cells.
*/
virtual void
resetDielectrics(EBAMRIVData& a_phi, const Real a_value) const noexcept;
Note that one can always call SurfaceODESolver<N>::getPhi() to iterate over other types of cell subsets and set the values from there.
Regridding
When regridding the SurfaceODESolver<N>, one must first call call
/*!
@brief Pre-regrid function.
@details This stores the data on the old mesh so it can be regridded later.
@param[in] a_lbase Coarsest level which will change during regrids.
@param[in] a_oldFinestLevel Finest level before the regrid operation.
*/
virtual void
preRegrid(const int a_lbase, const int a_oldFinestLevel) noexcept;
This must be done before AmrMesh creates the new grids, and 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
/*!
@brief Regrid function.
@param[in] a_lmin Coarsest level where grids did not change.
@param[in] a_oldFinestLevel Finest AMR level before the regrid.
@param[in] a_newFinestLevel Finest AMR level after the regrid.
@details This interpolates or coarsens conservatively, e.g. sigma_c = sum(A_f * sigma_f)/A_c if we coarsen.
*/
virtual void
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 proper configuration option in the configuration file.
Input options
Several input options are available for configuring the run-time configuration of MeshODESolver, which are listed below
# ====================================================================================================
# SurfaceODESolver solver settings.
# ====================================================================================================
SurfaceODESolver.verbosity = -1 ## Chattiness
SurfaceODESolver.regrid = conservative ## Regrid method. 'conservative' or 'arithmetic'
SurfaceODESolver.plt_vars = phi ## Plot variables. Valid arguments are 'phi' and 'rhs'
Note
SurfaceODESolver checkpoint files only contain \(\vec{\phi}\).