chombo-discharge
Loading...
Searching...
No Matches
CD_EBAMRParticleMesh.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_EBAMRPARTICLEMESH_H
14#define CD_EBAMRPARTICLEMESH_H
15
16// Std includes
17#include <cstddef>
18#include <map>
19
20// Chombo includes
21#include <CH_Timer.H>
22#include <RefCountedPtr.H>
23#include <Vector.H>
24#include <Copier.H>
25#include <DataIterator.H>
26#include <NeighborIterator.H>
27#include <LevelData.H>
28#include <BaseFab.H>
29#include <FArrayBox.H>
30#include <EBCellFAB.H>
31#include <EBLevelGrid.H>
32#include <EBAlias.H>
33#include <IntVectSet.H>
34#include <BoxIterator.H>
35
36// Our includes
37#include <CD_EBAMRData.H>
38#include <CD_EBAddOp.H>
39#include <CD_DataOps.H>
40#include <CD_OpenMP.H>
41#include <CD_DepositionType.H>
44#include <CD_EBParticleMesh.H>
46#include <CD_NamespaceHeader.H>
47
74{
75public:
80
86
90 ~EBAMRParticleMesh() = default;
91
96
102 operator=(const EBAMRParticleMesh&) = delete;
103
113 void
114 define(const Vector<RefCountedPtr<EBLevelGrid>>& a_eblgs,
115 const Vector<int>& a_refRat,
116 const Vector<Real>& a_dx,
117 const RealVect& a_probLo,
118 const int a_ghost,
119 const int a_finestLevel)
120 {
121 CH_TIME("EBAMRParticleMesh::define");
122
123 CH_assert(a_eblgs.size() > a_finestLevel);
124 CH_assert(a_refRat.size() > a_finestLevel);
125 CH_assert(a_dx.size() > a_finestLevel);
126
127 m_eblgs = a_eblgs;
128 m_refRat = a_refRat;
129 m_dx = a_dx;
130 m_probLo = a_probLo;
131 m_ghost = a_ghost;
132 m_finestLevel = a_finestLevel;
133
135 this->defineEBParticleMesh();
136 this->defineLevelMotion();
137 this->defineOuterHaloMasks();
138 this->defineTransitionMasks();
139
140 m_isDefined = true;
141 }
142
144
149
162 template <auto... Members, typename P, typename Traits>
163 void
165 const EBAMRCellData& a_meshData,
166 const DepositionType a_interpType,
167 const bool a_forceIrregNGP) const
168 {
169 CH_TIME("EBAMRParticleMesh::interpolate");
170
171 CH_assert(m_isDefined);
172
173 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
174 const DisjointBoxLayout& dbl = m_eblgs[lvl]->getDBL();
175 const DataIterator& dit = dbl.dataIterator();
176
177 const int nbox = dit.size();
178
179#pragma omp parallel for schedule(runtime)
180 for (int mybox = 0; mybox < nbox; mybox++) {
181 const DataIndex& din = dit[mybox];
182 const EBParticleMesh& interp = (*m_ebParticleMesh[lvl])[din];
183 const EBCellFAB& data = (*a_meshData[lvl])[din];
184
185 interp.template interpolate<Members...>(a_particles[lvl][din], data, a_interpType, a_forceIrregNGP);
186 }
187 }
188 }
189
202 template <typename P, typename Traits>
203 void
205 const EBAMRCellData& a_meshData,
206 const DepositionType a_interpType,
207 const bool a_forceIrregNGP) const
208 {
209 CH_TIME("EBAMRParticleMesh::interpolateWeight");
210
211 CH_assert(m_isDefined);
212
213 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
214 const DisjointBoxLayout& dbl = m_eblgs[lvl]->getDBL();
215 const DataIterator& dit = dbl.dataIterator();
216
217 const int nbox = dit.size();
218
219#pragma omp parallel for schedule(runtime)
220 for (int mybox = 0; mybox < nbox; mybox++) {
221 const DataIndex& din = dit[mybox];
222 const EBParticleMesh& interp = (*m_ebParticleMesh[lvl])[din];
223 const EBCellFAB& data = (*a_meshData[lvl])[din];
224
225 interp.interpolateWeight(a_particles[lvl][din], data, a_interpType, a_forceIrregNGP);
226 }
227 }
228 }
229
231
236
249 template <typename P, typename Traits>
250 void
251 depositWeight(EBAMRCellData& a_meshData,
252 const ParticleContainer<P, Traits>& a_particles,
253 const DepositionType a_depositionType,
254 const CoarseFineDeposition a_coarseFineDeposition,
255 const bool a_forceIrregNGP)
256 {
257 CH_TIME("EBAMRParticleMesh::depositWeight");
258
259 CH_assert(m_isDefined);
260
261 const auto patch =
262 [&](const EBParticleMesh& a_interp, EBCellFAB& a_rho, const auto& a_soa, const Real a_widthScale) {
263 a_interp.depositWeight(a_rho, a_soa, a_depositionType, a_widthScale, a_forceIrregNGP);
264 };
265 const auto patchNGP =
266 [&](const EBParticleMesh& a_interp, EBCellFAB& a_rho, const auto& a_soa, const Real a_widthScale) {
267 a_interp.depositWeight(a_rho, a_soa, DepositionType::NGP, a_widthScale, a_forceIrregNGP);
268 };
269
270 switch (a_coarseFineDeposition) {
271 case CoarseFineDeposition::Interp: {
272 this->depositInterpCore(a_meshData, a_particles, 1, patch);
273
274 break;
275 }
276 case CoarseFineDeposition::Halo: {
277 this->template depositHaloCore<1>(a_meshData, a_particles, patch);
278
279 break;
280 }
281 case CoarseFineDeposition::HaloNGP: {
282 this->template depositHaloNGPCore<1>(a_meshData, a_particles, patch, patchNGP);
283
284 break;
285 }
286 case CoarseFineDeposition::Transition: {
287 this->template depositTransitionCore<1>(a_meshData, a_particles, a_depositionType, patch);
288
289 break;
290 }
291 default: {
292 this->errorUnsupported();
293
294 break;
295 }
296 }
297 }
298
314 template <typename P, typename Traits, typename CellGather>
315 void
316 depositGathered(EBAMRCellData& a_meshData,
317 const ParticleContainer<P, Traits>& a_particles,
318 const DepositionType a_depositionType,
319 const CoarseFineDeposition a_coarseFineDeposition,
320 const bool a_forceIrregNGP,
321 CellGather a_cellGather)
322 {
323 CH_TIME("EBAMRParticleMesh::depositGathered");
324
325 CH_assert(m_isDefined);
326
327 const auto patch =
328 [&](const EBParticleMesh& a_interp, EBCellFAB& a_rho, const auto& a_soa, const Real a_widthScale) {
329 a_interp.depositGathered(a_rho,
330 0,
331 a_soa,
332 a_depositionType,
333 a_widthScale,
334 a_forceIrregNGP,
335 [&](const std::size_t a_i, Real* a_out) {
336 a_out[0] = a_cellGather(a_soa, a_i);
337 });
338 };
339 const auto patchNGP =
340 [&](const EBParticleMesh& a_interp, EBCellFAB& a_rho, const auto& a_soa, const Real a_widthScale) {
341 a_interp.depositGathered(a_rho,
342 0,
343 a_soa,
344 DepositionType::NGP,
345 a_widthScale,
346 a_forceIrregNGP,
347 [&](const std::size_t a_i, Real* a_out) {
348 a_out[0] = a_cellGather(a_soa, a_i);
349 });
350 };
351
352 switch (a_coarseFineDeposition) {
353 case CoarseFineDeposition::Interp: {
354 this->depositInterpCore(a_meshData, a_particles, 1, patch);
355
356 break;
357 }
358 case CoarseFineDeposition::Halo: {
359 this->template depositHaloCore<1>(a_meshData, a_particles, patch);
360
361 break;
362 }
363 case CoarseFineDeposition::HaloNGP: {
364 this->template depositHaloNGPCore<1>(a_meshData, a_particles, patch, patchNGP);
365
366 break;
367 }
368 case CoarseFineDeposition::Transition: {
369 this->template depositTransitionCore<1>(a_meshData, a_particles, a_depositionType, patch);
370
371 break;
372 }
373 default: {
374 this->errorUnsupported();
375
376 break;
377 }
378 }
379 }
380
393 template <auto... Members, typename P, typename Traits>
394 void
395 deposit(EBAMRCellData& a_meshData,
396 const ParticleContainer<P, Traits>& a_particles,
397 const DepositionType a_depositionType,
398 const CoarseFineDeposition a_coarseFineDeposition,
399 const bool a_forceIrregNGP)
400 {
401 CH_TIME("EBAMRParticleMesh::deposit");
402
403 CH_assert(m_isDefined);
404
405 const auto patch =
406 [&](const EBParticleMesh& a_interp, EBCellFAB& a_rho, const auto& a_soa, const Real a_widthScale) {
407 a_interp.template deposit<Members...>(a_rho, a_soa, a_depositionType, a_widthScale, a_forceIrregNGP);
408 };
409 const auto patchNGP =
410 [&](const EBParticleMesh& a_interp, EBCellFAB& a_rho, const auto& a_soa, const Real a_widthScale) {
411 a_interp.template deposit<Members...>(a_rho, a_soa, DepositionType::NGP, a_widthScale, a_forceIrregNGP);
412 };
413
414 switch (a_coarseFineDeposition) {
415 case CoarseFineDeposition::Interp: {
416 this->depositInterpCore(a_meshData, a_particles, static_cast<int>(sizeof...(Members)), patch);
417
418 break;
419 }
420 case CoarseFineDeposition::Halo: {
421 this->template depositHaloCore<static_cast<int>(sizeof...(Members))>(a_meshData, a_particles, patch);
422
423 break;
424 }
425 case CoarseFineDeposition::HaloNGP: {
426 this->template depositHaloNGPCore<static_cast<int>(sizeof...(Members))>(a_meshData, a_particles, patch, patchNGP);
427
428 break;
429 }
430 case CoarseFineDeposition::Transition: {
431 this->template depositTransitionCore<static_cast<int>(sizeof...(Members))>(a_meshData,
432 a_particles,
433 a_depositionType,
434 patch);
435 break;
436 }
437 default: {
438 this->errorUnsupported();
439
440 break;
441 }
442 }
443 }
444
446
447protected:
451 Vector<RefCountedPtr<EBLevelGrid>> m_eblgs;
452
456 Vector<int> m_refRat;
457
461 Vector<Real> m_dx;
462
466 RealVect m_probLo;
467
472
477
482
486 Vector<RefCountedPtr<LayoutData<EBParticleMesh>>> m_ebParticleMesh;
487
491 Vector<Copier> m_levelCopiers;
492
496 Vector<RefCountedPtr<EBCoarseFineParticleMesh>> m_coarseFinePM;
497
501 Vector<RefCountedPtr<LayoutData<EBParticleMesh>>> m_ebParticleMeshFiCo;
502
506 std::map<int, Vector<RefCountedPtr<LevelData<BaseFab<bool>>>>> m_outerHaloMasks;
507
511 std::map<int, Vector<RefCountedPtr<LevelData<BaseFab<bool>>>>> m_transitionMasks;
512
516 void
518 {
519 MayDay::Error("EBAMRParticleMesh: unsupported CoarseFineDeposition strategy");
520 }
521
525 void
527 {
528 CH_TIME("EBAMRParticleMesh::defineEBParticleMesh");
529
532
533 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
534 const ProblemDomain& domain = m_eblgs[lvl]->getDomain();
535 const DisjointBoxLayout& dbl = m_eblgs[lvl]->getDBL();
536 const EBISLayout& ebisl = m_eblgs[lvl]->getEBISL();
537 const DataIterator& dit = dbl.dataIterator();
538
539 m_ebParticleMesh[lvl] = RefCountedPtr<LayoutData<EBParticleMesh>>(new LayoutData<EBParticleMesh>(dbl));
540
541 const int nbox = dit.size();
542
543#pragma omp parallel for schedule(runtime)
544 for (int mybox = 0; mybox < nbox; mybox++) {
545 const DataIndex& din = dit[mybox];
546
547 (*m_ebParticleMesh[lvl])[din].define(domain, dbl[din], ebisl[din], m_dx[lvl] * RealVect::Unit, m_probLo);
548 }
549
550 // Refined-coarse leaves: deposit coarse-level halo particles at fine resolution (dx of this level).
551 if (lvl > 0) {
552 const EBLevelGrid& eblgFiCo = m_coarseFinePM[lvl]->getEblgFiCo();
553 const ProblemDomain& domainFiCo = eblgFiCo.getDomain();
554 const DisjointBoxLayout& dblFiCo = eblgFiCo.getDBL();
555 const EBISLayout& ebislFiCo = eblgFiCo.getEBISL();
556 const DataIterator& ditFiCo = dblFiCo.dataIterator();
557 const int nboxFiCo = ditFiCo.size();
558
559 m_ebParticleMeshFiCo[lvl] = RefCountedPtr<LayoutData<EBParticleMesh>>(new LayoutData<EBParticleMesh>(dblFiCo));
560
561#pragma omp parallel for schedule(runtime)
562 for (int mybox = 0; mybox < nboxFiCo; mybox++) {
563 const DataIndex& din = ditFiCo[mybox];
564
565 (*m_ebParticleMeshFiCo[lvl])[din].define(domainFiCo,
566 dblFiCo[din],
567 ebislFiCo[din],
568 m_dx[lvl] * RealVect::Unit,
569 m_probLo);
570 }
571 }
572 else {
573 m_ebParticleMeshFiCo[lvl] = RefCountedPtr<LayoutData<EBParticleMesh>>(nullptr);
574 }
575 }
576 }
577
581 void
583 {
584 CH_TIME("EBAMRParticleMesh::defineLevelMotion");
585
586 m_levelCopiers.resize(1 + m_finestLevel);
587 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
588 const EBLevelGrid& eblg = *m_eblgs[lvl];
589 const DisjointBoxLayout& dbl = eblg.getDBL();
590
591 m_levelCopiers[lvl].define(dbl, dbl, eblg.getDomain(), m_ghost * IntVect::Unit, true);
592 m_levelCopiers[lvl].reverse();
593 }
594 }
595
599 void
601 {
602 CH_TIME("EBAMRParticleMesh::defineCoarseFineMotion");
603
604 m_coarseFinePM.resize(1 + m_finestLevel);
605
606 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
607 if (lvl > 0) {
608 m_coarseFinePM[lvl] = RefCountedPtr<EBCoarseFineParticleMesh>(
609 new EBCoarseFineParticleMesh(*m_eblgs[lvl - 1], *m_eblgs[lvl], m_refRat[lvl - 1], m_ghost * IntVect::Unit));
610 }
611 else {
612 m_coarseFinePM[lvl] = RefCountedPtr<EBCoarseFineParticleMesh>(nullptr);
613 }
614 }
615 }
616
629 template <typename Container, typename PatchDeposit>
630 void
631 depositInterpCore(EBAMRCellData& a_meshData,
632 const Container& a_particles,
633 const int a_numComp,
634 PatchDeposit a_patchDeposit) const
635 {
636 CH_TIME("EBAMRParticleMesh::depositInterpCore");
637
638 CH_assert(m_isDefined);
639 CH_assert(a_meshData[0]->nComp() == a_numComp);
640
641 DataOps::setValue(a_meshData, 0.0);
642
643 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
644 const DisjointBoxLayout& dbl = m_eblgs[lvl]->getDBL();
645 const bool hasCoar = (lvl > 0);
646 const DataIterator& dit = dbl.dataIterator();
647
648 // 1. Deposit this level's valid particles.
649 const int nbox = dit.size();
650
651#pragma omp parallel for schedule(runtime)
652 for (int mybox = 0; mybox < nbox; mybox++) {
653 const DataIndex& din = dit[mybox];
654 const EBParticleMesh& interp = (*m_ebParticleMesh[lvl])[din];
655
656 EBCellFAB& rho = (*a_meshData[lvl])[din];
657
658 a_patchDeposit(interp, rho, a_particles[lvl][din], 1.0);
659 }
660
661 // 2. Fold the mass deposited into ghost cells into the owning patch's valid region.
662 a_meshData[lvl]->exchange(Interval(0, a_numComp - 1), m_levelCopiers[lvl], EBAddOp());
663
664 // 3. Move over-refinement-boundary mass between this level and the coarser one (mesh-side).
665 if (hasCoar) {
666 for (int comp = 0; comp < a_numComp; comp++) {
667 LevelData<EBCellFAB> coarAlias;
668 LevelData<EBCellFAB> fineAlias;
669
670 aliasLevelData<EBCellFAB>(coarAlias, &(*a_meshData[lvl - 1]), Interval(comp, comp));
671 aliasLevelData<EBCellFAB>(fineAlias, &(*a_meshData[lvl]), Interval(comp, comp));
672
673 m_coarseFinePM[lvl]->addFineGhostsToCoarse(coarAlias, fineAlias);
674 m_coarseFinePM[lvl]->addInvalidCoarseToFine(fineAlias, coarAlias);
675 }
676 }
677 }
678 }
679
687 void
689 {
690 CH_TIME("EBAMRParticleMesh::defineOuterHaloMasks");
691
692 constexpr int comp = 0;
693 constexpr int numComp = 1;
694
695 m_outerHaloMasks.clear();
696
697 for (int ighost = 1; ighost <= m_ghost; ighost++) {
698 Vector<RefCountedPtr<LevelData<BaseFab<bool>>>> mask(1 + m_finestLevel);
699
700 for (int lvl = 0; lvl < m_finestLevel; lvl++) {
701 const DisjointBoxLayout& grids = m_eblgs[lvl]->getDBL();
702 const DisjointBoxLayout& gridsFine = m_eblgs[lvl + 1]->getDBL();
703 const ProblemDomain& domain = m_eblgs[lvl]->getDomain();
704
705 DisjointBoxLayout gridsCoFi;
706 coarsen(gridsCoFi, gridsFine, m_refRat[lvl]);
707
708 mask[lvl] = RefCountedPtr<LevelData<BaseFab<bool>>>(
709 new LevelData<BaseFab<bool>>(grids, numComp, IntVect::Zero));
710
711 LevelData<BaseFab<bool>>& levelMask = *mask[lvl];
712 {
713 const DataIterator& dit = grids.dataIterator();
714
715 const int nbox = dit.size();
716
717#pragma omp parallel for schedule(runtime)
718 for (int mybox = 0; mybox < nbox; mybox++) {
719 const DataIndex& din = dit[mybox];
720
721 levelMask[din].setVal(false);
722 }
723 }
724
725 // The coarse-grid cells surrounding the fine level, viewed from the coarsened-fine grids.
726 IntVectSet halo;
727 {
728 const DataIterator& dit = gridsCoFi.dataIterator();
729 const int nbox = dit.size();
730
731#pragma omp parallel for schedule(runtime) reduction(+ : halo)
732 for (int mybox = 0; mybox < nbox; mybox++) {
733 const DataIndex& din = dit[mybox];
734 const Box coFiBox = gridsCoFi[din];
735 const Box grownBox = grow(coFiBox, ighost) & domain;
736 IntVectSet myHalo(grownBox);
737 myHalo -= coFiBox;
738
739 NeighborIterator nit(gridsCoFi);
740 for (nit.begin(din); nit.ok(); ++nit) {
741 myHalo -= gridsCoFi[nit()];
742 }
743 halo |= myHalo;
744 }
745 }
746
747 // Re-express the halo on the coarse grid via a CoFi data holder whose ghosts add onto the coarse grid.
748 LevelData<FArrayBox> coFiMask(gridsCoFi, numComp, ighost * IntVect::Unit);
749 LevelData<FArrayBox> coarMask(grids, numComp, IntVect::Zero);
750 {
751 const DataIterator& dit = gridsFine.dataIterator();
752 const int nbox = dit.size();
753
754#pragma omp parallel for schedule(runtime)
755 for (int mybox = 0; mybox < nbox; mybox++) {
756 const DataIndex& din = dit[mybox];
757
758 coFiMask[din].setVal(0.0);
759 }
760 }
761 {
762 const DataIterator& dit = grids.dataIterator();
763 const int nbox = dit.size();
764
765#pragma omp parallel for schedule(runtime)
766 for (int mybox = 0; mybox < nbox; mybox++) {
767 const DataIndex& din = dit[mybox];
768
769 coarMask[din].setVal(0.0);
770 }
771 }
772 {
773 const DataIterator& dit = gridsFine.dataIterator();
774 const int nbox = dit.size();
775
776#pragma omp parallel for schedule(runtime)
777 for (int mybox = 0; mybox < nbox; mybox++) {
778 const DataIndex& din = dit[mybox];
779 const Box region = coFiMask[din].box();
780 const IntVectSet curHalo = halo & region;
781
782 for (IVSIterator ivsit(curHalo); ivsit.ok(); ++ivsit) {
783 coFiMask[din](ivsit(), comp) = 1.0;
784 }
785 }
786 }
787
788 Copier copier;
789 copier.ghostDefine(gridsCoFi, grids, domain, ighost * IntVect::Unit);
790 coFiMask.copyTo(Interval(comp, comp), coarMask, Interval(comp, comp), copier, LDaddOp<FArrayBox>());
791
792 // Make the boolean mask; undefine empty BaseFabs (so copyMaskParticles skips them).
793 const DataIterator& dit = grids.dataIterator();
794 const int nbox = dit.size();
795
796#pragma omp parallel for schedule(runtime)
797 for (int mybox = 0; mybox < nbox; mybox++) {
798 const DataIndex& din = dit[mybox];
799 const Box box = grids[din];
800 const FArrayBox& realMask = coarMask[din];
801
802 BaseFab<bool>& boolMask = levelMask[din];
803
804 bool emptyMask = true;
805 for (BoxIterator bit(box); bit.ok(); ++bit) {
806 if (realMask(bit(), comp) > 0.0) {
807 boolMask(bit(), comp) = true;
808 emptyMask = false;
809 }
810 }
811 if (emptyMask) {
812 boolMask.clear();
813 }
814 }
815 }
816
817 mask[m_finestLevel] = RefCountedPtr<LevelData<BaseFab<bool>>>(nullptr);
818 m_outerHaloMasks.emplace(ighost, mask);
819 }
820 }
821
835 template <int NCOMP, typename Container, typename PatchDeposit>
836 void
837 depositHaloCore(EBAMRCellData& a_meshData, const Container& a_particles, PatchDeposit a_patchDeposit) const
838 {
839 CH_TIME("EBAMRParticleMesh::depositHaloCore");
840
841 CH_assert(m_isDefined);
842 CH_assert(a_meshData[0]->nComp() == NCOMP);
843
844 DataOps::setValue(a_meshData, 0.0);
845
846 // Copy the coarse-side halo particles (width 1) into the container's mask holder.
847 constexpr int coarseMaskWidth = 1;
848 Container& particles = const_cast<Container&>(a_particles);
849 particles.copyMaskParticles(m_outerHaloMasks.at(coarseMaskWidth));
850
851 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
852 const DisjointBoxLayout& dbl = m_eblgs[lvl]->getDBL();
853 const bool hasCoar = (lvl > 0);
854
855 // 1. Deposit this level's valid particles.
856 const DataIterator& dit = dbl.dataIterator();
857 const int nbox = dit.size();
858
859#pragma omp parallel for schedule(runtime)
860 for (int mybox = 0; mybox < nbox; mybox++) {
861 const DataIndex& din = dit[mybox];
862 const EBParticleMesh& interp = (*m_ebParticleMesh[lvl])[din];
863
864 EBCellFAB& rho = (*a_meshData[lvl])[din];
865
866 a_patchDeposit(interp, rho, a_particles[lvl][din], 1.0);
867 }
868
869 // 2. Fold ghost-deposited mass into the owner patch.
870 a_meshData[lvl]->exchange(Interval(0, NCOMP - 1), m_levelCopiers[lvl], EBAddOp());
871
872 // 3. Mass deposited into fine ghosts across the refinement boundary belongs to the coarse level.
873 if (hasCoar) {
874 m_coarseFinePM[lvl]->addFineGhostsToCoarse(*a_meshData[lvl - 1], *a_meshData[lvl]);
875 }
876
877 // 4. Re-deposit the coarse halo particles on the refined-coarse grid and add to the fine level.
878 if (hasCoar) {
879 const auto& coarHalo = a_particles.getMaskParticles()[lvl - 1];
880 const Real widthScale = static_cast<Real>(m_refRat[lvl - 1]);
881 const EBLevelGrid& eblgFiCo = m_coarseFinePM[lvl]->getEblgFiCo();
882 const DisjointBoxLayout& dblFiCo = eblgFiCo.getDBL();
883
884 LevelData<EBCellFAB>& bufferFiCo = m_coarseFinePM[lvl]->template getBufferFiCo<NCOMP>();
885
886 const DataIterator& ditFiCo = dblFiCo.dataIterator();
887
888 const int nboxFiCo = ditFiCo.size();
889#pragma omp parallel for schedule(runtime)
890 for (int mybox = 0; mybox < nboxFiCo; mybox++) {
891 const DataIndex& din = ditFiCo[mybox];
892 const EBParticleMesh& interp = (*m_ebParticleMeshFiCo[lvl])[din];
893
894 EBCellFAB& dataFiCo = bufferFiCo[din];
895
896 dataFiCo.setVal(0.0);
897 a_patchDeposit(interp, dataFiCo, (*coarHalo)[din], widthScale);
898 }
899
900 for (int comp = 0; comp < NCOMP; comp++) {
901 LevelData<EBCellFAB> meshAlias;
902 LevelData<EBCellFAB> bufAlias;
903
904 aliasLevelData<EBCellFAB>(meshAlias, &(*a_meshData[lvl]), Interval(comp, comp));
905 aliasLevelData<EBCellFAB>(bufAlias, &bufferFiCo, Interval(comp, comp));
906
907 m_coarseFinePM[lvl]->addFiCoDataToFine(meshAlias, bufAlias);
908 }
909 }
910 }
911
912 particles.clearMaskParticles();
913 }
914
931 template <int NCOMP, typename Container, typename PatchDeposit, typename PatchDepositNGP>
932 void
933 depositHaloNGPCore(EBAMRCellData& a_meshData,
934 const Container& a_particles,
935 PatchDeposit a_patch,
936 PatchDepositNGP a_patchNGP) const
937 {
938 CH_TIME("EBAMRParticleMesh::depositHaloNGPCore");
939
940 CH_assert(m_isDefined);
941 CH_assert(a_meshData[0]->nComp() == NCOMP);
942
943 DataOps::setValue(a_meshData, 0.0);
944
945 // Move the coarse-side halo particles (width 1) out of the valid holder into the mask holder.
946 constexpr int coarseMaskWidth = 1;
947 Container& particles = const_cast<Container&>(a_particles);
948
949 particles.transferMaskParticles(m_outerHaloMasks.at(coarseMaskWidth));
950
951 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
952 const DisjointBoxLayout& dbl = m_eblgs[lvl]->getDBL();
953 const bool hasCoar = (lvl > 0);
954
955 // 1. Deposit the non-halo particles with the requested kernel, the halo particles with NGP.
956 const DataIterator& dit = dbl.dataIterator();
957 const int nbox = dit.size();
958
959#pragma omp parallel for schedule(runtime)
960 for (int mybox = 0; mybox < nbox; mybox++) {
961 const DataIndex& din = dit[mybox];
962 const EBParticleMesh& interp = (*m_ebParticleMesh[lvl])[din];
963
964 EBCellFAB& rho = (*a_meshData[lvl])[din];
965
966 a_patch(interp, rho, a_particles[lvl][din], 1.0);
967 a_patchNGP(interp, rho, (*a_particles.getMaskParticles()[lvl])[din], 1.0);
968 }
969
970 // 2. Fold ghost-deposited mass into the owner patch.
971 a_meshData[lvl]->exchange(Interval(0, NCOMP - 1), m_levelCopiers[lvl], EBAddOp());
972
973 // 3. Mass deposited into fine ghosts across the refinement boundary belongs to the coarse level.
974 if (hasCoar) {
975 for (int comp = 0; comp < NCOMP; comp++) {
976 LevelData<EBCellFAB> coarAlias;
977 LevelData<EBCellFAB> fineAlias;
978
979 aliasLevelData<EBCellFAB>(coarAlias, &(*a_meshData[lvl - 1]), Interval(comp, comp));
980 aliasLevelData<EBCellFAB>(fineAlias, &(*a_meshData[lvl]), Interval(comp, comp));
981
982 m_coarseFinePM[lvl]->addFineGhostsToCoarse(coarAlias, fineAlias);
983 }
984 }
985 }
986
987 // Return the halo particles to the valid holder.
988 particles.transferParticles(particles.getMaskParticles());
989 }
990
997 int
998 getTransitionMaskWidth(const DepositionType a_depositionType, const int a_refRat) const
999 {
1000 int maskWidth = 0;
1001 if (a_depositionType == DepositionType::CIC) {
1002 maskWidth = a_refRat / 2;
1003 }
1004 else if (a_depositionType == DepositionType::TSC) {
1005 maskWidth = a_refRat;
1006 }
1007 else {
1008 MayDay::Abort("EBAMRParticleMesh::getTransitionMaskWidth - logic bust");
1009 }
1010 if (maskWidth > m_ghost) {
1011 MayDay::Abort("EBAMRParticleMesh::getTransitionMaskWidth - not enough ghost cells");
1012 }
1013 return maskWidth;
1014 }
1015
1023 void
1025 {
1026 CH_TIME("EBAMRParticleMesh::defineTransitionMasks");
1027
1028 constexpr int comp = 0;
1029 constexpr int numComp = 1;
1030 const Interval interv = Interval(comp, comp);
1031
1032 m_transitionMasks.clear();
1033
1034 for (int ighost = 1; ighost <= m_ghost; ighost++) {
1035 Vector<RefCountedPtr<LevelData<BaseFab<bool>>>> mask(1 + m_finestLevel);
1036
1037 for (int lvl = 0; lvl < m_finestLevel; lvl++) {
1038 const DisjointBoxLayout& gridsFine = m_eblgs[lvl + 1]->getDBL();
1039 const EBLevelGrid& eblgFiCo = m_coarseFinePM[lvl + 1]->getEblgFiCo();
1040 const DisjointBoxLayout& gridsFiCo = eblgFiCo.getDBL();
1041 const ProblemDomain& domainFine = m_eblgs[lvl + 1]->getDomain();
1042
1043 mask[lvl] = RefCountedPtr<LevelData<BaseFab<bool>>>(
1044 new LevelData<BaseFab<bool>>(gridsFiCo, numComp, IntVect::Zero));
1045
1046 LevelData<BaseFab<bool>>& levelMask = *mask[lvl];
1047 LevelData<FArrayBox> cfivsFine(gridsFine, numComp, ighost * IntVect::Unit);
1048 LevelData<FArrayBox> cfivsFiCo(gridsFiCo, numComp, IntVect::Zero);
1049
1050 {
1051 const DataIterator& dit = gridsFiCo.dataIterator();
1052 const int nbox = dit.size();
1053
1054#pragma omp parallel for schedule(runtime)
1055 for (int mybox = 0; mybox < nbox; mybox++) {
1056 const DataIndex& din = dit[mybox];
1057
1058 levelMask[din].setVal(false);
1059 cfivsFiCo[din].setVal(0.0);
1060 }
1061 }
1062
1063 // Fine-grid coarse-fine interface band: ghost cells outside the fine boxes (minus neighbours).
1064 {
1065 const DataIterator& dit = gridsFine.dataIterator();
1066 const int nbox = dit.size();
1067
1068#pragma omp parallel for schedule(runtime)
1069 for (int mybox = 0; mybox < nbox; mybox++) {
1070 const DataIndex& din = dit[mybox];
1071 const Box cellBox = gridsFine[din];
1072 const Box ghostBox = grow(cellBox, ighost) & domainFine;
1073
1074 cfivsFine[din].setVal(1.0, ghostBox, comp);
1075 cfivsFine[din].setVal(0.0, cellBox, comp);
1076
1077 NeighborIterator nit(gridsFine);
1078 for (nit.begin(din); nit.ok(); ++nit) {
1079 cfivsFine[din].setVal(0.0, ghostBox & gridsFine[nit()], comp);
1080 }
1081 }
1082 }
1083
1084 Copier copier;
1085 copier.ghostDefine(gridsFine, gridsFiCo, domainFine, ighost * IntVect::Unit);
1086 cfivsFine.copyTo(interv, cfivsFiCo, interv, copier, LDaddOp<FArrayBox>());
1087
1088 const DataIterator& dit = gridsFiCo.dataIterator();
1089 const int nbox = dit.size();
1090
1091#pragma omp parallel for schedule(runtime)
1092 for (int mybox = 0; mybox < nbox; mybox++) {
1093 const DataIndex& din = dit[mybox];
1094 const Box cellBox = gridsFiCo[din];
1095 const FArrayBox& realMask = cfivsFiCo[din];
1096
1097 BaseFab<bool>& boolMask = levelMask[din];
1098
1099 bool emptyMask = true;
1100 for (BoxIterator bit(cellBox); bit.ok(); ++bit) {
1101 if (realMask(bit(), comp) > 0.5) {
1102 boolMask(bit(), comp) = true;
1103 emptyMask = false;
1104 }
1105 }
1106 if (emptyMask) {
1107 boolMask.clear();
1108 }
1109 }
1110 }
1111
1112 mask[m_finestLevel] = RefCountedPtr<LevelData<BaseFab<bool>>>(nullptr);
1113 m_transitionMasks.emplace(ighost, mask);
1114 }
1115 }
1116
1126 template <typename Container>
1127 void
1128 transferMaskParticlesTransition(Container& a_particles, const DepositionType a_depositionType) const
1129 {
1130 CH_TIME("EBAMRParticleMesh::transferMaskParticlesTransition");
1131
1132 if (a_depositionType == DepositionType::NGP) {
1133 return;
1134 }
1135
1136 for (int lvl = 0; lvl < m_finestLevel; lvl++) {
1137 const int maskWidth = this->getTransitionMaskWidth(a_depositionType, m_refRat[lvl]);
1138 const DisjointBoxLayout& dbl = m_eblgs[lvl]->getDBL();
1139 const Real dxFine = m_dx[lvl + 1];
1140
1141 const DataIterator& dit = dbl.dataIterator();
1142 const int nbox = dit.size();
1143
1144#pragma omp parallel for schedule(runtime)
1145 for (int mybox = 0; mybox < nbox; mybox++) {
1146 const DataIndex& din = dit[mybox];
1147 const BaseFab<bool>& mask = (*m_transitionMasks.at(maskWidth)[lvl])[din];
1148
1149 if (!mask.isUsable()) {
1150 continue;
1151 }
1152
1153 const Box maskBox = mask.box();
1154
1155 auto& valid = a_particles[lvl][din];
1156 auto& maskLeaf = (*a_particles.getMaskParticles()[lvl])[din];
1157
1158 std::size_t i = 0;
1159 while (i < valid.size()) {
1160 const RealVect pos = valid.position(i);
1161 IntVect iv;
1162 for (int dir = 0; dir < SpaceDim; dir++) {
1163 iv[dir] = static_cast<int>(std::floor((pos[dir] - m_probLo[dir]) / dxFine));
1164 }
1165 if (maskBox.contains(iv) && mask(iv, 0)) {
1166 maskLeaf.append(pos, valid.weight(i), valid.gather(i));
1167
1168 const std::size_t k = maskLeaf.size() - 1;
1169
1170 maskLeaf.particleID(k) = valid.particleID(i);
1171 maskLeaf.rankID(k) = valid.rankID(i);
1172
1173 valid.remove(i);
1174 }
1175 else {
1176 i++;
1177 }
1178 }
1179 }
1180 }
1181 }
1182
1199 template <int NCOMP, typename Container, typename PatchDeposit>
1200 void
1201 depositTransitionCore(EBAMRCellData& a_meshData,
1202 const Container& a_particles,
1203 const DepositionType a_depositionType,
1204 PatchDeposit a_patch) const
1205 {
1206 CH_TIME("EBAMRParticleMesh::depositTransitionCore");
1207
1208 CH_assert(m_isDefined);
1209 CH_assert(a_meshData[0]->nComp() == NCOMP);
1210
1211 if (a_depositionType == DepositionType::NGP) {
1212 this->depositInterpCore(a_meshData, a_particles, NCOMP, a_patch);
1213
1214 return;
1215 }
1216
1217 DataOps::setValue(a_meshData, 0.0);
1218
1219 Container& particles = const_cast<Container&>(a_particles);
1220 this->transferMaskParticlesTransition(particles, a_depositionType);
1221
1222 // 1. Deposit the non-transition particles on their levels.
1223 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
1224 const DisjointBoxLayout& dbl = m_eblgs[lvl]->getDBL();
1225 const DataIterator& dit = dbl.dataIterator();
1226 const int nbox = dit.size();
1227
1228#pragma omp parallel for schedule(runtime)
1229 for (int mybox = 0; mybox < nbox; mybox++) {
1230 const DataIndex& din = dit[mybox];
1231 const EBParticleMesh& interp = (*m_ebParticleMesh[lvl])[din];
1232
1233 EBCellFAB& rho = (*a_meshData[lvl])[din];
1234
1235 a_patch(interp, rho, a_particles[lvl][din], 1.0);
1236 }
1237 }
1238
1239 // 2. Fold ghost mass into the owner patch; fine-ghost mass over the boundary goes to coarse.
1240 for (int lvl = 0; lvl <= m_finestLevel; lvl++) {
1241 a_meshData[lvl]->exchange(Interval(0, NCOMP - 1), m_levelCopiers[lvl], EBAddOp());
1242 if (lvl > 0) {
1243 for (int comp = 0; comp < NCOMP; comp++) {
1244 LevelData<EBCellFAB> coarAlias;
1245 LevelData<EBCellFAB> fineAlias;
1246
1247 aliasLevelData<EBCellFAB>(coarAlias, &(*a_meshData[lvl - 1]), Interval(comp, comp));
1248 aliasLevelData<EBCellFAB>(fineAlias, &(*a_meshData[lvl]), Interval(comp, comp));
1249
1250 m_coarseFinePM[lvl]->addFineGhostsToCoarse(coarAlias, fineAlias);
1251 }
1252 }
1253 }
1254
1255 // 3a. Deposit the transition particles on the refined-coarse grid (fine-grid width).
1256 for (int lvl = 0; lvl < m_finestLevel; lvl++) {
1257 const int maskWidth = this->getTransitionMaskWidth(a_depositionType, m_refRat[lvl]);
1258 const DisjointBoxLayout& dblFiCo = m_coarseFinePM[lvl + 1]->getEblgFiCo().getDBL();
1259 LevelData<EBCellFAB>& bufferFiCo = m_coarseFinePM[lvl + 1]->template getBufferFiCo<NCOMP>();
1260
1261 const DataIterator& ditFiCo = dblFiCo.dataIterator();
1262 const int nboxFiCo = ditFiCo.size();
1263
1264#pragma omp parallel for schedule(runtime)
1265 for (int mybox = 0; mybox < nboxFiCo; mybox++) {
1266 const DataIndex& din = ditFiCo[mybox];
1267
1268 EBCellFAB& dataFiCo = bufferFiCo[din];
1269
1270 dataFiCo.setVal(0.0);
1271
1272 const BaseFab<bool>& mask = (*m_transitionMasks.at(maskWidth)[lvl])[din];
1273 if (mask.isUsable()) {
1274 const EBParticleMesh& interp = (*m_ebParticleMeshFiCo[lvl + 1])[din];
1275
1276 a_patch(interp, dataFiCo, (*a_particles.getMaskParticles()[lvl])[din], 1.0);
1277 }
1278 }
1279 }
1280
1281 // 3b/c/d. Distribute the refined-coarse buffer to the fine level and (restricted) to the coarse level.
1282 for (int lvl = 0; lvl < m_finestLevel; lvl++) {
1283 LevelData<EBCellFAB>& bufferFiCo = m_coarseFinePM[lvl + 1]->template getBufferFiCo<NCOMP>();
1284
1285 m_coarseFinePM[lvl + 1]->addFiCoDataToFine(*a_meshData[lvl + 1], bufferFiCo);
1286 m_coarseFinePM[lvl + 1]->exchangeAndAddFiCoData(bufferFiCo);
1287 m_coarseFinePM[lvl + 1]->restrictAndAddFiCoDataToCoar(*a_meshData[lvl],
1288 bufferFiCo,
1289 EBCoarseFineParticleMesh::Average::Conservative);
1290 }
1291
1292 // Return the transition particles to the valid holder.
1293 particles.transferParticles(particles.getMaskParticles());
1294 }
1295};
1296
1297#include <CD_NamespaceFooter.H>
1298
1299#endif
Declaration of deposition algorithms in an AMR context.
CoarseFineDeposition
Coarse-fine deposition types (see CD_EBAMRParticleMesh for how these are handled).
Definition CD_CoarseFineDeposition.H:28
Agglomeration of useful data operations.
Declaration of deposition types.
DepositionType
Deposition types.
Definition CD_DepositionType.H:24
Class for holding data across EBAMR hierarchies.
Declaration of a Copier class for making incrementation between LevelData<EBCellFAB> easier.
Declaration of a class for handling particle deposition arithmetic near refinement boundaries.
Single-patch ParticleSoA deposit/interpolate onto an embedded-boundary mesh.
Declaration of various useful OpenMP-related utilities.
Declaration of an AMR-hierarchy container that owns per-patch ParticleSoA leaves.
static void setValue(LevelData< MFInterfaceFAB< T > > &a_lhs, const T &a_value)
Set value in an MFInterfaceFAB data holder.
Definition CD_DataOpsImplem.H:24
AMR driver that deposits/interpolates ParticleContainer particles across the hierarchy.
Definition CD_EBAMRParticleMesh.H:74
int m_ghost
Number of ghost cells in the mesh data holders.
Definition CD_EBAMRParticleMesh.H:471
void defineTransitionMasks()
Build the per-width transition masks: the fine-side transition band, on the refined-coarse grid.
Definition CD_EBAMRParticleMesh.H:1024
void depositWeight(EBAMRCellData &a_meshData, const ParticleContainer< P, Traits > &a_particles, const DepositionType a_depositionType, const CoarseFineDeposition a_coarseFineDeposition, const bool a_forceIrregNGP)
Deposit the container-owned weight onto the AMR mesh.
Definition CD_EBAMRParticleMesh.H:251
void interpolate(ParticleContainer< P, Traits > &a_particles, const EBAMRCellData &a_meshData, const DepositionType a_interpType, const bool a_forceIrregNGP) const
Interpolate a mesh field onto one or more payload columns, across all levels.
Definition CD_EBAMRParticleMesh.H:164
~EBAMRParticleMesh()=default
Destructor.
void define(const Vector< RefCountedPtr< EBLevelGrid > > &a_eblgs, const Vector< int > &a_refRat, const Vector< Real > &a_dx, const RealVect &a_probLo, const int a_ghost, const int a_finestLevel)
Define the per-level leaves, coarse-fine mesh operators, and halo/transition masks.
Definition CD_EBAMRParticleMesh.H:114
void interpolateWeight(ParticleContainer< P, Traits > &a_particles, const EBAMRCellData &a_meshData, const DepositionType a_interpType, const bool a_forceIrregNGP) const
Interpolate a mesh field onto the container-owned weight column, across all levels.
Definition CD_EBAMRParticleMesh.H:204
int getTransitionMaskWidth(const DepositionType a_depositionType, const int a_refRat) const
Transition-mask width for a kernel: CIC -> refRat/2, TSC -> refRat (NGP is handled upstream).
Definition CD_EBAMRParticleMesh.H:998
void transferMaskParticlesTransition(Container &a_particles, const DepositionType a_depositionType) const
Move the coarse-side transition particles into the container mask holder (using the FiCo mask).
Definition CD_EBAMRParticleMesh.H:1128
void depositGathered(EBAMRCellData &a_meshData, const ParticleContainer< P, Traits > &a_particles, const DepositionType a_depositionType, const CoarseFineDeposition a_coarseFineDeposition, const bool a_forceIrregNGP, CellGather a_cellGather)
Deposit a custom per-particle scalar (computed by a_cellGather) onto the AMR mesh.
Definition CD_EBAMRParticleMesh.H:316
EBAMRParticleMesh & operator=(const EBAMRParticleMesh &)=delete
Copy assignment is deleted.
std::map< int, Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > > m_outerHaloMasks
Outer-halo masks keyed by halo width: per-level coarse cells just outside the fine patch.
Definition CD_EBAMRParticleMesh.H:506
Vector< RefCountedPtr< EBCoarseFineParticleMesh > > m_coarseFinePM
Per-level coarse-fine mesh operators (null on level 0).
Definition CD_EBAMRParticleMesh.H:496
Vector< Real > m_dx
Per-level grid spacing (isotropic).
Definition CD_EBAMRParticleMesh.H:461
void errorUnsupported() const
Abort on an unrecognized coarse-fine deposition strategy.
Definition CD_EBAMRParticleMesh.H:517
void defineEBParticleMesh()
Build the per-level per-patch EBParticleMesh leaves (valid grids + refined-coarse grids).
Definition CD_EBAMRParticleMesh.H:526
int m_finestLevel
Finest AMR level index.
Definition CD_EBAMRParticleMesh.H:476
EBAMRParticleMesh(const EBAMRParticleMesh &)=delete
Copy construction is deleted (shared RefCountedPtr state).
void defineOuterHaloMasks()
Build the per-width outer-halo masks: per level, the coarse cells just outside the fine patch.
Definition CD_EBAMRParticleMesh.H:688
void depositHaloNGPCore(EBAMRCellData &a_meshData, const Container &a_particles, PatchDeposit a_patch, PatchDepositNGP a_patchNGP) const
The CoarseFineDeposition::HaloNGP deposition algorithm.
Definition CD_EBAMRParticleMesh.H:933
RealVect m_probLo
Lower-left corner of the physical domain.
Definition CD_EBAMRParticleMesh.H:466
bool m_isDefined
Whether define() has been called.
Definition CD_EBAMRParticleMesh.H:481
Vector< RefCountedPtr< LayoutData< EBParticleMesh > > > m_ebParticleMesh
Per-level per-patch deposition/interpolation leaves.
Definition CD_EBAMRParticleMesh.H:486
Vector< RefCountedPtr< EBLevelGrid > > m_eblgs
Per-level EB level grids.
Definition CD_EBAMRParticleMesh.H:451
std::map< int, Vector< RefCountedPtr< LevelData< BaseFab< bool > > > > > m_transitionMasks
Transition masks keyed by width: per-level fine-side transition band, on the refined-coarse grid.
Definition CD_EBAMRParticleMesh.H:511
Vector< Copier > m_levelCopiers
Per-level valid+ghost -> valid Copiers (fold ghost-deposited mass into the owner patch).
Definition CD_EBAMRParticleMesh.H:491
void deposit(EBAMRCellData &a_meshData, const ParticleContainer< P, Traits > &a_particles, const DepositionType a_depositionType, const CoarseFineDeposition a_coarseFineDeposition, const bool a_forceIrregNGP)
Deposit one or more payload columns onto the AMR mesh.
Definition CD_EBAMRParticleMesh.H:395
EBAMRParticleMesh()
Default constructor. Leaves the object undefined; call define().
Definition CD_EBAMRParticleMesh.H:84
void depositTransitionCore(EBAMRCellData &a_meshData, const Container &a_particles, const DepositionType a_depositionType, PatchDeposit a_patch) const
The CoarseFineDeposition::Transition deposition algorithm.
Definition CD_EBAMRParticleMesh.H:1201
void depositInterpCore(EBAMRCellData &a_meshData, const Container &a_particles, const int a_numComp, PatchDeposit a_patchDeposit) const
The CoarseFineDeposition::Interp deposition algorithm, parameterized by the per-patch deposit.
Definition CD_EBAMRParticleMesh.H:631
Vector< RefCountedPtr< LayoutData< EBParticleMesh > > > m_ebParticleMeshFiCo
Per-level per-patch leaves on the refined-coarse (FiCo) grid (null on level 0).
Definition CD_EBAMRParticleMesh.H:501
void depositHaloCore(EBAMRCellData &a_meshData, const Container &a_particles, PatchDeposit a_patchDeposit) const
The CoarseFineDeposition::Halo deposition algorithm.
Definition CD_EBAMRParticleMesh.H:837
void defineCoarseFineMotion()
Build the per-level coarse-fine mesh operators (null on level 0).
Definition CD_EBAMRParticleMesh.H:600
void defineLevelMotion()
Build the per-level valid+ghost -> valid Copiers.
Definition CD_EBAMRParticleMesh.H:582
Vector< int > m_refRat
Per-level refinement ratios.
Definition CD_EBAMRParticleMesh.H:456
A Copier class for making copying between BoxLayoutData<EBCellFAB> easier. This increments EBCellFABs...
Definition CD_EBAddOp.H:28
A class for handling particle deposition clouds that hang over refinement boundaries....
Definition CD_EBCoarseFineParticleMesh.H:42
Deposits/interpolates ParticleSoA leaves on a single patch, with embedded-boundary (cut-cell) awarene...
Definition CD_EBParticleMesh.H:71
void depositWeight(EBCellFAB &a_meshData, const int a_comp, const ParticleSoA< P, Traits > &a_particles, const DepositionType a_depositionType, const Real a_widthScale, const bool a_forceIrregNGP) const
Deposit the container-owned weight column onto mesh component a_comp.
Definition CD_EBParticleMesh.H:136
void interpolateWeight(ParticleSoA< P, Traits > &a_particles, const EBCellFAB &a_meshData, const int a_comp, const DepositionType a_interpType, const bool a_forceIrregNGP) const
Interpolate mesh component a_comp onto the container-owned weight column.
Definition CD_EBParticleMesh.H:360
void depositGathered(EBCellFAB &a_meshData, const int a_comp, const ParticleSoA< P, Traits > &a_particles, const DepositionType a_depositionType, const Real a_widthScale, const bool a_forceIrregNGP, GatherFunc &&a_gather) const
Deposit a custom per-particle scalar (computed by a_gather) onto mesh component a_comp.
Definition CD_EBParticleMesh.H:263
AMR-hierarchy container of computational particles, stored per patch in Struct-of-Arrays form.
Definition CD_ParticleContainer.H:123