28 const Array4<Real >& t,
29 const Array4<Real const>& sstore,
30 const Array4<Real const>& Huon,
31 const Array4<Real const>& Hvom,
32 const Array4<Real const>& Hz,
33 const Array4<Real const>& pn,
34 const Array4<Real const>& pm,
35 const Array4<Real const>& W ,
36 const Array4<Real >& FC,
37 const Array4<Real const>& mskr,
38 const Array4<Real const>& msku,
39 const Array4<Real const>& mskv,
40 const Array4<int const>& river_pos,
41 const Array4<Real const>& river_source,
42 int nrhs,
int nnew,
int N, Real dt_lev)
44 const Box& domain = geom[0].Domain();
45 const auto dlo = amrex::lbound(domain);
46 const auto dhi = amrex::ubound(domain);
48 GeometryData
const& geomdata = geom[0].data();
49 bool is_periodic_in_x = geomdata.isPeriodic(0);
50 bool is_periodic_in_y = geomdata.isPeriodic(1);
60 tbxp1x.grow(IntVect(
NGROW-1,0,0));
61 tbxp1y.grow(IntVect(0,
NGROW-1,0));
64 Box utbxp1 = surroundingNodes(tbxp1x, 0);
65 Box vtbxp1 = surroundingNodes(tbxp1y, 1);
66 Box ubx = surroundingNodes(bx, 0);
67 Box vbx = surroundingNodes(bx, 1);
73 FArrayBox fab_grad(tbxp2,1,amrex::The_Async_Arena());
74 FArrayBox fab_curv(tbxp2,1,amrex::The_Async_Arena());
76 FArrayBox fab_FX(tbxp2,1,amrex::The_Async_Arena());
77 FArrayBox fab_FE(tbxp2,1,amrex::The_Async_Arena());
79 auto curv=fab_curv.array();
80 auto grad=fab_grad.array();
82 auto FX=fab_FX.array();
83 auto FE=fab_FE.array();
85 fab_grad.template setVal<RunOn::Device>(0.);
86 fab_curv.template setVal<RunOn::Device>(0.);
88 fab_FX.template setVal<RunOn::Device>(0.);
89 fab_FE.template setVal<RunOn::Device>(0.);
91 ParallelFor(utbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
93 FX(i,j,k)=(sstore(i,j,k,nrhs)-sstore(i-1,j,k,nrhs)) * msku(i,j,0);
96 Box utbxp1_slab_lo = makeSlab(utbxp1,0,dlo.x-1) & utbxp1;
97 Box utbxp1_slab_hi = makeSlab(utbxp1,0,dhi.x+1) & utbxp1;
98 if (utbxp1_slab_lo.ok() && !is_periodic_in_x) {
99 ParallelFor(utbxp1_slab_lo, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
101 FX(i,j,k) = FX(i+1,j,k);
104 if (utbxp1_slab_hi.ok() && !is_periodic_in_x) {
105 ParallelFor(utbxp1_slab_hi, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
107 FX(i+1,j,k) = FX(i,j,k);
111 Real cffa=1.0_rt/6.0_rt;
112 Real cffb=1.0_rt/3.0_rt;
118 ParallelFor(tbxp1x, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
121 curv(i,j,k)=-FX(i,j,k)+FX(i+1,j,k);
124 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
126 Real max_Huon = std::max(Huon(i,j,k),0.0_rt);
127 Real min_Huon = std::min(Huon(i,j,k),0.0_rt);
128 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i-1,j,k))+
129 cffa*(curv(i,j,k)*min_Huon+ curv(i-1,j,k)*max_Huon);
134 ParallelFor(tbxp1x, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
137 grad(i,j,k)=0.5_rt*(FX(i,j,k)+FX(i+1,j,k));
140 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
142 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i-1,j,k))+
143 cffb*(grad(i,j,k)+ grad(i-1,j,k));
147 Error(
"Not a valid horizontal advection scheme");
154 ParallelFor(tbxp1x, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
157 curv(i,j,k)=-FX(i,j,k)+FX(i+1,j,k);
161 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
163 Real max_Huon = std::max(Huon(i,j,k),0.0_rt);
164 Real min_Huon = std::min(Huon(i,j,k),0.0_rt);
165 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i-1,j,k))-
166 cffa*(curv(i,j,k)*min_Huon+ curv(i-1,j,k)*max_Huon);
171 ParallelFor(tbxp1x, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
174 grad(i,j,k)=0.5_rt*(FX(i,j,k)+FX(i+1,j,k));
177 ParallelFor(ubx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
179 FX(i,j,k)=Huon(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i-1,j,k)-
180 cffb*(grad(i,j,k)- grad(i-1,j,k)));
184 Error(
"Not a valid horizontal advection scheme");
188 ParallelFor(vtbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
190 FE(i,j,k)=(sstore(i,j,k,nrhs)-sstore(i,j-1,k,nrhs)) * mskv(i,j,0);
193 Box vtbxp1_slab_lo = makeSlab(vtbxp1,1,dlo.y-1) & vtbxp1;
194 Box vtbxp1_slab_hi = makeSlab(vtbxp1,1,dhi.y+1) & vtbxp1;
195 if (vtbxp1_slab_lo.ok() && !is_periodic_in_y) {
196 ParallelFor(vtbxp1_slab_lo, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
198 FE(i,j,k) = FE(i,j+1,k);
201 if (vtbxp1_slab_hi.ok() && !is_periodic_in_y) {
202 ParallelFor(vtbxp1_slab_hi, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
204 FE(i,j+1,k) = FE(i,j,k);
215 ParallelFor(tbxp1y, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
217 curv(i,j,k)=-FE(i,j,k)+FE(i,j+1,k);
220 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
222 Real max_Hvom = std::max(Hvom(i,j,k),0.0_rt);
223 Real min_Hvom = std::min(Hvom(i,j,k),0.0_rt);
225 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i,j-1,k))+
226 cffa*(curv(i,j,k)*min_Hvom+ curv(i,j-1,k)*max_Hvom);
231 ParallelFor(tbxp1y, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
233 grad(i,j,k)=0.5_rt*(FE(i,j,k)+FE(i,j+1,k));
236 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
238 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i,j-1,k))+
239 cffb*(grad(i,j,k)+ grad(i,j-1,k));
243 Error(
"Not a valid horizontal advection scheme");
249 ParallelFor(tbxp1y, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
251 curv(i,j,k)=-FE(i,j,k)+FE(i,j+1,k);
255 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
257 Real max_Hvom = std::max(Hvom(i,j,k),0.0_rt);
258 Real min_Hvom = std::min(Hvom(i,j,k),0.0_rt);
260 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i,j-1,k))-
261 cffa*(curv(i,j,k)*min_Hvom+ curv(i,j-1,k)*max_Hvom);
266 ParallelFor(tbxp1y, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
268 grad(i,j,k)=0.5_rt*(FE(i,j,k)+FE(i,j+1,k));
271 ParallelFor(vbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
273 FE(i,j,k)=Hvom(i,j,k)*0.5_rt*(sstore(i,j,k)+sstore(i,j-1,k)-
274 cffb*(grad(i,j,k)- grad(i,j-1,k)));
278 Error(
"Not a valid horizontal advection scheme");
282 bool do_rivers_cons = (river_source.size() > 0);
285 ParallelFor(tbxp1, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
287 int iriver = river_pos(i,j,0);
289 if (river_direction_d[iriver] == 0) {
290 if (do_rivers_cons) {
291 FX(i,j,k) = Huon(i,j,k) * river_source(iriver,0,k);
292 }
else if ((mskr(i,j,0)==0) && (mskr(i-1,j,0)==1)) {
293 FX(i,j,k) = Huon(i,j,k) * sstore(i-1,j,k);
294 }
else if ((mskr(i,j,0)==1) && (mskr(i-1,j,0)==0)) {
295 FX(i,j,k) = Huon(i,j,k) * sstore(i,j,k);
297 }
else if (river_direction_d[iriver] == 1) {
298 if (do_rivers_cons) {
299 FE(i,j,k) = Hvom(i,j,k) * river_source(iriver,0,k);
300 }
else if ((mskr(i,j,0)==0) && (mskr(i,j-1,0)==1)) {
301 FE(i,j,k) = Hvom(i,j,k) * sstore(i,j-1,k);
302 }
else if ((mskr(i,j,0)==1) && (mskr(i,j-1,0)==0)) {
303 FE(i,j,k) = Hvom(i,j,k) * sstore(i,j,k);
311 [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
316 Real cff = dt_lev*pm(i,j,0)*pn(i,j,0);
317 Real cff1=cff*(FX(i+1,j,k)-FX(i,j,k));
318 Real cff2=cff*(FE(i,j+1,k)-FE(i,j,k));
321 t(i,j,k,nnew) -= cff3;
333 ParallelFor(surroundingNodes(bx,2), [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
340 Real cff2=7.0_rt/12.0_rt;
341 Real cff3=1.0_rt/12.0_rt;
345 FC(i,j,k)=( cff2*(sstore(i ,j,k-1)+ sstore(i,j,k))
346 -cff3*(sstore(i ,j,k-2)+ sstore(i,j,k+1)) ) * ( W(i,j,k));
350 FC(i,j,N)=( cff2*sstore(i ,j,N-1)+ cff1*sstore(i,j,N )
351 -cff3*sstore(i ,j,N-2) ) * ( W(i ,j,N));
353 FC(i,j,1)=( cff2*sstore(i ,j,1)+ cff1*sstore(i,j,0)
354 -cff3*sstore(i ,j,2) ) * ( W(i ,j,1));
360 ParallelFor(bx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
362 Real cff1=dt_lev*pm(i,j,0)*pn(i,j,0);
363 Real cff4=FC(i,j,k+1)-FC(i,j,k);
365 t(i,j,k) = (t(i,j,k)-cff1*cff4) / Hz(i,j,k);