36 MultiFab& mf_u , MultiFab& mf_v ,
38 MultiFab* mf_ru , MultiFab* mf_rv,
39 std::unique_ptr<MultiFab>& mf_DU_avg1,
40 std::unique_ptr<MultiFab>& mf_DU_avg2,
41 std::unique_ptr<MultiFab>& mf_DV_avg1,
42 std::unique_ptr<MultiFab>& mf_DV_avg2,
43 std::unique_ptr<MultiFab>& mf_ubar,
44 std::unique_ptr<MultiFab>& mf_vbar,
45 std::unique_ptr<MultiFab>& mf_Akv,
46 std::unique_ptr<MultiFab>& mf_Akt,
47 std::unique_ptr<MultiFab>& mf_Hz,
48 std::unique_ptr<MultiFab>& mf_Huon,
49 std::unique_ptr<MultiFab>& mf_Hvom,
50 std::unique_ptr<MultiFab>& mf_z_w,
52 MultiFab
const* mf_pm,
53 MultiFab
const* mf_pn,
54 MultiFab
const* mf_mskr,
55 MultiFab
const* mf_msku,
56 MultiFab
const* mf_mskv,
57 const int N, Real dt_lev)
71 const BoxArray& ba = mf_cons.boxArray();
72 const DistributionMapping& dm = mf_cons.DistributionMap();
75 MultiFab mf_AK (convert(ba,IntVect(0,0,1)),dm,1,IntVect(
NGROW,
NGROW,0));
79 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
81 Array4<Real >
const& u = mf_u.array(mfi);
82 Array4<Real >
const& v = mf_v.array(mfi);
84 Array4<Real >
const& ru = mf_ru->array(mfi);
85 Array4<Real >
const& rv = mf_rv->array(mfi);
87 Array4<Real >
const& AK = mf_AK.array(mfi);
88 Array4<Real >
const& DC = mf_DC.array(mfi);
90 Array4<Real >
const& Hzk = mf_Hzk.array(mfi);
91 Array4<Real >
const& Akv = mf_Akv->array(mfi);
93 Array4<Real const>
const& Hz = mf_Hz->const_array(mfi);
95 Array4<Real const>
const& DU_avg1 = mf_DU_avg1->const_array(mfi);
96 Array4<Real const>
const& DV_avg1 = mf_DV_avg1->const_array(mfi);
98 Array4<Real const>
const& pm = mf_pm->const_array(mfi);
99 Array4<Real const>
const& pn = mf_pn->const_array(mfi);
101 Array4<Real const>
const& msku = mf_msku->const_array(mfi);
102 Array4<Real const>
const& mskv = mf_mskv->const_array(mfi);
104 Box bx = mfi.tilebox();
105 Box gbx2 = mfi.growntilebox(IntVect(
NGROW,
NGROW,0));
108 Box xbx = mfi.nodaltilebox(0);
109 Box ybx = mfi.nodaltilebox(1);
121 FArrayBox fab_FC(convert(gbx2,IntVect(0,0,1)),1,amrex::The_Async_Arena());
122 FArrayBox fab_BC(convert(gbx2,IntVect(0,0,1)),1,amrex::The_Async_Arena());
123 FArrayBox fab_CF(gbx21,1,amrex::The_Async_Arena());
124 FArrayBox fab_W(tbxp2,1,amrex::The_Async_Arena());
126 auto FC = fab_FC.array();
127 auto BC = fab_BC.array();
128 auto CF = fab_CF.array();
133 }
else if (iic==ntfirst+1) {
134 cff=0.25_rt*dt_lev*3.0_rt/2.0_rt;
136 cff=0.25_rt*dt_lev*23.0_rt/12.0_rt;
139 ParallelFor(xbx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
141 u(i,j,k) += cff * (pm(i,j,0)+pm(i-1,j,0)) * (pn(i,j,0)+pn(i-1,j,0)) * ru(i,j,k,nrhs);
142 u(i,j,k) *= 2.0_rt / (Hz(i-1,j,k) + Hz(i,j,k));
145 ParallelFor(ybx, [=] AMREX_GPU_DEVICE (
int i,
int j,
int k)
147 v(i,j,k) += cff * (pm(i,j,0)+pm(i,j-1,0)) * (pn(i,j,0)+pn(i,j-1,0)) * rv(i,j,k,nrhs);
148 v(i,j,k) *= 2.0_rt / (Hz(i,j-1,k) + Hz(i,j,k));
155 mf_DC[mfi].template setVal<RunOn::Device>(0.,xbx);
156 fab_CF.template setVal<RunOn::Device>(0.,xbx);
158 vert_visc_3d(xbx,1,0,u,Hz,Hzk,AK,Akv,BC,DC,FC,CF,nnew,N,dt_lev);
161 mf_DC[mfi].template setVal<RunOn::Device>(0.,ybx);
162 fab_CF.template setVal<RunOn::Device>(0.,ybx);
164 vert_visc_3d(ybx,0,1,v,Hz,Hzk,AK,Akv,BC,DC,FC,CF,nnew,N,dt_lev);
167 mf_DC[mfi].template setVal<RunOn::Device>(0.,xbx);
168 fab_CF.template setVal<RunOn::Device>(0.,xbx);
170 vert_mean_3d(xbx,1,0,u,Hz,DU_avg1,DC,CF,pn,msku,nnew,N);
173 mf_DC[mfi].template setVal<RunOn::Device>(0.,ybx);
174 fab_CF.template setVal<RunOn::Device>(0.,ybx);
176 vert_mean_3d(ybx,0,1,v,Hz,DV_avg1,DC,CF,pm,mskv,nnew,N);
183#ifdef REMORA_USE_NETCDF
195 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
197 Array4<Real >
const& u = mf_u.array(mfi);
198 Array4<Real >
const& v = mf_v.array(mfi);
200 Array4<Real >
const& DC = mf_DC.array(mfi);
202 Array4<Real const>
const& Hz = mf_Hz->const_array(mfi);
204 Array4<Real const>
const& DU_avg1 = mf_DU_avg1->const_array(mfi);
205 Array4<Real const>
const& DV_avg1 = mf_DV_avg1->const_array(mfi);
207 Array4<Real const>
const& DU_avg2 = mf_DU_avg2->const_array(mfi);
208 Array4<Real const>
const& DV_avg2 = mf_DV_avg2->const_array(mfi);
210 Array4<Real>
const& ubar = mf_ubar->array(mfi);
211 Array4<Real>
const& vbar = mf_vbar->array(mfi);
213 Array4<Real>
const& Huon = mf_Huon->array(mfi);
214 Array4<Real>
const& Hvom = mf_Hvom->array(mfi);
216 Array4<Real const>
const& pm = mf_pm->const_array(mfi);
217 Array4<Real const>
const& pn = mf_pn->const_array(mfi);
218 Array4<Real const>
const& msku = mf_msku->const_array(mfi);
219 Array4<Real const>
const& mskv = mf_mskv->const_array(mfi);
221 Array4<Real const>
const& z_w = mf_z_w->const_array(mfi);
223 Box bx = mfi.tilebox();
224 Box gbx1 = mfi.growntilebox(IntVect(
NGROW-1,
NGROW-1,0));
225 Box gbx2 = mfi.growntilebox(IntVect(
NGROW,
NGROW,0));
227 FArrayBox fab_FC(gbx2,1,amrex::The_Async_Arena());
228 auto FC = fab_FC.array();
230#ifdef REMORA_USE_NETCDF
235 ParallelFor(gbx1, [=] AMREX_GPU_DEVICE(
int i,
int j,
int k)
237 int iriver = river_pos(i,j,0);
239 if (river_direction_d[iriver] == 0) {
240 Real on_u = 2.0_rt / (pn(i,j,0)+pn(i-1,j,0));
241 Real cff = 1.0_rt / (on_u * 0.5_rt * (z_w(i-1,j,k+1) - z_w(i-1,j,k) + z_w(i,j,k+1) - z_w(i,j,k)));
242 u(i,j,k) = cff * river_transport(iriver,0,k);
244 Real om_v = 2.0_rt / (pm(i,j,0)+pm(i,j-1,0));
245 Real cff = 1.0_rt / (om_v * 0.5_rt * (z_w(i,j-1,k+1) - z_w(i,j-1,k) + z_w(i,j,k+1) - z_w(i,j,k)));
246 v(i,j,k) = cff * river_transport(iriver,0,k);
255 mf_DC[mfi].template setVal<RunOn::Device>(0.,grow(xbx,IntVect(0,0,1)));
256 fab_CF.template setVal<RunOn::Device>(0.,grow(xbx,IntVect(0,0,1)));
258 update_massflux_3d(xbx,1,0,u,ubar,Huon,Hz,pn,DU_avg1,DU_avg2,DC,FC,nnew);
261 mf_DC[mfi].template setVal<RunOn::Device>(0.,grow(ybx,IntVect(0,0,1)));
262 fab_CF.template setVal<RunOn::Device>(0.,grow(ybx,IntVect(0,0,1)));
264 update_massflux_3d(ybx,0,1,v,vbar,Hvom,Hz,pm,DV_avg1,DV_avg2,DC,FC,nnew);
269 fab_FC.template setVal<RunOn::Device>(0.,gbx2);
270 mf_DC[mfi].template setVal<RunOn::Device>(0.,grow(gbx2,IntVect(0,0,1)));
271 update_massflux_3d(gbx2,1,0,u,ubar,Huon,Hz,pn,DU_avg1,DU_avg2,DC,FC,msku,nnew);
274 fab_FC.template setVal<RunOn::Device>(0.,gbx2);
275 mf_DC[mfi].template setVal<RunOn::Device>(0.,grow(gbx2,IntVect(0,0,1)));
276 update_massflux_3d(gbx2,0,1,v,vbar,Hvom,Hz,pm,DV_avg1,DV_avg2,DC,FC,mskv,nnew);
288 MultiFab mf_W(convert(ba,IntVect(0,0,1)),dm,1,IntVect(
NGROW+1,
NGROW+1,0));
290 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
292 Array4<Real>
const& Huon = mf_Huon->array(mfi);
293 Array4<Real>
const& Hvom = mf_Hvom->array(mfi);
295 Array4<Real const>
const& z_w = mf_z_w->const_array(mfi);
296 Array4<Real const>
const& h = mf_h->const_array(mfi);
298 Box bx = mfi.tilebox();
299 Box gbx1 = mfi.growntilebox(IntVect(
NGROW-1,
NGROW-1,0));
300 Box gbx2 = mfi.growntilebox(IntVect(
NGROW,
NGROW,0));
310 FArrayBox fab_FC(surroundingNodes(gbx2,2),1,amrex::The_Async_Arena());
311 FArrayBox fab_BC(gbx2,1,amrex::The_Async_Arena());
312 FArrayBox fab_CF(gbx21,1,amrex::The_Async_Arena());
314 auto W = mf_W.array(mfi);
330 ParallelFor(gbx1D, [=] AMREX_GPU_DEVICE (
int i,
int j,
int )
333 for (
int k=1; k<=N+1; k++) {
334 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));
343 ParallelFor(gbx1D, [=] AMREX_GPU_DEVICE (
int i,
int j,
int )
345 Real wrk_ij = W(i,j,N+1) / (z_w(i,j,N+1)+h(i,j,0,0));
347 for (
int k=1; k<=N; k++) {
348 W(i,j,k) -= wrk_ij * (z_w(i,j,k)+h(i,j,0,0));
354 const int nstp = (iic) % 2;
360 nstp, nnew, N, dt_lev);
364 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
366 Array4<Real>
const& Hz = mf_Hz->array(mfi);
368 Array4<Real>
const& Huon = mf_Huon->array(mfi);
369 Array4<Real>
const& Hvom = mf_Hvom->array(mfi);
371 Array4<Real const>
const& pm = mf_pm->const_array(mfi);
372 Array4<Real const>
const& pn = mf_pn->const_array(mfi);
373 Array4<Real const>
const& mskr = mf_mskr->const_array(mfi);
374 Array4<Real const>
const& msku = mf_msku->const_array(mfi);
375 Array4<Real const>
const& mskv = mf_mskv->const_array(mfi);
377 Box bx = mfi.tilebox();
378 Box gbx2 = mfi.growntilebox(IntVect(
NGROW,
NGROW,0));
388 FArrayBox fab_FC(surroundingNodes(gbx2,2),1,amrex::The_Async_Arena());
389 FArrayBox fab_BC(gbx2,1,amrex::The_Async_Arena());
390 FArrayBox fab_CF(gbx21,1,amrex::The_Async_Arena());
392 auto FC = fab_FC.array();
393 auto W = mf_W.array(mfi);
399 for (
int i_comp=0; i_comp <
NCONS; i_comp++)
401#ifdef REMORA_USE_NETCDF
402 FArrayBox* fab_river_source;
407 const Array4<const Real>& river_source = (
solverChoice.
do_rivers_cons[i_comp]) ? fab_river_source->const_array() : Array4<const Real>();
409 const Array4<const int >& river_pos = Array4<const int>();
410 const Array4<const Real>& river_source = Array4<const Real>();
412 Array4<Real>
const& sstore = mf_sstore->array(mfi, i_comp);
413 rhs_t_3d(bx, mf_cons.array(mfi,i_comp), sstore, Huon, Hvom,
414 Hz, pn, pm, W, FC, mskr, msku, mskv, river_pos, river_source, nrhs, nnew, N,dt_lev);
419 FillPatch(lev,
t_old[lev], mf_cons,
cons_new,
BCVars::cons_bc,
BdyVars::t,0,
true,
false,0,0,dt_lev,*
cons_old[lev]);
421 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
423 Array4<Real>
const& AK = mf_AK.array(mfi);
424 Array4<Real>
const& DC = mf_DC.array(mfi);
426 Array4<Real>
const& Hzk = mf_Hzk.array(mfi);
427 Array4<Real const>
const& Hz = mf_Hz->const_array(mfi);
429 Box bx = mfi.tilebox();
442 FArrayBox fab_FC(tbxp2,1,amrex::The_Async_Arena());
443 FArrayBox fab_BC(tbxp2,1,amrex::The_Async_Arena());
444 FArrayBox fab_CF(tbxp21,1,amrex::The_Async_Arena());
445 FArrayBox fab_W(tbxp2,1,amrex::The_Async_Arena());
447 auto FC = fab_FC.array();
448 auto BC = fab_BC.array();
449 auto CF = fab_CF.array();
451 for (
int i_comp=0; i_comp <
NCONS; i_comp++) {
453 AK,mf_Akt->array(mfi,i_comp),BC,DC,FC,CF,nnew,N,dt_lev);
456 FillPatch(lev,
t_old[lev], *
cons_new[lev],
cons_new,
BCVars::cons_bc,
BdyVars::t,0,
true,
false,0,0,dt_lev,*
cons_old[lev]);
459#ifdef REMORA_USE_NETCDF
463 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
465 Box bx = mfi.growntilebox(IntVect(1,1,0));
469 Array4<const Real>
const& Hz =
vec_Hz[lev]->const_array(mfi);
470 Array4<const Real>
const& pm =
vec_pm[lev]->const_array(mfi);
471 Array4<const Real>
const& pn =
vec_pn[lev]->const_array(mfi);
473 apply_clim_nudg(bx, 0, 0, temp, temp, temp_clim, temp_nudg_coeff, Hz, pm, pn, dt_lev);
479 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
481 Box bx = mfi.growntilebox(IntVect(1,1,0));
485 Array4<const Real>
const& Hz =
vec_Hz[lev]->const_array(mfi);
486 Array4<const Real>
const& pm =
vec_pm[lev]->const_array(mfi);
487 Array4<const Real>
const& pn =
vec_pn[lev]->const_array(mfi);
489 apply_clim_nudg(bx, 0, 0, salt, salt, salt_clim, salt_nudg_coeff, Hz, pm, pn, dt_lev);