36 const Array4<Real >& tempold,
37 const Array4<Real >& tempcache,
38 const Array4<Real >& Hz,
39 const Array4<Real >& Huon,
40 const Array4<Real >& Hvom,
41 const Array4<Real >& W ,
42 const Array4<Real >& DC,
43 const Array4<Real >& FC ,
44 const Array4<Real >& tempstore,
45 const Array4<Real const>& z_w,
46 const Array4<Real const>& h,
47 const Array4<Real const>& pm,
48 const Array4<Real const>& pn,
49 const Array4<Real const>& msku,
50 const Array4<Real const>& mskv,
51 const Array4<int const>& river_pos,
52 const Array4<Real const>& river_source,
53 int iic,
int ntfirst,
int nrhs,
int N,
56 BL_PROFILE(
"REMORA::prestep_t_advection()");
57 const Box& domain = geom[lev].Domain();
58 const auto dlo = amrex::lbound(domain);
59 const auto dhi = amrex::ubound(domain);
61 GeometryData
const& geomdata = geom[0].data();
62 bool is_periodic_in_x = geomdata.isPeriodic(0);
63 bool is_periodic_in_y = geomdata.isPeriodic(1);
75 int FX_comp = ncomp++;
76 int FE_comp = ncomp++;
77 int curv_comp = ncomp++;
78 int grad_comp = ncomp++;
80 FArrayBox fab(tbxp2,ncomp,amrex::The_Async_Arena());
81 fab.template setVal<RunOn::Device>(0.0_rt);
83 auto FX=fab.array(FX_comp);
84 auto FE=fab.array(FE_comp);
85 auto curv=fab.array(curv_comp);
86 auto grad=fab.array(grad_comp);
88 Box ubx = surroundingNodes(tbx,0);
89 Box vbx = surroundingNodes(tbx,1);
91 Box utbxp1 = surroundingNodes(tbxp1,0);
92 Box vtbxp1 = surroundingNodes(tbxp1,1);
94 Box gbx3uneven_init(IntVect(AMREX_D_DECL(tbx.smallEnd(0)-3,tbx.smallEnd(1)-3,tbx.smallEnd(2))),
95 IntVect(AMREX_D_DECL(tbx.bigEnd(0)+2,tbx.bigEnd(1)+2,tbx.bigEnd(2))));
96 BoxArray ba_gbx3uneven = intersect(BoxArray(gbx3uneven_init), gbx);
97 AMREX_ASSERT((ba_gbx3uneven.size() == 1));
98 Box gbx3uneven = ba_gbx3uneven[0];
101 BoxArray ba_gbx2 = intersect(BoxArray(gbx2), gbx);
102 AMREX_ASSERT((ba_gbx2.size() == 1));
106 BoxArray ba_gbx1 = intersect(BoxArray(gbx1), gbx);
107 AMREX_ASSERT((ba_gbx1.size() == 1));
115 Box gbx3unevenD = gbx3uneven;
116 gbx3unevenD.makeSlab(2,0);
121 ParallelFor(gbx1D, N+1,
122 [=] AMREX_GPU_DEVICE (
int i,
int j,
int ,
int kk)
130 W(i,j,k) = W(i,j,k-1) - (Huon(i+1,j,k-1)-Huon(i,j,k-1)) - (Hvom(i,j+1,k-1)-Hvom(i,j,k-1));
132 ParallelFor(gbx1D, [=] AMREX_GPU_DEVICE (
int i,
int j,
int )
134 W(i,j,N+1)=W(i,j,N+1)/(z_w(i,j,N+1)+h(i,j,0,0));
136 ParallelFor(gbx1D, N,
137 [=] AMREX_GPU_DEVICE (
int i,
int j,
int ,
int kk)
140 W(i,j,k) = W(i,j,k)- W(i,j,N+1)*(z_w(i,j,k)+h(i,j,0,0));
142 ParallelFor(gbx1D, [=] AMREX_GPU_DEVICE (
int i,
int j,
int )
150 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
152 FX(i,j,k)=Box(tempold).contains(i-1,j,k) ? Huon(i,j,k)*
153 0.5_rt*(tempold(i-1,j,k)+tempold(i ,j,k)) : 1e34_rt;
155 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
157 FE(i,j,k)=Box(tempold).contains(i,j-1,k) ? Hvom(i,j,k)*
158 0.5_rt*(tempold(i,j-1,k)+tempold(i,j,k)) : 1e34_rt;
163 ParallelFor(utbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
166 FX(i,j,k)=(tempold(i,j,k,nrhs)-tempold(i-1,j,k,nrhs)) * msku(i,j,0);
169 Box utbxp1_slab_lo = makeSlab(utbxp1,0,dlo.x-1) & utbxp1;
170 Box utbxp1_slab_hi = makeSlab(utbxp1,0,dhi.x+1) & utbxp1;
171 if (utbxp1_slab_lo.ok() && !is_periodic_in_x) {
172 ParallelFor(utbxp1_slab_lo, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
174 FX(i,j,k) = FX(i+1,j,k);
177 if (utbxp1_slab_hi.ok() && !is_periodic_in_x) {
178 ParallelFor(utbxp1_slab_hi, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
180 FX(i+1,j,k) = FX(i,j,k);
184 ParallelFor(vtbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
187 FE(i,j,k)=(tempold(i,j,k,nrhs)-tempold(i,j-1,k,nrhs)) * mskv(i,j,0);
190 Box vtbxp1_slab_lo = makeSlab(vtbxp1,1,dlo.y-1) & vtbxp1;
191 Box vtbxp1_slab_hi = makeSlab(vtbxp1,1,dhi.y+1) & vtbxp1;
192 if (vtbxp1_slab_lo.ok() && !is_periodic_in_y) {
193 ParallelFor(vtbxp1_slab_lo, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
195 FE(i,j,k) = FE(i,j+1,k);
198 if (vtbxp1_slab_hi.ok() && !is_periodic_in_y) {
199 ParallelFor(vtbxp1_slab_hi, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
201 FE(i,j+1,k) = FE(i,j,k);
205 Real cffa=1.0_rt/6.0_rt;
206 Real cffb=1.0_rt/3.0_rt;
209 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
212 curv(i,j,k)=-FX(i,j,k)+FX(i+1,j,k);
215 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
217 Real max_Huon = std::max(Huon(i,j,k),0.0_rt);
218 Real min_Huon = std::min(Huon(i,j,k),0.0_rt);
220 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(tempold(i,j,k)+tempold(i-1,j,k))-
221 cffa*(curv(i,j,k)*min_Huon+ curv(i-1,j,k)*max_Huon);
226 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
229 grad(i,j,k)=0.5_rt*(FX(i,j,k)+FX(i+1,j,k));
232 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
234 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(tempold(i,j,k)+tempold(i-1,j,k)-
235 cffb*(grad(i,j,k)-grad(i-1,j,k)));
238 Error(
"Not a valid horizontal advection scheme");
243 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
245 curv(i,j,k)=-FE(i,j,k)+FE(i,j+1,k);
248 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
250 Real max_Hvom = std::max(Hvom(i,j,k),0.0_rt);
251 Real min_Hvom = std::min(Hvom(i,j,k),0.0_rt);
253 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(tempold(i,j,k)+tempold(i,j-1,k))-
254 cffa*(curv(i,j,k)*min_Hvom+ curv(i,j-1,k)*max_Hvom);
259 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
261 grad(i,j,k)=0.5_rt*(FE(i,j,k)+FE(i,j+1,k));
264 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
266 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(tempold(i,j,k)+tempold(i,j-1,k)-
267 cffb*(grad(i,j,k)- grad(i,j-1,k)));
270 Error(
"Not a valid horizontal advection scheme");
274 bool do_rivers_cons = (river_source.size() > 0);
277 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
279 int iriver = river_pos(i,j,0);
281 if (river_direction_d[iriver] == 0) {
282 FX(i,j,k) = (!do_rivers_cons) ? 0.0_rt : Huon(i,j,k) * river_source(iriver,0,k);
284 FE(i,j,k) = (!do_rivers_cons) ? 0.0_rt : Hvom(i,j,k) * river_source(iriver,0,k);
294 Real cff1 = 0.0_rt, cff2 = 0.0_rt, cff;
296 Real GammaT = 1.0_rt/6.0_rt;
304 cff=(1.0_rt-GammaT)*dt_lev;
309 ParallelFor(tbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
311 tempstore(i,j,k)=Hz(i,j,k)*( cff1 * tempold(i,j,k)+
312 cff2 * tempcache(i,j,k) )-
313 cff * pm(i,j,0)*pn(i,j,0) * (FX(i+1,j,k)-FX(i,j,k)+
314 FE(i,j+1,k)-FE(i,j,k));
318 Real c2=7.0_rt/12.0_rt;
319 Real c3=1.0_rt/12.0_rt;
325 ParallelFor(growHi(growLo(convert(tbx,IntVect(0,0,1)),2,-2),2,-1), [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
331 FC(i,j,k)=( c2*(tempold(i ,j,k-1,nrhs)+ tempold(i,j,k ,nrhs))
332 -c3*(tempold(i ,j,k-2 ,nrhs)+ tempold(i,j,k+1,nrhs)) )*
335 ParallelFor(makeSlab(tbx,2,0), [=] AMREX_GPU_DEVICE (
int i,
int j,
int )
338 FC(i,j,N) = ( c2*tempold(i,j,N-1,nrhs)+ c1*tempold(i,j,N,nrhs)-c3*tempold(i,j,N-2,nrhs) )
340 FC(i,j, 1) = ( c2*tempold(i,j, 1,nrhs)+ c1*tempold(i,j,0,nrhs)-c3*tempold(i,j,2,nrhs) )
345 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
347 DC(i,j,k)=1.0_rt/(Hz(i,j,k)-
348 cff*pm(i,j,0)*pn(i,j,0)*
349 (Huon(i+1,j,k)-Huon(i,j,k)+
350 Hvom(i,j+1,k)-Hvom(i,j,k)+
351 (W(i,j,k+1)-W(i,j,k))));
355 [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
357 Real c_p = cff*pm(i,j,0)*pn(i,j,0);
359 Real c4 = FC(i,j,k+1)-FC(i,j,k);
361 tempstore(i,j,k) = DC(i,j,k)*(tempstore(i,j,k)-c_p*c4);