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