chombo-discharge
Loading...
Searching...
No Matches
CD_FieldStepperImplem.H
Go to the documentation of this file.
1/* chombo-discharge
2 * Copyright © 2021 SINTEF Energy Research.
3 * Please refer to Copyright.txt and LICENSE in the chombo-discharge root directory.
4 */
5
12#ifndef CD_FieldStepperImplem_H
13#define CD_FieldStepperImplem_H
14
15// Std includes
16#include <math.h>
17
18// Chombo includes
19#include <CH_Timer.H>
20#include <ParmParse.H>
21
22// Our includes
23#include <CD_FieldStepper.H>
24#include <CD_DataOps.H>
25#include <CD_NamespaceHeader.H>
26
27namespace Physics {
28 namespace Electrostatics {
29
30 template <class T>
32 {
33 CH_TIME("FieldStepper::FieldStepper");
34
35 m_verbosity = -1;
36
37 ParmParse pp("FieldStepper");
38
39 Real rho0 = 0.0;
40 Real sigma0 = 0.0;
41 Real blobRadius = 1.0;
43
46
47 // Read in parameters
48 pp.get("init_rho", rho0);
49 pp.get("init_sigma", sigma0);
50 pp.get("rho_radius", blobRadius);
51 pp.get("load_balance", m_loadBalance);
52 pp.get("box_sorting", str);
53 pp.get("realm", m_realm);
54 pp.get("verbosity", m_verbosity);
55 pp.getarr("rho_center", vec, 0, SpaceDim);
56
57 blobCenter = RealVect(D_DECL(vec[0], vec[1], vec[2]));
58
59 m_rhoGas = [a = rho0, c = blobCenter, r = blobRadius](const RealVect x) -> Real {
60 const Real d = (x - c).dotProduct(x - c);
61 return a * exp(-d / (2 * r * r));
62 };
63
64 m_rhoDielectric = m_rhoGas;
65 m_surfaceChargeDensity = [s = sigma0](const RealVect& x) -> Real {
66 return s;
67 };
68
69 if (str == "none") {
70 m_boxSort = BoxSorting::None;
71 }
72 if (str == "std") {
73 m_boxSort = BoxSorting::Std;
74 }
75 else if (str == "shuffle") {
76 m_boxSort = BoxSorting::Shuffle;
77 }
78 else if (str == "morton") {
79 m_boxSort = BoxSorting::Morton;
80 }
81 else if (str == "hilbert") {
82 m_boxSort = BoxSorting::Hilbert;
83 }
84 else {
85 MayDay::Error("FieldStepper::FieldStepper - unknown box sorting method requested for argument 'BoxSorting'");
86 }
87 }
88
89 template <class T>
91 {
92 CH_TIME("FieldStepper::~FieldStepper");
93 }
94
95 template <class T>
96 void
98 {
99 CH_TIME("FieldStepper::setupSolvers");
100 if (m_verbosity > 5) {
101 pout() << "FieldStepper<T>::setupSolvers" << endl;
102 }
103
104 // Define a voltage function to be used in the simulation.
105 auto voltage = [](const Real a_time) -> Real {
106 return 1.0;
107 };
108
109 // Instantiate the FieldSolver and set it up.
110 m_fieldSolver = RefCountedPtr<FieldSolver>(new T());
111 m_fieldSolver->parseOptions();
112 m_fieldSolver->setAmr(m_amr);
113 m_fieldSolver->setComputationalGeometry(m_computationalGeometry);
114 m_fieldSolver->setVoltage(voltage);
115 m_fieldSolver->setRealm(m_realm);
116 m_fieldSolver->setTime(0, 0.0, 0.0);
117 m_fieldSolver->setVerbosity(m_verbosity);
118
119 // Instantiate the surface charge solver and set it up.
121 m_sigma->setPhase(phase::gas);
122 m_sigma->setRealm(m_realm);
123 m_sigma->setName("Surface charge");
124 m_sigma->parseOptions();
125 m_sigma->setTime(0, 0.0, 0.0);
126 m_sigma->setVerbosity(m_verbosity);
127 }
128
129 template <class T>
130 void
132 {
133 CH_TIME("FieldStepper::registerOperators");
134 if (m_verbosity > 5) {
135 pout() << "FieldStepper<T>::registerOperators" << endl;
136 }
137
138 m_fieldSolver->registerOperators();
139 m_sigma->registerOperators();
140 }
141
142 template <class T>
143 void
145 {
146 CH_TIME("FieldStepper::registerRealms");
147 if (m_verbosity > 5) {
148 pout() << "FieldStepper<T>::registerRealms" << endl;
149 }
150
151 m_amr->registerRealm(m_realm);
152 }
153
154 template <class T>
155 void
157 {
158 CH_TIME("FieldStepper::allocate");
159 if (m_verbosity > 5) {
160 pout() << "FieldStepper<T>::allocate" << endl;
161 }
162
163 m_fieldSolver->allocate();
164 m_sigma->allocate();
165 }
166
167 template <class T>
170 {
171 CH_TIME("FieldStepper::getPotential");
172 if (m_verbosity > 5) {
173 pout() << "FieldStepper<T>::getPotential" << endl;
174 }
175
176 return m_fieldSolver->getPotential();
177 }
178
179 template <class T>
180 void
182 {
183 CH_TIME("FieldStepper::initialData");
184 if (m_verbosity > 5) {
185 pout() << "FieldStepper<T>::initialData" << endl;
186 }
187 }
188
189 template <class T>
190 void
192 {
193 CH_TIME("FieldStepper::solvePoisson");
194 if (m_verbosity > 5) {
195 pout() << "FieldStepper<T>::solvePoisson" << endl;
196 }
197
198 // Solve using rho from fieldsolver and sigma from SurfaceODESolver.
199 MFAMRCellData& phi = m_fieldSolver->getPotential();
200 MFAMRCellData& rho = m_fieldSolver->getRho();
201 EBAMRIVData& sigma = m_sigma->getPhi();
202
203 // Solve and issue error message if we did not converge.
204 const bool converged = m_fieldSolver->solve(phi, rho, sigma);
205
206 if (!converged) {
207 MayDay::Warning("FieldStepper<T>::solvePoisson - did not converge");
208 }
209
210 // Compute the electric field.
211 m_fieldSolver->computeElectricField();
212 }
213
214 template <class T>
215 void
217 {
218 CH_TIME("FieldStepper::postInitialize");
219 if (m_verbosity > 5) {
220 pout() << "FieldStepper<T>::postInitialize" << endl;
221 }
222
223 // Fetch the potential and surface/space charges and initialize them. The potential is set to zero
224 // and the space/surface charge set from m_rhoGas, m_rhoDielectric, and m_surfaceChargeDensity
225 MFAMRCellData& state = m_fieldSolver->getPotential();
226 EBAMRIVData& sigma = m_sigma->getPhi();
227
229 DataOps::setValue(sigma, m_surfaceChargeDensity, m_amr->getProbLo(), m_amr->getDx(), 0);
230 m_sigma->resetElectrodes(sigma, 0.0);
231 m_fieldSolver->setRho(m_rhoGas);
232
233 // Solve Poisson equation.
234 this->solvePoisson();
235 }
236
237 template <class T>
238 Real
240 {
241 CH_TIME("FieldStepper::advance");
242 if (m_verbosity > 5) {
243 pout() << "FieldStepper<T>::advance" << endl;
244 }
245
246 MayDay::Error("FieldStepper<T>::advance - callling this is an error. Please set Driver.max_steps = 0");
247
248 return std::numeric_limits<Real>::max();
249 }
250
251#ifdef CH_USE_HDF5
252 template <class T>
253 void
255 {
256 CH_TIME("FieldStepper::writeCheckpointData");
257 if (m_verbosity > 5) {
258 pout() << "FieldStepper<T>::writeCheckpointData" << endl;
259 }
260 }
261#endif
262
263#ifdef CH_USE_HDF5
264 template <class T>
265 void
266 FieldStepper<T>::readCheckpointData(HDF5Handle& a_handle, const int a_lvl)
267 {
268 CH_TIME("FieldStepper::readCheckpointData");
269 if (m_verbosity > 5) {
270 pout() << "FieldStepper<T>::readCheckpointData" << endl;
271 }
272
273 MayDay::Error("FieldStepper<T>::readCheckpointData - checkpointing not supported for this module");
274 }
275#endif
276
277 template <class T>
278 int
280 {
281 CH_TIME("FieldStepper::getNumberOfPlotVariables");
282 if (m_verbosity > 5) {
283 pout() << "FieldStepper<T>::getNumberOfPlotVariables" << endl;
284 }
285
286 int ncomp = 0;
287
288 ncomp += m_fieldSolver->getNumberOfPlotVariables();
289 ncomp += m_sigma->getNumberOfPlotVariables();
290
291 return ncomp;
292 }
293
294 template <class T>
297 {
298 CH_TIME("FieldStepper::getPlotVariableNames");
299 if (m_verbosity > 5) {
300 pout() << "FieldStepper<T>::getPlotVariableNames" << endl;
301 }
302
304
305 plotVars.append(m_fieldSolver->getPlotVariableNames());
306 plotVars.append(m_sigma->getPlotVariableNames());
307
308 return plotVars;
309 }
310
311 template <class T>
312 void
314 int& a_icomp,
316 const int a_level) const
317 {
318 CH_TIME("FieldStepper::writePlotData");
319 if (m_verbosity > 5) {
320 pout() << "FieldStepper<T>::writePlotData" << endl;
321 }
322
323 CH_assert(a_level >= 0);
324 CH_assert(a_level <= m_amr->getFinestLevel());
325
326 // Write into plot data holder memory.
327 m_fieldSolver->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
328 m_sigma->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
329 }
330
331 template <class T>
332 void
334 {
335 CH_TIME("FieldStepper::synchronizeSolverTimes");
336 if (m_verbosity > 5) {
337 pout() << "FieldStepper<T>::synchronizeSolverTimes" << endl;
338 }
339
340 m_timeStep = a_step;
341 m_time = a_time;
342 m_dt = a_dt;
343
344 m_fieldSolver->setTime(a_step, a_time, a_dt);
345 }
346
347 template <class T>
348 void
350 {
351 CH_TIME("FieldStepper::preRegrid");
352 if (m_verbosity > 5) {
353 pout() << "FieldStepper<T>::preRegrid" << endl;
354 }
355
356 m_fieldSolver->preRegrid(a_lbase, a_oldFinestLevel);
358 }
359
360 template <class T>
361 void
363 {
364 CH_TIME("FieldStepper::regrid");
365 if (m_verbosity > 5) {
366 pout() << "FieldStepper<T>::regrid" << endl;
367 }
368
369 // TLDR: The FieldSolver regrid methods just regrids the data -- it does not re-solve the Poisson equation. Here,
370 // that is done in postRegrid.
371
374 }
375
376 template <class T>
377 void
379 {
380 CH_TIME("FieldStepper::postRegrid");
381 if (m_verbosity > 5) {
382 pout() << "FieldStepper<T>::postRegrid" << endl;
383 }
384
385 this->solvePoisson();
386 }
387
388 template <class T>
389 bool
391 {
392 CH_TIME("FieldStepper::loadBalanceThisRealm");
393 if (m_verbosity > 5) {
394 pout() << "FieldStepper<T>::loadBalanceThisRealm" << endl;
395 }
396
397 return (a_realm == m_realm) && m_loadBalance;
398 }
399
400 template <class T>
401 void
404 const std::string a_realm,
406 const int a_lmin,
407 const int a_finestLevel)
408 {
409 CH_TIME("FieldStepper::loadBalanceBoxes");
410 if (m_verbosity > 5) {
411 pout() << "FieldStepper<T>::loadBalanceBoxes" << endl;
412 }
413
414 CH_assert(m_loadBalance && a_realm == m_realm);
415
416 // TLDR: This code tries to compute a load for each grid patch by applying a relaxation operator to each box. This means that the load
417 // should be a decent estimate that takes into account boundary conditions, coarse-fine interface arithmetic, and enlargened stencils
418 // near the embedded boundary.
419
420 a_procs.resize(1 + a_finestLevel);
421 a_boxes.resize(1 + a_finestLevel);
422
423 // We need to make AmrMesh restore some operators that we need in order to create a multigrid object. Fortunately, FieldSolver has routines
424 // for doing that but it will not know if AmrMesh has updated it's operators or not. So, we need to regrid them.
425 m_amr->regridOperators(a_lmin);
426
428 rankLoads.resetLoads();
429
430 // Field solver implementation gets the responsibility of computing loads on each level.
431 for (int lvl = 0; lvl <= a_finestLevel; lvl++) {
432 Vector<long long> boxLoads = m_fieldSolver->computeLoads(a_grids[lvl], lvl);
433
434 // Do the desired sorting and load balancing
435 a_boxes[lvl] = a_grids[lvl].boxArray();
436
439 }
440 }
441
442 template <class T>
443 void
445 const phase::which_phase a_phase) noexcept
446 {
447 CH_TIME("FieldStepper::setRho");
448 if (m_verbosity > 5) {
449 pout() << "FieldStepper<T>::setRho" << endl;
450 }
451
452 if (a_phase == phase::gas) {
453 m_rhoGas = a_rho;
454 }
455 else if (a_phase == phase::solid) {
456 m_rhoDielectric = a_rho;
457 }
458 }
459
460 template <class T>
461 void
463 {
464 CH_TIME("FieldStepper::setSigma");
465 if (m_verbosity > 5) {
466 pout() << "FieldStepper<T>::setSigma" << endl;
467 }
468
469 m_surfaceChargeDensity = a_sigma;
470 }
471 } // namespace Electrostatics
472} // namespace Physics
473
474#include <CD_NamespaceFooter.H>
475
476#endif
Agglomeration of useful data operations.
TimeStepper class for only solving the Poisson equation (with surface charge)
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 makeBalance(Vector< int > &a_ranks, const Vector< T > &a_loads, const Vector< Box > &a_boxes)
Load balancing, assigning ranks to boxes.
Definition CD_LoadBalancingImplem.H:35
static void sort(Vector< Vector< Box > > &a_boxes, Vector< Vector< T > > &a_loads, const BoxSorting a_whichSorting)
Sorts boxes and loads over a hierarchy according to some sorting criterion.
Definition CD_LoadBalancingImplem.H:225
Class for holding computational loads.
Definition CD_Loads.H:30
Implementation of TimeStepper for solving electrostatic problems. The template parameter is the Field...
Definition CD_FieldStepper.H:36
void setRho(const std::function< Real(const RealVect &a_pos)> &a_rho, const phase::which_phase a_phase) noexcept
Set space charge.
Definition CD_FieldStepperImplem.H:444
void writePlotData(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string a_outputRealm, const int a_level) const override
Write plot data to file.
Definition CD_FieldStepperImplem.H:313
void preRegrid(const int a_lbase, const int a_finestLevel) override
Perform pre-regrid operations.
Definition CD_FieldStepperImplem.H:349
Vector< std::string > getPlotVariableNames() const override
Get plot variable names.
Definition CD_FieldStepperImplem.H:296
void initialData() override
Set initial data – this sets the space and surface charges.
Definition CD_FieldStepperImplem.H:181
void regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) override
Regrid method – regrids the potential distribution in FieldSolver (but does not solve the Poisson equ...
Definition CD_FieldStepperImplem.H:362
void setSigma(const std::function< Real(const RealVect &a_pos)> &a_sigma) noexcept
Set surface charge.
Definition CD_FieldStepperImplem.H:462
void solvePoisson()
Internal routine for solving the Poisson equation.
Definition CD_FieldStepperImplem.H:191
void loadBalanceBoxes(Vector< Vector< int > > &a_procs, Vector< Vector< Box > > &a_boxes, const std::string a_realm, const Vector< DisjointBoxLayout > &a_grids, const int a_lmin, const int a_finestLevel) override
Load balance grid boxes for a specified realm.
Definition CD_FieldStepperImplem.H:402
void postInitialize() override
Post-initialization routine. This solves the Poisson equation.
Definition CD_FieldStepperImplem.H:216
int getNumberOfPlotVariables() const override
Get number of plot variables.
Definition CD_FieldStepperImplem.H:279
void registerRealms() override
Register simulation realms to be used for this simulation module.
Definition CD_FieldStepperImplem.H:144
void allocate() override
Allocation method – allocates memory and internal data for solvers.
Definition CD_FieldStepperImplem.H:156
void registerOperators() override
Register operators for this simulation module.
Definition CD_FieldStepperImplem.H:131
void synchronizeSolverTimes(const int a_step, const Real a_time, const Real a_dt) override
Synchronzie solver times and time steps.
Definition CD_FieldStepperImplem.H:333
virtual ~FieldStepper()
Destructor (does nothing)
Definition CD_FieldStepperImplem.H:90
void postRegrid() override
Perform post-regrid operations – this will resolve the Poisson equation.
Definition CD_FieldStepperImplem.H:378
MFAMRCellData & getPotential()
Get the potential.
Definition CD_FieldStepperImplem.H:169
FieldStepper()
Constructor – parses some input options.
Definition CD_FieldStepperImplem.H:31
bool loadBalanceThisRealm(const std::string a_realm) const override
Load balancing query for a specified realm. If this returns true for a_realm, load balancing routines...
Definition CD_FieldStepperImplem.H:390
Real advance(const Real a_dt) override
Perform a single time step with step a_dt.
Definition CD_FieldStepperImplem.H:239
void setupSolvers() override
Solver setup routine. This instantiates the FieldSolver and parses input options.
Definition CD_FieldStepperImplem.H:97
Base class for a tracer particle solver. This solver can advance particles in a pre-defined velocity ...
Definition CD_TracerParticleSolver.H:37
virtual void setRealm(const std::string &a_realm)
Set the solver realm.
Definition CD_TracerParticleSolverImplem.H:232
virtual void registerOperators() const
Register operators needed for AMR core functionality.
Definition CD_TracerParticleSolverImplem.H:176
virtual void setName(const std::string &a_name) noexcept
Set the solver name.
Definition CD_TracerParticleSolverImplem.H:208
TracerParticleSolver()
Default constructor.
Definition CD_TracerParticleSolverImplem.H:25
virtual void setTime(const int a_step, const Real a_time, const Real a_dt)
Set the time for this solver.
Definition CD_TracerParticleSolverImplem.H:256
virtual void preRegrid(const int a_lbase, const int a_oldFinestLevel)
Perform pre-regrid operations.
Definition CD_TracerParticleSolverImplem.H:306
virtual void setPhase(const phase::which_phase &a_phase)
Set the solver phase.
Definition CD_TracerParticleSolverImplem.H:244
virtual void allocate()
Allocate storage for this solver.
Definition CD_TracerParticleSolverImplem.H:194
virtual void regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel)
Regrid this solver.
Definition CD_TracerParticleSolverImplem.H:321
virtual void parseOptions()
Parse solver options.
Definition CD_TracerParticleSolverImplem.H:62
virtual int getNumberOfPlotVariables() const
Get the number of plot variables.
Definition CD_TracerParticleSolverImplem.H:460
Name containing various physics models for running chombo-discharge code.
Definition CD_AdvectionDiffusion.H:15