8 #ifndef ERFPC_PARTICLE_TO_MESH_H_
9 #define ERFPC_PARTICLE_TO_MESH_H_
13 template<
typename ValueFunc>
14 void ERFPC::ERFPCParticleToMesh(amrex::MultiFab& a_mf,
15 const amrex::MultiFab& a_z_phys_nd,
16 int a_lev,
int a_comp,
17 ValueFunc&& value_func)
const
19 using namespace amrex;
22 AMREX_ASSERT(numParticlesOutOfRange(*
this, 0) == 0);
24 const auto& geom = Geom(a_lev);
25 const auto plo = geom.ProbLoArray();
26 const auto dxi = geom.InvCellSizeArray();
27 const Real dx = geom.CellSize(0);
28 const Real dy = geom.CellSize(1);
29 const Box domain = geom.Domain();
30 const int k_max = domain.bigEnd(AMREX_SPACEDIM-1);
35 #pragma omp parallel if (Gpu::notInLaunchRegion())
37 for (ParConstIterType pti(*
this, a_lev); pti.isValid(); ++pti)
39 const int grid = pti.index();
40 const auto& ptile = ParticlesAt(a_lev, pti);
41 const auto& aos = ptile.GetArrayOfStructs();
42 const int np = aos.numParticles();
43 if (np == 0) {
continue; }
45 auto rho = a_mf[grid].array();
46 auto zheight = a_z_phys_nd[grid].array();
48 const auto ptd = ptile.getConstParticleTileData();
52 const auto&
p = ptd.m_aos[i];
53 if (
p.id() <= 0) { return; }
55 const Real pval = value_func(ptd, i);
57 const Real lx = (
p.pos(0) - plo[0]) * dxi[0] +
Real(0.5);
58 const int ix =
static_cast<int>(Math::floor(lx)) - 1;
59 const Real wx1 = lx -
static_cast<Real>(ix + 1);
62 const Real ly = (
p.pos(1) - plo[1]) * dxi[1] +
Real(0.5);
63 const int iy =
static_cast<int>(Math::floor(ly)) - 1;
64 const Real wy1 = ly -
static_cast<Real>(iy + 1);
67 const int kz =
p.idata(ERFParticlesIntIdxAoS::k);
68 const int ix_p =
static_cast<int>(Math::floor((
p.pos(0) - plo[0]) * dxi[0]));
69 const int iy_p =
static_cast<int>(Math::floor((
p.pos(1) - plo[1]) * dxi[1]));
70 const Real fx = (
p.pos(0) - plo[0]) * dxi[0] -
static_cast<Real>(ix_p);
71 const Real fy = (
p.pos(1) - plo[1]) * dxi[1] -
static_cast<Real>(iy_p);
73 auto zface = [=] AMREX_GPU_DEVICE (
int k_face) ->
Real {
74 return zheight(ix_p , iy_p , k_face) * (
Real(1.0)-fx) * (
Real(1.0)-fy)
75 + zheight(ix_p+1, iy_p , k_face) * fx * (
Real(1.0)-fy)
76 + zheight(ix_p , iy_p+1, k_face) * (
Real(1.0)-fx) * fy
77 + zheight(ix_p+1, iy_p+1, k_face) * fx * fy;
80 const Real z_lo_k = zface(kz);
81 const Real z_hi_k = zface(kz + 1);
82 const Real z_ctr_k =
Real(0.5) * (z_lo_k + z_hi_k);
89 if (
p.pos(2) >= z_ctr_k) {
94 const Real z_hi2 = zface(kz + 2);
95 const Real z_ctr_hi =
Real(0.5) * (z_hi_k + z_hi2);
96 span = z_ctr_hi - z_ctr_k;
98 span = z_hi_k - z_lo_k;
100 wz_hi = (
p.pos(2) - z_ctr_k) / span;
101 wz_lo =
Real(1.0) - wz_hi;
107 const Real z_lo2 = zface(kz - 1);
108 const Real z_ctr_lo =
Real(0.5) * (z_lo2 + z_lo_k);
109 span = z_ctr_k - z_ctr_lo;
111 span = z_hi_k - z_lo_k;
113 wz_lo = (z_ctr_k -
p.pos(2)) / span;
114 wz_hi =
Real(1.0) - wz_lo;
118 auto dz_cell = [=] AMREX_GPU_DEVICE (
int ic,
int jc,
int kc) ->
Real {
120 zheight(ic , jc , kc+1) - zheight(ic , jc , kc)
121 + zheight(ic+1, jc , kc+1) - zheight(ic+1, jc , kc)
122 + zheight(ic , jc+1, kc+1) - zheight(ic , jc+1, kc)
123 + zheight(ic+1, jc+1, kc+1) - zheight(ic+1, jc+1, kc) );
129 auto deposit = [=] AMREX_GPU_DEVICE (
int ic,
int jc,
int kc,
Real w_horiz,
Real w_z)
132 const int kc_dz = amrex::max(0, amrex::min(k_max, kc));
133 const Real dz = dz_cell(ic, jc, kc_dz);
134 const Real contrib = pval * w_horiz * w_z * inv_dxdy /
dz;
135 Gpu::Atomic::AddNoRet(&
rho(ic, jc, kc, a_comp), contrib);
138 deposit(ix , iy , kz_lo, wx0*wy0, wz_lo);
139 deposit(ix+1, iy , kz_lo, wx1*wy0, wz_lo);
140 deposit(ix , iy+1, kz_lo, wx0*wy1, wz_lo);
141 deposit(ix+1, iy+1, kz_lo, wx1*wy1, wz_lo);
142 deposit(ix , iy , kz_hi, wx0*wy0, wz_hi);
143 deposit(ix+1, iy , kz_hi, wx1*wy0, wz_hi);
144 deposit(ix , iy+1, kz_hi, wx0*wy1, wz_hi);
145 deposit(ix+1, iy+1, kz_hi, wx1*wy1, wz_hi);
149 a_mf.SumBoundary(geom.periodicity());
const Real dy
Definition: ERF_InitCustomPert_ABL.H:24
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
rho
Definition: ERF_InitCustomPert_Bubble.H:106
const Real dz
Definition: ERF_InitCustomPert_Bubble.H:25
ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { const Real *dx=geomdata.CellSize();const Real x=(i+0.5) *dx[0];const Real y=(j+0.5) *dx[1];const Real Omg=erf_vortex_Gaussian(x, y, xc, yc, R, beta, sigma);const Real deltaT=-(gamma - 1.0)/(2.0 *sigma *sigma) *Omg *Omg;const Real rho_norm=std::pow(1.0+deltaT, inv_gm1);const Real T=(1.0+deltaT) *T_inf;const Real p=std::pow(rho_norm, Gamma)/Gamma *rho_0 *a_inf *a_inf;const Real rho_theta=rho_0 *rho_norm *(T *std::pow(p_0/p, rdOcp));state_pert(i, j, k, RhoTheta_comp)=rho_theta - getRhoThetagivenP(p_hse(i, j, k));const Real r2d_xy=std::sqrt((x-xc) *(x-xc)+(y-yc) *(y-yc));state_pert(i, j, k, RhoScalar_comp)=0.25 *(1.0+std::cos(PI *std::min(r2d_xy, R)/R));})
Real * p
Definition: ERF_InitCustomPert_SquallLine.H:61
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_ConsoleIO.cpp:12