Line data Source code
1 : //
2 : // Pure abstract class for managing data structures, time integration (with substepping),
3 : // mesh refinement, and I/O.
4 : //
5 : // Native input file parameters:
6 : //
7 : // .. code-block:: make
8 : //
9 : // max_step = [maximum number of timesteps]
10 : // stop_time = [maximum simulation time]
11 : // timestep = [time step for coarsest level]
12 : //
13 : // amr.regrid_int = [number of timesteps between regridding]
14 : // amr.plot_int = [number of timesteps between dumping output]
15 : // amr.plot_file = [base name of output directory]
16 : //
17 : // amr.nsubsteps = [number of temporal substeps at each level. This can be
18 : // either a single int (which is then applied to every refinement
19 : // level) or an array of ints (equal to amr.max_level)
20 : // corresponding to the refinement for each level.]
21 : //
22 : // Inherited input file parameters (from amrex AmrMesh class):
23 : //
24 : // .. code-block:: make
25 : //
26 : // amr.v = [verbosity level]
27 : // amr.max_level = [maximum level of refinement]
28 : // amr.n_proper =
29 : // amr.grid_eff =
30 : // amr.n_error_buff =
31 : // amr.ref_ratio_vect = [refinement ratios in each direction]
32 : // amr.ref_ratio = [refinement ratio in all directions (cannot be used with ref_ratio_vect)]
33 : // amr.max_grid_x =
34 : // amr.blocking_factor =
35 : // amr.n_cell = [number of cells on coarsest level]
36 : // amr.refine_grid_layout =
37 : // amr.check_input =
38 : //
39 :
40 : #ifndef INTEGRATOR_INTEGRATOR_H
41 : #define INTEGRATOR_INTEGRATOR_H
42 :
43 : #include <chrono>
44 : #include <ctime>
45 : #include <string>
46 : #include <limits>
47 : #include <memory>
48 :
49 : #ifdef _OPENMP
50 : #include <omp.h>
51 : #endif
52 :
53 : #include <AMReX_ParallelDescriptor.H>
54 : #include <AMReX_ParmParse.H>
55 : #include <AMReX_MultiFabUtil.H>
56 : #include <AMReX_FillPatchUtil.H>
57 : #include <AMReX_BC_TYPES.H>
58 : #include <AMReX_AmrCore.H>
59 : #include <AMReX_FluxRegister.H>
60 : #include <AMReX_Utility.H>
61 : #include <AMReX_PlotFileUtil.H>
62 :
63 : #include "Set/Set.H"
64 : #include "BC/BC.H"
65 : #include "BC/Nothing.H"
66 : #include "IO/WriteMetaData.H"
67 : #include "BaseField.H"
68 :
69 : /// \brief Collection of numerical integrator objects
70 : namespace Integrator
71 : {
72 :
73 : class Integrator
74 : : public amrex::AmrCore
75 : {
76 : public:
77 :
78 : /// This is the constructor for the intetgrator class, which reads timestep information,
79 : /// simulation output and AMR, initialized time substep, and creates a new directory.
80 : Integrator();
81 :
82 : /// Virtual destructure; make sure delete any pointers that you create here.
83 : virtual ~Integrator();
84 :
85 : /// Front-end method to initialize simulation on all levels
86 : void InitData();
87 :
88 : /// Read in output from previous simulation and start simulation at that point -
89 : /// Not currently tested
90 : void Restart(std::string restartfile, bool a_node = false);
91 :
92 : /// Front-end method to start simulation
93 : void Evolve();
94 :
95 : /// Simple setter to set filename
96 : void SetFilename(std::string _plot_file) { plot_file = _plot_file; };
97 :
98 : /// Simple getter to get filename
99 : std::string GetFilename() { return plot_file; };
100 :
101 : /// This overrides an AMReX method just to allow for explicit meshing when
102 : /// desired.
103 684 : void regrid(int lbase, Set::Scalar time, bool initial = false) override
104 : {
105 684 : if (!explicitmesh.on)
106 676 : AmrCore::regrid(lbase, time, initial);
107 684 : }
108 :
109 : /// This creates a new levels that have not previously been
110 : /// used.
111 36 : void InitFromScratch(Set::Scalar time)
112 : {
113 36 : if (!explicitmesh.on) AmrCore::InitFromScratch(time);
114 : else
115 : {
116 : // Generate the coarse level mesh.
117 : {
118 7 : finest_level = 0;
119 7 : const amrex::BoxArray& ba = MakeBaseGrids();
120 7 : amrex::DistributionMapping dm(ba);
121 7 : const auto old_num_setdm = num_setdm;
122 7 : const auto old_num_setba = num_setba;
123 7 : MakeNewLevelFromScratch(0, time, ba, dm);
124 7 : if (old_num_setba == num_setba) SetBoxArray(0, ba);
125 7 : if (old_num_setdm == num_setdm) SetDistributionMap(0, dm);
126 7 : }
127 : // Generate subsequent level meshes based on user input
128 13 : for (int ilev = 0; ilev < maxLevel(); ++ilev)
129 : {
130 6 : finest_level = ilev + 1;
131 6 : amrex::BoxArray grids(explicitmesh.box[ilev]);
132 6 : ChopGrids(ilev + 1, grids, amrex::ParallelDescriptor::NProcs());
133 6 : amrex::DistributionMapping dmap(grids);
134 6 : SetBoxArray(ilev + 1, grids);
135 6 : SetDistributionMap(ilev + 1, dmap);
136 6 : MakeNewLevelFromScratch(ilev + 1, time, grids, dmap);
137 6 : }
138 :
139 : }
140 36 : }
141 :
142 : protected:
143 :
144 : /// You must override this function to inherit this class;
145 : /// this function is called before the simulation begins, and is where
146 : /// initial conditions should be applied.
147 : virtual void Initialize(int lev ///<[in] AMR Level
148 : ) = 0;
149 :
150 : /// You must override this function to inherit this class;
151 : /// Advance is called every time(sub)step, and implements the evolution of
152 : /// the system in time.
153 : virtual void Advance(int lev, ///<[in] AMR Level
154 : amrex::Real time, ///< [in] System time
155 : amrex::Real dt ///< [in] Timestep for this level
156 : ) = 0;
157 :
158 : /// You must override this function to inherit this class;
159 : /// Advance is called every time(sub)step, and implements the evolution of
160 : /// the system in time.
161 : virtual void TagCellsForRefinement(int lev, amrex::TagBoxArray& tags, amrex::Real time,
162 : int ngrow) = 0;
163 :
164 : /// This optional function is called at the beginning of every timestep, and can be used
165 : /// to complete additional global solves, e.g. a MLMG implicit solve.
166 606 : virtual void TimeStepBegin(Set::Scalar /*time*/, int /*iter*/) {};
167 :
168 : /// This optional function is called at the end of every timestep, and can be used
169 : /// to complete additional global solves, e.g. a MLMG implicit solve.
170 1032 : virtual void TimeStepComplete(Set::Scalar /*time*/, int /*iter*/) {};
171 :
172 : /// This is a function that is called by `Integrator` to update the variables registered in
173 : /// RegisterIntegratedVariable; you can override this to do your integration.
174 0 : virtual void Integrate( int /*amrlev*/,
175 : Set::Scalar /*time*/,
176 : int /*iter*/,
177 : const amrex::MFIter&/*mfi*/,
178 : const amrex::Box&/*box*/
179 : )
180 : {
181 0 : if (thermo.number > 0)
182 0 : Util::Warning(INFO, "integrated variables registered, but no integration implemented!");
183 0 : }
184 :
185 : /// An optionally overridable method to trigger behavior whenver a regrid occurs.
186 400 : virtual void Regrid(int /* amrlev */, Set::Scalar /* time */)
187 400 : {}
188 :
189 :
190 : /// Add a new cell-based scalar field.
191 : void RegisterNewFab(Set::Field<Set::Scalar>& new_fab, BC::BC<Set::Scalar>* new_bc, int ncomp, int nghost, std::string name, bool writeout,bool evolving = true,std::vector<std::string> suffix = {});
192 : /// Add a new cell-based scalar field (with additional arguments).
193 : void RegisterNewFab(Set::Field<Set::Scalar>& new_fab, int ncomp, std::string name, bool writeout,bool evolving=true, std::vector<std::string> suffix = {});
194 : /// Add a new node-based scalar field
195 : void RegisterNodalFab(Set::Field<Set::Scalar>& new_fab, int ncomp, int nghost, std::string name, bool writeout,bool evolving=true,std::vector<std::string> suffix = {});
196 : /// Add a new node-based scalar field (wtih additional arguments)
197 : void RegisterNodalFab(Set::Field<Set::Scalar>& new_fab, BC::BC<Set::Scalar>* new_bc, int ncomp, int nghost, std::string name, bool writeout,bool evolving=true, std::vector<std::string> suffix = {});
198 : template<class T>
199 : /// Add a templated nodal field
200 : void RegisterGeneralFab(Set::Field<T>& new_fab, int ncomp, int nghost, bool evolving = true);
201 : template<class T>
202 : /// Add a templated nodal field (additional arguments)
203 : void RegisterGeneralFab(Set::Field<T>& new_fab, int ncomp, int nghost, std::string a_name, bool evolving = true);
204 : template<class T>
205 : /// Add a templated nodal field (additional arguments)
206 : void RegisterGeneralFab(Set::Field<T>& new_fab, int ncomp, int nghost, bool writeout, std::string a_name, bool evolving = true);
207 :
208 : /// Add a field with arbitrary type (templated with T) and grid location (templated with d).
209 : template<class T, int d>
210 : void AddField( Set::Field<T>& new_field, BC::BC<T>* new_bc, int ncomp, int nghost,
211 : std::string, bool writeout, bool evolving, std::vector<std::string> suffix = {});
212 :
213 : /// Utility to ensure that all fields know what the finest level is
214 21208 : void SetFinestLevel(const int a_finestlevel)
215 : {
216 142402 : for (unsigned int i = 0; i < cell.fab_array.size(); i++)
217 121194 : cell.fab_array[i]->finest_level = a_finestlevel;
218 30147 : for (unsigned int i = 0; i < node.fab_array.size(); i++)
219 8939 : node.fab_array[i]->finest_level = a_finestlevel;
220 21208 : for (unsigned int i = 0; i < m_basefields_cell.size(); i++)
221 0 : m_basefields_cell[i]->SetFinestLevel(finest_level);
222 25028 : for (unsigned int i = 0; i < m_basefields.size(); i++)
223 3820 : m_basefields[i]->SetFinestLevel(finest_level);
224 21208 : }
225 :
226 : /// Register a variable to be integrated over the spatial domain using
227 : /// the Integrate function.
228 : void RegisterIntegratedVariable(Set::Scalar* integrated_variable, std::string name, bool extensive=true);
229 :
230 : /// Utility to set the coarse-grid timestep
231 : void SetTimestep(Set::Scalar _timestep);
232 :
233 : /// Utility to set the frequency (in timesteps) of plotfile dumping
234 : void SetPlotInt(int plot_int);
235 :
236 : /// Utility to set the frequency (in timesteps) of thermo data calculation
237 1 : void SetThermoInt(int a_thermo_int) { thermo.interval = a_thermo_int; }
238 : /// Utility to set the frequency (in timesteps) of thermo data writing to file
239 : void SetThermoPlotInt(int a_thermo_plot_int) { thermo.plot_int = a_thermo_plot_int; }
240 : /// Utility to set the global stop time.
241 : void SetStopTime(Set::Scalar a_stop_time) { stop_time = a_stop_time; }
242 :
243 :
244 : // Dynamic timestep adjustment
245 :
246 : struct {
247 : // user params
248 : bool on = false;
249 : int verbose = -1;
250 : int nprevious = -1;
251 : Set::Scalar cfl = NAN;
252 : Set::Scalar min = NAN;
253 : Set::Scalar max = NAN;
254 : // internal variables
255 : std::vector<Set::Scalar> dt_limit_min;
256 : std::vector<Set::Scalar> previous_timesteps;
257 : } dynamictimestep; /// Params for the dynamic timestp
258 0 : void DynamicTimestep_SyncTimeStep(int lev, Set::Scalar dt_min)
259 : {
260 0 : if (!dynamictimestep.on) return;
261 0 : if (!dynamictimestep.dt_limit_min.size())
262 : {
263 0 : dynamictimestep.dt_limit_min.resize(max_level+1,
264 0 : std::numeric_limits<Set::Scalar>::max());
265 : }
266 0 : dynamictimestep.dt_limit_min[lev] = std::min(dt_min,
267 0 : dynamictimestep.dt_limit_min[lev]);
268 :
269 0 : amrex::ParallelDescriptor::ReduceRealMin(dynamictimestep.dt_limit_min[lev]);
270 : }
271 : void DynamicTimestep_Reset()
272 : {
273 : if (!dynamictimestep.on) return;
274 : dynamictimestep.previous_timesteps.clear();
275 : }
276 44 : void DynamicTimestep_Update()
277 : {
278 44 : if (!dynamictimestep.on) return;
279 0 : if (!dynamictimestep.dt_limit_min.size()) return;
280 :
281 0 : Set::Scalar final_timestep = NAN;
282 :
283 0 : if (amrex::ParallelDescriptor::IOProcessor())
284 : {
285 0 : Set::Scalar timestep_average = this->dt[0];
286 0 : if (dynamictimestep.previous_timesteps.size() > 0)
287 : {
288 0 : timestep_average = 0.0;
289 0 : for (unsigned int d = 0; d < dynamictimestep.previous_timesteps.size(); d++)
290 0 : timestep_average += dynamictimestep.previous_timesteps[d];
291 0 : timestep_average /= dynamictimestep.previous_timesteps.size();
292 : }
293 :
294 0 : Set::Scalar new_timestep = std::numeric_limits<Set::Scalar>::max();
295 0 : for (int lev = 0; lev <= this->max_level; lev++)
296 : {
297 : //const Set::Scalar* DX = this->geom[lev].CellSize();
298 0 : Set::Scalar dt_lev = dynamictimestep.dt_limit_min[lev];
299 :
300 0 : Util::Message(INFO,"lev=",lev," ",dt_lev, " (",this->nsubsteps[lev],")");
301 :
302 0 : for (int ilev = lev; ilev > 0; ilev--) dt_lev *= (Set::Scalar)(this->nsubsteps[ilev]);
303 :
304 0 : Util::Message(INFO,"lev=",lev," --> ",dt_lev);
305 :
306 0 : new_timestep = std::min(new_timestep,dt_lev);
307 : }
308 :
309 0 : if (new_timestep < timestep_average)
310 : {
311 0 : dynamictimestep.previous_timesteps.clear();
312 :
313 0 : final_timestep = new_timestep;
314 0 : final_timestep = std::max(final_timestep,dynamictimestep.min);
315 0 : final_timestep = std::min(final_timestep,dynamictimestep.max);
316 :
317 0 : dynamictimestep.previous_timesteps.push_back(new_timestep);
318 : }
319 : else
320 : {
321 0 : final_timestep = timestep_average;
322 0 : final_timestep = std::max(final_timestep,dynamictimestep.min);
323 0 : final_timestep = std::min(final_timestep,dynamictimestep.max);
324 :
325 0 : if ((int)(dynamictimestep.previous_timesteps.size()) > dynamictimestep.nprevious)
326 0 : dynamictimestep.previous_timesteps.erase(dynamictimestep.previous_timesteps.begin()); // pop first
327 0 : dynamictimestep.previous_timesteps.push_back(new_timestep); // push back new timestep
328 : }
329 :
330 : }
331 0 : amrex::ParallelDescriptor::Bcast(&final_timestep,1);
332 0 : this->SetTimestep(final_timestep);
333 0 : dynamictimestep.dt_limit_min.clear();
334 : }
335 :
336 :
337 :
338 : amrex::Vector<amrex::Real> t_new; ///< Keep track of current old simulation time on each level
339 : amrex::Vector<int> istep; ///< Keep track of where each level is
340 : // PLOT FILES
341 : std::string plot_file{ "plt" }; ///< Plotfile name
342 :
343 : private:
344 : virtual void MakeNewLevelFromScratch(int lev, amrex::Real time, const amrex::BoxArray& ba,
345 : const amrex::DistributionMapping& dm) override;
346 : virtual void MakeNewLevelFromCoarse(int lev, amrex::Real time, const amrex::BoxArray& ba,
347 : const amrex::DistributionMapping& dm) override;
348 : virtual void RemakeLevel(int lev, amrex::Real time, const amrex::BoxArray& ba,
349 : const amrex::DistributionMapping& dm) override;
350 : virtual void ClearLevel(int lev) override;
351 : virtual void ErrorEst(int lev, amrex::TagBoxArray& tags, amrex::Real time, int ngrow) override;
352 :
353 :
354 : /// This is the function that is responsible for updating patch data.
355 : void FillPatch(int lev, amrex::Real time,
356 : amrex::Vector<std::unique_ptr<amrex::MultiFab>>& source_mf,
357 : amrex::MultiFab& destination_multifab,
358 : BC::BC<Set::Scalar>& physbc,
359 : int icomp);
360 : /// Simple utility to count cells
361 : long CountCells(int lev);
362 : /// Timestep marching
363 : void TimeStep(int lev, amrex::Real time, int iteration);
364 : void FillCoarsePatch(int lev, amrex::Real time, Set::Field<Set::Scalar>& mf, BC::BC<Set::Scalar>& physbc, int icomp, int ncomp);
365 : void GetData(const int lev, const amrex::Real time, amrex::Vector<amrex::MultiFab*>& data, amrex::Vector<amrex::Real>& datatime);
366 :
367 : std::vector<std::string> PlotFileName(int lev, std::string prefix = "") const;
368 : protected:
369 : void IntegrateVariables(Set::Scalar cur_time, int step);
370 : void WritePlotFile(bool initial = false) const;
371 : void WritePlotFile(std::string prefix, Set::Scalar time, int step) const;
372 : void WritePlotFile(Set::Scalar time, amrex::Vector<int> iter, bool initial = false, std::string prefix = "") const;
373 :
374 : //
375 : // MEMBER VARIABLES
376 : //
377 :
378 : // TIME (STEP) KEEPINGamrex::Vector<std::unique_ptr<amrex::MultiFab> >
379 : protected:
380 : amrex::Real timestep = NAN; ///< Timestep for the base level of refinement
381 : amrex::Vector<amrex::Real> dt; ///< Timesteps for each level of refinement
382 : amrex::Vector<int> nsubsteps; ///< how many substeps on each level?
383 : private:
384 : int max_plot_level = -1;
385 :
386 : amrex::Vector<amrex::Real> t_old;///< Keep track of current old simulation time on each level
387 : int max_step = std::numeric_limits<int>::max(); ///< Maximum allowable timestep
388 : amrex::Real tstart = 0; ///< Default start time (default: 0)
389 : amrex::Real stop_time = NAN; ///< Default stop time
390 :
391 : protected:
392 : bool integrate_variables_before_advance = true;
393 : bool integrate_variables_after_advance = false;
394 :
395 : protected:
396 : struct {
397 : int number_of_fabs = 0;
398 : std::vector<Set::Field<Set::Scalar>*> fab_array;
399 : std::vector<int> ncomp_array;
400 : std::vector<int> nghost_array;
401 : std::vector<std::vector<std::string>> name_array;
402 : std::vector<BC::BC<Set::Scalar>*> physbc_array;
403 : std::vector<bool> writeout_array;
404 : std::vector<bool> evolving_array;
405 : bool any = true;
406 : bool all = false;
407 : } node;
408 :
409 : struct {
410 : int number_of_fabs = 0;
411 : std::vector<Set::Field<Set::Scalar>*> fab_array;
412 : std::vector<int> ncomp_array;
413 : std::vector<int> nghost_array;
414 : std::vector<std::vector<std::string>> name_array;
415 : std::vector<BC::BC<Set::Scalar>*> physbc_array;
416 : std::vector<bool> writeout_array;
417 : std::vector<bool> evolving_array;
418 : bool any = true;
419 : bool all = false;
420 : } cell;
421 :
422 : std::vector<BaseField*> m_basefields;
423 : std::vector<BaseField*> m_basefields_cell;
424 :
425 : BC::Nothing bcnothing;
426 :
427 : // KEEP TRACK OF ALL INTEGRATED VARIABLES
428 : struct {
429 : int interval = -1;
430 : Set::Scalar dt = NAN;
431 : int plot_int = -1;
432 : Set::Scalar plot_dt = NAN;
433 : int number = 0;
434 : std::vector<Set::Scalar*> vars;
435 : std::vector<std::string> names;
436 : std::vector<bool> extensives;
437 : } thermo;
438 :
439 : // REGRIDDING
440 : int regrid_int = -1; ///< Determine how often to regrid (default: 2)
441 : int base_regrid_int = -1; ///< Determine how often to regrid based on coarse level only (default: 0)
442 :
443 : std::string restart_file_cell = "";
444 : std::string restart_file_node = "";
445 :
446 : struct {
447 : int on = 0;
448 : std::vector<amrex::Box> box;
449 : } explicitmesh;
450 :
451 : protected:
452 : int plot_int = -1; ///< How frequently to dump plot file (default: never)
453 : Set::Scalar plot_dt = -1.0;
454 :
455 : int abort_on_nan = true;
456 : };
457 :
458 :
459 : template<>
460 : ALAMO_SINGLE_DEFINITION
461 150 : void Integrator::AddField<Set::Scalar, Set::Hypercube::Cell>
462 : ( Set::Field<Set::Scalar>& new_field,
463 : BC::BC<Set::Scalar>* new_bc,
464 : int ncomp,
465 : int nghost,
466 : std::string name,
467 : bool writeout,
468 : bool evolving,
469 : std::vector<std::string> suffix)
470 : {
471 150 : int nlevs_max = maxLevel() + 1;
472 150 : new_field.resize(nlevs_max);
473 150 : cell.fab_array.push_back(&new_field);
474 150 : if (new_bc != nullptr) cell.physbc_array.push_back(new_bc);
475 0 : else cell.physbc_array.push_back(&bcnothing);
476 150 : cell.ncomp_array.push_back(ncomp);
477 150 : cell.nghost_array.push_back(nghost);
478 : //cell.name_array.push_back(name);
479 150 : cell.writeout_array.push_back(writeout);
480 150 : cell.evolving_array.push_back(evolving);
481 150 : cell.number_of_fabs++;
482 :
483 1050 : Util::Assert(INFO,TEST((int)suffix.size() == 0 || (int)suffix.size() == ncomp));
484 150 : std::vector<std::string> names;
485 150 : if (ncomp == 1)
486 102 : names.push_back(name);
487 : else
488 : {
489 48 : if (suffix.size() == 0)
490 82 : for (int j = 0; j < ncomp; j++)
491 64 : names.push_back(amrex::Concatenate(name,j+1,3));
492 : else
493 90 : for (int j = 0; j < ncomp; j++)
494 60 : names.push_back(name + suffix[j]);
495 : }
496 150 : cell.name_array.push_back(names);
497 150 : }
498 :
499 : template<>
500 : ALAMO_SINGLE_DEFINITION
501 21 : void Integrator::AddField<Set::Scalar, Set::Hypercube::Node>
502 : ( Set::Field<Set::Scalar>& new_field,
503 : BC::BC<Set::Scalar>* new_bc,
504 : int ncomp,
505 : int nghost,
506 : std::string name,
507 : bool writeout,
508 : bool evolving,
509 : std::vector<std::string> suffix)
510 : {
511 : BL_PROFILE("Integrator::RegisterNodalFab");
512 147 : Util::Assert(INFO, TEST(new_bc == nullptr));
513 21 : int nlevs_max = maxLevel() + 1;
514 21 : new_field.resize(nlevs_max);
515 21 : node.fab_array.push_back(&new_field);
516 21 : node.physbc_array.push_back(&bcnothing);
517 21 : node.ncomp_array.push_back(ncomp);
518 21 : node.nghost_array.push_back(nghost);
519 21 : node.evolving_array.push_back(evolving);
520 21 : node.writeout_array.push_back(writeout);
521 21 : node.number_of_fabs++;
522 :
523 147 : Util::Assert(INFO,TEST((int)suffix.size() == 0 || (int)suffix.size() == ncomp));
524 21 : std::vector<std::string> names;
525 21 : if (ncomp == 1)
526 18 : names.push_back(name);
527 : else
528 : {
529 3 : if (suffix.size() == 0)
530 9 : for (int j = 0; j < ncomp; j++)
531 6 : names.push_back(amrex::Concatenate(name,j+1,3));
532 : else
533 0 : for (int j = 0; j < ncomp; j++)
534 0 : names.push_back(name + suffix[j]);
535 : }
536 21 : node.name_array.push_back(names);
537 21 : }
538 :
539 : template<class T, int d>
540 : ALAMO_SINGLE_DEFINITION
541 98 : void Integrator::AddField
542 : ( Set::Field<T>& new_field, BC::BC<T>* new_bc, int ncomp,
543 : int nghost, std::string name, bool writeout, bool evolving,
544 : std::vector<std::string> /*suffix*/)
545 : {
546 : if (d == Set::Hypercube::Node)
547 : {
548 686 : Util::Assert(INFO, TEST(new_bc == nullptr));
549 98 : int nlevs_max = maxLevel() + 1;
550 98 : new_field.resize(nlevs_max);
551 98 : m_basefields.push_back(new Field<T>(new_field, geom, refRatio(), ncomp, nghost));
552 98 : m_basefields.back()->evolving = evolving;
553 98 : m_basefields.back()->writeout = writeout;
554 98 : m_basefields.back()->setName(name);
555 98 : m_basefields.back()->evolving = evolving;
556 98 : m_basefields.back()->m_gridtype = Set::Hypercube::Node;
557 : }
558 : else if (d == Set::Hypercube::Cell)
559 : {
560 : int nlevs_max = maxLevel() + 1;
561 : new_field.resize(nlevs_max);
562 : m_basefields_cell.push_back(new Field<T>(new_field, geom, refRatio(), ncomp, nghost));
563 : m_basefields_cell.back()->evolving = evolving;
564 : m_basefields_cell.back()->writeout = writeout;
565 : m_basefields_cell.back()->setName(name);
566 : m_basefields_cell.back()->evolving = evolving;
567 : if (new_bc) m_basefields_cell.back()->setBC(new_bc);
568 : else m_basefields_cell.back()->setBC(&bcnothing);
569 : m_basefields_cell.back()->m_gridtype = Set::Hypercube::Cell;
570 : }
571 : else
572 : {
573 : Util::Abort(INFO, "Only node and cell based fields can be added at this time");
574 : }
575 98 : }
576 :
577 :
578 :
579 : template<class T>
580 : ALAMO_SINGLE_DEFINITION
581 19 : void Integrator::RegisterGeneralFab(Set::Field<T>& new_fab, int ncomp, int nghost, bool evolving)
582 : {
583 : //Util::Warning(INFO, "RegisterGeneralFab is depricated. Please replace with AddField");
584 57 : AddField<T, Set::Hypercube::Node>(new_fab, nullptr, ncomp, nghost, "", true, evolving);
585 19 : }
586 : template<class T>
587 : ALAMO_SINGLE_DEFINITION
588 3 : void Integrator::RegisterGeneralFab(Set::Field<T>& new_fab, int ncomp, int nghost, std::string a_name, bool evolving)
589 : {
590 : //Util::Warning(INFO, "RegisterGeneralFab is depricated. Please replace with AddField");
591 3 : AddField<T, Set::Hypercube::Node>(new_fab, nullptr, ncomp, nghost, a_name, true, evolving);
592 3 : }
593 : template<class T>
594 : AMREX_ATTRIBUTE_WEAK
595 76 : void Integrator::RegisterGeneralFab(Set::Field<T>& new_fab, int ncomp, int nghost, bool writeout, std::string a_name, bool evolving)
596 : {
597 : //Util::Warning(INFO, "RegisterGeneralFab is depricated. Please replace with AddField");
598 76 : AddField<T, Set::Hypercube::Node>(new_fab, nullptr, ncomp, nghost, a_name, writeout, evolving);
599 76 : }
600 :
601 : }
602 : #endif
|