chombo-discharge
CD_ItoKMCFieldTaggerImplem.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_ItoKMCFieldTaggerImplem_H
13 #define CD_ItoKMCFieldTaggerImplem_H
14 
15 // Our includes
16 #include <CD_ItoKMCFieldTagger.H>
17 #include <CD_DataOps.H>
18 #include <CD_Location.H>
19 #include <CD_NamespaceHeader.H>
20 
21 using namespace Physics::ItoKMC;
22 
23 template <typename S>
25 {
26  CH_TIME("ItoKMCFieldTagger::ItoKMCFieldTagger");
27  if (this->m_verbosity > 5) {
28  pout() << "ItoKMCFieldTagger::ItoKMCFieldTagger" << endl;
29  }
30 
31  this->m_name = "ItoKMCFieldTagger";
32 }
33 
34 template <typename S>
36 {}
37 
38 template <typename S>
39 void
41 {
42  CH_TIME("ItoKMCFieldTagger::allocateStorage");
43  if (this->m_verbosity > 5) {
44  pout() << this->m_name + "::allocateStorage" << endl;
45  }
46 
47  CH_assert(this->m_isDefined);
48 
49  (this->m_amr)->allocate(m_scratch, this->m_realm, this->m_phase, 1);
50  (this->m_amr)->allocate(m_E, this->m_realm, this->m_phase, SpaceDim);
51  (this->m_amr)->allocate(m_gradE, this->m_realm, this->m_phase, SpaceDim);
52 }
53 
54 template <typename S>
55 void
57 {
58  CH_TIME("ItoKMCFieldTagger::deallocateStorage");
59  if (this->m_verbosity > 5) {
60  pout() << this->m_name + "::deallocateStorage" << endl;
61  }
62 
63  this->m_amr->deallocate(m_scratch);
64  this->m_amr->deallocate(m_E);
65  this->m_amr->deallocate(m_gradE);
66 }
67 
68 template <typename S>
69 void
71 {
72  CH_TIME("ItoKMCFieldTagger::computeElectricField");
73  if (this->m_verbosity > 5) {
74  pout() << this->m_name + "::computeElectricField" << endl;
75  }
76 
77  CH_assert(this->m_isDefined);
78  CH_assert(a_E[0]->nComp() == SpaceDim);
79  CH_assert(a_gradE[0]->nComp() == SpaceDim);
80 
81  this->m_timeStepper->computeElectricField(a_E, this->m_phase);
82  DataOps::vectorLength(m_scratch, a_E);
83  this->m_amr->computeGradient(a_gradE, m_scratch, this->m_realm, this->m_phase);
84 
85  this->m_amr->conservativeAverage(a_gradE, this->m_realm, this->m_phase);
86  this->m_amr->interpGhost(a_gradE, this->m_realm, this->m_phase);
87 
88  // Interpolate to centroids
89  this->m_amr->interpToCentroids(a_E, this->m_realm, this->m_phase);
90  this->m_amr->interpToCentroids(a_gradE, this->m_realm, this->m_phase);
91 }
92 
93 template <typename S>
94 void
96 {
97  CH_TIME("ItoKMCFieldTagger::computeTagFields");
98  if (this->m_verbosity > 5) {
99  pout() << this->m_name + "::computeTagFields" << endl;
100  }
101 
102  CH_assert(this->m_isDefined);
103 
104  this->allocateStorage();
105  this->computeElectricField(m_E, m_gradE);
106 
107  const RealVect probLo = this->m_amr->getProbLo();
108  const Real time = this->m_timeStepper->getTime();
109 
110  Real maxE, minE;
111  Real maxGradE, minGradE;
112 
113  DataOps::getMaxMinNorm(maxE, minE, m_E);
114  DataOps::getMaxMinNorm(maxGradE, minGradE, m_gradE);
115 
116  for (int lvl = 0; lvl <= this->m_amr->getFinestLevel(); lvl++) {
117  const DisjointBoxLayout& dbl = this->m_amr->getGrids(this->m_realm)[lvl];
118  const DataIterator& dit = dbl.dataIterator();
119  const EBISLayout& ebisl = this->m_amr->getEBISLayout(this->m_realm, this->m_phase)[lvl];
120  const Real dx = this->m_amr->getDx()[lvl];
121 
122  const int nbox = dit.size();
123 
124 #pragma omp parallel for schedule(runtime)
125  for (int mybox = 0; mybox < nbox; mybox++) {
126  const DataIndex& din = dit[mybox];
127 
128  const Box& box = dbl[din];
129  const EBISBox& ebisbox = ebisl[din];
130 
131  const EBCellFAB& electricField = (*m_E[lvl])[din];
132  const EBCellFAB& gradElectricField = (*m_gradE[lvl])[din];
133 
134  const FArrayBox& electricFieldReg = electricField.getFArrayBox();
135  const FArrayBox& gradElectricFieldReg = gradElectricField.getFArrayBox();
136 
137  Vector<EBCellFAB*> tagFields;
138  Vector<FArrayBox*> tagFieldsReg;
139  for (int i = 0; i < this->m_numTagFields; i++) {
140  tagFields.push_back(&((*this->m_tagFields[i][lvl])[din]));
141  tagFieldsReg.push_back(&(tagFields[i]->getFArrayBox()));
142  }
143 
144  auto regularKernel = [&](const IntVect& iv) -> void {
145  if (ebisbox.isRegular(iv)) {
146  const RealVect pos = probLo + RealVect(iv) * dx;
147 
148  const RealVect E = RealVect(
149  D_DECL(electricFieldReg(iv, 0), electricFieldReg(iv, 1), electricFieldReg(iv, 2)));
150  const RealVect gradE = RealVect(
151  D_DECL(gradElectricFieldReg(iv, 0), gradElectricFieldReg(iv, 1), gradElectricFieldReg(iv, 2)));
152 
153  const Vector<Real>
154  compTagFields = this->computeTagFields(pos, time, dx, E, minE, maxE, gradE, minGradE, maxGradE);
155 
156  for (int i = 0; i < this->m_numTagFields; i++) {
157  (*tagFieldsReg[i])(iv, 0) = compTagFields[i];
158  }
159  }
160  };
161 
162  // Irregular box loop
163  auto irregularKernel = [&](const VolIndex& vof) -> void {
164  const RealVect pos = probLo + Location::position(Location::Cell::Center, vof, ebisbox, dx);
165 
166  const RealVect E = RealVect(D_DECL(electricField(vof, 0), electricField(vof, 1), electricField(vof, 2)));
167  const RealVect gradE = RealVect(
168  D_DECL(gradElectricField(vof, 0), gradElectricField(vof, 1), gradElectricField(vof, 2)));
169 
170  const Vector<Real>
171  compTagFields = this->computeTagFields(pos, time, dx, E, minE, maxE, gradE, minGradE, maxGradE);
172 
173  for (int i = 0; i < this->m_numTagFields; i++) {
174  (*tagFields[i])(vof, 0) = compTagFields[i];
175  }
176  };
177 
178  // Run the kernels
179  VoFIterator& vofit = (*this->m_amr->getVofIterator(this->m_realm, this->m_phase)[lvl])[din];
180  BoxLoops::loop(box, regularKernel);
181  BoxLoops::loop(vofit, irregularKernel);
182  }
183 
184  for (int i = 0; i < this->m_numTagFields; i++) {
185  this->m_amr->conservativeAverage(this->m_tagFields[i], this->m_realm, this->m_phase);
186  this->m_amr->interpGhost(this->m_tagFields[i], this->m_realm, this->m_phase);
187  }
188 
189  // Compute gradient of tracers
190  for (int i = 0; i < this->m_numTagFields; i++) {
191  this->m_amr->computeGradient(this->m_gradTagFields[i], this->m_tagFields[i], this->m_realm, this->m_phase);
192  this->m_amr->conservativeAverage(this->m_gradTagFields[i], this->m_realm, this->m_phase);
193  }
194  }
195 
196  this->deallocateStorage();
197 }
198 
199 #include <CD_NamespaceFooter.H>
200 
201 #endif
Agglomeration of useful data operations.
Declaration of an abstract field-only tagging class for ito plasmas.
Declaration of cell positions.
static void vectorLength(EBAMRCellData &a_lhs, const EBAMRCellData &a_rhs)
Compute the vector length of a data holder. Sets a_lhs = |a_rhs| where a_rhs contains SpaceDim compon...
Definition: CD_DataOps.cpp:3396
static void getMaxMinNorm(Real &a_max, Real &a_min, EBAMRCellData &data)
Get maximum and minimum value of normed data.
Definition: CD_DataOps.cpp:1783
ItoKMCFieldTagger() noexcept
Weak constructor. User MUST subsequently call define.
Definition: CD_ItoKMCFieldTaggerImplem.H:24
virtual void computeElectricField(EBAMRCellData &a_E, EBAMRCellData &a_gradE) const noexcept
Compute electric field.
Definition: CD_ItoKMCFieldTaggerImplem.H:70
virtual void allocateStorage() const noexcept
Allocate memory for scratch, electric field, and gradient of electric field.
Definition: CD_ItoKMCFieldTaggerImplem.H:40
virtual ~ItoKMCFieldTagger() noexcept
Destructor.
Definition: CD_ItoKMCFieldTaggerImplem.H:35
virtual void computeTagFields() const noexcept override
Compute tagging fields.
Definition: CD_ItoKMCFieldTaggerImplem.H:95
virtual void deallocateStorage() const noexcept
Deallocate memory.
Definition: CD_ItoKMCFieldTaggerImplem.H:56
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