12 #ifndef CD_MeshODESolverImplem_H
13 #define CD_MeshODESolverImplem_H
17 #include <ParmParse.H>
24 #include <CD_NamespaceHeader.H>
29 CH_TIME(
"MeshODESolver::MeshODESolver()");
33 m_name =
"MeshODESolver";
34 m_className =
"MeshODESolver";
44 CH_TIME(
"MeshODESolver::MeshODESolver(AMR)");
52 CH_TIME(
"MeshODESolver::~MeshODESolver");
59 CH_TIME(
"MeshODESolver::setAmr");
60 if (m_verbosity > 5) {
61 pout() << m_name +
"::setAmr" << endl;
71 CH_TIME(
"MeshODESolver::parseOptions");
73 ParmParse pp(m_className.c_str());
75 pp.get(
"verbosity", m_verbosity);
76 pp.get(
"use_regrid_slopes", m_regridSlopes);
78 this->parsePlotVariables();
80 if (m_verbosity > 5) {
81 pout() << m_name +
"::parseOptions()" << endl;
89 CH_TIME(
"MeshODESolver::parseRuntimeOptions()");
90 if (m_verbosity > 5) {
91 pout() << m_name +
"::parseRuntimeOptions()" << endl;
94 ParmParse pp(m_className.c_str());
96 pp.get(
"verbosity", m_verbosity);
97 pp.get(
"use_regrid_slopes", m_regridSlopes);
99 this->parsePlotVariables();
106 CH_TIME(
"MeshODESolver::parsePlotVariables()");
107 if (m_verbosity > 5) {
108 pout() << m_name +
"::parsePlotVariables()" << endl;
114 ParmParse pp(m_className.c_str());
115 const int num = pp.countval(
"plt_vars");
118 Vector<std::string> str(num);
119 pp.getarr(
"plt_vars", str, 0, num);
121 for (
int i = 0; i < num; i++) {
122 if (str[i] ==
"phi") {
125 else if (str[i] ==
"rhs") {
136 CH_TIME(
"MeshODESolver::getPhi()");
137 if (m_verbosity > 5) {
138 pout() << m_name +
"::getPhi()" << endl;
148 CH_TIME(
"MeshODESolver::getPhi()");
149 if (m_verbosity > 5) {
150 pout() << m_name +
"::getPhi()" << endl;
160 CH_TIME(
"MeshODESolver::getRHS()");
161 if (m_verbosity > 5) {
162 pout() << m_name +
"::getRHS()" << endl;
172 CH_TIME(
"MeshODESolver::getRHS()");
173 if (m_verbosity > 5) {
174 pout() << m_name +
"::getRHS()" << endl;
184 CH_TIME(
"MeshODESolver::setPhi(std::function, size_t)");
185 if (m_verbosity > 5) {
186 pout() << m_name +
"::setPhi(std::function, size_t)" << endl;
196 CH_TIME(
"MeshODESolver::setPhi(std::function)");
197 if (m_verbosity > 5) {
198 pout() << m_name +
"::setPhi(std::function)" << endl;
201 constexpr
int comp = 0;
203 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
204 const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
205 const DataIterator& dit = dbl.dataIterator();
206 const Real& dx = m_amr->getDx()[lvl];
207 const EBISLayout& ebisl = m_amr->getEBISLayout(m_realm, m_phase)[lvl];
208 const RealVect& probLo = m_amr->getProbLo();
210 const int nbox = dit.size();
212 #pragma omp parallel for schedule(runtime)
213 for (
int mybox = 0; mybox < nbox; mybox++) {
214 const DataIndex& din = dit[mybox];
216 EBCellFAB& phi = (*m_phi[lvl])[din];
217 const EBISBox& ebisbox = ebisl[din];
218 FArrayBox& phiFAB = phi.getFArrayBox();
219 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_realm)[lvl])[din];
222 auto regularKernel = [&](
const IntVect& iv) ->
void {
223 std::array<Real, N> y{};
225 if (validCells(iv, comp) && ebisbox.isRegular(iv)) {
226 const RealVect pos = probLo + (0.5 * RealVect::Unit + RealVect(iv)) * dx;
232 for (
size_t i = 0; i < N; i++) {
233 phiFAB(iv, i) = y[i];
238 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
239 std::array<Real, N> y{};
240 const IntVect iv = vof.gridIndex();
242 if (validCells(iv, comp)) {
243 const RealVect pos = probLo +
Location::position(Location::Cell::Centroid, vof, ebisbox, dx);
249 for (
size_t i = 0; i < N; i++) {
255 const Box cellBox = dbl[din];
256 VoFIterator& vofit = (*m_amr->getVofIterator(m_realm, m_phase)[lvl])[din];
269 CH_TIME(
"MeshODESolver::setRHS(std::function, size_t)");
270 if (m_verbosity > 5) {
271 pout() << m_name +
"::setRHS(std::function, size_t)" << endl;
281 CH_TIME(
"MeshODESolver::computeRHS(std::function<std::array<Real, N>(...)>)");
282 if (m_verbosity > 5) {
283 pout() << m_name +
"::computeRHS(std::function<std::array<Real, N>(...)>)" << endl;
286 this->computeRHS(m_rhs, a_rhsFunction);
293 CH_TIME(
"MeshODESolver::computeRHS(EBAMRCellData, std::function<std::array<Real, N>(...)>)");
294 if (m_verbosity > 5) {
295 pout() << m_name +
"::computeRHS(EBAMRCellData, std::function<std::array<Real, N>(...)>)" << endl;
298 constexpr
int comp = 0;
300 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
301 const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
302 const EBISLayout& ebisl = m_amr->getEBISLayout(m_realm, m_phase)[lvl];
303 const DataIterator& dit = dbl.dataIterator();
305 const int nbox = dit.size();
307 #pragma omp parallel for schedule(runtime)
308 for (
int mybox = 0; mybox < nbox; mybox++) {
309 const DataIndex& din = dit[mybox];
311 EBCellFAB& rhs = (*a_rhs[lvl])[din];
312 const EBCellFAB& phi = (*m_phi[lvl])[din];
313 const EBISBox& ebisbox = ebisl[din];
315 FArrayBox& rhsFAB = rhs.getFArrayBox();
316 const FArrayBox& phiFAB = phi.getFArrayBox();
318 const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_realm)[lvl])[din];
321 auto regularKernel = [&](
const IntVect& iv) ->
void {
322 std::array<Real, N> y{};
323 std::array<Real, N> f{};
325 if (validCells(iv, comp) && ebisbox.isRegular(iv)) {
328 for (
size_t i = 0; i < N; i++) {
329 y[i] = phiFAB(iv, i);
333 f = a_rhsFunction(y, m_time);
337 for (
size_t i = 0; i < N; i++) {
338 rhsFAB(iv, i) = f[i];
343 auto irregularKernel = [&](
const VolIndex& vof) ->
void {
344 std::array<Real, N> y{};
345 std::array<Real, N> f{};
347 const IntVect iv = vof.gridIndex();
349 if (validCells(iv, comp)) {
352 for (
size_t i = 0; i < N; i++) {
357 f = a_rhsFunction(y, m_time);
361 for (
size_t i = 0; i < N; i++) {
367 const Box cellBox = dbl[din];
368 VoFIterator& vofit = (*m_amr->getVofIterator(m_realm, m_phase)[lvl])[din];
381 CH_TIME(
"MeshODESolver::allocate()");
382 if (m_verbosity > 5) {
383 pout() << m_name +
"::allocate()" << endl;
386 m_amr->allocate(m_phi, m_realm, m_phase, N);
387 m_amr->allocate(m_rhs, m_realm, m_phase, N);
394 CH_TIME(
"MeshODESolver::preRegrid(int, int)");
395 if (m_verbosity > 5) {
396 pout() << m_name +
"::preRegrid(int, int)" << endl;
399 m_amr->allocate(m_cache, m_realm, m_phase, N);
400 m_amr->copyData(m_cache, m_phi);
409 CH_TIME(
"MeshODESolver::regrid(int, int, int)");
410 if (m_verbosity > 5) {
411 pout() << m_name +
"::regrid(int, int, int)" << endl;
417 : EBCoarseToFineInterp::Type::ConservativePWC;
419 m_amr->interpToNewGrids(m_phi, m_cache, m_phase, a_lmin, a_oldFinestLevel, a_newFinestLevel, interpType);
421 m_amr->conservativeAverage(m_phi, m_realm, m_phase);
422 m_amr->interpGhost(m_phi, m_realm, m_phase);
431 CH_TIME(
"MeshODESolver::getRealm()");
432 if (m_verbosity > 5) {
433 pout() << m_name +
"::getRealm()" << endl;
443 CH_TIME(
"MeshODESolver::getName()");
444 if (m_verbosity > 5) {
445 pout() << m_name +
"::getName()" << endl;
455 CH_TIME(
"MeshODESolver::setName()");
456 if (m_verbosity > 5) {
457 pout() << m_name +
"::setName()" << endl;
467 CH_TIME(
"MeshODESolver::registerOperators()");
468 if (m_verbosity > 5) {
469 pout() << m_name +
"::registerOperators()" << endl;
472 CH_assert(!m_amr.isNull());
474 m_amr->registerOperator(s_eb_coar_ave, m_realm, m_phase);
475 m_amr->registerOperator(s_eb_fill_patch, m_realm, m_phase);
476 m_amr->registerOperator(s_eb_fine_interp, m_realm, m_phase);
483 CH_TIME(
"MeshODESolver::setRealm(std::string)");
484 if (m_verbosity > 5) {
485 pout() << m_name +
"::setRealm(std::string)" << endl;
488 m_realm.assign(a_realm);
495 CH_TIME(
"MeshODESolver::setPhase(phase)");
496 if (m_verbosity > 5) {
497 pout() << m_name +
"::setPhase(phase)" << endl;
507 CH_TIME(
"MeshODESolver::setVerbosity(int)");
508 if (m_verbosity > 5) {
509 pout() << m_name +
"::setVerbosity(int)" << endl;
512 m_verbosity = a_verbosity;
519 CH_TIME(
"MeshODESolver::setTime(int, Real, Real)");
520 if (m_verbosity > 5) {
521 pout() << m_name +
"::setTime(int, Real, Real)" << endl;
533 CH_TIME(
"MeshODESolver::writePlotFile()");
534 if (m_verbosity > 5) {
535 pout() << m_name +
"::writePlotFile()" << endl;
539 const int numPlotVars = this->getNumberOfPlotVariables();
540 const Vector<std::string> plotVarNames = this->getPlotVariableNames();
544 m_amr->allocate(output, m_realm, m_phase, numPlotVars);
548 for (
int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
549 this->writePlotData(*output[lvl], icomp, m_realm, lvl);
553 sprintf(filename,
"%s.step%07d.%dd.hdf5", m_name.c_str(), m_timeStep, SpaceDim);
554 std::string fname(filename);
557 Vector<LevelData<EBCellFAB>*> outputPtr;
558 m_amr->alias(outputPtr, output);
561 constexpr
int numPlotGhost = 0;
563 DischargeIO::writeEBHDF5(fname,
565 m_amr->getGrids(m_realm),
569 m_amr->getRefinementRatios(),
573 m_amr->getFinestLevel() + 1,
582 CH_TIME(
"MeshODESolver::getNumberOfPlotVariables()");
583 if (m_verbosity > 5) {
584 pout() << m_name +
"::getNumberOfPlotVariables()" << endl;
590 numPlotVars += int(N);
594 numPlotVars += int(N);
604 CH_TIME(
"MeshODESolver::getPlotVariableNames()");
605 if (m_verbosity > 5) {
606 pout() << m_name +
"::getPlotVariableNames()" << endl;
609 Vector<std::string> plotVarNames(0);
612 for (
size_t i = 0; i < N; i++) {
613 plotVarNames.push_back(m_name +
" phi-" + std::to_string(i));
618 for (
size_t i = 0; i < N; i++) {
619 plotVarNames.push_back(m_name +
" source-" + std::to_string(i));
630 const std::string a_outputRealm,
631 const int a_level)
const noexcept
633 CH_TIME(
"MeshODESolver::writePlotData");
634 if (m_verbosity > 5) {
635 pout() << m_name +
"::writePlotData" << endl;
639 this->writeData(a_output, a_icomp, m_phi, a_outputRealm, a_level,
false,
true);
643 this->writeData(a_output, a_icomp, m_rhs, a_outputRealm, a_level,
false,
true);
652 const std::string a_outputRealm,
654 const bool a_interpToCentroids,
655 const bool a_interpGhost)
const noexcept
658 CH_TIMERS(
"MeshODESolver::writeData");
659 CH_TIMER(
"MeshODESolver::writeData::allocate", t1);
660 CH_TIMER(
"MeshODESolver::writeData::local_copy", t2);
661 CH_TIMER(
"MeshODESolver::writeData::interp_ghost", t3);
662 CH_TIMER(
"MeshODESolver::writeData::interp_centroid", t4);
663 CH_TIMER(
"MeshODESolver::writeData::final_copy", t5);
664 if (m_verbosity > 5) {
665 pout() << m_name +
"::writeData" << endl;
669 const int numComp = a_data[a_level]->nComp();
672 const Interval srcInterv(0, numComp - 1);
673 const Interval dstInterv(a_comp, a_comp + numComp - 1);
676 LevelData<EBCellFAB> scratch;
677 m_amr->allocate(scratch, m_realm, m_phase, a_level, numComp);
681 m_amr->copyData(scratch, *a_data[a_level], a_level, m_realm, m_realm);
686 if (a_level > 0 && a_interpGhost) {
687 m_amr->interpGhost(scratch, *a_data[a_level - 1], a_level, m_realm, m_phase);
692 if (a_interpToCentroids) {
693 m_amr->interpToCentroids(scratch, m_realm, m_phase, a_level);
700 m_amr->copyData(a_output, scratch, a_level, a_outputRealm, m_realm, dstInterv, srcInterv);
711 CH_TIME(
"MeshODESolver::writeCheckpointLevel(HDF5Handle, int)");
712 if (m_verbosity > 5) {
713 pout() << m_name +
"::writeCheckpointLevel(HDF5Handle, int)" << endl;
716 write(a_handle, *m_phi[a_level], m_name);
717 write(a_handle, *m_rhs[a_level], m_name +
"_src");
726 CH_TIME(
"MeshODESolver::writeCheckpointLevel(HDF5Handle, int)");
727 if (m_verbosity > 5) {
728 pout() << m_name +
"::writeCheckpointLevel(HDF5Handle, int)" << endl;
731 read<EBCellFAB>(a_handle, *m_phi[a_level], m_name, m_amr->getGrids(m_realm)[a_level], Interval(0, N - 1),
false);
732 read<EBCellFAB>(a_handle,
735 m_amr->getGrids(m_realm)[a_level],
741 #include <CD_NamespaceFooter.H>
Declaration of a namespace for proto-typing grid and EB loops.
Silly, but useful functions that override standard Chombo HDF5 IO.
Declaration of cell positions.
Encapsulation of an ODE solver on the mesh.
static void setValue(LevelData< MFInterfaceFAB< T >> &a_lhs, const T &a_value)
Set value in an MFInterfaceFAB data holder.
Definition: CD_DataOpsImplem.H:23
static void setCoveredValue(EBAMRCellData &a_lhs, const int a_comp, const Real a_value)
Set value in covered cells. Does specified component.
Definition: CD_DataOps.cpp:2538
Type
Type of interpolation methods supported. PWC = Piecewise constant, ignoring the embedded boundary....
Definition: CD_EBCoarseToFineInterp.H:42
Class for solving dy/dt = f on an AMR hierarchy.
Definition: CD_MeshODESolver.H:28
virtual std::string getRealm() const noexcept
Get the realm where this solver is registered.
Definition: CD_MeshODESolverImplem.H:429
virtual void writePlotData(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string a_outputRealm, const int a_level) const noexcept
Write plot data to output holder.
Definition: CD_MeshODESolverImplem.H:628
virtual Vector< std::string > getPlotVariableNames() const noexcept
Get output plot names.
Definition: CD_MeshODESolverImplem.H:602
virtual void regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) noexcept
Regrid this solver.
Definition: CD_MeshODESolverImplem.H:407
virtual void writePlotFile() const noexcept
Write plot file.
Definition: CD_MeshODESolverImplem.H:531
std::function< std::array< Real, N >(const std::array< Real, N > &, const Real)> RHSFunction
Alias for right-hand side.
Definition: CD_MeshODESolver.H:33
virtual void setName(const std::string &a_name) noexcept
Set solver name.
Definition: CD_MeshODESolverImplem.H:453
virtual void preRegrid(const int a_lbase, const int a_oldFinestLevel) noexcept
Perform pre-regrid operations.
Definition: CD_MeshODESolverImplem.H:392
virtual void setPhi(const std::function< Real(const RealVect &a_pos)> &a_phiFunc, const size_t a_comp) noexcept
Set phi for a specific component.
Definition: CD_MeshODESolverImplem.H:182
virtual void parseRuntimeOptions() noexcept
Parse run-time configurable class options.
Definition: CD_MeshODESolverImplem.H:87
MeshODESolver()
Default constructor. Must subsequently set everything through public member functions.
Definition: CD_MeshODESolverImplem.H:27
virtual void registerOperators() const noexcept
Register operators for AMR operations.
Definition: CD_MeshODESolverImplem.H:465
virtual void setVerbosity(const int a_verbosity) noexcept
Set verbosity.
Definition: CD_MeshODESolverImplem.H:505
virtual void setRHS(const std::function< Real(const RealVect &a_pos)> &a_srcFunc, const size_t a_comp) noexcept
Set right-hand side for specified component.
Definition: CD_MeshODESolverImplem.H:267
virtual void setRealm(const std::string a_realm) noexcept
Set the realm for this solver.
Definition: CD_MeshODESolverImplem.H:481
EBAMRCellData & getPhi() noexcept
Get the solution vector (left-hand side of equation).
Definition: CD_MeshODESolverImplem.H:134
virtual ~MeshODESolver()
Destructor.
Definition: CD_MeshODESolverImplem.H:50
virtual int getNumberOfPlotVariables() const noexcept
Get number of output fields.
Definition: CD_MeshODESolverImplem.H:580
virtual void parseOptions() noexcept
Parse class options.
Definition: CD_MeshODESolverImplem.H:69
virtual void parsePlotVariables() noexcept
Parse plot variables.
Definition: CD_MeshODESolverImplem.H:104
EBAMRCellData & getRHS() noexcept
Get the solution vector (left-hand side of equation).
Definition: CD_MeshODESolverImplem.H:158
virtual void setAmr(const RefCountedPtr< AmrMesh > &a_amrMesh) noexcept
Set AmrMesh.
Definition: CD_MeshODESolverImplem.H:57
virtual void setPhase(phase::which_phase a_phase) noexcept
Set phase.
Definition: CD_MeshODESolverImplem.H:493
virtual void allocate() noexcept
Allocate internal storage.
Definition: CD_MeshODESolverImplem.H:379
virtual void setTime(const int a_step, const Real a_time, const Real a_dt) noexcept
Set the time for this solver.
Definition: CD_MeshODESolverImplem.H:517
virtual std::string getName() const noexcept
Get solver name.
Definition: CD_MeshODESolverImplem.H:441
virtual void computeRHS(const RHSFunction &a_rhsFunction) noexcept
Compute right-hand side from left-hand side. I.e. compute f = f(y,t).
Definition: CD_MeshODESolverImplem.H:279
virtual void writeData(LevelData< EBCellFAB > &a_output, int &a_comp, const EBAMRCellData &a_data, const std::string a_outputRealm, const int a_level, const bool a_interpToCentroids, const bool a_interpGhost) const noexcept
Write data to output. Convenience function.
Definition: CD_MeshODESolverImplem.H:649
static const std::string Primal
Identifier for perimal realm.
Definition: CD_Realm.H:47
ALWAYS_INLINE void loop(const Box &a_computeBox, Functor &&kernel, const IntVect &a_stride=IntVect::Unit)
Launch a C++ kernel over a regular grid.
Definition: CD_BoxLoopsImplem.H:20
RealVect position(const Location::Cell a_location, const VolIndex &a_vof, const EBISBox &a_ebisbox, const Real &a_dx)
Compute the position (ignoring the "origin) of a Vof.
Definition: CD_LocationImplem.H:20