chombo-discharge
CD_SurfaceODESolverImplem.H
Go to the documentation of this file.
1 /* chombo-discharge
2  * Copyright © 2022 SINTEF Energy Research.
3  * Please refer to Copyright.txt and LICENSE in the chombo-discharge root directory.
4  */
5 
12 #ifndef CD_SurfaceODESolverImplem_H
13 #define CD_SurfaceODESolverImplem_H
14 
15 // Chombo includes
16 #include <CH_Timer.H>
17 #include <ParmParse.H>
18 
19 // Our includes
20 #include <CD_SurfaceODESolver.H>
21 #include <CD_DischargeIO.H>
22 #include <CD_NamespaceHeader.H>
23 
24 template <int N>
26 {
27  CH_TIME("SurfaceODESolver::SurfaceODESolver");
28 
29  m_className = "SurfaceODESolver";
30 
31  m_verbosity = -1;
32 
33  this->setVerbosity(-1);
34  this->setRealm(Realm::Primal);
35  this->setPhase(phase::gas);
36  this->setName(m_className);
37  this->setTime(0, 0.0, 0.0);
38 }
39 
40 template <int N>
41 SurfaceODESolver<N>::SurfaceODESolver(const RefCountedPtr<AmrMesh>& a_amr) : SurfaceODESolver<N>()
42 {
43  CH_TIME("SurfaceODESolver::SurfaceODESolver");
44  if (m_verbosity > 5) {
45  pout() << m_name + "::SurfaceODESolver()" << endl;
46  }
47 
48  m_amr = a_amr;
49 }
50 
51 template <int N>
53 {
54  CH_TIME("SurfaceODESolver::~SurfaceODESolver");
55  if (m_verbosity > 5) {
56  pout() << m_name + "::~SurfaceODESolver()" << endl;
57  }
58 }
59 
60 template <int N>
61 void
63 {
64  CH_TIME("SurfaceODESolver::parseOptions");
65  if (m_verbosity > 5) {
66  pout() << m_name + "::parseOptions" << endl;
67  }
68 
69  this->parseVerbosity();
70  this->parseRegrid();
71  this->parsePlotVariables();
72 }
73 
74 template <int N>
75 void
77 {
78  CH_TIME("SurfaceODESolver::parseRuntimeOptions");
79  if (m_verbosity > 5) {
80  pout() << m_name + "::parseRuntimeOptions" << endl;
81  }
82 
83  this->parseVerbosity();
84  this->parseRegrid();
85  this->parsePlotVariables();
86 }
87 
88 template <int N>
89 void
91 {
92  CH_TIME("SurfaceODESolver::parseVerbosity");
93  if (m_verbosity > 5) {
94  pout() << m_name + "::parseVerbosity" << endl;
95  }
96 
97  ParmParse pp(m_className.c_str());
98 
99  pp.get("verbosity", m_verbosity);
100 }
101 
102 template <int N>
103 void
105 {
106  CH_TIME("SurfaceODESolver::parseRegrid");
107  if (m_verbosity > 5) {
108  pout() << m_name + "::parseRegrid" << endl;
109  }
110 
111  ParmParse pp(m_className.c_str());
112 
113  std::string str;
114  pp.get("regrid", str);
115 
116  if (str == "conservative") {
117  m_conservativeRegrid = true;
118  }
119  else if (str == "arithmetic") {
120  m_conservativeRegrid = false;
121  }
122  else {
123  const std::string err = "SurfaceODESolver<N>::parseRegrid() - argument '" + str + "' not recognized";
124  MayDay::Error(err.c_str());
125  }
126 }
127 
128 template <int N>
129 void
131 {
132  CH_TIME("SurfaceODESolver::parsePlotVariables");
133  if (m_verbosity > 5) {
134  pout() << m_name + "::parsePlotVariables" << endl;
135  }
136 
137  m_plotPhi = false;
138  m_plotRHS = false;
139 
140  ParmParse pp(m_className.c_str());
141 
142  const int num = pp.countval("plt_vars");
143 
144  if (num > 0) {
145  Vector<std::string> str(num);
146  pp.getarr("plt_vars", str, 0, num);
147 
148  for (int i = 0; i < num; i++) {
149  if (str[i] == "phi") {
150  m_plotPhi = true;
151  }
152  else if (str[i] == "rhs") {
153  m_plotRHS = true;
154  }
155  }
156  }
157 }
158 
159 template <int N>
160 void
161 SurfaceODESolver<N>::setAmr(const RefCountedPtr<AmrMesh>& a_amr) noexcept
162 {
163  CH_TIME("SurfaceODESolver::setAmr");
164  if (m_verbosity > 5) {
165  pout() << m_name + "::setAmr" << endl;
166  }
167 
168  CH_assert(!(a_amr.isNull()));
169 
170  m_amr = a_amr;
171 }
172 
173 template <int N>
174 void
175 SurfaceODESolver<N>::setRealm(const std::string a_realm) noexcept
176 {
177  CH_TIME("SurfaceODESolver::setRealm");
178  if (m_verbosity > 5) {
179  pout() << m_name + "::setRealm" << endl;
180  }
181 
182  m_realm = a_realm;
183 }
184 
185 template <int N>
186 void
187 SurfaceODESolver<N>::setName(const std::string a_name) noexcept
188 {
189  CH_TIME("SurfaceODESolver::setName");
190  if (m_verbosity > 5) {
191  pout() << "SurfaceODESolver::setName" << endl;
192  }
193 
194  m_name = a_name;
195 }
196 
197 template <int N>
198 std::string
200 {
201  CH_TIME("SurfaceODESolver::getRealm");
202  if (m_verbosity > 5) {
203  pout() << "SurfaceODESolver::getRealm" << endl;
204  }
205 
206  return m_realm;
207 }
208 
209 template <int N>
210 void
211 SurfaceODESolver<N>::setPhase(const phase::which_phase a_phase) noexcept
212 {
213  CH_TIME("SurfaceODESolver::setPhase");
214  if (m_verbosity > 5) {
215  pout() << m_name + "::setPhase" << endl;
216  }
217 
218  m_phase = a_phase;
219 }
220 
221 template <int N>
222 phase::which_phase
224 {
225  CH_TIME("SurfaceODESolver::getPhase");
226  if (m_verbosity > 5) {
227  pout() << m_name + "::getPhase" << endl;
228  }
229 
230  return m_phase;
231 }
232 
233 template <int N>
234 void
235 SurfaceODESolver<N>::setVerbosity(const int a_verbosity) noexcept
236 {
237  CH_TIME("SurfaceODESolver::setVerbosity");
238  if (m_verbosity > 5) {
239  pout() << m_name + "::setVerbosity" << endl;
240  }
241 
242  m_verbosity = a_verbosity;
243 }
244 
245 template <int N>
246 int
248 {
249  CH_TIME("SurfaceODESolver::getVerbosity");
250  if (m_verbosity > 5) {
251  pout() << m_name + "::getVerbosity" << endl;
252  }
253 
254  return m_verbosity;
255 }
256 
257 template <int N>
258 void
259 SurfaceODESolver<N>::setTime(const int a_step, const Real a_time, const Real a_dt) noexcept
260 {
261  CH_TIME("SurfaceODESolver::setTime");
262  if (m_verbosity > 5) {
263  pout() << m_name + "::setTime" << endl;
264  }
265 
266  m_step = a_step;
267  m_time = a_time;
268  m_dt = a_dt;
269 }
270 
271 template <int N>
272 Real
273 SurfaceODESolver<N>::computeMass(const int a_comp) const noexcept
274 {
275  CH_TIME("SurfaceODESolver::computeMass(int)");
276  if (m_verbosity > 5) {
277  pout() << m_name + "::computeMass(int)" << endl;
278  }
279 
280  return this->computeMass(m_phi, a_comp);
281 }
282 
283 template <int N>
284 Real
285 SurfaceODESolver<N>::computeMass(const EBAMRIVData& a_data, const int a_comp) const noexcept
286 {
287  CH_TIME("SurfaceODESolver::computeMass(EBAMRIVData, int)");
288  if (m_verbosity > 5) {
289  pout() << m_name + "::computeMass(EBAMRIVData, int)" << endl;
290  }
291 
292  Real dataSum = 0.0;
293 
294  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
295  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
296  const DataIterator& dit = dbl.dataIterator();
297  const EBISLayout& ebisl = m_amr->getEBISLayout(m_realm, m_phase)[lvl];
298  const Real dx = m_amr->getDx()[lvl];
299  const Real dxArea = std::pow(dx, SpaceDim - 1);
300 
301  CH_assert(a_data[lvl]->nComp() > a_comp);
302 
303  const int nbox = dit.size();
304 
305 #pragma omp parallel for schedule(runtime) reduction(+ : dataSum)
306  for (int mybox = 0; mybox < nbox; mybox++) {
307  const DataIndex& din = dit[mybox];
308 
309  const EBISBox& ebisbox = ebisl[din];
310  const BaseFab<bool>& validCells = (*m_amr->getValidCells(m_realm)[lvl])[din];
311  const BaseIVFAB<Real>& data = (*a_data[lvl])[din];
312 
313  auto irregularKernel = [&](const VolIndex& vof) -> void {
314  const IntVect iv = vof.gridIndex();
315 
316  if (validCells(iv)) {
317  dataSum += data(vof, a_comp) * ebisbox.bndryArea(vof) * dxArea;
318  }
319  };
320 
321  VoFIterator& vofit = (*m_amr->getVofIterator(m_realm, m_phase)[lvl])[din];
322 
323  BoxLoops::loop(vofit, irregularKernel);
324  }
325  }
326 
327  return ParallelOps::sum(dataSum);
328 }
329 
330 template <int N>
331 int
333 {
334  CH_TIME("SurfaceODESolver::getStep");
335  if (m_verbosity > 5) {
336  pout() << m_name + "::getStep" << endl;
337  }
338 
339  return m_step;
340 }
341 
342 template <int N>
343 Real
345 {
346  CH_TIME("SurfaceODESolver::getTime");
347  if (m_verbosity > 5) {
348  pout() << m_name + "::getTime" << endl;
349  }
350 
351  return m_time;
352 }
353 
354 template <int N>
355 Real
357 {
358  CH_TIME("SurfaceODESolver::getDt");
359  if (m_verbosity > 5) {
360  pout() << m_name + "::getDt" << endl;
361  }
362 
363  return m_dt;
364 }
365 
366 template <int N>
367 void
369 {
370  CH_TIME("SurfaceODESolver::setPhi(Real)");
371  if (m_verbosity > 5) {
372  pout() << m_name + "::setPhi(Real)" << endl;
373  }
374 
375  DataOps::setValue(m_phi, a_phi);
376 }
377 
378 template <int N>
379 void
380 SurfaceODESolver<N>::setPhi(const std::array<Real, N>& a_phi)
381 {
382  CH_TIME("SurfaceODESolver::setPhi(std::array<Real, N>)");
383  if (m_verbosity > 5) {
384  pout() << m_name + "::setPhi(std::array<Real, N>)" << endl;
385  }
386 
387  for (int i = 0; i < N; i++) {
388  DataOps::setValue(m_phi, a_phi[i]);
389  }
390 }
391 
392 template <int N>
393 void
395 {
396  CH_TIME("SurfaceODESolver::setPhi(EBAMRIVData)");
397  if (m_verbosity > 5) {
398  pout() << m_name + "::setPhi(EBAMRIVData)" << endl;
399  }
400 
401  DataOps::copy(m_phi, a_phi);
402 }
403 
404 template <int N>
407 {
408  CH_TIME("SurfaceODESolver::getPhi");
409  if (m_verbosity > 5) {
410  pout() << m_name + "::getPhi" << endl;
411  }
412 
413  return m_phi;
414 }
415 
416 template <int N>
417 const EBAMRIVData&
419 {
420  CH_TIME("SurfaceODESolver::getPhi");
421  if (m_verbosity > 5) {
422  pout() << m_name + "::getPhi" << endl;
423  }
424 
425  return m_phi;
426 }
427 
428 template <int N>
429 void
431 {
432  CH_TIME("SurfaceODESolver::setRHS(Real)");
433  if (m_verbosity > 5) {
434  pout() << m_name + "::setRHS(Real)" << endl;
435  }
436 
437  DataOps::setValue(m_rhs, a_rhs);
438 }
439 
440 template <int N>
441 void
442 SurfaceODESolver<N>::setRHS(const std::array<Real, N>& a_rhs)
443 {
444  CH_TIME("SurfaceODESolver::setRHS(std::array<Real, N>)");
445  if (m_verbosity > 5) {
446  pout() << m_name + "::setRHS(std::array<Real, N>)" << endl;
447  }
448 
449  for (int i = 0; i < N; i++) {
450  DataOps::setValue(m_rhs, a_rhs[i]);
451  }
452 }
453 
454 template <int N>
455 void
457 {
458  CH_TIME("SurfaceODESolver::setRHS(EBAMRIVData)");
459  if (m_verbosity > 5) {
460  pout() << m_name + "::setRHS(EBAMRIVData)" << endl;
461  }
462 
463  DataOps::copy(m_rhs, a_rhs);
464 }
465 
466 template <int N>
469 {
470  CH_TIME("SurfaceODESolver::getRHS");
471  if (m_verbosity > 5) {
472  pout() << m_name + "::getRHS" << endl;
473  }
474 
475  return m_rhs;
476 }
477 
478 template <int N>
479 const EBAMRIVData&
481 {
482  CH_TIME("SurfaceODESolver::getRHS");
483  if (m_verbosity > 5) {
484  pout() << m_name + "::getRHS" << endl;
485  }
486 
487  return m_rhs;
488 }
489 
490 template <int N>
491 void
493 {
494  CH_TIME("SurfaceODESolver::allocate");
495  if (m_verbosity > 5) {
496  pout() << m_name + "::allocate" << endl;
497  }
498 
499  CH_assert(!(m_amr.isNull()));
500 
501  m_amr->allocate(m_phi, m_realm, m_phase, N);
502  m_amr->allocate(m_rhs, m_realm, m_phase, N);
503 
504  this->defineVoFIterators();
505 }
506 
507 template <int N>
508 void
510 {
511  CH_TIME("SurfaceODESolver::deallocate");
512  if (m_verbosity > 5) {
513  pout() << m_name + "::deallocate" << endl;
514  }
515 
516  m_phi.clear();
517  m_rhs.clear();
518 }
519 
520 template <int N>
521 void
523 {
524  CH_TIME("SurfaceODESolver::defineVoFIterators");
525  if (m_verbosity > 5) {
526  pout() << m_name + "::defineVoFIterators" << endl;
527  }
528 
529  using LDVoFs = LayoutData<VoFIterator>;
530 
531  CH_assert(!(m_amr.isNull()));
532 
533  const int finestLevel = m_amr->getFinestLevel();
534 
535  m_dielectricVoFs.resize(1 + finestLevel);
536  m_electrodeVoFs.resize(1 + finestLevel);
537 
538  for (int lvl = 0; lvl <= finestLevel; lvl++) {
539  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
540  const DataIterator& dit = dbl.dataIterator();
541  const EBISLayout& ebisl = m_amr->getEBISLayout(m_realm, m_phase)[lvl];
542  const MFLevelGrid& mflg = *m_amr->getMFLevelGrid(m_realm)[lvl];
543 
544  m_dielectricVoFs[lvl] = RefCountedPtr<LDVoFs>(new LDVoFs(dbl));
545  m_electrodeVoFs[lvl] = RefCountedPtr<LDVoFs>(new LDVoFs(dbl));
546 
547  const int nbox = dit.size();
548 
549 #pragma omp parallel for schedule(runtime)
550  for (int mybox = 0; mybox < nbox; mybox++) {
551  const DataIndex& din = dit[mybox];
552 
553  const Box& cellBox = dbl[din];
554  const EBISBox& ebisBox = ebisl[din];
555  const EBGraph& ebGraph = ebisBox.getEBGraph();
556 
557  VoFIterator& dielectricVoFIt = (*m_dielectricVoFs[lvl])[din];
558  VoFIterator& electrodeVoFIt = (*m_electrodeVoFs[lvl])[din];
559 
560  IntVectSet dielectricIVS = mflg.interfaceRegion(cellBox, din);
561  IntVectSet electrodeIVS = ebisBox.getIrregIVS(cellBox) - dielectricIVS;
562 
563  dielectricVoFIt.define(dielectricIVS, ebGraph);
564  electrodeVoFIt.define(electrodeIVS, ebGraph);
565  }
566  }
567 }
568 
569 template <int N>
570 void
572 {
573  CH_TIME("SurfaceODESolver::registerOperators");
574  if (m_verbosity > 5) {
575  pout() << m_name + "::registerOperators" << endl;
576  }
577 
578  CH_assert(!(m_amr.isNull()));
579 
580  m_amr->registerOperator(s_eb_coar_ave, m_realm, m_phase);
581 }
582 
583 template <int N>
584 void
585 SurfaceODESolver<N>::preRegrid(const int a_lbase, const int a_oldFinestLevel) noexcept
586 {
587  CH_TIME("SurfaceODESolver::registerOperators");
588  if (m_verbosity > 5) {
589  pout() << m_name + "::registerOperators" << endl;
590  }
591 
592  CH_assert(!(m_amr.isNull()));
593 
594  m_amr->allocate(m_cache, m_realm, m_phase, N);
595 
596  DataOps::copy(m_cache, m_phi);
597 
598  m_phi.clear();
599 }
600 
601 template <int N>
602 void
603 SurfaceODESolver<N>::regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) noexcept
604 {
605  CH_TIME("SurfaceODESolver::regrid");
606  if (m_verbosity > 5) {
607  pout() << m_name + "::registerOperators" << endl;
608  }
609 
610  this->allocate();
611 
612  const EBCoarseToFineInterp::Type interpType = m_conservativeRegrid ? EBCoarseToFineInterp::Type::ConservativePWC
613  : EBCoarseToFineInterp::Type::PWC;
614 
615  m_amr->interpToNewGrids(m_phi, m_cache, m_phase, a_lmin, a_oldFinestLevel, a_newFinestLevel, interpType);
616 
617  m_cache.clear();
618 }
619 
620 template <int N>
621 void
622 SurfaceODESolver<N>::resetElectrodes(const Real a_value) noexcept
623 {
624  CH_TIME("SurfaceODESolver::resetElectrodes");
625  if (m_verbosity > 5) {
626  pout() << m_name + "::resetElectrodes" << endl;
627  }
628 
629  this->resetElectrodes(m_phi, a_value);
630 }
631 
632 template <int N>
633 void
634 SurfaceODESolver<N>::resetElectrodes(EBAMRIVData& a_phi, const Real a_value) const noexcept
635 {
636  CH_TIME("SurfaceODESolver::resetElectrodes(EBAMRIVData)");
637  if (m_verbosity > 5) {
638  pout() << m_name + "::resetElectrodes(EBAMRIVData)" << endl;
639  }
640 
641  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
642  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
643  const DataIterator& dit = dbl.dataIterator();
644 
645  const int nbox = dit.size();
646 
647 #pragma omp parallel for schedule(runtime)
648  for (int mybox = 0; mybox < nbox; mybox++) {
649  const DataIndex& din = dit[mybox];
650 
651  BaseIVFAB<Real>& phi = (*a_phi[lvl])[din];
652  VoFIterator& vofit = (*m_electrodeVoFs[lvl])[din];
653 
654  auto kernel = [&](const VolIndex& vof) -> void {
655  for (int comp = 0; comp < N; comp++) {
656  phi(vof, comp) = a_value;
657  }
658  };
659 
660  BoxLoops::loop(vofit, kernel);
661  }
662  }
663 }
664 
665 template <int N>
666 void
667 SurfaceODESolver<N>::resetDielectrics(const Real a_value) noexcept
668 {
669  CH_TIME("SurfaceODESolver::resetDielectrics");
670  if (m_verbosity > 5) {
671  pout() << m_name + "::resetDielectrics" << endl;
672  }
673 
674  this->resetDielectrics(m_phi, a_value);
675 }
676 
677 template <int N>
678 void
679 SurfaceODESolver<N>::resetDielectrics(EBAMRIVData& a_phi, const Real a_value) const noexcept
680 {
681  CH_TIME("SurfaceODESolver::resetDielectrics(EBAMRIVData)");
682  if (m_verbosity > 5) {
683  pout() << m_name + "::resetDielectrics(EBAMRIVData)" << endl;
684  }
685 
686  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
687  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
688  const DataIterator& dit = dbl.dataIterator();
689 
690  const int nbox = dit.size();
691 
692 #pragma omp parallel for schedule(runtime)
693  for (int mybox = 0; mybox < nbox; mybox++) {
694  const DataIndex& din = dit[mybox];
695 
696  BaseIVFAB<Real>& phi = (*a_phi[lvl])[din];
697  VoFIterator& vofit = (*m_dielectricVoFs[lvl])[din];
698 
699  auto kernel = [&](const VolIndex& vof) -> void {
700  for (int comp = 0; comp < N; comp++) {
701  phi(vof, comp) = a_value;
702  }
703  };
704 
705  BoxLoops::loop(vofit, kernel);
706  }
707  }
708 }
709 
710 #ifdef CH_USE_HDF5
711 template <int N>
712 void
713 SurfaceODESolver<N>::writeCheckpointLevel(HDF5Handle& a_handle, const int a_level) const noexcept
714 {
715  CH_TIME("SurfaceODESolver::writeCheckpointLevel");
716  if (m_verbosity > 5) {
717  pout() << m_name + "::writeCheckpointLevel" << endl;
718  }
719 
720  const std::string id = "SurfaceODESolver::" + m_name + "::phi";
721 
722  CH_assert(!(m_amr.isNull()));
723 
724  // HDF5 doesn't like irregular data so we copy the data onto an EBCellFAB, which also has storage for multi-cells
725  EBAMRCellData scratch;
726 
727  m_amr->allocate(scratch, m_realm, m_phase, N);
728 
729  DataOps::setValue(*scratch[a_level], 0.0);
730  DataOps::incr(*scratch[a_level], *m_phi[a_level], 1.0);
731 
732  write(a_handle, *scratch[a_level], id);
733 }
734 #endif
735 
736 #ifdef CH_USE_HDF5
737 
738 template <int N>
739 void
740 SurfaceODESolver<N>::readCheckpointLevel(HDF5Handle& a_handle, const int a_level) noexcept
741 {
742  CH_TIME("SurfaceODESolver::readCheckpointLevel");
743  if (m_verbosity > 5) {
744  pout() << m_name + "::readCheckpointLevel" << endl;
745  }
746 
747  const std::string id = "SurfaceODESolver::" + m_name + "::phi";
748 
749  CH_assert(!(m_amr.isNull()));
750 
751  // HDF5 doesn't like irregular data so we wrote the data onto an EBCellFAB, which also has storage for multi-cells. We
752  // also need to read from that...
753  EBAMRCellData scratch;
754 
755  m_amr->allocate(scratch, m_realm, m_phase, N);
756 
757  read<EBCellFAB>(a_handle, *scratch[a_level], id, m_amr->getGrids(m_realm)[a_level], Interval(0, N - 1), false);
758 
759  DataOps::setValue(*m_phi[a_level], 0.0);
760  DataOps::incr(*m_phi[a_level], *scratch[a_level], 1.0);
761 }
762 #endif
763 
764 template <int N>
765 void
767 {
768  CH_TIME("SurfaceODESolver::writePlotFile");
769  if (m_verbosity > 5) {
770  pout() << m_name + "::writePlotFile" << endl;
771  }
772 
773  const int numPlotVars = this->getNumberOfPlotVariables();
774 
775  if (numPlotVars > 0) {
776  const Vector<std::string> plotVarNames = this->getPlotVariableNames();
777 
778  CH_assert(plotVarNames.size() == numPlotVars);
779  CH_assert(!(m_amr.isNull()));
780 
781  EBAMRCellData output;
782  m_amr->allocate(output, m_realm, m_phase, numPlotVars);
783 
784  for (int lvl = 0; lvl <= m_amr->getFinestLevel(); lvl++) {
785  int icomp = 0;
786  this->writePlotData(*output[lvl], icomp, m_realm, lvl);
787  }
788 
789  // Filename
790  char filename[100];
791  sprintf(filename, "%s.step%07d.%dd.hdf5", m_name.c_str(), m_step, SpaceDim);
792  std::string fname(filename);
793 
794  // Alias, becuase Chombo is a bit anal about smart pointers.
795  Vector<LevelData<EBCellFAB>*> outputPtr;
796  m_amr->alias(outputPtr, output);
797 
798 #ifdef CH_USE_HDF5
799  constexpr int numPlotGhost = 0;
800 
801  DischargeIO::writeEBHDF5(fname,
802  plotVarNames,
803  m_amr->getGrids(m_realm),
804  outputPtr,
805  m_amr->getDomains(),
806  m_amr->getDx(),
807  m_amr->getRefinementRatios(),
808  m_dt,
809  m_time,
810  m_amr->getProbLo(),
811  m_amr->getFinestLevel() + 1,
812  numPlotGhost);
813 #endif
814  }
815 }
816 
817 template <int N>
818 void
819 SurfaceODESolver<N>::writePlotData(LevelData<EBCellFAB>& a_output,
820  int& a_comp,
821  const std::string a_outputRealm,
822  const int a_level) const noexcept
823 {
824  CH_TIME("SurfaceODESolver::writePlotData");
825  if (m_verbosity > 5) {
826  pout() << m_name + "::writePlotData" << endl;
827  }
828 
829  CH_assert(a_level >= 0);
830  CH_assert(a_level <= m_amr->getFinestLevel());
831 
832  // HDF5 doesn't do irregular data the way we want so we copy into EBCellFABs and
833  // use that as output.
834  LevelData<EBCellFAB> scratch;
835  m_amr->allocate(scratch, m_realm, m_phase, a_level, N);
836 
837  // Copy m_phi to a_output
838  if (m_plotPhi) {
839  DataOps::setValue(scratch, 0.0);
840  DataOps::incr(scratch, *m_phi[a_level], 1.0);
841 
842  const Interval srcInterv(0, N - 1);
843  const Interval dstInterv(a_comp, a_comp + N - 1);
844 
845  m_amr->copyData(a_output, scratch, a_level, a_outputRealm, m_realm, dstInterv, srcInterv);
846 
847  a_output.exchange(dstInterv);
848 
849  a_comp += N;
850  }
851 
852  // Copy m_rhs to a_output
853  if (m_plotRHS) {
854  DataOps::setValue(scratch, 0.0);
855  DataOps::incr(scratch, *m_rhs[a_level], 1.0);
856 
857  const Interval srcInterv(0, N - 1);
858  const Interval dstInterv(a_comp, a_comp + N - 1);
859 
860  m_amr->copyData(a_output, scratch, a_level, a_outputRealm, m_realm, dstInterv, srcInterv);
861 
862  a_output.exchange(dstInterv);
863 
864  a_comp += N;
865  }
866 }
867 
868 template <int N>
869 int
871 {
872  CH_TIME("SurfaceODESolver::getNumberOfPlotVariables");
873  if (m_verbosity > 5) {
874  pout() << m_name + "::getNumberOfPlotVariables" << endl;
875  }
876 
877  int num = 0;
878 
879  if (m_plotPhi) {
880  num += N;
881  }
882 
883  if (m_plotRHS) {
884  num += N;
885  }
886 
887  return num;
888 }
889 
890 template <int N>
891 Vector<std::string>
893 {
894  CH_TIME("SurfaceODESolver::getPlotVariableNames");
895  if (m_verbosity > 5) {
896  pout() << m_name + "::getPlotVariablesNames" << endl;
897  }
898 
899  Vector<std::string> plotVarNames;
900 
901  if (m_plotPhi) {
902  for (int i = 0; i < N; i++) {
903  if (N > 1) {
904  plotVarNames.push_back(m_name + " phi-" + std::to_string(i));
905  }
906  else {
907  plotVarNames.push_back(m_name + " phi");
908  }
909  }
910  }
911 
912  if (m_plotRHS) {
913  for (int i = 0; i < N; i++) {
914  if (N > 1) {
915  plotVarNames.push_back(m_name + " rhs-" + std::to_string(i));
916  }
917  else {
918  plotVarNames.push_back(m_name + " rhs");
919  }
920  }
921  }
922 
923  return plotVarNames;
924 }
925 
926 #include <CD_NamespaceFooter.H>
927 
928 #endif
Silly, but useful functions that override standard Chombo HDF5 IO.
Declaration of a cut-cell ODE solver.
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 incr(MFAMRCellData &a_lhs, const MFAMRCellData &a_rhs, const Real a_scale) noexcept
Function which increments data in the form a_lhs = a_lhs + a_rhs*a_scale for all components.
Definition: CD_DataOps.cpp:787
static void copy(MFAMRCellData &a_dst, const MFAMRCellData &a_src)
Copy data from one data holder to another.
Definition: CD_DataOps.cpp:1118
Type
Type of interpolation methods supported. PWC = Piecewise constant, ignoring the embedded boundary....
Definition: CD_EBCoarseToFineInterp.H:42
Wrapper class for holding multifluid EBLevelGrids.
Definition: CD_MFLevelGrid.H:29
virtual IntVectSet interfaceRegion(const Box &a_box, const DataIndex &a_dit, const int a_phase1=0, const int a_phase2=1) const
Get interface region between two phases.
Definition: CD_MFLevelGrid.cpp:98
static const std::string Primal
Identifier for perimal realm.
Definition: CD_Realm.H:47
Surface ODE solver.
Definition: CD_SurfaceODESolver.H:28
virtual void setName(const std::string a_name) noexcept
Set the solver name.
Definition: CD_SurfaceODESolverImplem.H:187
virtual int getVerbosity() const noexcept
Get verbosity.
Definition: CD_SurfaceODESolverImplem.H:247
virtual EBAMRIVData & getRHS()
Get internal state.
Definition: CD_SurfaceODESolverImplem.H:468
void parseVerbosity() noexcept
Parse verbosity.
Definition: CD_SurfaceODESolverImplem.H:90
virtual EBAMRIVData & getPhi() noexcept
Get internal state.
Definition: CD_SurfaceODESolverImplem.H:406
virtual void setRHS(const Real a_rhs)
Convenience function for setting m_rhs.
Definition: CD_SurfaceODESolverImplem.H:430
virtual phase::which_phase getPhase() const noexcept
Get phase.
Definition: CD_SurfaceODESolverImplem.H:223
virtual void setRealm(const std::string a_realm) noexcept
Set the realm.
Definition: CD_SurfaceODESolverImplem.H:175
std::string m_name
Solver name.
Definition: CD_SurfaceODESolver.H:405
virtual void resetElectrodes(const Real a_value) noexcept
Reset m_phi on electrode cells.
Definition: CD_SurfaceODESolverImplem.H:622
virtual int getStep() const noexcept
Get current time step.
Definition: CD_SurfaceODESolverImplem.H:332
virtual void parseOptions() noexcept
Parse solver options.
Definition: CD_SurfaceODESolverImplem.H:62
void parsePlotVariables() noexcept
Parse plot variables.
Definition: CD_SurfaceODESolverImplem.H:130
virtual void setPhase(const phase::which_phase a_phase) noexcept
Set phase.
Definition: CD_SurfaceODESolverImplem.H:211
virtual void setAmr(const RefCountedPtr< AmrMesh > &a_amrMesh) noexcept
Set the amr object.
Definition: CD_SurfaceODESolverImplem.H:161
SurfaceODESolver()
Default constructor. Must subsequently set AmrMesh.
Definition: CD_SurfaceODESolverImplem.H:25
void parseRegrid() noexcept
Parse regrid method.
Definition: CD_SurfaceODESolverImplem.H:104
virtual void allocate() noexcept
Allocate internal storage for this class.
Definition: CD_SurfaceODESolverImplem.H:492
virtual Real getDt() const noexcept
Get last time step.
Definition: CD_SurfaceODESolverImplem.H:356
std::string getRealm() const noexcept
Get the realm where the solver is registered.
Definition: CD_SurfaceODESolverImplem.H:199
RefCountedPtr< AmrMesh > m_amr
AMR; needed for grid stuff.
Definition: CD_SurfaceODESolver.H:435
virtual void preRegrid(const int a_lbase, const int a_oldFinestLevel) noexcept
Pre-regrid function.
Definition: CD_SurfaceODESolverImplem.H:585
virtual ~SurfaceODESolver()
Destructor (does nothing).
Definition: CD_SurfaceODESolverImplem.H:52
virtual Real getTime() const noexcept
Get current time.
Definition: CD_SurfaceODESolverImplem.H:344
virtual void setVerbosity(const int a_verbosity) noexcept
Set verbosity.
Definition: CD_SurfaceODESolverImplem.H:235
virtual void writePlotData(LevelData< EBCellFAB > &a_output, int &a_comp, const std::string a_outputRealm, const int a_level) const noexcept
Write output data to a_output.
Definition: CD_SurfaceODESolverImplem.H:819
virtual void setPhi(const Real a_phi)
Convenience function for setting m_phi.
Definition: CD_SurfaceODESolverImplem.H:368
virtual Real computeMass(const int a_comp=0) const noexcept
Compute the total mass for component a_comp in m_phi.
Definition: CD_SurfaceODESolverImplem.H:273
virtual Vector< std::string > getPlotVariableNames() const noexcept
Get output plot names.
Definition: CD_SurfaceODESolverImplem.H:892
virtual void regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) noexcept
Regrid function.
Definition: CD_SurfaceODESolverImplem.H:603
virtual void registerOperators() noexcept
Register operators.
Definition: CD_SurfaceODESolverImplem.H:571
int m_verbosity
Solver verbosity.
Definition: CD_SurfaceODESolver.H:466
virtual void deallocate() noexcept
Deallocate internal storage.
Definition: CD_SurfaceODESolverImplem.H:509
virtual void parseRuntimeOptions() noexcept
Parse runtime solver options.
Definition: CD_SurfaceODESolverImplem.H:76
virtual void writePlotFile() const noexcept
Write a plot file.
Definition: CD_SurfaceODESolverImplem.H:766
virtual void setTime(const int a_step, const Real a_time, const Real a_dt) noexcept
Set the time.
Definition: CD_SurfaceODESolverImplem.H:259
void defineVoFIterators() noexcept
Define iterators for iterating over cell subsets.
Definition: CD_SurfaceODESolverImplem.H:522
virtual int getNumberOfPlotVariables() const noexcept
Get number of variables to be plotted.
Definition: CD_SurfaceODESolverImplem.H:870
virtual void resetDielectrics(const Real a_value) noexcept
Reset m_phi on dielectric cells.
Definition: CD_SurfaceODESolverImplem.H:667
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
Real sum(const Real &a_value) noexcept
Compute the sum across all MPI ranks.
Definition: CD_ParallelOpsImplem.H:353