81 BL_PROFILE(
"TracerPC::AdvectWithUmac()");
82 AMREX_ASSERT(OK(lev, lev, umac[0]->nGrow()-1));
83 AMREX_ASSERT(lev >= 0 && lev < GetParticles().size());
85 AMREX_D_TERM(AMREX_ASSERT(umac[0]->nGrow() >= 1);,
86 AMREX_ASSERT(umac[1]->nGrow() >= 1);,
87 AMREX_ASSERT(umac[2]->nGrow() >= 1););
89 AMREX_D_TERM(AMREX_ASSERT(!umac[0]->contains_nan());,
90 AMREX_ASSERT(!umac[1]->contains_nan());,
91 AMREX_ASSERT(!umac[2]->contains_nan()););
93 const auto strttime = amrex::second();
94 const Geometry& geom = m_gdb->Geom(lev);
95 const Box& domain = geom.Domain();
96 const auto plo = geom.ProbLoArray();
97 const auto dxi = geom.InvCellSizeArray();
98 const auto dx = geom.CellSizeArray();
100 Vector<std::unique_ptr<MultiFab> > raii_umac(AMREX_SPACEDIM);
101 Vector<MultiFab const*> umac_pointer(AMREX_SPACEDIM);
102 AMREX_ALWAYS_ASSERT(OnSameGrids(lev, *umac[0]));
104 for (
int i = 0; i < AMREX_SPACEDIM; i++) {
105 umac_pointer[i] = umac[i];
108 for (
int ipass = 0; ipass < 2; ipass++)
111 #pragma omp parallel if (Gpu::notInLaunchRegion())
113 for (ParIterType pti(*
this, lev); pti.isValid(); ++pti)
115 int grid = pti.index();
116 auto& ptile = ParticlesAt(lev, pti);
117 auto& aos = ptile.GetArrayOfStructs();
118 const int n = aos.numParticles();
119 auto *p_pbox = aos().data();
120 const FArrayBox* fab[AMREX_SPACEDIM] = { AMREX_D_DECL(&((*umac_pointer[0])[grid]),
121 &((*umac_pointer[1])[grid]),
122 &((*umac_pointer[2])[grid])) };
125 GpuArray<Array4<const Real>, AMREX_SPACEDIM>
126 const umacarr {{AMREX_D_DECL((*fab[0]).array(),
128 (*fab[2]).array() )}};
130 auto zheight = use_terrain ? a_z_height[grid].array() : Array4<Real>{};
133 [=] AMREX_GPU_DEVICE (
int i)
135 ParticleType& p = p_pbox[i];
136 if (p.id() <= 0) { return; }
137 ParticleReal
v[AMREX_SPACEDIM];
138 mac_interpolate(p, plo, dxi, umacarr,
v);
141 for (
int dim=0; dim < AMREX_SPACEDIM; dim++)
143 p.rdata(dim) = p.pos(dim);
144 p.pos(dim) +=
static_cast<ParticleReal
>(ParticleReal(0.5)*dt*
v[dim]);
149 for (
int dim=0; dim < AMREX_SPACEDIM; dim++)
151 p.pos(dim) = p.rdata(dim) +
static_cast<ParticleReal
>(dt*
v[dim]);
152 p.rdata(dim) =
v[dim];
157 AMREX_D_DECL(
int(amrex::Math::floor((p.pos(0)-plo[0])*dxi[0])),
158 int(amrex::Math::floor((p.pos(1)-plo[1])*dxi[1])),
160 iv[0] += domain.smallEnd()[0];
161 iv[1] += domain.smallEnd()[1];
162 ParticleReal zlo, zhi;
164 zlo = zheight(iv[0], iv[1], iv[2]);
165 zhi = zheight(iv[0], iv[1], iv[2]+1);
168 zhi = (iv[2]+1) * dx[2];
170 if (p.pos(2) > zhi) {
172 }
else if (p.pos(2) <= zlo) {
182 auto stoptime = amrex::second() - strttime;
185 Lazy::QueueReduction( [=] ()
mutable {
187 ParallelReduce::Max(stoptime, ParallelContext::IOProcessorNumberSub(),
188 ParallelContext::CommunicatorSub());
190 amrex::Print() <<
"TracerParticleContainer::AdvectWithUmac() time: " << stoptime <<
'\n';
@ v
Definition: IndexDefines.H:35