chombo-discharge
CD_EBAMRSurfaceDepositionImplem.H
Go to the documentation of this file.
1 /* chombo-discharge
2  * Copyright © 2023 SINTEF Energy Research.
3  * Please refer to Copyright.txt and LICENSE in the chombo-discharge root directory.
4  */
5 
12 #ifndef CD_EBAMRSurfaceDepositionImplem_H
13 #define CD_EBAMRSurfaceDepositionImplem_H
14 
15 // Chombo includes
16 #include <ParmParse.H>
17 #include <CH_Timer.H>
18 
19 // Our includes
20 #include <CD_IrregAddOp.H>
21 #include <CD_DataOps.H>
22 #include <CD_ParticleOps.H>
24 #include <CD_NamespaceHeader.H>
25 
26 template <class P, const Real& (P::*particleScalarField)() const>
27 void
28 EBAMRSurfaceDeposition::deposit(EBAMRIVData& a_meshData, const ParticleContainer<P>& a_particles) const noexcept
29 {
30  CH_TIME("EBAMRSurfaceDeposition::deposit");
31  if (m_verbose) {
32  pout() << "EBAMRSurfaceDeposition::deposit<P, const Real& P::*func const>" << endl;
33  }
34 
35  CH_assert(a_meshData.getRealm() == a_particles.getRealm());
36 
37  // Deposit on this level
38  for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
39  const DisjointBoxLayout& dbl = m_ebGrids[lvl]->getDBL();
40  const EBISLayout& ebisl = m_ebGrids[lvl]->getEBISL();
41  const DataIterator& dit = dbl.dataIterator();
42 
43  const int nbox = dit.size();
44 #pragma omp parallel for schedule(runtime)
45  for (int mybox = 0; mybox < nbox; mybox++) {
46  const DataIndex& din = dit[mybox];
47 
48  const Box cellBox = dbl[din];
49  const EBISBox& ebisbox = ebisl[din];
50  const BaseIVFAB<VoFStencil>& stencils = (*m_depositionStencils[lvl])[din];
51 
52  BaseIVFAB<Real>& meshData = (*m_data[lvl])[din];
53  const List<P>& particles = a_particles[lvl][din].listItems();
54 
55  meshData.setVal(0.0);
56 
57  for (ListIterator<P> lit(particles); lit.ok(); ++lit) {
58  const P& p = lit();
59 
60  const IntVect iv = ParticleOps::getParticleCellIndex(p.position(), m_probLo, m_dx[lvl]);
61 
62  // If this fails the particle is not in a valid cell.
63  if (!(cellBox.contains(iv))) {
64  MayDay::Error("CD_EBAMRSurfaceDeposition::deposit -- particle is not inside the box");
65  }
66 
67  if (ebisbox.isIrregular(iv)) {
68  const VoFStencil& stencil = stencils(VolIndex(iv, 0), 0);
69 
70  for (int i = 0; i < stencil.size(); i++) {
71  const VolIndex& stencilVoF = stencil.vof(i);
72  const Real& stencilWeight = stencil.weight(i);
73  const Real depositionWeight = stencilWeight * (p.*particleScalarField)();
74 
75  meshData(stencilVoF, 0) += depositionWeight;
76  }
77  }
78  }
79  }
80 
81  // Above, we will have deposited over patch boundaries. Add the deposted data into the neighboring patches.
82  m_data[lvl]->exchange(Interval(0, 0), m_copierLevel[lvl], IrregAddOp());
83  }
84 
85  // Ensure conservation across coarse-fine interface. This involves interpolation of the data going from
86  // the coarse level to the fine level, and coarsening of the data from the fine level to coarse level.
87  this->addInvalidCoarseDataToFineData();
88  this->addFineGhostDataToValidCoarData();
89 
90  // Finally, copy our buffers to the input data.
91  for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
92  CH_assert(!(a_meshData[lvl].isNull()));
93  CH_assert(a_meshData[lvl]->nComp() == 1);
94 
95  const Interval interv = Interval(0, 0);
96 
97  m_data[lvl]->copyTo(interv, *a_meshData[lvl], interv, m_validToValidCopiers[lvl]);
98  }
99 }
100 
101 template <class P, Real (P::*particleScalarField)()>
102 void
103 EBAMRSurfaceDeposition::deposit(EBAMRIVData& a_meshData, const ParticleContainer<P>& a_particles) const noexcept
104 {
105  CH_TIME("EBAMRSurfaceDeposition::deposit");
106  if (m_verbose) {
107  pout() << "EBAMRSurfaceDeposition::deposit<P, Real P::*func>" << endl;
108  }
109 
110  CH_assert(a_meshData.getRealm() == a_particles.getRealm());
111 
112  // Deposit on this level
113  for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
114  const DisjointBoxLayout& dbl = m_ebGrids[lvl]->getDBL();
115  const EBISLayout& ebisl = m_ebGrids[lvl]->getEBISL();
116  const DataIterator& dit = dbl.dataIterator();
117 
118  const int nbox = dit.size();
119 #pragma omp parallel for schedule(runtime)
120  for (int mybox = 0; mybox < nbox; mybox++) {
121  const DataIndex& din = dit[mybox];
122 
123  const Box cellBox = dbl[din];
124  const EBISBox& ebisbox = ebisl[din];
125  const BaseIVFAB<VoFStencil>& stencils = (*m_depositionStencils[lvl])[din];
126 
127  BaseIVFAB<Real>& meshData = (*m_data[lvl])[din];
128  const List<P>& particles = a_particles[lvl][din].listItems();
129 
130  meshData.setVal(0.0);
131 
132  for (ListIterator<P> lit(particles); lit.ok(); ++lit) {
133  const P& p = lit();
134 
135  const IntVect iv = ParticleOps::getParticleCellIndex(p.position(), m_probLo, m_dx[lvl]);
136 
137  // If this fails the particle is not in a valid cell.
138  if (!(cellBox.contains(iv))) {
139  MayDay::Error("CD_EBAMRSurfaceDeposition::deposit -- particle is not inside the box");
140  }
141 
142  if (ebisbox.isIrregular(iv)) {
143  const VoFStencil& stencil = stencils(VolIndex(iv, 0), 0);
144 
145  for (int i = 0; i < stencil.size(); i++) {
146  const VolIndex& stencilVoF = stencil.vof(i);
147  const Real& stencilWeight = stencil.weight(i);
148  const Real depositionWeight = stencilWeight * (p.*particleScalarField)();
149 
150  meshData(stencilVoF, 0) += depositionWeight;
151  }
152  }
153  }
154  }
155 
156  // Above, we will have deposited over patch boundaries. Add the deposted data into the neighboring patches.
157  m_data[lvl]->exchange(Interval(0, 0), m_copierLevel[lvl], IrregAddOp());
158  }
159 
160  // Ensure conservation across coarse-fine interface. This involves interpolation of the data going from
161  // the coarse level to the fine level, and coarsening of the data from the fine level to coarse level.
162  this->addInvalidCoarseDataToFineData();
163  this->addFineGhostDataToValidCoarData();
164 
165  // Finally, copy our buffers to the input data.
166  for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
167  CH_assert(!(a_meshData[lvl].isNull()));
168  CH_assert(a_meshData[lvl]->nComp() == 1);
169 
170  const Interval interv = Interval(0, 0);
171 
172  m_data[lvl]->copyTo(interv, *a_meshData[lvl], interv, m_validToValidCopiers[lvl]);
173  }
174 }
175 
176 #include <CD_NamespaceFooter.H>
177 
178 #endif
Agglomeration of useful data operations.
Declaration of a class for handling surface deposition of particles with EB and AMR.
Declaration of a Copier class for making incrementation between LevelData<BaseIVFAB<Real>> easier.
Declaration of a static class containing some common useful particle routines that would otherwise be...
void deposit(EBAMRIVData &a_meshData, const ParticleContainer< P > &a_particles) const noexcept
Deposit function. Deposits particle on surface.
Definition: CD_EBAMRSurfaceDepositionImplem.H:28
A Copier class for making copying between LevelData<BaseIVFAB<Real>> easier. This is an incrementatio...
Definition: CD_IrregAddOp.H:26
Templated class for holding particles on an AMR hierarchy with particle remapping.
Definition: CD_ParticleContainer.H:50
static IntVect getParticleCellIndex(const RealVect &a_particlePosition, const RealVect &a_probLo, const Real &a_dx) noexcept
Get the cell index corresponding to the particle position.
Definition: CD_ParticleOpsImplem.H:26