REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_advance_2d.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4/** Nonlinear shallow-water rpimitive equations predictor (Leap-frog) and
5 * corrector (Adams-Moulton) time-stepping engine. Corresponds to Nonlinear/step2d_LF_AM3.h
6 * in ROMS.
7 *
8 * @param[in ] lev level of refinement (coarsest level is 0)
9 * @param[in ] mf_rhoS density perturbation
10 * @param[in ] mf_rhoA vertically-averaged density
11 * @param[inout] mf_ru2d RHS contributions to 2D u-momentum
12 * @param[inout] mf_rv2d RHS contribtuions to 2D v-momentum
13 * @param[inout] mf_rufrc before first predictor, vertical integral of 3D RHS for uvel, converted to forcing terms
14 * @param[inout] mf_rvfrc before first predictor, vertical integral of 3D RHS for vvel, converted to forcing term
15 * @param[inout] mf_Zt_avg1 average of sea surface height over all fast steps
16 * @param[inout] mf_DU_avg1 time-averaged u-flux for 2D equations
17 * @param[inout] mf_DU_avg2 time-averaged u-flux for 3D equation coupling
18 * @param[inout] mf_DV_avg1 time-averaged v-flux for 2D equations
19 * @param[inout] mf_DV_avg2 time-averaged v-flux for 3D equation coupling
20 * @param[inout] mf_rubar RHS of vertically integrated u-momentum
21 * @param[inout] mf_rvbar RHS of vertically integrated v-momentum
22 * @param[inout] mf_rzeta RHS of sea surface height
23 * @param[inout] mf_ubar vertically integrated u-momentum
24 * @param[inout] mf_vbar vertically integrated v-momentum
25 * @param[inout] mf_zeta Sea-surface height
26 * @param[in ] mf_h Bathymetry
27 * @param[in ] mf_pm 1 / dx
28 * @param[in ] mf_pn 1 / dy
29 * @param[in ] mf_fcor Coriolis factor
30 * @param[inout] mf_visc2_p Harmonic viscosity at psi points
31 * @param[inout] mf_visc2_r Harmoic viscosity at rho points
32 * @param[in ] mf_mskr Land-sea mask at rho-points
33 * @param[in ] mf_msku Land-sea mask at u-points
34 * @param[in ] mf_mskv Land-sea mask at v-points
35 * @param[in ] mf_mskp Land-sea mask at psi-points
36 * @param[in ] dtfast_lev Length of current barotropic step
37 * @param[in ] predictor_2d_step Is this a predictor step?
38 * @param[in ] first_2d_step Is this the first barotropic step?
39 * @param[in ] my_iif Which barotropic predictor-corrector pair?
40 * @param[inout] next_indx1 Cached index for
41 */
42
43void
45 MultiFab const* mf_rhoS,
46 MultiFab const* mf_rhoA,
47 MultiFab * mf_ru2d,
48 MultiFab * mf_rv2d,
49 MultiFab * mf_rufrc,
50 MultiFab * mf_rvfrc,
51 MultiFab * mf_Zt_avg1,
52 std::unique_ptr<MultiFab>& mf_DU_avg1,
53 std::unique_ptr<MultiFab>& mf_DU_avg2,
54 std::unique_ptr<MultiFab>& mf_DV_avg1,
55 std::unique_ptr<MultiFab>& mf_DV_avg2,
56 std::unique_ptr<MultiFab>& mf_rubar,
57 std::unique_ptr<MultiFab>& mf_rvbar,
58 std::unique_ptr<MultiFab>& mf_rzeta,
59 std::unique_ptr<MultiFab>& mf_ubar,
60 std::unique_ptr<MultiFab>& mf_vbar,
61 MultiFab * mf_zeta,
62 MultiFab const* mf_h,
63 MultiFab const* mf_pm,
64 MultiFab const* mf_pn,
65 MultiFab const* mf_fcor,
66 MultiFab const* mf_visc2_p,
67 MultiFab const* mf_visc2_r,
68 MultiFab const* mf_mskr,
69 MultiFab const* mf_msku,
70 MultiFab const* mf_mskv,
71 MultiFab const* mf_mskp,
72 Real dtfast_lev,
73 bool predictor_2d_step,
74 bool first_2d_step, int my_iif,
75 int & next_indx1)
76{
77 BL_PROFILE("REMORA::advance2d()");
78 int iic = istep[lev];
79 const int nnew = 0;
80 const int nstp = 0;
81 int ntfirst = 0;
82
83 int knew = 3;
84 int krhs = (my_iif + iic) % 2 + 1;
85 int kstp = my_iif <=1 ? iic % 2 + 1 : (iic % 2 + my_iif % 2 + 1) % 2 + 1;
86 int indx1 = krhs;
87 if (predictor_2d_step) {
88 next_indx1 = 3 - indx1;
89 } else {
90 knew = next_indx1;
91 kstp = 3 - knew;
92 krhs = 3;
93 //If it's not the auxiliary time step, set indx1 to next_indx1
94 // NOTE: should this ever not execute?
95 // Include indx1 updates for diagnostic purposes?
96 // if (my_iif<nfast+1)
97 // indx1=next_indx1;
98 }
99 int ptsk = 3-kstp;
100 knew-=1;
101 krhs-=1;
102 kstp-=1;
103 // Include indx1 updates for diagnostic purposes?
104 //indx1-=1;
105 ptsk-=1;
106 auto ba = mf_h->boxArray();
107 auto dm = mf_h->DistributionMap();
108
109 MultiFab mf_DUon(convert(ba,IntVect(1,0,0)),dm,1,IntVect(NGROW,NGROW,0));
110 MultiFab mf_DVom(convert(ba,IntVect(0,1,0)),dm,1,IntVect(NGROW,NGROW,0));
111
112 const auto dlo = amrex::lbound(Geom(lev).Domain());
113 const auto dhi = amrex::ubound(Geom(lev).Domain());
114
115 int ncomp = 0;
116 int fomn_comp = ncomp++;
117 int Drhs_comp = ncomp++;
118 int Dnew_comp = ncomp++;
119 int zwrk_comp = ncomp++;
120 int gzeta_comp = ncomp++;
121 int gzeta2_comp = ncomp++;
122 int gzetaSA_comp = ncomp++;
123 int Dstp_comp = ncomp++;
124 int rhs_ubar_comp = ncomp++;
125 int rhs_vbar_comp = ncomp++;
126 int rhs_zeta_comp = ncomp++;
127 int zeta_new_comp = ncomp++;
128
129 MultiFab mf(ba,dm,ncomp,IntVect(NGROW+1,NGROW+1,0));
130
131 for ( MFIter mfi(*mf_rhoS, TilingIfNotGPU()); mfi.isValid(); ++mfi )
132 {
133 Array4<Real > const& ubar = mf_ubar->array(mfi);
134 Array4<Real > const& vbar = mf_vbar->array(mfi);
135 Array4<Real > const& zeta = mf_zeta->array(mfi);
136 Array4<Real const> const& h = mf_h->const_array(mfi);
137
138 Array4<Real const> const& pm = mf_pm->const_array(mfi);
139 Array4<Real const> const& pn = mf_pn->const_array(mfi);
140
141 Box bx = mfi.tilebox();
142 Box gbx = mfi.growntilebox();
143 Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
144 Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
145 Box xgbx2 = mfi.grownnodaltilebox(0, IntVect(NGROW,NGROW,0));
146 Box ygbx2 = mfi.grownnodaltilebox(1, IntVect(NGROW,NGROW,0));
147
148 Box tbxp1 = bx;
149 Box tbxp2 = bx;
150 Box tbxp3 = bx;
151 tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
152 tbxp2.grow(IntVect(NGROW,NGROW,0));
153 tbxp3.grow(IntVect(NGROW+1,NGROW+1,0));
154
155 Box bxD = bx ; bxD.makeSlab(2,0);
156 Box gbxD = gbx ; gbxD.makeSlab(2,0);
157 Box gbx1D = gbx1; gbx1D.makeSlab(2,0);
158 Box gbx2D = gbx2; gbx2D.makeSlab(2,0);
159
160 Box tbxp2D = tbxp2;
161 tbxp2D.makeSlab(2,0);
162
163 // step2d work arrays
164 FArrayBox fab_Drhs(makeSlab(tbxp3,2,0),1,The_Async_Arena());
165 auto Drhs=fab_Drhs.array();
166
167 auto DUon = mf_DUon.array(mfi);
168 auto DVom = mf_DVom.array(mfi);
169
170 ParallelFor(makeSlab(tbxp3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
171 {
172 Drhs(i,j,0)=zeta(i,j,0,krhs)+h(i,j,0);
173 });
174
175 ParallelFor(makeSlab(xgbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
176 {
177 Real on_u = 2.0_rt / (pn(i,j,0)+pn(i-1,j,0));
178 Real cff1= 0.5_rt * on_u *(Drhs(i,j,0)+Drhs(i-1,j,0));
179 DUon(i,j,0)=ubar(i,j,0,krhs)*cff1;
180 });
181
182 ParallelFor(makeSlab(ygbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
183 {
184 Real om_v = 2.0_rt / (pm(i,j,0)+pm(i,j-1,0));
185 Real cff1= 0.5_rt * om_v * (Drhs(i,j,0)+Drhs(i,j-1,0));
186 DVom(i,j,0)=vbar(i,j,0,krhs)*cff1;
187 });
188 }
189
190 // These are needed to pass the tests with bathymetry but I don't quite see why
191 mf_DUon.FillBoundary(geom[lev].periodicity());
192 mf_DVom.FillBoundary(geom[lev].periodicity());
193
194#ifdef REMORA_USE_NETCDF
198 }
199#endif
200
201 for ( MFIter mfi(*mf_rhoS, TilingIfNotGPU()); mfi.isValid(); ++mfi )
202 {
203 Array4<Real const> const& rhoS = mf_rhoS->const_array(mfi);
204 Array4<Real const> const& rhoA = mf_rhoA->const_array(mfi);
205 Array4<Real const> const& h = mf_h->const_array(mfi);
206
207 Array4<Real > const& rufrc = mf_rufrc->array(mfi);
208 Array4<Real > const& rvfrc = mf_rvfrc->array(mfi);
209 Array4<Real > const& Zt_avg1 = mf_Zt_avg1->array(mfi);
210 Array4<Real > const& ubar = mf_ubar->array(mfi);
211 Array4<Real > const& vbar = mf_vbar->array(mfi);
212 Array4<Real > const& zeta = mf_zeta->array(mfi);
213 Array4<Real > const& DU_avg1 = (mf_DU_avg1)->array(mfi);
214 Array4<Real > const& DU_avg2 = (mf_DU_avg2)->array(mfi);
215 Array4<Real > const& DV_avg1 = (mf_DV_avg1)->array(mfi);
216 Array4<Real > const& DV_avg2 = (mf_DV_avg2)->array(mfi);
217 Array4<Real > const& ru2d = (mf_ru2d)->array(mfi);
218 Array4<Real > const& rv2d = (mf_rv2d)->array(mfi);
219 Array4<Real > const& rubar = (mf_rubar)->array(mfi);
220 Array4<Real > const& rvbar = (mf_rvbar)->array(mfi);
221 Array4<Real > const& rzeta = (mf_rzeta)->array(mfi);
222 Array4<Real const> const& visc2_p = mf_visc2_p->const_array(mfi);
223 Array4<Real const> const& visc2_r = mf_visc2_r->const_array(mfi);
224
225 Array4<Real const> const& pm = mf_pm->const_array(mfi);
226 Array4<Real const> const& pn = mf_pn->const_array(mfi);
227 Array4<Real const> const& fcor = mf_fcor->const_array(mfi);
228
229 Array4<Real const> const& mskr = mf_mskr->const_array(mfi);
230 Array4<Real const> const& msku = mf_msku->const_array(mfi);
231 Array4<Real const> const& mskv = mf_mskv->const_array(mfi);
232 Array4<Real const> const& mskp = mf_mskp->const_array(mfi);
233
234 Box bx = mfi.tilebox();
235 Box gbx = mfi.growntilebox();
236 Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
237 Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
238 Box gbx3 = mfi.growntilebox(IntVect(NGROW+1,NGROW+1,0));
239 Box xgbx2 = mfi.grownnodaltilebox(0, IntVect(NGROW,NGROW,0));
240 Box ygbx2 = mfi.grownnodaltilebox(1, IntVect(NGROW,NGROW,0));
241
242 Box xbxD = mfi.nodaltilebox(0);
243 xbxD.makeSlab(2,0);
244
245 Box ybxD = mfi.nodaltilebox(1);
246 ybxD.makeSlab(2,0);
247
248 Box xbxD_adj = mfi.nodaltilebox(0);
249 xbxD_adj.makeSlab(2,0);
250 Box ybxD_adj = mfi.nodaltilebox(1);
251 ybxD_adj.makeSlab(2,0);
252
253 auto xbxD_lo = lbound(xbxD_adj);
254 auto xbxD_hi = ubound(xbxD_adj);
255 auto ybxD_lo = lbound(ybxD_adj);
256 auto ybxD_hi = ubound(ybxD_adj);
257
258 if (xbxD_lo.x == dlo.x) {
259 xbxD_adj.growLo(0,-1);
260 } else if (xbxD_hi.x == dhi.x) {
261 xbxD_adj.growHi(0,-1);
262 }
263
264 if (ybxD_lo.y == dlo.y) {
265 ybxD_adj.growLo(1,-1);
266 } else if (ybxD_hi.y == dhi.y) {
267 ybxD_adj.growHi(1,-1);
268 }
269
270 Box tbxp1 = bx; tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
271 Box tbxp2 = bx; tbxp2.grow(IntVect(NGROW,NGROW,0));
272 Box tbxp3 = bx; tbxp3.grow(IntVect(NGROW+1,NGROW+1,0));
273
274 Box bxD = bx; bxD.makeSlab(2,0);
275 Box gbxD = gbx; gbxD.makeSlab(2,0);
276 Box gbx1D = gbx1; gbx1D.makeSlab(2,0);
277 Box gbx2D = gbx2; gbx2D.makeSlab(2,0);
278
279 Box tbxp2D = tbxp2;
280 tbxp2D.makeSlab(2,0);
281
282 auto fomn = mf.array(mfi,fomn_comp);
283 auto Drhs = mf.array(mfi,Drhs_comp);
284 auto Drhs_const = mf.const_array(mfi,Drhs_comp);
285 auto Dnew = mf.array(mfi,Dnew_comp);
286 auto zwrk = mf.array(mfi,zwrk_comp);
287 auto gzeta = mf.array(mfi,gzeta_comp);
288 auto gzeta2 = mf.array(mfi,gzeta2_comp);
289 auto gzetaSA = mf.array(mfi,gzetaSA_comp);
290 auto Dstp = mf.array(mfi,Dstp_comp);
291 auto rhs_ubar = mf.array(mfi,rhs_ubar_comp);
292 auto rhs_vbar = mf.array(mfi,rhs_vbar_comp);
293 auto rhs_zeta = mf.array(mfi,rhs_zeta_comp);
294 auto zeta_new = mf.array(mfi,zeta_new_comp);
295
296 FArrayBox & fab_DUon=mf_DUon[mfi];
297 FArrayBox & fab_DVom=mf_DVom[mfi];
298 auto DUon=fab_DUon.array();
299 auto DVom=fab_DVom.array();
300
301 auto weight1 = vec_weight1.dataPtr();
302 auto weight2 = vec_weight2.dataPtr();
303
304 //From ana_grid.h and metrics.F
305 ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int)
306 {
307 rhs_ubar(i,j,0)=0.0_rt;
308 });
309
310 ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int)
311 {
312 rhs_vbar(i,j,0)=0.0_rt;
313 });
314
316 ParallelFor(tbxp2D, [=] AMREX_GPU_DEVICE (int i, int j, int )
317 {
318 fomn(i,j,0) = fcor(i,j,0)*(1.0_rt/(pm(i,j,0)*pn(i,j,0)));
319 });
320 }
321
322 ParallelFor(makeSlab(tbxp3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
323 {
324 Drhs(i,j,0)=zeta(i,j,0,krhs)+h(i,j,0);
325 });
326
327 if(predictor_2d_step)
328 {
329 if(first_2d_step) {
330 Real cff2=(-1.0_rt/12.0_rt)*weight2[my_iif+1];
331 ParallelFor(makeSlab(gbx3,2,0),
332 [=] AMREX_GPU_DEVICE (int i, int j, int)
333 {
334 Zt_avg1(i,j,0)=0.0_rt;
335 });
336 ParallelFor(makeSlab(xgbx2,2,0),
337 [=] AMREX_GPU_DEVICE (int i, int j, int)
338 {
339 DU_avg1(i,j,0)=0.0_rt;
340 DU_avg2(i,j,0)=cff2*DUon(i,j,0);
341 });
342 ParallelFor(makeSlab(ygbx2,2,0),
343 [=] AMREX_GPU_DEVICE (int i, int j, int)
344 {
345 DV_avg1(i,j,0)=0.0_rt;
346 DV_avg2(i,j,0)=cff2*DVom(i,j,0);
347 });
348 }
349 else {
350 Real cff1_wt1 = weight1[my_iif-1];
351 Real cff2_wt1 = (8.0_rt/12.0_rt)*weight2[my_iif]-
352 (1.0_rt/12.0_rt)*weight2[my_iif+1];
353
354 ParallelFor(makeSlab(gbx3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
355 {
356 Zt_avg1(i,j,0) += cff1_wt1*zeta(i,j,0,krhs);
357 });
358
359 ParallelFor(makeSlab(xgbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
360 {
361 DU_avg1(i,j,0) += cff1_wt1*DUon(i,j,0);
362 DU_avg2(i,j,0) += cff2_wt1*DUon(i,j,0);
363 });
364
365 ParallelFor(makeSlab(ygbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
366 {
367 DV_avg1(i,j,0) += cff1_wt1*DVom(i,j,0);
368 DV_avg2(i,j,0) += cff2_wt1*DVom(i,j,0);
369 });
370 }
371 }
372 else {
373 Real cff2_wt2;
374
375 if (first_2d_step) {
376 cff2_wt2=weight2[my_iif];
377 } else {
378 cff2_wt2=5.0_rt/12.0_rt*weight2[my_iif];
379 }
380
381 ParallelFor(makeSlab(xgbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
382 {
383 DU_avg2(i,j,0)=DU_avg2(i,j,0)+cff2_wt2*DUon(i,j,0);
384 });
385
386 ParallelFor(makeSlab(ygbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
387 {
388 DV_avg2(i,j,0)=DV_avg2(i,j,0)+cff2_wt2*DVom(i,j,0);
389 });
390 }
391 //
392 // Do not perform the actual time stepping during the auxiliary
393 // (nfast(ng)+1) time step. Jump to next box
394 //
395
396 if (my_iif>=nfast) {
397 continue; }
398 //Load new free-surface values into shared array at both predictor
399 //and corrector steps
400 //
401 //=======================================================================
402 // Time step free-surface equation.
403 //=======================================================================
404 //
405 // During the first time-step, the predictor step is Forward-Euler
406 // and the corrector step is Backward-Euler. Otherwise, the predictor
407 // step is Leap-frog and the corrector step is Adams-Moulton.
408 //
409
410 // todo: gzeta
411
412 // todo: HACKHACKHACK Should use rho0 from prob.H
413 Real fac=1000.0_rt/1025.0_rt;
414
415 if (my_iif==0) {
416 Real cff1=dtfast_lev;
417
418 ParallelFor(makeSlab(tbxp1,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
419 {
420 rhs_zeta(i,j,0) = (DUon(i,j,0)-DUon(i+1,j,0))+
421 (DVom(i,j,0)-DVom(i,j+1,0));
422 zeta_new(i,j,0) = (zeta(i,j,0,kstp)+ pm(i,j,0)*pn(i,j,0)*cff1*rhs_zeta(i,j,0)) * mskr(i,j,0);
423 Dnew(i,j,0) = zeta_new(i,j,0)+h(i,j,0);
424
425 //Pressure gradient terms:
426 zwrk(i,j,0)=0.5_rt*(zeta(i,j,0,kstp)+zeta_new(i,j,0));
427 gzeta(i,j,0)=(fac+rhoS(i,j,0))*zwrk(i,j,0);
428 gzeta2(i,j,0)=gzeta(i,j,0)*zwrk(i,j,0);
429 gzetaSA(i,j,0)=zwrk(i,j,0)*(rhoS(i,j,0)-rhoA(i,j,0));
430 });
431
432 } else if (predictor_2d_step) {
433
434 Real cff1=2.0_rt * dtfast_lev;
435 Real cff4=4.0_rt / 25.0_rt;
436 Real cff5=1.0_rt - 2.0_rt*cff4;
437
438 ParallelFor(makeSlab(tbxp1,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
439 {
440 rhs_zeta(i,j,0)=(DUon(i,j,0)-DUon(i+1,j,0))+
441 (DVom(i,j,0)-DVom(i,j+1,0));
442 zeta_new(i,j,0)=(zeta(i,j,0,kstp)+
443 pm(i,j,0)*pn(i,j,0)*cff1*rhs_zeta(i,j,0)) * mskr(i,j,0);
444 Dnew(i,j,0)=zeta_new(i,j,0)+h(i,j,0);
445 //Pressure gradient terms
446 zwrk(i,j,0)=cff5*zeta(i,j,0,krhs)+
447 cff4*(zeta(i,j,0,kstp)+zeta_new(i,j,0));
448 gzeta(i,j,0)=(fac+rhoS(i,j,0))*zwrk(i,j,0);
449 gzeta2(i,j,0)=gzeta(i,j,0)*zwrk(i,j,0);
450 gzetaSA(i,j,0)=zwrk(i,j,0)*(rhoS(i,j,0)-rhoA(i,j,0));
451 });
452
453 } else if (!predictor_2d_step) { //AKA if(corrector_2d_step)
454
455 Real cff1=dtfast_lev * 5.0_rt/12.0_rt;
456 Real cff2=dtfast_lev * 8.0_rt/12.0_rt;
457 Real cff3=dtfast_lev * 1.0_rt/12.0_rt;
458 Real cff4=2.0_rt/5.0_rt;
459 Real cff5=1.0_rt-cff4;
460
461 ParallelFor(makeSlab(tbxp1,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
462 {
463 Real cff=cff1*((DUon(i,j,0)-DUon(i+1,j,0))+
464 (DVom(i,j,0)-DVom(i,j+1,0)));
465 zeta_new(i,j,0)=zeta(i,j,0,kstp)+
466 pm(i,j,0)*pn(i,j,0)*(cff+
467 cff2*rzeta(i,j,0,kstp)-
468 cff3*rzeta(i,j,0,ptsk));
469 zeta_new(i,j,0) *= mskr(i,j,0);
470 Dnew(i,j,0)=zeta_new(i,j,0)+h(i,j,0);
471 //Pressure gradient terms
472 zwrk(i,j,0)=cff5*zeta_new(i,j,0)+cff4*zeta(i,j,0,krhs);
473 gzeta(i,j,0)=(fac+rhoS(i,j,0))*zwrk(i,j,0);
474 gzeta2(i,j,0)=gzeta(i,j,0)*zwrk(i,j,0);
475 gzetaSA(i,j,0)=zwrk(i,j,0)*(rhoS(i,j,0)-rhoA(i,j,0));
476 });
477 }
478
479 //
480 // Load new free-surface values into shared array at both predictor
481 // and corrector steps.
482 //
483 //// zeta(knew) only valid at zeta_new, i.e. tbxp1
484 ParallelFor(makeSlab(gbx1,2,0),
485 [=] AMREX_GPU_DEVICE (int i, int j, int )
486 {
487 zeta(i,j,0,knew) = zeta_new(i,j,0);
488 });
489
490 //
491 // If predictor step, load right-side-term into shared array.
492 //
493 if (predictor_2d_step) {
494 ParallelFor(makeSlab(gbx1,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
495 {
496 rzeta(i,j,0,krhs)=rhs_zeta(i,j,0);
497 });
498 }
499
500 //
501 //=======================================================================
502 // Compute right-hand-side for the 2D momentum equations.
503 //=======================================================================
504 //
505/*
506!
507!-----------------------------------------------------------------------
508! Compute pressure gradient terms.
509!-----------------------------------------------------------------------
510!
511*/
512 Real cff1 = 0.5_rt * g;
513 Real cff2 = 1.0_rt / 3.0_rt;
514 ParallelFor(xbxD,
515 [=] AMREX_GPU_DEVICE (int i, int j, int )
516 {
517 Real on_u = 2.0_rt / (pn(i,j,0)+pn(i-1,j,0));
518 rhs_ubar(i,j,0)=cff1 * on_u *
519 (( h(i-1,j,0) + h(i,j,0))*
520 (gzeta(i-1,j,0) - gzeta(i,j,0))+
521 ( h(i-1,j,0) - h(i,j,0))*
522 ( gzetaSA(i-1,j,0) + gzetaSA(i,j,0)+
523 cff2*( rhoA(i-1,j,0) - rhoA(i,j,0))*
524 ( zwrk(i-1,j,0) - zwrk(i,j,0)))+
525 (gzeta2(i-1,j,0)- gzeta2(i ,j,0)));
526 });
527
528 ParallelFor(ybxD,
529 [=] AMREX_GPU_DEVICE (int i, int j, int )
530 {
531 Real om_v = 2.0_rt / (pm(i,j,0)+pm(i,j-1,0));
532 rhs_vbar(i,j,0) = cff1*om_v *
533 (( h(i,j-1,0) + h(i,j,0))*
534 (gzeta(i,j-1,0) - gzeta(i,j,0))+
535 ( h(i,j-1,0) - h(i,j,0))*
536 (gzetaSA(i,j-1,0)+ gzetaSA(i,j ,0)+
537 cff2*(rhoA(i,j-1,0)- rhoA(i,j ,0))*
538 (zwrk(i,j-1,0)- zwrk(i,j ,0)))+
539 (gzeta2(i,j-1,0)- gzeta2(i,j ,0)));
540 });
541
542 // Advection terms for 2d ubar, vbar added to rhs_ubar and rhs_vbar
543 //
544 //-----------------------------------------------------------------------
545 // rhs_uv_2d
546 //-----------------------------------------------------------------------
547 //
548 Array4<Real const> const& ubar_const = mf_ubar->const_array(mfi);
549 Array4<Real const> const& vbar_const = mf_vbar->const_array(mfi);
550
551 rhs_uv_2d(lev,xbxD, ybxD, ubar_const, vbar_const, rhs_ubar, rhs_vbar, DUon, DVom, krhs);
552
553 //-----------------------------------------------------------------------
554 // Add Coriolis forcing
555 //-----------------------------------------------------------------------
557 // Coriolis terms for 2d ubar, vbar added to rhs_ubar and rhs_vbar
558 //
559 //-----------------------------------------------------------------------
560 // coriolis
561 //-----------------------------------------------------------------------
562 //
563 coriolis(xbxD, ybxD, ubar_const, vbar_const, rhs_ubar, rhs_vbar, Drhs, fomn, krhs, 0);
564 }
565 //-----------------------------------------------------------------------
566 //Add in horizontal harmonic viscosity.
567 // Consider generalizing or copying uv3dmix, where Drhs is used instead of Hz and u=>ubar v=>vbar, drop dt terms
568 //-----------------------------------------------------------------------
569 uv3dmix(xbxD, ybxD, ubar, vbar, ubar, vbar, rhs_ubar, rhs_vbar,
570 visc2_p, visc2_r, Drhs_const,
571 pm, pn, mskp, krhs, nnew, 0.0_rt);
572
573#ifdef REMORA_USE_NETCDF
575 Array4<Real > const& ubar_krhs = mf_ubar->array(mfi, krhs);
576 Array4<Real > const& vbar_krhs = mf_vbar->array(mfi, krhs);
577 Array4<const Real> const& ubar_clim = ubar_clim_data_from_file->mf_interpolated->const_array(mfi);
578 Array4<const Real> const& vbar_clim = vbar_clim_data_from_file->mf_interpolated->const_array(mfi);
579 Array4<const Real> const& ubar_nudg_coeff = vec_nudg_coeff[BdyVars::ubar][lev]->const_array(mfi);
580 Array4<const Real> const& vbar_nudg_coeff = vec_nudg_coeff[BdyVars::vbar][lev]->const_array(mfi);
581 // Boxes are like this to match ROMS
582 apply_clim_nudg(xbxD_adj, 1, 0, rhs_ubar, ubar_krhs, ubar_clim, ubar_nudg_coeff, Drhs_const, pm, pn);
583 apply_clim_nudg(ybxD_adj, 0, 1, rhs_vbar, vbar_krhs, vbar_clim, vbar_nudg_coeff, Drhs_const, pm, pn);
584 }
585#endif
586
587 //-----------------------------------------------------------------------
588 // Coupling from 3d to 2d
589 //-----------------------------------------------------------------------
590 if (first_2d_step&&predictor_2d_step)
591 {
592 if (iic==ntfirst) {
593 ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
594 {
595 rufrc(i,j,0) -= rhs_ubar(i,j,0);
596 rhs_ubar(i,j,0) += rufrc(i,j,0);
597 ru2d(i,j,0,nstp) = rufrc(i,j,0);
598 });
599
600 ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
601 {
602 rvfrc(i,j,0) -= rhs_vbar(i,j,0);
603 rhs_vbar(i,j,0) += rvfrc(i,j,0);
604 rv2d(i,j,0,nstp) = rvfrc(i,j,0);
605 });
606
607 } else if (iic==(ntfirst+1)) {
608
609 ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
610 {
611 rufrc(i,j,0)=rufrc(i,j,0)-rhs_ubar(i,j,0);
612 rhs_ubar(i,j,0)=rhs_ubar(i,j,0)+1.5_rt*rufrc(i,j,0)-0.5_rt*ru2d(i,j,0,0);
613 ru2d(i,j,0,1)=rufrc(i,j,0);
614 Real r_swap= ru2d(i,j,0,1);
615 ru2d(i,j,0,1) = ru2d(i,j,0,0);
616 ru2d(i,j,0,0) = r_swap;
617 });
618
619 ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
620 {
621 rvfrc(i,j,0)=rvfrc(i,j,0)-rhs_vbar(i,j,0);
622 rhs_vbar(i,j,0)=rhs_vbar(i,j,0)+1.5_rt*rvfrc(i,j,0)-0.5_rt*rv2d(i,j,0,0);
623 rv2d(i,j,0,1)=rvfrc(i,j,0);
624 Real r_swap= rv2d(i,j,0,1);
625 rv2d(i,j,0,1) = rv2d(i,j,0,0);
626 rv2d(i,j,0,0) = r_swap;
627 });
628
629 } else {
630 cff1=23.0_rt/12.0_rt;
631 cff2=16.0_rt/12.0_rt;
632 Real cff3= 5.0_rt/12.0_rt;
633
634 ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
635 {
636 rufrc(i,j,0)=rufrc(i,j,0)-rhs_ubar(i,j,0);
637 rhs_ubar(i,j,0)=rhs_ubar(i,j,0)+
638 cff1*rufrc(i,j,0)-
639 cff2*ru2d(i,j,0,0)+
640 cff3*ru2d(i,j,0,1);
641 ru2d(i,j,0,1)=rufrc(i,j,0);
642 Real r_swap= ru2d(i,j,0,1);
643 ru2d(i,j,0,1) = ru2d(i,j,0,0);
644 ru2d(i,j,0,0) = r_swap;
645 });
646
647 ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
648 {
649 rvfrc(i,j,0)=rvfrc(i,j,0)-rhs_vbar(i,j,0);
650 rhs_vbar(i,j,0)=rhs_vbar(i,j,0)+
651 cff1*rvfrc(i,j,0)-
652 cff2*rv2d(i,j,0,0)+
653 cff3*rv2d(i,j,0,1);
654 rv2d(i,j,0,1)=rvfrc(i,j,0);
655
656 Real r_swap= rv2d(i,j,0,1);
657 rv2d(i,j,0,1) = rv2d(i,j,0,0);
658 rv2d(i,j,0,0) = r_swap;
659 });
660 }
661 } else {
662 ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
663 {
664 rhs_ubar(i,j,0) += rufrc(i,j,0);
665 });
666
667 ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
668 {
669 rhs_vbar(i,j,0) += rvfrc(i,j,0);
670 });
671 }
672
673 //
674 //=======================================================================
675 // Time step 2D momentum equations.
676 //=======================================================================
677 //
678 // Compute total water column depth.
679 //
680 ParallelFor(makeSlab(tbxp3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
681 {
682 Dstp(i,j,0)=zeta(i,j,0,kstp)+h(i,j,0);
683 });
684
685 //
686 // During the first time-step, the predictor step is Forward-Euler
687 // and the corrector step is Backward-Euler. Otherwise, the predictor
688 // step is Leap-frog and the corrector step is Adams-Moulton.
689 //
690 if (my_iif==0) {
691 cff1=0.5_rt*dtfast_lev;
692 ParallelFor(xbxD,
693 [=] AMREX_GPU_DEVICE (int i, int j, int )
694 {
695 Real cff=(pm(i,j,0)+pm(i-1,j,0))*(pn(i,j,0)+pn(i-1,j,0));
696 Real Dnew_avg =1.0_rt/(Dnew(i,j,0)+Dnew(i-1,j,0));
697 ubar(i,j,0,knew)=(ubar(i,j,0,kstp)*
698 (Dstp(i,j,0)+Dstp(i-1,j,0))+
699 cff*cff1*rhs_ubar(i,j,0))*Dnew_avg * msku(i,j,0);
700 });
701 ParallelFor(ybxD,
702 [=] AMREX_GPU_DEVICE (int i, int j, int )
703 {
704 Real cff=(pm(i,j,0)+pm(i,j-1,0))*(pn(i,j,0)+pn(i,j-1,0));
705 Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i,j-1,0));
706 vbar(i,j,0,knew)=(vbar(i,j,0,kstp)*
707 (Dstp(i,j,0)+Dstp(i,j-1,0))+
708 cff*cff1*rhs_vbar(i,j,0))*Dnew_avg * mskv(i,j,0);
709 });
710
711 } else if (predictor_2d_step) {
712
713 cff1=dtfast_lev;
714 ParallelFor(xbxD,
715 [=] AMREX_GPU_DEVICE (int i, int j, int )
716 {
717 Real cff=(pm(i,j,0)+pm(i-1,j,0))*(pn(i,j,0)+pn(i-1,j,0));
718 Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i-1,j,0));
719 ubar(i,j,0,knew)=(ubar(i,j,0,kstp)*
720 (Dstp(i,j,0)+Dstp(i-1,j,0))+
721 cff*cff1*rhs_ubar(i,j,0))*Dnew_avg * msku(i,j,0);
722 });
723 ParallelFor(ybxD,
724 [=] AMREX_GPU_DEVICE (int i, int j, int )
725 {
726 Real cff=(pm(i,j,0)+pm(i,j-1,0))*(pn(i,j,0)+pn(i,j-1,0));
727 Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i,j-1,0));
728 vbar(i,j,0,knew)=(vbar(i,j,0,kstp)*
729 (Dstp(i,j,0)+Dstp(i,j-1,0))+
730 cff*cff1*rhs_vbar(i,j,0))*Dnew_avg * mskv(i,j,0);
731 });
732
733 } else if ((!predictor_2d_step)) {
734
735 cff1=0.5_rt*dtfast_lev*5.0_rt/12.0_rt;
736 cff2=0.5_rt*dtfast_lev*8.0_rt/12.0_rt;
737 Real cff3=0.5_rt*dtfast_lev*1.0_rt/12.0_rt;
738 ParallelFor(xbxD,
739 [=] AMREX_GPU_DEVICE (int i, int j, int )
740 {
741 Real cff=(pm(i,j,0)+pm(i-1,j,0))*(pn(i,j,0)+pn(i-1,j,0));
742 Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i-1,j,0));
743 ubar(i,j,0,knew)=(ubar(i,j,0,kstp)*
744 (Dstp(i,j,0)+Dstp(i-1,j,0))+
745 cff*(cff1*rhs_ubar(i,j,0)+
746 cff2*rubar(i,j,0,kstp)-
747 cff3*rubar(i,j,0,ptsk)))*Dnew_avg * msku(i,j,0);
748 });
749 ParallelFor(ybxD,
750 [=] AMREX_GPU_DEVICE (int i, int j, int )
751 {
752 Real cff=(pm(i,j,0)+pm(i,j-1,0))*(pn(i,j,0)+pn(i,j-1,0));
753 Real Dnew_avg=1.0_rt/(Dnew(i,j,0)+Dnew(i,j-1,0));
754 vbar(i,j,0,knew)=(vbar(i,j,0,kstp)*
755 (Dstp(i,j,0)+Dstp(i,j-1,0))+
756 cff*(cff1*rhs_vbar(i,j,0)+
757 cff2*rvbar(i,j,0,kstp)-
758 cff3*rvbar(i,j,0,ptsk)))*Dnew_avg * mskv(i,j,0);
759 });
760 }
761
762 //store rhs_ubar and rhs_vbar to save later
763 //
764 // If predictor step, load right-side-term into shared arrays for
765 // future use during the subsequent corrector step.
766 //
767
768 if (predictor_2d_step) {
769 ParallelFor(xbxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
770 {
771 rubar(i,j,0,krhs)=rhs_ubar(i,j,0);
772 });
773 ParallelFor(ybxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
774 {
775 rvbar(i,j,0,krhs)=rhs_vbar(i,j,0);
776 });
777 }
778 }
779
780 // Don't do the FillPatch or rivers at the last truncated predictor step.
781 // We may need to move the zeta FillPatch further up
782 if (my_iif<nfast) {
783 int know;
784 Real dt2d;
785 if (my_iif==0) {
786 know = krhs;
787 dt2d = dtfast_lev;
788 } else if (predictor_2d_step) {
789 know = krhs;
790 dt2d = 2.0_rt * dtfast_lev;
791 } else {
792 know = kstp;
793 dt2d = dtfast_lev;
794 }
795
796 FillPatch(lev, t_old[lev], *vec_ubar[lev], GetVecOfPtrs(vec_ubar), BCVars::ubar_bc, BdyVars::ubar,
797 knew, false,true, 0,know, dt2d);
798 FillPatch(lev, t_old[lev], *vec_vbar[lev], GetVecOfPtrs(vec_vbar), BCVars::vbar_bc, BdyVars::vbar,
799 knew, false,true, 0,know, dt2d);
800 FillPatch(lev, t_old[lev], *vec_zeta[lev], GetVecOfPtrs(vec_zeta), BCVars::zeta_bc, BdyVars::zeta,
801 knew, false,false, 0,know, dt2d);
802
803#ifdef REMORA_USE_NETCDF
806 int* river_direction_d = river_direction.data();
807 for ( MFIter mfi(*mf_rhoS, TilingIfNotGPU()); mfi.isValid(); ++mfi )
808 {
809 Array4<const int > const& river_pos = vec_river_position[lev]->const_array(mfi);
810 Array4<const Real> const& river_transportbar = river_source_transportbar->fab_interp->array();
811 Array4<Real > const& ubar = mf_ubar->array(mfi);
812 Array4<Real > const& vbar = mf_vbar->array(mfi);
813 Array4<Real const> const& zeta = mf_zeta->const_array(mfi);
814 Array4<Real const> const& h = mf_h->const_array(mfi);
815 Array4<Real const> const& pm = mf_pm->const_array(mfi);
816 Array4<Real const> const& pn = mf_pn->const_array(mfi);
817
818 Box gbx1D = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
819 gbx1D.makeSlab(2,0);
820
821 ParallelFor(gbx1D, [=] AMREX_GPU_DEVICE (int i, int j, int )
822 {
823 int iriver = river_pos(i,j,0);
824 if (iriver >= 0) {
825 if (river_direction_d[iriver] == 0) {
826 Real on_u = 2.0_rt / (pn(i,j,0)+pn(i-1,j,0));
827 Real cff = 1.0_rt / (on_u * 0.5_rt * (zeta(i-1,j,0,knew) + h(i-1,j,0) +
828 zeta(i,j,0,knew) + h(i,j,0)));
829 ubar(i,j,0,knew) = river_transportbar(iriver,0,0) * cff;
830 } else {
831 Real om_v = 2.0_rt / (pm(i,j,0)+pm(i,j-1,0));
832 Real cff = 1.0_rt / (om_v * 0.5_rt * (zeta(i,j-1,0,knew) + h(i,j-1,0) +
833 zeta(i,j,0,knew) + h(i,j,0)));
834 vbar(i,j,0,knew) = river_transportbar(iriver,0,0) * cff;
835 }
836 }
837 });
838 }
839 }
840 FillPatchNoBC(lev, t_old[lev], *vec_ubar[lev], GetVecOfPtrs(vec_ubar), BdyVars::ubar,
841 knew, false,false);
842 FillPatchNoBC(lev, t_old[lev], *vec_vbar[lev], GetVecOfPtrs(vec_vbar), BdyVars::vbar,
843 knew, false,false);
844#endif
845 }
846}
constexpr amrex::Real g
#define NGROW
void update_interpolated_to_time(amrex::Real time)
Calculate.
amrex::FArrayBox * fab_interp
Container for interpolated data; Only used if save_interpolated == true.
amrex::MultiFab * mf_interpolated
void update_interpolated_to_time(amrex::Real time)
Calculate interpolated values at time, reading in data as necessary.
NCTimeSeriesRiver * river_source_transportbar
Data container for vertically integrated momentum transport in rivers.
Definition REMORA.H:1091
int nfast
Number of fast steps to take.
Definition REMORA.H:1238
NCTimeSeries * vbar_clim_data_from_file
Data container for vbar climatology data read from file.
Definition REMORA.H:1076
void FillPatchNoBC(int lev, amrex::Real time, amrex::MultiFab &mf_to_be_filled, amrex::Vector< amrex::MultiFab * > const &mfs, const int bdy_var_type=BdyVars::null, const int icomp=0, const bool fill_all=true, const bool fill_set=true)
Fill a new MultiFab by copying in phi from valid region and filling ghost cells without applying boun...
NCTimeSeries * ubar_clim_data_from_file
Data container for ubar climatology data read from file.
Definition REMORA.H:1074
amrex::Vector< amrex::Real > vec_weight2
Weights for calculating avg2 in 2D advance.
Definition REMORA.H:410
void FillPatch(int lev, amrex::Real time, amrex::MultiFab &mf_to_be_filled, amrex::Vector< amrex::MultiFab * > const &mfs, const int bccomp, const int bdy_var_type=BdyVars::null, const int icomp=0, const bool fill_all=true, const bool fill_set=true, const int n_not_fill=0, const int icomp_calc=0, const amrex::Real dt=amrex::Real(0.0), const amrex::MultiFab &mf_calc=amrex::MultiFab())
Fill a new MultiFab by copying in phi from valid region and filling ghost cells.
amrex::Vector< int > istep
which step?
Definition REMORA.H:1152
void apply_clim_nudg(const amrex::Box &bx, int ioff, int joff, const amrex::Array4< amrex::Real > &var, const amrex::Array4< amrex::Real const > &var_old, const amrex::Array4< amrex::Real const > &var_clim, const amrex::Array4< amrex::Real const > &clim_coeff, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const amrex::Real dt_lev=amrex::Real(0.0))
Apply climatology nudging.
void uv3dmix(const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real > &u, const amrex::Array4< amrex::Real > &v, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &rufrc, const amrex::Array4< amrex::Real > &rvfrc, const amrex::Array4< amrex::Real const > &visc2_p, const amrex::Array4< amrex::Real const > &visc2_r, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const amrex::Array4< amrex::Real const > &mskp, int nrhs, int nnew, const amrex::Real dt_lev)
Harmonic viscosity.
void rhs_uv_2d(int lev, const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &Duon, const amrex::Array4< amrex::Real const > &Dvom, const int nrhs)
RHS terms for 2D momentum.
amrex::Vector< amrex::Real > t_new
new time at each level
Definition REMORA.H:1156
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1279
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > vec_river_position
iMultiFab for river positions; contents are indices of rivers
Definition REMORA.H:1094
amrex::Vector< amrex::Real > vec_weight1
Weights for calculating avg1 in 2D advance.
Definition REMORA.H:408
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta
free surface height (2D)
Definition REMORA.H:354
amrex::Gpu::DeviceVector< int > river_direction
Vector over rivers of river direction: 0: u-face; 1: v-face; 2: w-face.
Definition REMORA.H:1096
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vbar
barotropic y velocity (2D)
Definition REMORA.H:352
void advance_2d(int lev, amrex::MultiFab const *mf_rhoS, amrex::MultiFab const *mf_rhoA, amrex::MultiFab *mf_ru2d, amrex::MultiFab *mf_rv2d, amrex::MultiFab *mf_rufrc, amrex::MultiFab *mf_rvfrc, amrex::MultiFab *mf_Zt_avg1, std::unique_ptr< amrex::MultiFab > &mf_DU_avg1, std::unique_ptr< amrex::MultiFab > &mf_DU_avg2, std::unique_ptr< amrex::MultiFab > &mf_DV_avg1, std::unique_ptr< amrex::MultiFab > &mf_DV_avg2, std::unique_ptr< amrex::MultiFab > &mf_rubar, std::unique_ptr< amrex::MultiFab > &mf_rvbar, std::unique_ptr< amrex::MultiFab > &mf_rzeta, std::unique_ptr< amrex::MultiFab > &mf_ubar, std::unique_ptr< amrex::MultiFab > &mf_vbar, amrex::MultiFab *mf_zeta, amrex::MultiFab const *mf_h, amrex::MultiFab const *mf_pm, amrex::MultiFab const *mf_pn, amrex::MultiFab const *mf_fcor, amrex::MultiFab const *mf_visc2_p, amrex::MultiFab const *mf_visc2_r, amrex::MultiFab const *mf_mskr, amrex::MultiFab const *mf_msku, amrex::MultiFab const *mf_mskv, amrex::MultiFab const *mf_mskp, amrex::Real dtfast_lev, bool predictor_2d_step, bool first_2d_step, int my_iif, int &next_indx1)
Perform a 2D predictor (predictor_2d_step=True) or corrector (predictor_2d_step=False) step.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_ubar
barotropic x velocity (2D)
Definition REMORA.H:350
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > vec_nudg_coeff
Climatology nudging coefficients.
Definition REMORA.H:425
amrex::Vector< amrex::Real > t_old
old time at each level
Definition REMORA.H:1158
void coriolis(const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &fomn, int nrhs, int nr)
Calculate Coriolis terms.