12 #ifndef CD_EBParticleMeshImplem_H
13 #define CD_EBParticleMeshImplem_H
21 #include <CD_NamespaceHeader.H>
23 template <
class P, const Real& (P::*particleScalarField)() const>
28 const bool a_forceIrregNGP)
const
30 CH_TIME(
"EBParticleMesh::deposit");
32 const Interval variables(0, 0);
34 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
35 const P& curParticle = lit();
36 const RealVect& curPosition = curParticle.position();
37 const Real& curStrength = (curParticle.*particleScalarField)();
40 ->depositParticle(a_rho,
m_probLo,
m_dx, curPosition, &curStrength, variables, a_depositionType, a_forceIrregNGP);
44 template <
class P, Real (P::*particleScalarField)() const>
49 const bool a_forceIrregNGP)
const
51 CH_TIME(
"EBParticleMesh::deposit");
53 const Interval variables(0, 0);
55 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
56 const P& curParticle = lit();
57 const RealVect& curPosition = curParticle.position();
58 const Real& curStrength = (curParticle.*particleScalarField)();
61 ->depositParticle(a_rho,
m_probLo,
m_dx, curPosition, &curStrength, variables, a_depositionType, a_forceIrregNGP);
65 template <
class P, const Real& (P::*particleScalarField)() const>
70 const bool a_forceIrregNGP)
const
72 CH_TIME(
"EBParticleMesh::deposit2");
74 const Interval variables(0, 0);
76 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
77 const P& curParticle = lit();
78 const RealVect& curPosition = curParticle.position();
79 const Real& curStrength = (curParticle.*particleScalarField)();
92 template <
class P, Real (P::*particleScalarField)() const>
97 const bool a_forceIrregNGP)
const
99 CH_TIME(
"EBParticleMesh::deposit2");
101 const Interval variables(0, 0);
103 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
104 const P& curParticle = lit();
105 const RealVect& curPosition = curParticle.position();
106 const Real& curStrength = (curParticle.*particleScalarField)();
119 template <
class P, const Real& (P::*particleScalarField)() const>
124 const bool a_forceIrregNGP)
const
126 CH_TIME(
"EBParticleMesh::deposit4");
128 const Interval variables(0, 0);
130 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
131 const P& curParticle = lit();
132 const RealVect& curPosition = curParticle.position();
133 const Real& curStrength = (curParticle.*particleScalarField)();
146 template <
class P, Real (P::*particleScalarField)() const>
151 const bool a_forceIrregNGP)
const
153 CH_TIME(
"EBParticleMesh::deposit4");
155 const Interval variables(0, 0);
157 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
158 const P& curParticle = lit();
159 const RealVect& curPosition = curParticle.position();
160 const Real& curStrength = (curParticle.*particleScalarField)();
173 template <
class P, const RealVect& (P::*particleVectorField)() const>
178 const bool a_forceIrregNGP)
const
180 CH_TIME(
"EBParticleMesh::deposit");
185 const Interval variables(0, SpaceDim - 1);
187 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
188 const P& curParticle = lit();
189 const RealVect& curPosition = curParticle.position();
190 const RealVect& curStrength = (curParticle.*particleVectorField)();
196 curStrength.dataPtr(),
203 template <
class P, RealVect (P::*particleVectorField)() const>
208 const bool a_forceIrregNGP)
const
210 CH_TIME(
"EBParticleMesh::deposit");
212 const Interval variables(0, SpaceDim - 1);
214 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
215 const P& curParticle = lit();
216 const RealVect& curPosition = curParticle.position();
217 const RealVect& curStrength = (curParticle.*particleVectorField)();
223 curStrength.dataPtr(),
230 template <
class P, const RealVect& (P::*particleVectorField)() const>
235 const bool a_forceIrregNGP)
const
237 CH_TIME(
"EBParticleMesh::deposit2");
239 const Interval variables(0, SpaceDim - 1);
241 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
242 const P& curParticle = lit();
243 const RealVect& curPosition = curParticle.position();
244 const RealVect& curStrength = (curParticle.*particleVectorField)();
250 curStrength.dataPtr(),
257 template <
class P, RealVect (P::*particleVectorField)() const>
262 const bool a_forceIrregNGP)
const
264 CH_TIME(
"EBParticleMesh::deposit2");
266 const Interval variables(0, SpaceDim - 1);
268 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
269 const P& curParticle = lit();
270 const RealVect& curPosition = curParticle.position();
271 const RealVect& curStrength = (curParticle.*particleVectorField)();
277 curStrength.dataPtr(),
284 template <
class P, const RealVect& (P::*particleVectorField)() const>
289 const bool a_forceIrregNGP)
const
291 CH_TIME(
"EBParticleMesh::deposit4");
293 const Interval variables(0, SpaceDim - 1);
295 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
296 const P& curParticle = lit();
297 const RealVect& curPosition = curParticle.position();
298 const RealVect& curStrength = (curParticle.*particleVectorField)();
304 curStrength.dataPtr(),
311 template <
class P, RealVect (P::*particleVectorField)() const>
316 const bool a_forceIrregNGP)
const
318 CH_TIME(
"EBParticleMesh::deposit4");
320 const Interval variables(0, SpaceDim - 1);
322 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
323 const P& curParticle = lit();
324 const RealVect& curPosition = curParticle.position();
325 const RealVect& curStrength = (curParticle.*particleVectorField)();
331 curStrength.dataPtr(),
338 template <
class P, Real& (P::*particleScalarField)()>
341 const EBCellFAB& a_meshScalarField,
343 const bool a_forceIrregNGP)
const
345 CH_TIME(
"EBParticleMesh::interpolate(Real)");
347 CH_assert(a_meshScalarField.nComp() == 1);
349 const Interval variables(0, 0);
351 Box validBox =
m_domain.domainBox();
353 switch (a_interpType) {
354 case DepositionType::NGP: {
359 case DepositionType::CIC: {
360 validBox = grow(validBox, -1);
364 case DepositionType::TSC: {
365 validBox = grow(validBox, -2);
369 case DepositionType::W4: {
370 validBox = grow(validBox, -3);
375 MayDay::Error(
"EBParticleMesh::interpolate - logic bust");
379 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
380 P& curParticle = lit();
381 const RealVect& curPosition = curParticle.position();
383 Real& curParticleField = (curParticle.*particleScalarField)();
397 template <
class P, RealVect& (P::*particleVectorField)()>
400 const EBCellFAB& a_meshVectorField,
402 const bool a_forceIrregNGP)
const
404 CH_TIME(
"EBParticleMesh::interpolate(RealVect)");
406 CH_assert(a_meshVectorField.nComp() == SpaceDim);
408 const Interval variables(0, SpaceDim - 1);
413 Box validBox =
m_domain.domainBox();
415 switch (a_interpType) {
416 case DepositionType::NGP: {
421 case DepositionType::CIC: {
422 validBox = grow(validBox, -1);
426 case DepositionType::TSC: {
427 validBox = grow(validBox, -2);
431 case DepositionType::W4: {
432 validBox = grow(validBox, -3);
437 MayDay::Error(
"EBParticleMesh::interpolate - logic bust");
441 for (ListIterator<P> lit(a_particleList); lit; ++lit) {
442 P& curParticle = lit();
443 const RealVect& curPosition = curParticle.position();
445 RealVect& curParticleField = (curParticle.*particleVectorField)();
461 const RealVect& a_probLo,
462 const RealVect& a_dx,
463 const RealVect& a_position,
464 const Real* a_strength,
465 const Interval a_components,
467 const bool a_forceIrregNGP)
const
469 CH_TIME(
"EBParticleMesh::depositParticle");
471 const int startComp = a_components.begin();
472 const int endComp = a_components.end();
474 CH_assert(a_rho.nComp() >= endComp - 1);
481 const auto& dx = a_dx;
482 auto getCellIndex = [&dx](
const RealVect a_rv) -> IntVect {
483 return IntVect(D_DECL(std::floor(a_rv[0] / dx[0]), std::floor(a_rv[1] / dx[1]), std::floor(a_rv[2] / dx[2])));
487 const IntVect particleIndex = getCellIndex(a_position - a_probLo);
490 CH_assert(
m_region.contains(particleIndex));
494 const Real invVol = 1. / std::pow(a_dx[0], SpaceDim);
496 auto particleDisplacement = [&](
const IntVect& iv) -> RealVect {
497 return (a_probLo + (RealVect(iv) + 0.5 * RealVect::Unit) * a_dx - a_position) / a_dx;
501 FArrayBox& rho = a_rho.getFArrayBox();
504 if (
m_ebisbox.isIrregular(particleIndex) && a_forceIrregNGP) {
505 for (
int comp = startComp; comp <= endComp; comp++) {
506 rho(particleIndex, comp) += a_strength[comp] * invVol;
510 switch (a_depositionType) {
511 case DepositionType::NGP: {
512 for (
int comp = startComp; comp <= endComp; comp++) {
513 rho(particleIndex, comp) += a_strength[comp] * invVol;
517 case DepositionType::CIC: {
520 const IntVect loIndex = getCellIndex(a_position - a_probLo - 0.5 * a_dx);
521 const Box cicBox = Box(loIndex, loIndex + IntVect::Unit);
524 auto cicKernel = [&](
const IntVect& iv) ->
void {
525 Real weight = invVol;
528 const RealVect L = particleDisplacement(iv);
529 for (
int dir = 0; dir < SpaceDim; dir++) {
530 weight *= (1. - std::abs(L[dir]));
533 for (
int comp = startComp; comp <= endComp; comp++) {
534 rho(iv, comp) += weight * a_strength[comp];
543 case DepositionType::TSC: {
547 const IntVect loIndex = getCellIndex(a_position - a_probLo - a_dx);
548 const Box tscBox = Box(loIndex, loIndex + 2 * IntVect::Unit);
551 auto tscKernel = [&](
const IntVect& iv) ->
void {
552 Real weight = invVol;
554 const RealVect L = particleDisplacement(iv);
555 for (
int dir = 0; dir < SpaceDim; dir++) {
556 const Real l = std::abs(L[dir]);
559 weight *= 0.75 - l * l;
562 weight *= 0.5 * (1.5 - l) * (1.5 - l);
566 for (
int comp = startComp; comp <= endComp; comp++) {
567 rho(iv, comp) += weight * a_strength[comp];
576 case DepositionType::W4: {
580 const IntVect loIndex = getCellIndex(a_position - a_probLo - 1.5 * a_dx);
581 const Box w4Box = Box(loIndex, loIndex + 3 * IntVect::Unit);
584 auto w4Kernel = [&](
const IntVect& iv) ->
void {
585 Real weight = invVol;
588 const RealVect L = particleDisplacement(iv);
589 for (
int dir = 0; dir < SpaceDim; dir++) {
590 const Real l = std::abs(L[dir]);
593 weight *= 1.0 - 2.5 * l * l + 1.5 * l * l * l;
596 weight *= 0.5 * (2. - l) * (2. - l) * (1. - l);
600 for (
int comp = startComp; comp <= endComp; comp++) {
601 rho(iv, comp) += weight * a_strength[comp];
611 MayDay::Error(
"EBParticleMesh::depositParticle - logic bust, unknown particle deposition.");
620 const RealVect& a_probLo,
621 const RealVect& a_dx,
622 const RealVect& a_position,
623 const Real* a_strength,
624 const Interval a_components,
626 const bool a_forceIrregNGP)
const
628 CH_TIME(
"EBParticleMesh::depositParticle2");
630 const int startComp = a_components.begin();
631 const int endComp = a_components.end();
633 CH_assert(a_rho.nComp() >= endComp - 1);
643 const auto& dx = a_dx;
644 auto getCellIndex = [&dx](
const RealVect a_rv) -> IntVect {
645 return IntVect(D_DECL(std::floor(a_rv[0] / dx[0]), std::floor(a_rv[1] / dx[1]), std::floor(a_rv[2] / dx[2])));
649 const IntVect particleIndex = getCellIndex(a_position - a_probLo);
652 CH_assert(
m_region.contains(particleIndex));
656 const Real invVol = 1. / std::pow(a_dx[0], SpaceDim);
658 auto particleDisplacement = [&](
const IntVect& iv) -> RealVect {
659 return (a_probLo + (RealVect(iv) + 0.5 * RealVect::Unit) * a_dx - a_position) / a_dx;
663 FArrayBox& rho = a_rho.getFArrayBox();
666 if (
m_ebisbox.isIrregular(particleIndex) && a_forceIrregNGP) {
667 for (
int comp = startComp; comp <= endComp; comp++) {
668 rho(particleIndex, comp) += a_strength[comp] * invVol;
672 switch (a_depositionType) {
673 case DepositionType::NGP: {
674 for (
int comp = startComp; comp <= endComp; comp++) {
675 rho(particleIndex, comp) += a_strength[comp] * invVol;
680 case DepositionType::CIC: {
683 const IntVect loIndex = getCellIndex(a_position - a_probLo - 1.0 * a_dx);
684 const Box cic2Box = Box(loIndex, loIndex + 2 * IntVect::Unit);
687 auto cic2Kernel = [&](
const IntVect& iv) ->
void {
688 Real weight = invVol;
691 const RealVect L = particleDisplacement(iv);
692 for (
int dir = 0; dir < SpaceDim; dir++) {
693 const Real l = std::abs(L[dir]);
696 weight *= 0.5 * (1.5 - l);
703 for (
int comp = startComp; comp <= endComp; comp++) {
704 rho(iv, comp) += a_strength[comp] * weight;
714 "EBParticleMesh::depositParticle2 - Invalid deposition type - only NGP and CIC supported for this deposition method. TSC/W4 have not been worked out.");
723 const RealVect& a_probLo,
724 const RealVect& a_dx,
725 const RealVect& a_position,
726 const Real* a_strength,
727 const Interval a_components,
729 const bool a_forceIrregNGP)
const
731 CH_TIME(
"EBParticleMesh::depositParticle2");
733 const int startComp = a_components.begin();
734 const int endComp = a_components.end();
736 CH_assert(a_rho.nComp() >= endComp - 1);
746 const auto& dx = a_dx;
747 auto getCellIndex = [&dx](
const RealVect a_rv) -> IntVect {
748 return IntVect(D_DECL(std::floor(a_rv[0] / dx[0]), std::floor(a_rv[1] / dx[1]), std::floor(a_rv[2] / dx[2])));
752 const IntVect particleIndex = getCellIndex(a_position - a_probLo);
755 CH_assert(
m_region.contains(particleIndex));
759 const Real invVol = 1.0 / std::pow(a_dx[0], SpaceDim);
761 auto particleDisplacement = [&](
const IntVect& iv) -> RealVect {
762 return (a_probLo + (RealVect(iv) + 0.5 * RealVect::Unit) * a_dx - a_position) / a_dx;
766 FArrayBox& rho = a_rho.getFArrayBox();
769 if (
m_ebisbox.isIrregular(particleIndex) && a_forceIrregNGP) {
770 for (
int comp = startComp; comp <= endComp; comp++) {
771 rho(particleIndex, comp) += a_strength[comp] * invVol;
775 switch (a_depositionType) {
776 case DepositionType::NGP: {
777 for (
int comp = startComp; comp <= endComp; comp++) {
778 rho(particleIndex, comp) += a_strength[comp] * invVol;
782 case DepositionType::CIC: {
785 const IntVect loIndex = getCellIndex(a_position - a_probLo - 2.0 * a_dx);
786 const Box cic4Box = Box(loIndex, loIndex + 4 * IntVect::Unit);
789 auto cic4Kernel = [&](
const IntVect& iv) ->
void {
790 Real weight = invVol;
793 const RealVect L = particleDisplacement(iv);
794 for (
int dir = 0; dir < SpaceDim; dir++) {
795 const Real l = std::abs(L[dir]);
798 weight *= 0.25 * (2.5 - l);
805 for (
int comp = startComp; comp <= endComp; comp++) {
806 rho(iv, comp) += a_strength[comp] * weight;
816 "EBParticleMesh::depositParticle4 - Invalid deposition type - only NGP and CIC supported for this deposition method. TSC/W4 have not been worked out.");
825 const EBCellFAB& a_meshField,
826 const Box& a_validBox,
827 const RealVect& a_probLo,
828 const RealVect& a_dx,
829 const RealVect& a_position,
830 const Interval& a_interval,
832 const bool a_forceIrregNGP)
const
834 CH_TIME(
"EBParticleMesh::interpolateParticle");
836 const int startComp = a_interval.begin();
837 const int endComp = a_interval.end();
839 CH_assert(a_meshField.nComp() >= endComp - 1);
846 const auto& dx = a_dx;
848 auto getCellIndex = [&dx](
const RealVect a_rv) -> IntVect {
849 return IntVect(D_DECL(std::floor(a_rv[0] / dx[0]), std::floor(a_rv[1] / dx[1]), std::floor(a_rv[2] / dx[2])));
853 const IntVect particleIndex = getCellIndex(a_position - a_probLo);
856 CH_assert(
m_region.contains(particleIndex));
859 auto particleDisplacement = [&](
const IntVect& iv) -> RealVect {
860 return (a_probLo + (RealVect(iv) + 0.5 * RealVect::Unit) * a_dx - a_position) / a_dx;
864 const FArrayBox& meshField = a_meshField.getFArrayBox();
867 if ((
m_ebisbox.isIrregular(particleIndex) && a_forceIrregNGP) || !(a_validBox.contains(particleIndex))) {
868 for (
int comp = startComp; comp <= endComp; comp++) {
869 a_particleField[comp] = meshField(particleIndex, comp);
872 else if (
m_ebisbox.isCovered(particleIndex)) {
873 for (
int comp = startComp; comp <= endComp; comp++) {
874 a_particleField[comp] = 0.0;
878 switch (a_interpType) {
879 case DepositionType::NGP:
881 for (
int comp = startComp; comp <= endComp; comp++) {
882 a_particleField[comp] = meshField(particleIndex, comp);
887 case DepositionType::CIC:
891 const IntVect loIndex = getCellIndex(a_position - a_probLo - 0.5 * a_dx);
892 const Box cicBox = Box(loIndex, loIndex + IntVect::Unit);
896 auto cicKernel = [&](
const IntVect& iv) ->
void {
900 const RealVect L = particleDisplacement(iv);
901 for (
int dir = 0; dir < SpaceDim; dir++) {
902 weight *= (1. - std::abs(L[dir]));
905 for (
int comp = startComp; comp <= endComp; comp++) {
906 a_particleField[comp] += weight * meshField(iv, comp);
911 for (
int comp = startComp; comp <= endComp; comp++) {
912 a_particleField[comp] = 0.0;
919 case DepositionType::TSC:
923 const IntVect loIndex = getCellIndex(a_position - a_probLo - 1.0 * a_dx);
924 const Box tscBox = Box(loIndex, loIndex + 2 * IntVect::Unit);
928 auto tscKernel = [&](
const IntVect& iv) ->
void {
932 const RealVect L = particleDisplacement(iv);
933 for (
int dir = 0; dir < SpaceDim; dir++) {
934 const Real& l = std::abs(L[dir]);
937 weight *= 0.75 - l * l;
940 weight *= 0.5 * (1.5 - l) * (1.5 - l);
944 for (
int comp = startComp; comp <= endComp; comp++) {
945 a_particleField[comp] += weight * meshField(iv, comp);
950 for (
int comp = startComp; comp <= endComp; comp++) {
951 a_particleField[comp] = 0.0;
958 case DepositionType::W4:
962 const IntVect loIndex = getCellIndex(a_position - a_probLo - 1.5 * a_dx);
963 const Box w4Box = Box(loIndex, loIndex + 3 * IntVect::Unit);
966 auto w4Kernel = [&](
const IntVect& iv) ->
void {
970 const RealVect L = particleDisplacement(iv);
971 for (
int dir = 0; dir < SpaceDim; dir++) {
972 const Real l = std::abs(L[dir]);
975 weight *= 1.0 - 2.5 * l * l + 1.5 * l * l * l;
978 weight *= 0.5 * (2. - l) * (2. - l) * (1. - l);
982 for (
int comp = startComp; comp <= endComp; comp++) {
983 a_particleField[comp] += weight * meshField(iv, comp);
988 for (
int comp = startComp; comp <= endComp; comp++) {
989 a_particleField[comp] = 0.0;
997 MayDay::Error(
"EBParticleMesh::interpolateParticle(RealVect) - Invalid interpolation type requested.");
1002 #include <CD_NamespaceFooter.H>
Declaration of a namespace for proto-typing grid and EB loops.
DepositionType
Deposition types.
Definition: CD_DepositionType.H:23
Declaration of a class for handling particle-mesh interpolation and deposition.
Box m_region
Cell-centered box, i.e. valid region.
Definition: CD_EBParticleMesh.H:437
void interpolate(List< P > &a_particleList, const EBCellFAB &a_meshScalarField, const DepositionType a_interpType, const bool a_forceIrregNGP=false) const
Interpolate a scalar field onto the particle position.
Definition: CD_EBParticleMeshImplem.H:340
void deposit2(const List< P > &a_particleList, EBCellFAB &a_rho, const DepositionType a_depositionType, const bool a_forceIrregNGP=false) const
Deposit particle onto the mesh using twice the standard cloud width.
Definition: CD_EBParticleMeshImplem.H:67
void interpolateParticle(Real *a_particleField, const EBCellFAB &a_field, const Box &a_validBox, const RealVect &a_probLo, const RealVect &a_dx, const RealVect &a_position, const Interval &a_interval, const DepositionType a_interpType, const bool a_forceIrregNGP) const
Wrapper function that interpolates a particle fields onto positions.
Definition: CD_EBParticleMeshImplem.H:824
void depositParticle(EBCellFAB &a_rho, const RealVect &a_probLo, const RealVect &a_dx, const RealVect &a_position, const Real *a_strength, const Interval a_components, const DepositionType a_depositionType, const bool a_forceIrregNGP) const
Wrapper function for depositing a single particle.
Definition: CD_EBParticleMeshImplem.H:460
void deposit4(const List< P > &a_particleList, EBCellFAB &a_rho, const DepositionType a_depositionType, const bool a_forceIrregNGP=false) const
Deposit particle onto the mesh using 4x the standard cloud width.
Definition: CD_EBParticleMeshImplem.H:121
void deposit(const List< P > &a_particleList, EBCellFAB &a_rho, const DepositionType a_depositionType, const bool a_forceIrregNGP=false) const
Deposit particle onto the mesh using a standard cloud width.
Definition: CD_EBParticleMeshImplem.H:25
RealVect m_dx
Grid resolution.
Definition: CD_EBParticleMesh.H:447
ProblemDomain m_domain
Problem domain.
Definition: CD_EBParticleMesh.H:432
void depositParticle2(EBCellFAB &a_rho, const RealVect &a_probLo, const RealVect &a_dx, const RealVect &a_position, const Real *a_strength, const Interval a_components, const DepositionType a_depositionType, const bool a_forceIrregNGP) const
Wrapper function for depositing a single particle which has twice the usual cloud width.
Definition: CD_EBParticleMeshImplem.H:619
EBISBox m_ebisbox
EBIS box.
Definition: CD_EBParticleMesh.H:442
RealVect m_probLo
Lower-left corner of computational domain.
Definition: CD_EBParticleMesh.H:452
void depositParticle4(EBCellFAB &a_rho, const RealVect &a_probLo, const RealVect &a_dx, const RealVect &a_position, const Real *a_strength, const Interval a_components, const DepositionType a_depositionType, const bool a_forceIrregNGP) const
Wrapper function for depositing a single particle which has four times the usual cloud width.
Definition: CD_EBParticleMeshImplem.H:722
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