29 const Array4<Real >& t,
30 const Array4<Real const>& sstore,
31 const Array4<Real const>& Huon,
32 const Array4<Real const>& Hvom,
33 const Array4<Real const>& Hz,
34 const Array4<Real const>& pn,
35 const Array4<Real const>& pm,
36 const Array4<Real const>& W ,
37 const Array4<Real >& FC,
38 const Array4<Real const>& mskr,
39 const Array4<Real const>& msku,
40 const Array4<Real const>& mskv,
41 const Array4<int const>& river_pos,
42 const Array4<Real const>& river_source,
43 int nrhs,
int nnew,
int N, Real dt_lev)
45 BL_PROFILE(
"REMORA::rhs_t_3d()");
46 const Box& domain = geom[lev].Domain();
47 const auto dlo = amrex::lbound(domain);
48 const auto dhi = amrex::ubound(domain);
50 GeometryData
const& geomdata = geom[0].data();
51 bool is_periodic_in_x = geomdata.isPeriodic(0);
52 bool is_periodic_in_y = geomdata.isPeriodic(1);
62 tbxp1x.grow(IntVect(
NGROW-1,0,0));
63 tbxp1y.grow(IntVect(0,
NGROW-1,0));
66 Box utbxp1 = surroundingNodes(tbxp1x, 0);
67 Box vtbxp1 = surroundingNodes(tbxp1y, 1);
68 Box ubx = surroundingNodes(bx, 0);
69 Box vbx = surroundingNodes(bx, 1);
75 FArrayBox fab_grad(tbxp2,1,amrex::The_Async_Arena());
76 FArrayBox fab_curv(tbxp2,1,amrex::The_Async_Arena());
78 FArrayBox fab_FX(tbxp2,1,amrex::The_Async_Arena());
79 FArrayBox fab_FE(tbxp2,1,amrex::The_Async_Arena());
81 auto curv=fab_curv.array();
82 auto grad=fab_grad.array();
84 auto FX=fab_FX.array();
85 auto FE=fab_FE.array();
87 fab_grad.template setVal<RunOn::Device>(0.);
88 fab_curv.template setVal<RunOn::Device>(0.);
90 fab_FX.template setVal<RunOn::Device>(0.);
91 fab_FE.template setVal<RunOn::Device>(0.);
93 BL_PROFILE_VAR(
"REMORA::rhs_t_3d()::hadv",phadv);
94 ParallelFor(utbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
96 FX(i,j,k)=(sstore(i,j,k,nrhs)-sstore(i-1,j,k,nrhs)) * msku(i,j,0);
99 Box utbxp1_slab_lo = makeSlab(utbxp1,0,dlo.x-1) & utbxp1;
100 Box utbxp1_slab_hi = makeSlab(utbxp1,0,dhi.x+1) & utbxp1;
101 if (utbxp1_slab_lo.ok() && !is_periodic_in_x) {
102 ParallelFor(utbxp1_slab_lo, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
104 FX(i,j,k) = FX(i+1,j,k);
107 if (utbxp1_slab_hi.ok() && !is_periodic_in_x) {
108 ParallelFor(utbxp1_slab_hi, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
110 FX(i+1,j,k) = FX(i,j,k);
114 Real cffa=1.0_rt/6.0_rt;
115 Real cffb=1.0_rt/3.0_rt;
121 ParallelFor(tbxp1x, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
124 curv(i,j,k)=-FX(i,j,k)+FX(i+1,j,k);
127 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
129 Real max_Huon = std::max(Huon(i,j,k),0.0_rt);
130 Real min_Huon = std::min(Huon(i,j,k),0.0_rt);
131 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i-1,j,k))+
132 cffa*(curv(i,j,k)*min_Huon+ curv(i-1,j,k)*max_Huon);
137 ParallelFor(tbxp1x, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
140 grad(i,j,k)=0.5_rt*(FX(i,j,k)+FX(i+1,j,k));
143 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
145 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i-1,j,k))+
146 cffb*(grad(i,j,k)+ grad(i-1,j,k));
150 Error(
"Not a valid horizontal advection scheme");
157 ParallelFor(tbxp1x, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
160 curv(i,j,k)=-FX(i,j,k)+FX(i+1,j,k);
164 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
166 Real max_Huon = std::max(Huon(i,j,k),0.0_rt);
167 Real min_Huon = std::min(Huon(i,j,k),0.0_rt);
168 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i-1,j,k))-
169 cffa*(curv(i,j,k)*min_Huon+ curv(i-1,j,k)*max_Huon);
174 ParallelFor(tbxp1x, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
177 grad(i,j,k)=0.5_rt*(FX(i,j,k)+FX(i+1,j,k));
180 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
182 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i-1,j,k)-
183 cffb*(grad(i,j,k)- grad(i-1,j,k)));
187 Error(
"Not a valid horizontal advection scheme");
191 ParallelFor(vtbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
193 FE(i,j,k)=(sstore(i,j,k,nrhs)-sstore(i,j-1,k,nrhs)) * mskv(i,j,0);
196 Box vtbxp1_slab_lo = makeSlab(vtbxp1,1,dlo.y-1) & vtbxp1;
197 Box vtbxp1_slab_hi = makeSlab(vtbxp1,1,dhi.y+1) & vtbxp1;
198 if (vtbxp1_slab_lo.ok() && !is_periodic_in_y) {
199 ParallelFor(vtbxp1_slab_lo, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
201 FE(i,j,k) = FE(i,j+1,k);
204 if (vtbxp1_slab_hi.ok() && !is_periodic_in_y) {
205 ParallelFor(vtbxp1_slab_hi, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
207 FE(i,j+1,k) = FE(i,j,k);
218 ParallelFor(tbxp1y, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
220 curv(i,j,k)=-FE(i,j,k)+FE(i,j+1,k);
223 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
225 Real max_Hvom = std::max(Hvom(i,j,k),0.0_rt);
226 Real min_Hvom = std::min(Hvom(i,j,k),0.0_rt);
228 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i,j-1,k))+
229 cffa*(curv(i,j,k)*min_Hvom+ curv(i,j-1,k)*max_Hvom);
234 ParallelFor(tbxp1y, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
236 grad(i,j,k)=0.5_rt*(FE(i,j,k)+FE(i,j+1,k));
239 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
241 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i,j-1,k))+
242 cffb*(grad(i,j,k)+ grad(i,j-1,k));
246 Error(
"Not a valid horizontal advection scheme");
252 ParallelFor(tbxp1y, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
254 curv(i,j,k)=-FE(i,j,k)+FE(i,j+1,k);
258 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
260 Real max_Hvom = std::max(Hvom(i,j,k),0.0_rt);
261 Real min_Hvom = std::min(Hvom(i,j,k),0.0_rt);
263 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i,j-1,k))-
264 cffa*(curv(i,j,k)*min_Hvom+ curv(i,j-1,k)*max_Hvom);
269 ParallelFor(tbxp1y, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
271 grad(i,j,k)=0.5_rt*(FE(i,j,k)+FE(i,j+1,k));
274 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
276 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i,j-1,k)-
277 cffb*(grad(i,j,k)- grad(i,j-1,k)));
281 Error(
"Not a valid horizontal advection scheme");
285 bool do_rivers_cons = (river_source.size() > 0);
288 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
290 int iriver = river_pos(i,j,0);
292 if (river_direction_d[iriver] == 0) {
293 if (do_rivers_cons) {
294 FX(i,j,k) = Huon(i,j,k) * river_source(iriver,0,k);
295 }
else if ((mskr(i,j,0)==0) && (mskr(i-1,j,0)==1)) {
296 FX(i,j,k) = Huon(i,j,k) * sstore(i-1,j,k);
297 }
else if ((mskr(i,j,0)==1) && (mskr(i-1,j,0)==0)) {
298 FX(i,j,k) = Huon(i,j,k) * sstore(i,j,k);
300 }
else if (river_direction_d[iriver] == 1) {
301 if (do_rivers_cons) {
302 FE(i,j,k) = Hvom(i,j,k) * river_source(iriver,0,k);
303 }
else if ((mskr(i,j,0)==0) && (mskr(i,j-1,0)==1)) {
304 FE(i,j,k) = Hvom(i,j,k) * sstore(i,j-1,k);
305 }
else if ((mskr(i,j,0)==1) && (mskr(i,j-1,0)==0)) {
306 FE(i,j,k) = Hvom(i,j,k) * sstore(i,j,k);
314 [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
319 Real cff = dt_lev*pm(i,j,0)*pn(i,j,0);
320 Real cff1=cff*(FX(i+1,j,k)-FX(i,j,k));
321 Real cff2=cff*(FE(i,j+1,k)-FE(i,j,k));
324 t(i,j,k,nnew) -= cff3;
327 BL_PROFILE_VAR_STOP(phadv);
337 BL_PROFILE_VAR(
"REMORA::rhs_t_3d()::vadv",pvadv);
338 ParallelFor(surroundingNodes(bx,2), [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
345 Real cff2=7.0_rt/12.0_rt;
346 Real cff3=1.0_rt/12.0_rt;
350 FC(i,j,k)=( cff2*(sstore(i ,j,k-1)+ sstore(i,j,k))
351 -cff3*(sstore(i ,j,k-2)+ sstore(i,j,k+1)) ) * ( W(i,j,k));
355 FC(i,j,N)=( cff2*sstore(i ,j,N-1)+ cff1*sstore(i,j,N )
356 -cff3*sstore(i ,j,N-2) ) * ( W(i ,j,N));
358 FC(i,j,1)=( cff2*sstore(i ,j,1)+ cff1*sstore(i,j,0)
359 -cff3*sstore(i ,j,2) ) * ( W(i ,j,1));
365 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
367 Real cff1=dt_lev*pm(i,j,0)*pn(i,j,0);
368 Real cff4=FC(i,j,k+1)-FC(i,j,k);
370 t(i,j,k) = (t(i,j,k)-cff1*cff4) / Hz(i,j,k);
372 BL_PROFILE_VAR_STOP(pvadv);