REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_advance_3d.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4
5/** Corresponds to step3d_uv.F and step3d_t.F in ROMS
6 *
7 * @param[in ] lev level of refinement (coarsest level is 0)
8 * @param[inout] mf_cons scalar variables (temp, salt, scalar, etc)
9 * @param[inout] mf_u u-velocity
10 * @param[inout] mf_v v-velocity
11 * @param[inout] mf_sstore intermediate-step scalar variables
12 * @param[inout] mf_ru RHS of total u-velocity
13 * @param[inout] mf_rv RHS of total v-velocity
14 * @param[in ] mf_DU_avg1 time-averaged u-flux for 2D equations
15 * @param[in ] mf_DU_avg2 time-averaged u-flux for 3D equation coupling
16 * @param[in ] mf_DV_avg1 time-averaged v-flux for 2D equations
17 * @param[in ] mf_DV_avg2 time-averaged v-flux for 3D equation coupling
18 * @param[inout] mf_ubar vertically integrated u-momentum
19 * @param[inout] mf_vbar vertically integrated v-momentum
20 * @param[inout] mf_Akv vertical viscosity coefficient
21 * @param[inout] mf_Akt vertical diffusivity coefficient
22 * @param[inout] mf_Hz vertical height of cells
23 * @param[inout] mf_Huon u-volume flux
24 * @param[inout] mf_Huon v-volume flux
25 * @param[inout] mf_z_w vertical coordinates on w points
26 * @param[in ] mf_h bathymetry
27 * @param[in ] mf_pm 1 / dx
28 * @param[in ] mf_pn 1 / dy
29 * @param[in ] mf_msku land-sea mask at u-points
30 * @param[in ] mf_mskv land-sea mask at v-points
31 * @param[in ] N number of vertical levels
32 * @param[in ] dt_lev time step at this refinement level
33 */
34void
36 MultiFab& mf_u , MultiFab& mf_v ,
37 MultiFab* mf_sstore,
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,
51 MultiFab const* mf_h,
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)
58{
59 BL_PROFILE("REMORA::advance_3d()");
60 const int nrhs = 0;
61 int nnew = 0;
62
63 int iic = istep[lev];
64 int ntfirst = 0;
65
66 // ROMS accumulates the finer level's perimeter tracer flux over its substeps and
67 // subtracts the mismatch against the coarse flux from the coarse ring (correct_tracer,
68 // nesting.F). YAFluxRegister is the same construction.
69 const bool refluxing = do_reflux && do_substep && finest_level > 0 &&
71
72 // Because zeta may have changed
74
75 const BoxArray& ba = mf_cons.boxArray();
76 const DistributionMapping& dm = mf_cons.DistributionMap();
77
78 //Only used locally, probably should be rearranged into FArrayBox declaration
79 MultiFab mf_AK (convert(ba,IntVect(0,0,1)),dm,1,IntVect(NGROW,NGROW,0)); //2d missing j coordinate
80 MultiFab mf_DC (ba,dm,1,IntVect(NGROW,NGROW,NGROW-1)); //2d missing j coordinate
81 MultiFab mf_Hzk(ba,dm,1,IntVect(NGROW,NGROW,NGROW-1)); //2d missing j coordinate
82
83 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
84 {
85 Array4<Real > const& u = mf_u.array(mfi);
86 Array4<Real > const& v = mf_v.array(mfi);
87
88 Array4<Real > const& ru = mf_ru->array(mfi);
89 Array4<Real > const& rv = mf_rv->array(mfi);
90
91 Array4<Real > const& AK = mf_AK.array(mfi);
92 Array4<Real > const& DC = mf_DC.array(mfi);
93
94 Array4<Real > const& Hzk = mf_Hzk.array(mfi);
95 Array4<Real > const& Akv = mf_Akv->array(mfi);
96
97 Array4<Real const> const& Hz = mf_Hz->const_array(mfi);
98
99 Array4<Real const> const& DU_avg1 = mf_DU_avg1->const_array(mfi);
100 Array4<Real const> const& DV_avg1 = mf_DV_avg1->const_array(mfi);
101
102 Array4<Real const> const& pm = mf_pm->const_array(mfi);
103 Array4<Real const> const& pn = mf_pn->const_array(mfi);
104
105 Array4<Real const> const& msku = mf_msku->const_array(mfi);
106 Array4<Real const> const& mskv = mf_mskv->const_array(mfi);
107
108 Box bx = mfi.tilebox();
109 Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
110 Box gbx21 = mfi.growntilebox(IntVect(NGROW,NGROW,NGROW-1));
111
112 Box xbx = mfi.nodaltilebox(0);
113 Box ybx = mfi.nodaltilebox(1);
114
115 Box gbx2D = gbx2;
116 gbx2D.makeSlab(2,0);
117
118 Box tbxp1 = bx;
119 Box tbxp11 = bx;
120 Box tbxp2 = bx;
121 tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
122 tbxp2.grow(IntVect(NGROW,NGROW,0));
123 tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
124
125 FArrayBox fab_FC(convert(gbx2,IntVect(0,0,1)),1,amrex::The_Async_Arena());
126 FArrayBox fab_BC(convert(gbx2,IntVect(0,0,1)),1,amrex::The_Async_Arena());
127 FArrayBox fab_CF(gbx21,1,amrex::The_Async_Arena());
128 FArrayBox fab_W(tbxp2,1,amrex::The_Async_Arena());
129
130 auto FC = fab_FC.array();
131 auto BC = fab_BC.array();
132 auto CF = fab_CF.array();
133
134 Real cff;
135 if (iic==ntfirst) {
136 cff=Real(0.25)*dt_lev;
137 } else if (iic==ntfirst+1) {
138 cff=Real(0.25)*dt_lev*Real(3.0)/Real(2.0);
139 } else {
140 cff=Real(0.25)*dt_lev*Real(23.0)/Real(12.0);
141 }
142
143 ParallelFor(xbx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
144 {
145 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);
146 u(i,j,k) *= two / (Hz(i-1,j,k) + Hz(i,j,k));
147 });
148
149 ParallelFor(ybx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
150 {
151 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);
152 v(i,j,k) *= two / (Hz(i,j-1,k) + Hz(i,j,k));
153 });
154
155 // NOTE: DC is only used as scratch in vert_visc_3d -- no need to pass or return a value
156 // NOTE: may not actually need to set these to zero
157
158 // Reset to zero on the box on which they'll be used
161
162 vert_visc_3d(xbx,1,0,u,Hz,Hzk,AK,Akv,BC,DC,FC,CF,nnew,N,dt_lev);
163
164 // Reset to zero on the box on which they'll be used
167
168 vert_visc_3d(ybx,0,1,v,Hz,Hzk,AK,Akv,BC,DC,FC,CF,nnew,N,dt_lev);
169
170 // Reset to zero on the box on which they'll be used
173
174 vert_mean_3d(xbx,1,0,u,Hz,DU_avg1,DC,CF,pn,msku,nnew,N);
175
176 // Reset to zero on the box on which they'll be used
179
180 vert_mean_3d(ybx,0,1,v,Hz,DV_avg1,DC,CF,pm,mskv,nnew,N);
181 }
182
183 // Apply physical boundary conditions to u and v
184 (*physbcs[lev])(mf_u,*mf_msku,0,1,mf_u.nGrowVect(),t_old[lev],xvel_bc(),0,*xvel_old[lev]);
185 (*physbcs[lev])(mf_v,*mf_mskv,0,1,mf_v.nGrowVect(),t_old[lev],yvel_bc(),0,*yvel_old[lev]);
186
187#ifdef REMORA_USE_NETCDF
188 // Fill the data which is stored in the boundary data read from netcdf files
190 {
193 }
194
196 river_source_transport->update_interpolated_to_time(model_time(t_old[lev]));
197 }
198#endif
199 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
200 {
201 Array4<Real > const& u = mf_u.array(mfi);
202 Array4<Real > const& v = mf_v.array(mfi);
203
204 Array4<Real > const& DC = mf_DC.array(mfi);
205
206 Array4<Real const> const& Hz = mf_Hz->const_array(mfi);
207
208 Array4<Real const> const& DU_avg1 = mf_DU_avg1->const_array(mfi);
209 Array4<Real const> const& DV_avg1 = mf_DV_avg1->const_array(mfi);
210
211 Array4<Real const> const& DU_avg2 = mf_DU_avg2->const_array(mfi);
212 Array4<Real const> const& DV_avg2 = mf_DV_avg2->const_array(mfi);
213
214 Array4<Real> const& ubar = mf_ubar->array(mfi);
215 Array4<Real> const& vbar = mf_vbar->array(mfi);
216
217 Array4<Real> const& Huon = mf_Huon->array(mfi);
218 Array4<Real> const& Hvom = mf_Hvom->array(mfi);
219
220 Array4<Real const> const& pm = mf_pm->const_array(mfi);
221 Array4<Real const> const& pn = mf_pn->const_array(mfi);
222 Array4<Real const> const& msku = mf_msku->const_array(mfi);
223 Array4<Real const> const& mskv = mf_mskv->const_array(mfi);
224
225 Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
226
227 FArrayBox fab_FC(gbx2,1,amrex::The_Async_Arena());
228 auto FC = fab_FC.array();
229
230#ifdef REMORA_USE_NETCDF
232 Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
233 Array4<Real const> const& z_w = mf_z_w->const_array(mfi);
234 Array4<int const> const& river_pos = vec_river_position[lev]->const_array(mfi);
235 Array4<Real const> const& river_transport = river_source_transport->fab_interp->array();
237 ParallelFor(gbx1, [=] AMREX_GPU_DEVICE(int i, int j, int k)
238 {
239 int iriver = river_pos(i,j,0);
240 if (iriver >= 0) {
241 if (river_direction_d[iriver] == 0) {
242 Real on_u = two / (pn(i,j,0)+pn(i-1,j,0));
243 Real cff = one / (on_u * Real(0.5) * (z_w(i-1,j,k+1) - z_w(i-1,j,k) + z_w(i,j,k+1) - z_w(i,j,k)));
244 u(i,j,k) = cff * river_transport(iriver,0,k);
245 } else {
246 Real om_v = two / (pm(i,j,0)+pm(i,j-1,0));
247 Real cff = one / (om_v * Real(0.5) * (z_w(i,j-1,k+1) - z_w(i,j-1,k) + z_w(i,j,k+1) - z_w(i,j,k)));
248 v(i,j,k) = cff * river_transport(iriver,0,k);
249 }
250 }
251 });
252 }
253#endif
254
255#if 0
256 // Reset to zero on the box on which they'll be used
257 mf_DC[mfi].template setVal<RunOn::Device>(zero,grow(xbx,IntVect(0,0,1)));
258 fab_CF.template setVal<RunOn::Device>(zero,grow(xbx,IntVect(0,0,1)));
259
261
262 // Reset to zero on the box on which they'll be used
263 mf_DC[mfi].template setVal<RunOn::Device>(zero,grow(ybx,IntVect(0,0,1)));
264 fab_CF.template setVal<RunOn::Device>(zero,grow(ybx,IntVect(0,0,1)));
265
267
268#else
269
270 // Reset to zero on the box on which they'll be used
272 mf_DC[mfi].template setVal<RunOn::Device>(zero,grow(gbx2,IntVect(0,0,1)));
274
275 // Reset to zero on the box on which they'll be used
277 mf_DC[mfi].template setVal<RunOn::Device>(zero,grow(gbx2,IntVect(0,0,1)));
279
280#endif
281 }
282
283 // WE BELIEVE THESE VALUES SHOULD ALREADY BE FILLED
284 // mf_Huon->FillBoundary(geom[lev].periodicity());
285 // mf_Hvom->FillBoundary(geom[lev].periodicity());
286
287 // ************************************************************************
288 // This should fill both temp and salt with temp/salt currently in cons_old
289 // ************************************************************************
290
291 MultiFab mf_W(convert(ba,IntVect(0,0,1)),dm,1,IntVect(NGROW+1,NGROW+1,0));
292 mf_W.setVal(zero);
293 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
294 {
295 Array4<Real> const& Huon = mf_Huon->array(mfi);
296 Array4<Real> const& Hvom = mf_Hvom->array(mfi);
297
298 Array4<Real const> const& z_w = mf_z_w->const_array(mfi);
299 Array4<Real const> const& h = mf_h->const_array(mfi);
300
301 Box bx = mfi.tilebox();
302 Box gbx1 = mfi.growntilebox(IntVect(NGROW-1,NGROW-1,0));
303 Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
304 Box gbx21 = mfi.growntilebox(IntVect(NGROW,NGROW,NGROW-1));
305
306 Box tbxp1 = bx;
307 Box tbxp11 = bx;
308 Box tbxp2 = bx;
309 tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
310 tbxp2.grow(IntVect(NGROW,NGROW,0));
311 tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
312
313 FArrayBox fab_FC(surroundingNodes(gbx2,2),1,amrex::The_Async_Arena());
314 FArrayBox fab_BC(gbx2,1,amrex::The_Async_Arena());
315 FArrayBox fab_CF(gbx21,1,amrex::The_Async_Arena());
316
317 auto W = mf_W.array(mfi);
318
319 //
320 //------------------------------------------------------------------------
321 // Vertically integrate horizontal mass flux divergence.
322 //------------------------------------------------------------------------
323 //
324 //Should really use gbx3uneven
325 //TODO: go over these boxes and compare to other spots where we do the same thing
326 Box gbx1D = gbx1;
327 gbx1D.makeSlab(2,0);
328
329 compute_W(gbx1D, W, Huon, Hvom, z_w, h, N);
330 }
331
332 const int nstp = (iic) % 2;
333 nnew = 1-nstp;
335 gls_corrector(lev, vec_gls[lev].get(), vec_tke[lev].get(), mf_W, vec_Akv[lev].get(),
336 vec_Akt[lev].get(),vec_Akk[lev].get(), vec_Akp[lev].get(), vec_mskr[lev].get(),
337 vec_msku[lev].get(), vec_mskv[lev].get(),
338 nstp, nnew, N, dt_lev);
339 }
341 nnew = 0;
342
343 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
344 {
345 Array4<Real> const& Hz = mf_Hz->array(mfi);
346
347 Array4<Real> const& Huon = mf_Huon->array(mfi);
348 Array4<Real> const& Hvom = mf_Hvom->array(mfi);
349
350 Array4<Real const> const& pm = mf_pm->const_array(mfi);
351 Array4<Real const> const& pn = mf_pn->const_array(mfi);
352 Array4<Real const> const& mskr = mf_mskr->const_array(mfi);
353 Array4<Real const> const& msku = mf_msku->const_array(mfi);
354 Array4<Real const> const& mskv = mf_mskv->const_array(mfi);
355
356 Box bx = mfi.tilebox();
357 Box gbx2 = mfi.growntilebox(IntVect(NGROW,NGROW,0));
358 Box gbx21 = mfi.growntilebox(IntVect(NGROW,NGROW,NGROW-1));
359
360 Box tbxp1 = bx;
361 Box tbxp11 = bx;
362 Box tbxp2 = bx;
363 tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
364 tbxp2.grow(IntVect(NGROW,NGROW,0));
365 tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
366
367 FArrayBox fab_FC(surroundingNodes(gbx2,2),1,amrex::The_Async_Arena());
368 FArrayBox fab_BC(gbx2,1,amrex::The_Async_Arena());
369 FArrayBox fab_CF(gbx21,1,amrex::The_Async_Arena());
370
371 auto FC = fab_FC.array();
372 auto W = mf_W.array(mfi);
373
374 // Advective tracer fluxes for the coarse-fine correction, all components at once.
375 FArrayBox fab_fx_reg, fab_fy_reg, fab_fz_reg;
376 if (refluxing) {
382 // No refinement in the vertical, so nothing crosses a z interface.
384 }
385 //
386 //-----------------------------------------------------------------------
387 // rhs_t_3d
388 //-----------------------------------------------------------------------
389 //
390 for (int i_comp=0; i_comp < ncons; i_comp++)
391 {
392#ifdef REMORA_USE_NETCDF
393 FArrayBox* fab_river_source;
396 }
399#else
402#endif
403 Array4<Real> const& sstore = mf_sstore->array(mfi, i_comp);
408 }
409
410 if (refluxing) {
411 std::array<FArrayBox const*, AMREX_SPACEDIM> flux
413 const Real* dx = geom[lev].CellSize();
414 if (lev < finest_level) {
415 getAdvFluxReg(lev+1)->CrseAdd(mfi, flux, dx, dt_lev, RunOn::Device);
416 }
417 if (lev > 0) {
418 getAdvFluxReg(lev)->FineAdd(mfi, flux, dx, dt_lev, RunOn::Device);
419 }
420 // The flux FABs are temporaries scoped to this tile, so don't move on until the
421 // register has finished reading them. ERF does the same at its own CrseAdd.
422 Gpu::streamSynchronize();
423 }
424 } // mfi
425
427
428 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
429 {
430 Array4<Real> const& AK = mf_AK.array(mfi);
431 Array4<Real> const& DC = mf_DC.array(mfi);
432
433 Array4<Real> const& Hzk = mf_Hzk.array(mfi);
434 Array4<Real const> const& Hz = mf_Hz->const_array(mfi);
435
436 Box bx = mfi.tilebox();
437
438 // Copy the tilebox
439 Box tbxp1 = bx;
440 Box tbxp11 = bx;
441 Box tbxp2 = bx;
442 Box tbxp21 = bx;
443 //make only gbx be grown to match multifabs
444 tbxp21.grow(IntVect(NGROW,NGROW,NGROW-1));
445 tbxp2.grow(IntVect(NGROW,NGROW,0));
446 tbxp1.grow(IntVect(NGROW-1,NGROW-1,0));
447 tbxp11.grow(IntVect(NGROW-1,NGROW-1,NGROW-1));
448
449 FArrayBox fab_FC(tbxp2,1,amrex::The_Async_Arena());
450 FArrayBox fab_BC(tbxp2,1,amrex::The_Async_Arena());
451 FArrayBox fab_CF(tbxp21,1,amrex::The_Async_Arena());
452 FArrayBox fab_W(tbxp2,1,amrex::The_Async_Arena());
453
454 auto FC = fab_FC.array();
455 auto BC = fab_BC.array();
456 auto CF = fab_CF.array();
457
458 for (int i_comp=0; i_comp < ncons; i_comp++) {
460 AK,mf_Akt->array(mfi,akt_comp(i_comp)),BC,DC,FC,CF,nnew,N,dt_lev);
461 }
462 } // MFiter
464
465#ifdef REMORA_USE_NETCDF
466 // Nudge every tracer that was given a climatology toward it. temp and salt are just
467 // components 0 and 1 of this loop, so their behavior is unchanged.
468 for (int icomp = 0; icomp < ncons; ++icomp) {
469 if (!solverChoice.do_cons_clim_nudg[icomp]) { continue; }
470
471 cons_clim_data_from_file[icomp]->update_interpolated_to_time(model_time(t_old[lev]), lev, cons_new[lev], geom, ref_ratio);
472
473 for ( MFIter mfi(mf_cons, TilingIfNotGPU()); mfi.isValid(); ++mfi )
474 {
475 Box bx = mfi.growntilebox(IntVect(1,1,0));
477 Array4<const Real> const& cons_clim = cons_clim_data_from_file[icomp]->get_interpolated_mf(lev)->const_array(mfi);
478 Array4< Real> const& cons = cons_new[lev]->array(mfi, icomp);
479 Array4<const Real> const& Hz = vec_Hz[lev]->const_array(mfi);
480 Array4<const Real> const& pm = vec_pm[lev]->const_array(mfi);
481 Array4<const Real> const& pn = vec_pn[lev]->const_array(mfi);
482
483 apply_clim_nudg(bx, 0, 0, cons, cons, cons_clim, cons_nudg_coeff, Hz, pm, pn, dt_lev);
484 }
485 }
486#endif
487}
constexpr amrex::Real two
constexpr amrex::Real one
constexpr amrex::Real zero
#define NGROW
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int akt_comp(int icomp) noexcept
mf_h setVal(geomdata.ProbHi(2))
int ncons
Number of conserved scalars in the state (temperature + salt + passive scalars + biology tracers)
Definition REMORA.H:1839
void update_massflux_3d(int lev, const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real > &phibar, const amrex::Array4< amrex::Real > &Hphi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm_or_pn, const amrex::Array4< amrex::Real const > &Dphi1, const amrex::Array4< amrex::Real const > &Dphi2, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real const > &msk, const int nnew)
Correct mass flux.
int xvel_bc() const noexcept
Definition REMORA.H:1485
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pm
horizontal scaling factor: 1 / dx (2D)
Definition REMORA.H:603
amrex::Vector< amrex::MultiFab * > cons_new
multilevel data container for current step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:393
void stretch_transform(int lev)
Calculate vertical stretched coordinates.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr
land/sea mask at cell centers (2D)
Definition REMORA.H:584
void advance_3d(int lev, amrex::MultiFab &mf_cons, amrex::MultiFab &mf_u, amrex::MultiFab &mf_v, amrex::MultiFab *mf_sstore, amrex::MultiFab *mf_ru, amrex::MultiFab *mf_rv, 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_ubar, std::unique_ptr< amrex::MultiFab > &mf_vbar, std::unique_ptr< amrex::MultiFab > &mf_Akv, std::unique_ptr< amrex::MultiFab > &mf_Akt, std::unique_ptr< amrex::MultiFab > &mf_Hz, std::unique_ptr< amrex::MultiFab > &mf_Huon, std::unique_ptr< amrex::MultiFab > &mf_Hvom, std::unique_ptr< amrex::MultiFab > &mf_z_w, amrex::MultiFab const *mf_h, amrex::MultiFab const *mf_pm, amrex::MultiFab const *mf_pn, amrex::MultiFab const *mf_mskr, amrex::MultiFab const *mf_msku, amrex::MultiFab const *mf_mskv, const int N, const amrex::Real dt_lev)
Advance the 3D variables.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_tke
Turbulent kinetic energy.
Definition REMORA.H:667
int do_substep
Whether to substep fine levels in time.
Definition REMORA.H:1873
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_gls
Turbulent generic length scale.
Definition REMORA.H:669
void rhs_t_3d(int lev, const amrex::Box &bx, const amrex::Array4< amrex::Real > &t, const amrex::Array4< amrex::Real const > &tempstore, const amrex::Array4< amrex::Real const > &Huon, const amrex::Array4< amrex::Real const > &Hvom, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pn, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &W, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real const > &mskr, const amrex::Array4< amrex::Real const > &msku, const amrex::Array4< amrex::Real const > &mskv, const amrex::Array4< int const > &river_pos, const amrex::Array4< amrex::Real const > &river_source, int nrhs, int nnew, int N, const amrex::Real dt_lev, const amrex::Array4< amrex::Real > &fx_reg=amrex::Array4< amrex::Real >(), const amrex::Array4< amrex::Real > &fy_reg=amrex::Array4< amrex::Real >())
RHS terms for tracer.
int yvel_bc() const noexcept
Definition REMORA.H:1486
void fill_from_bdyfiles(int lev, amrex::MultiFab &mf_to_fill, const amrex::MultiFab &mf_mask, const amrex::Real time, const int bccomp, const int bdy_var_type, const int icomp_to_fill, const int icomp_calc=0, const amrex::MultiFab &mf_calc=amrex::MultiFab(), const amrex::Real=zero)
Fill boundary data from netcdf file.
void vert_mean_3d(const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &Dphi_avg1, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &CF, const amrex::Array4< amrex::Real const > &pm_or_pn, const amrex::Array4< amrex::Real const > &msk, const int nnew, const int N)
Adjust 3D momentum variables based on vertical mean momentum.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Hz
Width of cells in the vertical (z-) direction (3D, Hz in ROMS)
Definition REMORA.H:424
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akt
Vertical diffusion coefficient (3D)
Definition REMORA.H:444
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_msku
land/sea mask at x-faces (2D)
Definition REMORA.H:586
amrex::Vector< amrex::MultiFab * > xvel_old
multilevel data container for last step's x velocities (u in ROMS)
Definition REMORA.H:386
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskv
land/sea mask at y-faces (2D)
Definition REMORA.H:588
amrex::Vector< std::unique_ptr< REMORAPhysBCFunct > > physbcs
Vector (over level) of functors to apply physical boundary conditions.
Definition REMORA.H:1754
amrex::YAFluxRegister * getAdvFluxReg(int lev)
flux register between lev and lev-1
Definition REMORA.H:1760
amrex::Vector< int > istep
which step?
Definition REMORA.H:1733
amrex::Vector< amrex::MultiFab * > yvel_old
multilevel data container for last step's y velocities (v in ROMS)
Definition REMORA.H:388
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=zero)
Apply climatology nudging.
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:2017
amrex::Vector< std::unique_ptr< amrex::iMultiFab > > vec_river_position
iMultiFab for river positions; contents are indices of rivers
Definition REMORA.H:1671
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akk
Turbulent kinetic energy vertical diffusion coefficient.
Definition REMORA.H:673
int do_reflux
correct the coarse tracer with the finer level's accumulated advective flux at their interface....
Definition REMORA.H:1889
void vert_visc_3d(const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real > &Hzk, const amrex::Array4< amrex::Real > &AK, const amrex::Array4< amrex::Real const > &Akv, const amrex::Array4< amrex::Real > &BC, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real > &CF, const int nnew, const int N, const amrex::Real dt_lev)
Calculate effects of vertical viscosity or diffusivity.
void advance_biology(int lev, amrex::MultiFab const &mf_cons_old, amrex::MultiFab &mf_cons_new, int N, amrex::Real dt_lev)
Apply biological tracer source/sink terms.
amrex::Gpu::DeviceVector< int > river_direction
Vector over rivers of river direction: 0: u-face; 1: v-face; 2: w-face.
Definition REMORA.H:1673
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=false, const int n_not_fill=0, const int icomp_calc=0, const amrex::Real dt=zero, const amrex::MultiFab &mf_calc=amrex::MultiFab(), amrex::Vector< amrex::MultiFab * > const &mfs_crse_old={}, amrex::Vector< amrex::MultiFab * > const &mfs_crse_new={})
Fill a new MultiFab by copying in phi from valid region and filling ghost cells.
amrex::Vector< amrex::MultiFab * > cons_old
multilevel data container for last step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:384
amrex::Vector< std::unique_ptr< NCTimeSeries > > cons_clim_data_from_file
Vector over cons components of climatology data read from file.
Definition REMORA.H:1657
amrex::Vector< std::unique_ptr< NCTimeSeriesRiver > > river_source_cons
Vector of data containers for scalar data in rivers.
Definition REMORA.H:1660
std::unique_ptr< NCTimeSeriesRiver > river_source_transport
Data container for momentum transport in rivers.
Definition REMORA.H:1662
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > vec_nudg_coeff
Climatology nudging coefficients.
Definition REMORA.H:678
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pn
horizontal scaling factor: 1 / dy (2D)
Definition REMORA.H:605
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akv
Vertical viscosity coefficient (3D)
Definition REMORA.H:442
static void compute_W(const amrex::Box &bx2d, const amrex::Array4< amrex::Real > &W, const amrex::Array4< amrex::Real const > &Huon, const amrex::Array4< amrex::Real const > &Hvom, const amrex::Array4< amrex::Real const > &z_w, const amrex::Array4< amrex::Real const > &h, const int N)
Vertical volume flux W from the horizontal mass flux divergence.
amrex::Vector< amrex::Real > t_old
old time at each level, in seconds since start_time
Definition REMORA.H:1746
double model_time(amrex::Real elapsed) const noexcept
Time on the model clock, in seconds, of an elapsed time such as t_new.
Definition REMORA.H:2210
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akp
Turbulent length scale vertical diffusion coefficient.
Definition REMORA.H:675
void gls_corrector(int lev, amrex::MultiFab *mf_gls, amrex::MultiFab *mf_tke, amrex::MultiFab &mf_W, amrex::MultiFab *mf_Akv, amrex::MultiFab *mf_Akt, amrex::MultiFab *mf_Akk, amrex::MultiFab *mf_Akp, amrex::MultiFab *mf_mskr, amrex::MultiFab *mf_msku, amrex::MultiFab *mf_mskv, const int nstp, const int nnew, const int N, const amrex::Real dt_lev)
Corrector step for GLS calculation.
static constexpr int cons_bc
static constexpr int t
cons component Temp_comp
static constexpr int u
static constexpr int v
int cons(int icomp) noexcept
amrex::Vector< int > do_rivers_cons
VertMixingType vert_mixing_type
amrex::Vector< int > do_cons_clim_nudg
CouplingType coupling_type