chombo-discharge
CD_ItoKMCTaggerImplem.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_ItoKMCTaggerImplem_H
13 #define CD_ItoKMCTaggerImplem_H
14 
15 // Chombo includes
16 #include <ParmParse.H>
17 
18 // Our includes
19 #include <CD_ItoKMCTagger.H>
20 #include <CD_DataOps.H>
21 #include <CD_NamespaceHeader.H>
22 
23 using namespace Physics::ItoKMC;
24 
25 template <typename S>
27 {
28  CH_TIME("ItoKMCTagger::ItoKMCTagger");
29  m_verbosity = -1;
30  if (m_verbosity > 5) {
31  pout() << "ItoKMCTagger::ItoKMCTagger" << endl;
32  }
33 
34  m_name = "ItoKMCTagger";
35  m_phase = phase::gas;
36  m_realm = Realm::Primal;
37  m_isDefined = false;
38  m_plotData = false;
39 }
40 
41 template <typename S>
42 ItoKMCTagger<S>::ItoKMCTagger(const RefCountedPtr<ItoKMCPhysics>& a_physics,
43  const RefCountedPtr<S>& a_timeStepper,
44  const RefCountedPtr<AmrMesh>& a_amr) noexcept
45  : ItoKMCTagger<S>()
46 {
47  this->define(a_physics, a_timeStepper, a_amr);
48 }
49 
50 template <typename S>
52 {}
53 
54 template <typename S>
55 void
56 ItoKMCTagger<S>::define(const RefCountedPtr<ItoKMCPhysics>& a_physics,
57  const RefCountedPtr<S>& a_timeStepper,
58  const RefCountedPtr<AmrMesh>& a_amr) noexcept
59 
60 {
61  CH_TIME("ItoKMCTagger::define");
62  if (m_verbosity > 5) {
63  pout() << m_name + "::define" << endl;
64  }
65 
66  m_physics = a_physics;
67  m_timeStepper = a_timeStepper;
68  m_amr = a_amr;
69  m_isDefined = true;
70 }
71 
72 template <typename S>
73 void
75 {
76  CH_TIME("ItoKMCTagger::regrid");
77  if (m_verbosity > 5) {
78  pout() << m_name + "::regrid" << endl;
79  }
80 
81  CH_assert(m_isDefined);
82 
83  if (m_numTagFields > 0) {
84 
85  m_tagFields.resize(m_numTagFields);
86  m_gradTagFields.resize(m_numTagFields);
87 
88  for (int i = 0; i < m_numTagFields; i++) {
89  m_amr->allocate(m_tagFields[i], m_realm, m_phase, 1);
90  m_amr->allocate(m_gradTagFields[i], m_realm, m_phase, SpaceDim);
91  }
92  }
93 }
94 
95 template <typename S>
96 void
97 ItoKMCTagger<S>::setPhase(const phase::which_phase a_phase) noexcept
98 {
99  CH_TIME("ItoKMCTagger::setPhase");
100  if (m_verbosity > 5) {
101  pout() << m_name + "::setPhase" << endl;
102  }
103 
104  m_phase = a_phase;
105 }
106 
107 template <typename S>
108 int
110 {
111  CH_TIME("ItoKMCTagger::getNumberOfPlotVariables");
112  if (m_verbosity > 5) {
113  pout() << m_name + "::getNumberOfPlotVariables" << endl;
114  }
115 
116  return m_plotData ? m_numTagFields : 0;
117 }
118 
119 template <typename S>
120 Vector<std::string>
122 {
123  CH_TIME("ItoKMCTagger::getPlotVariableNames");
124  if (m_verbosity > 5) {
125  pout() << m_name + "::getPlotVariableNames" << endl;
126  }
127 
128  Vector<std::string> plotVars;
129 
130  if (m_plotData) {
131  for (int i = 0; i < m_numTagFields; i++) {
132  plotVars.push_back("Tag field-" + std::to_string(i));
133  }
134  }
135 
136  return plotVars;
137 }
138 
139 template <typename S>
140 Vector<EBAMRCellData>&
142 {
143  CH_TIME("ItoKMCTagger::getTagFields");
144  if (m_verbosity > 5) {
145  pout() << m_name + "::getTagFields" << endl;
146  }
147 
148  CH_assert(m_isDefined);
149 
150  return m_tagFields;
151 }
152 
153 template <typename S>
154 void
155 ItoKMCTagger<S>::writePlotData(LevelData<EBCellFAB>& a_output,
156  int& a_icomp,
157  const std::string a_outputRealm,
158  const int a_level) const noexcept
159 {
160  CH_TIME("ItoKMCTagger::writePlotData");
161  if (m_verbosity > 5) {
162  pout() << m_name + "::writePlotData" << endl;
163  }
164 
165  CH_assert(m_isDefined);
166 
167  if (m_plotData) {
168  this->computeTagFields();
169 
170  for (int i = 0; i < m_numTagFields; i++) {
171  const EBAMRCellData& tagField = m_tagFields[i];
172 
173  const Interval srcInterv(0, 0);
174  const Interval dstInterv(a_icomp, a_icomp);
175 
176  m_amr->copyData(a_output, *tagField[a_level], a_level, a_outputRealm, tagField.getRealm(), dstInterv, srcInterv);
177 
178  DataOps::setCoveredValue(a_output, a_icomp, 0.0);
179 
180  a_icomp++;
181  }
182  }
183 }
184 
185 template <typename S>
186 bool
188 {
189  CH_TIME("ItoKMCTagger::tagCells");
190  if (m_verbosity > 5) {
191  pout() << m_name + "::tagCells" << endl;
192  }
193 
194  CH_assert(m_isDefined);
195 
196  int gotNewTags = 0;
197 
198  const RealVect probLo = m_amr->getProbLo();
199  const Real curTime = m_timeStepper->getTime();
200  const int finestLevel = m_amr->getFinestLevel();
201  const int maxAmrDepth = m_amr->getMaxAmrDepth();
202  const int finestTagLevel = (finestLevel == maxAmrDepth) ? maxAmrDepth - 1 : finestLevel;
203 
204  if (m_numTagFields > 0) {
205  this->computeTagFields();
206 
207  for (int lvl = 0; lvl <= finestTagLevel; lvl++) {
208  const DisjointBoxLayout& dbl = m_amr->getGrids(m_realm)[lvl];
209  const DataIterator& dit = dbl.dataIterator();
210  const EBISLayout& ebisl = m_amr->getEBISLayout(m_realm, m_phase)[lvl];
211  const Real dx = m_amr->getDx()[lvl];
212 
213  const int nbox = dit.size();
214 
215 #pragma omp parallel for schedule(runtime) reduction(max : gotNewTags)
216  for (int mybox = 0; mybox < nbox; mybox++) {
217  const DataIndex& din = dit[mybox];
218 
219  const Box box = dbl.get(din);
220  const EBISBox& ebisbox = ebisl[din];
221 
222  const IntVectSet irregCells = ebisbox.getIrregIVS(box);
223  const IntVectSet backupTags = IntVectSet((*a_tags[lvl])[din]);
224 
225  DenseIntVectSet coarsenCells(box, false);
226  DenseIntVectSet refinedCells(box, false);
227 
228  Vector<EBCellFAB*> tagFields;
229  Vector<EBCellFAB*> gradTagFields;
230 
231  for (int i = 0; i < m_numTagFields; i++) {
232  tagFields.push_back(&((*m_tagFields[i][lvl])[din]));
233  gradTagFields.push_back(&((*m_gradTagFields[i][lvl])[din]));
234  }
235 
236  this->tagCellsBox(refinedCells,
237  coarsenCells,
238  tagFields,
239  gradTagFields,
240  lvl,
241  din,
242  box,
243  ebisbox,
244  curTime,
245  dx,
246  probLo);
247 
248  // Check if we got any new tags, or we are just recycling old tags.
249  // Basically we will check if (current_tags + refined_tags - coarsenCells) == current_tags
250  DenseIntVectSet& tags = (*a_tags[lvl])[din];
251 
252  DenseIntVectSet cpy1 = tags;
253  tags -= coarsenCells;
254  tags |= refinedCells;
255  DenseIntVectSet cpy2 = tags;
256 
257  cpy2 -= cpy1; // = new tags minus old tags. If nonzero, we got some new tags.
258  cpy1 -= tags; // = old_tags minus new tags. If nonzero, we got some new tags
259  if (cpy1.numPts() != 0 || cpy2.numPts() != 0) {
260  gotNewTags = 1;
261  }
262  }
263  }
264  }
265 
266  return (ParallelOps::max(gotNewTags) > 0);
267 }
268 
269 template <typename S>
270 void
271 ItoKMCTagger<S>::tagCellsBox(DenseIntVectSet& a_refinedCells,
272  DenseIntVectSet& a_coarsenedCells,
273  const Vector<EBCellFAB*>& a_tagFields,
274  const Vector<EBCellFAB*>& a_gradTagFields,
275  const int a_lvl,
276  const DataIndex a_dit,
277  const Box a_box,
278  const EBISBox& a_ebisbox,
279  const Real a_time,
280  const Real a_dx,
281  const RealVect a_probLo) const noexcept
282 {
283  CH_TIME("ItoKMCTagger::refineCellsBox");
284  if (m_verbosity > 5) {
285  pout() << "ItoKMCTagger::refineCellsBox" << endl;
286  }
287 
288  CH_assert(m_isDefined);
289 
290  Vector<FArrayBox*> tagFieldsReg;
291  Vector<FArrayBox*> gradTagFieldsReg;
292 
293  for (int i = 0; i < m_numTagFields; i++) {
294  tagFieldsReg.push_back(&(a_tagFields[i]->getFArrayBox()));
295  gradTagFieldsReg.push_back(&(a_gradTagFields[i]->getFArrayBox()));
296  }
297 
298  // Regular kernel.
299  auto regularKernel = [&](const IntVect& iv) -> void {
300  const RealVect pos = a_probLo + (0.5 * RealVect::Unit + RealVect(iv)) * a_dx;
301 
302  if (this->insideTagBox(pos) && a_ebisbox.isRegular(iv)) {
303 
304  Vector<Real> tr(m_numTagFields);
305  Vector<RealVect> gt(m_numTagFields);
306 
307  for (int i = 0; i < m_numTagFields; i++) {
308  tr[i] = (*tagFieldsReg[i])(iv, 0);
309  gt[i] = RealVect(
310  D_DECL((*gradTagFieldsReg[i])(iv, 0), (*gradTagFieldsReg[i])(iv, 1), (*gradTagFieldsReg[i])(iv, 2)));
311  }
312 
313  if (this->refineCell(pos, a_time, a_dx, a_lvl, tr, gt)) {
314  a_refinedCells |= iv;
315  }
316 
317  if (this->coarsenCell(pos, a_time, a_dx, a_lvl, tr, gt)) {
318  a_coarsenedCells |= iv;
319  }
320  }
321  };
322 
323  // Irregular box loop
324  auto irregularKernel = [&](const VolIndex& vof) -> void {
325  const RealVect pos = a_probLo + Location::position(Location::Cell::Center, vof, a_ebisbox, a_dx);
326 
327  if (this->insideTagBox(pos)) {
328 
329  Vector<Real> tr(m_numTagFields);
330  Vector<RealVect> gt(m_numTagFields);
331 
332  for (int i = 0; i < m_numTagFields; i++) {
333  tr[i] = (*a_tagFields[i])(vof, 0);
334  gt[i] = RealVect(
335  D_DECL((*a_gradTagFields[i])(vof, 0), (*a_gradTagFields[i])(vof, 1), (*a_gradTagFields[i])(vof, 2)));
336  }
337 
338  if (this->refineCell(pos, a_time, a_dx, a_lvl, tr, gt)) {
339  a_refinedCells |= vof.gridIndex();
340  }
341 
342  if (this->coarsenCell(pos, a_time, a_dx, a_lvl, tr, gt)) {
343  a_coarsenedCells |= vof.gridIndex();
344  }
345  }
346  };
347 
348  // Run the kernels.
349  VoFIterator& vofit = (*m_amr->getVofIterator(m_realm, m_phase)[a_lvl])[a_dit];
350 
351  BoxLoops::loop(a_box, regularKernel);
352  BoxLoops::loop(vofit, irregularKernel);
353 }
354 
355 #include <CD_NamespaceFooter.H>
356 
357 #endif
Agglomeration of useful data operations.
Vector< RefCountedPtr< LayoutData< DenseIntVectSet > >> EBAMRTags
Declaration of cell tags.
Definition: CD_EBAMRTags.H:22
Parent tagger class for ItoKMC.
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
const std::string getRealm() const noexcept
Returns the string identifier for whatever realm this data is supposed to be allocated over.
Definition: CD_EBAMRDataImplem.H:135
Class for tagging grid cells using the Ito-KMC-Poisson module. Note that S is the time integrator typ...
Definition: CD_ItoKMCTagger.H:30
ItoKMCTagger()
Weak constructor. User MUST subsequently call the define function.
Definition: CD_ItoKMCTaggerImplem.H:26
virtual void setPhase(const phase::which_phase a_phase) noexcept
Set the phase where we do the tagging.
Definition: CD_ItoKMCTaggerImplem.H:97
virtual bool tagCells(EBAMRTags &a_tags) noexcept override
Tag cells for refinement and coarsening.
Definition: CD_ItoKMCTaggerImplem.H:187
virtual Vector< EBAMRCellData > & getTagFields() noexcept
Get tag fields. This is data that live on the primal realm and specified input phase.
Definition: CD_ItoKMCTaggerImplem.H:141
virtual ~ItoKMCTagger() noexcept
Destructor.
Definition: CD_ItoKMCTaggerImplem.H:51
virtual void tagCellsBox(DenseIntVectSet &a_refinedCells, DenseIntVectSet &a_coarsenedCells, const Vector< EBCellFAB * > &a_tagFields, const Vector< EBCellFAB * > &a_gradTagFields, const int a_lvl, const DataIndex a_dit, const Box a_box, const EBISBox &a_ebisbox, const Real a_time, const Real a_dx, const RealVect a_probLo) const noexcept
Per-box refinement tagging routine.
Definition: CD_ItoKMCTaggerImplem.H:271
virtual int getNumberOfPlotVariables() const noexcept override
Get number of plot variables that will be written to file (by Driver).
Definition: CD_ItoKMCTaggerImplem.H:109
virtual void define(const RefCountedPtr< ItoKMCPhysics > &a_physics, const RefCountedPtr< S > &a_timeStepper, const RefCountedPtr< AmrMesh > &a_amr) noexcept
Define function.
Definition: CD_ItoKMCTaggerImplem.H:56
virtual Vector< std::string > getPlotVariableNames() const noexcept override
Get plot variable names.
Definition: CD_ItoKMCTaggerImplem.H:121
virtual void regrid() noexcept override
Regrid this class. Note that there is no preRegrid method.
Definition: CD_ItoKMCTaggerImplem.H:74
virtual void writePlotData(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string a_outputRealm, const int a_level) const noexcept override
Write plot data.
Definition: CD_ItoKMCTaggerImplem.H:155
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
Real max(const Real &a_input) noexcept
Get the maximum of the input, reduced over MPI ranks (in the Chombo communicator)
Definition: CD_ParallelOpsImplem.H:176