REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_init.cpp
Go to the documentation of this file.
1/**
2 * \file REMORA_init.cpp
3 */
4
5#include <REMORA.H>
6#include <REMORA_Constants.H>
8
9using namespace amrex;
10
11/**
12 * @param[in ] lev level whose coordinates to return
13 */
16{
18 coords.x_r = vec_xr[lev].get();
19 coords.y_r = vec_yr[lev].get();
20 coords.z_r = vec_z_r[lev].get();
21 coords.z_w = vec_z_w[lev].get();
22 return coords;
23}
24
25/**
26 * @param[in ] lev level to initialize on
27 */
28void
30{
31 prob->init_analytic_prob(lev, geom[lev], solverChoice, *this, prob_coords(lev), *cons_new[lev], *xvel_new[lev], *yvel_new[lev]);
32
34}
35
36/**
37 * \brief Initialize the biology tracers from whichever source
38 * remora.biology_ic_type selects.
39 *
40 * Deliberately decoupled from remora.ic_type. A NetCDF initial file supplies
41 * only the tracers it happens to contain -- the BioToy file has `oxygen` but
42 * no `PO4` or `ODU` -- so validating an option set the file does not cover
43 * would otherwise mean regenerating binary input that no fresh clone can
44 * reproduce. With biology_ic_type = analytic the physical fields still come
45 * from NetCDF while biology comes from the problem's analytic profile.
46 *
47 * Must be called after the physical fields are initialized: the analytic
48 * biology profiles are functions of temperature.
49 *
50 * @param[in ] lev level to initialize on
51 */
52void
54{
56 return;
57 }
58
59 const bool use_analytic =
63
64 if (use_analytic) {
65 // The base-class hook in REMORA_prob_common.H is an amrex::Error, so a
66 // problem that enables biology without providing an analytic biology
67 // IC fails loudly rather than starting from uninitialized tracers.
68 prob->init_analytic_biology(lev, geom[lev], solverChoice, fennel_params,
69 *this, *cons_new[lev]);
70 } else {
71#ifdef REMORA_USE_NETCDF
73#else
74 amrex::Abort("remora.biology_ic_type = netcdf requires a NetCDF build");
75#endif
76 }
77}
78
79/**
80 * \brief Full-domain counterpart of init_biology_ic, for the hires_init_level
81 * path where initial data is specified on a high-resolution level and
82 * averaged down.
83 *
84 * Fills the biology components of vec_cons_full_domain[hires_init_level].
85 * Must be called after the physical fields on that level are set (the
86 * analytic profiles are functions of temperature) and before whatever
87 * averages vec_cons_full_domain down.
88 */
89void
91{
93 return;
94 }
95
96 const bool use_analytic =
100
101 if (use_analytic) {
102 prob->init_analytic_biology(hires_init_level, geom[hires_init_level],
105 } else {
106#ifdef REMORA_USE_NETCDF
108#else
109 amrex::Abort("remora.biology_ic_type = netcdf requires a NetCDF build");
110#endif
111 }
112
113 // Average down here, after the branch, rather than inside one of the two sources. When
114 // this loop lived in the NetCDF reader, the analytic branch filled hires_init_level and
115 // nothing else, so every level below it -- including level 0, the one the run actually
116 // integrates -- kept the zeros that init_data_full_domain_from_netcdf had written.
117 for (int lev = hires_init_level-1; lev >= 0; lev--) {
119 }
120}
121
122/**
123 * @param[in ] lev level to initialize on
124 */
125void
127{
128 std::unique_ptr<MultiFab>& mf_fcor = vec_fcor[lev];
129 auto geomdata = Geom(lev).data();
130
131#ifdef _OPENMP
132#pragma omp parallel if (amrex::Gpu::notInLaunchRegion())
133#endif
134 for (MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi)
135 {
136 // Valid region only, since vec_yr's ghost cells aren't all filled. set_coriolis
137 // FillPatches vec_fcor with foextrap right after this, as for coriolis_type = netcdf.
138 Box bx = mfi.tilebox();
139 auto fcor_arr = (mf_fcor)->array(mfi);
140 auto yr_arr = vec_yr[lev]->const_array(mfi);
141 Real coriolis_f0 = solverChoice.coriolis_f0;
142 Real coriolis_beta = solverChoice.coriolis_beta;
143 // Units: yr is metric (1/pn, or y_rho from the grid file), so beta_plane assumes
144 // prob_lo/prob_hi are too. A domain given in degrees would silently mix the two.
145 Real Esize = geomdata.ProbHi()[1] - geomdata.ProbLo()[1];
146
147 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
148 {
149 // yr is measured from the southern edge of the domain (ROMS ana_grid convention), so
150 // f is coriolis_f0 at mid-domain. Adding prob_lo back would shift f by beta*prob_lo.
151 fcor_arr(i,j,0) = coriolis_f0 + coriolis_beta * (yr_arr(i,j,0) - Real(0.5) * Esize);
152 });
153 } //mfi
154
155 vec_fcor[lev]->FillBoundary(geom[lev].periodicity());
156}
157
158/**
159 * @param[in ] lev level to operate on
160 */
161void
163{
164 std::unique_ptr<MultiFab>& mf_zeta = vec_zeta[lev];
165 std::unique_ptr<MultiFab>& mf_Zt_avg1 = vec_Zt_avg1[lev];
166 for ( MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi )
167 {
168 int nstp = 0;
169 Array4<Real> const& Zt_avg1 = (mf_Zt_avg1)->array(mfi);
170 Array4<const Real> const& zeta = mf_zeta->const_array(mfi);
171
172 Box bx3 = mfi.tilebox() ; bx3.grow(IntVect(NGROW+1,NGROW+1,0)); // cell-centered, grown by 3
173
174 ParallelFor(makeSlab(bx3,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
175 {
176 Zt_avg1(i,j,0) = zeta(i,j,0,nstp);
177 });
178
179 }
180}
181
182/**
183 * @param[in ] lev level to operate on
184 */
185void
187{
188 auto N = Geom(lev).Domain().size()[2]-1; // Number of vertical "levs" aka, NZ
189
190 vec_ubar[lev]->setVal(zero);
191 vec_vbar[lev]->setVal(zero);
192
193 MultiFab* U_old = xvel_new[lev];
194 MultiFab* V_old = yvel_new[lev];
195 std::unique_ptr<MultiFab>& mf_ubar = vec_ubar[lev];
196 std::unique_ptr<MultiFab>& mf_vbar = vec_vbar[lev];
197 std::unique_ptr<MultiFab>& mf_Hz = vec_Hz[lev];
198 int nstp = 0;
199
200 for ( MFIter mfi(*cons_new[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi )
201 {
202 Array4<Real> const& ubar = (mf_ubar)->array(mfi);
203 Array4<Real> const& vbar = (mf_vbar)->array(mfi);
204
205 Array4<const Real> const& Hz = mf_Hz->const_array(mfi);
206 Array4<const Real> const& u = U_old->const_array(mfi);
207 Array4<const Real> const& v = V_old->const_array(mfi);
208
209 Box bx2 = mfi.tilebox() ; bx2.grow(IntVect(NGROW ,NGROW ,0)); // cell-centered, grown by 2
210 Box ubx2 = mfi.nodaltilebox(0); ubx2.grow(IntVect(NGROW ,NGROW ,0)); // x-face-centered, grown by 2
211 Box vbx2 = mfi.nodaltilebox(1); vbx2.grow(IntVect(NGROW ,NGROW ,0)); // y-face-centered, grown by 2
212
213 ParallelFor(makeSlab(ubx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
214 {
215 Real CF = zero;
216 Real sum_of_hz = zero;
217
218 for (int k=0; k<=N; k++) {
219 Real avg_hz = Real(0.5)*(Hz(i,j,k)+Hz(i-1,j,k));
220 sum_of_hz += avg_hz;
221 CF += avg_hz*u(i,j,k,nstp);
222 }
223 ubar(i,j,0,0) = CF / sum_of_hz;
224 });
225
226 ParallelFor(makeSlab(vbx2,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
227 {
228 Real CF = zero;
229 Real sum_of_hz = zero;
230
231 for(int k=0; k<=N; k++) {
232 Real avg_hz = Real(0.5)*(Hz(i,j,k)+Hz(i,j-1,k));
233 sum_of_hz += avg_hz;
234 CF += avg_hz*v(i,j,k,nstp);
235 }
236 vbar(i,j,0,0) = CF / sum_of_hz;
237 });
238 }
239
242}
243
244/**
245 * @param[in ] lev level to operate on
246 * @param[in ] solver_choice algorithmic choices
247 */
248void
250{
251 vec_tke[lev]->setVal(solver_choice.gls_Kmin);
252 vec_gls[lev]->setVal(solver_choice.gls_Pmin);
253 vec_Lscale[lev]->setVal(zero);
254 vec_Akk[lev]->setVal(solver_choice.Akk_bak);
255 vec_Akp[lev]->setVal(solver_choice.Akp_bak);
256 vec_Akv[lev]->setVal(solver_choice.Akv_bak);
257 for (int n = 0; n < NAT; n++) {
258 vec_Akt[lev]->setVal(solver_choice.Akt_bak[n], n, 1);
259 }
260
261 auto N = Geom(lev).Domain().size()[2]-1; // Number of vertical "levs" aka, NZ
262
263#ifdef _OPENMP
264#pragma omp parallel if (Gpu::notInLaunchRegion())
265#endif
266 for (MFIter mfi(*vec_Akk[lev], TilingIfNotGPU()); mfi.isValid(); ++mfi) {
267 Box bx = mfi.growntilebox(IntVect(NGROW,NGROW,0));
268 Array4<Real> const& Akk = vec_Akk[lev]->array(mfi);
269 Array4<Real> const& Akp = vec_Akp[lev]->array(mfi);
270 Array4<Real> const& Akt = vec_Akt[lev]->array(mfi);
271 Array4<Real> const& Akv = vec_Akv[lev]->array(mfi);
272
273 ParallelFor(makeSlab(bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
274 {
275 Akk(i,j, 0) = zero;
276 Akk(i,j, N+1) = zero;
277
278 Akp(i,j, 0) = zero;
279 Akp(i,j, N+1) = zero;
280
281 Akv(i,j, 0) = zero;
282 Akv(i,j, N+1) = zero;
283
284 Akt(i,j, 0) = zero;
285 Akt(i,j, N+1) = zero;
286 });
287 }
288}
289
290/**
291 * @param[in ] lev level to operate on
292 */
293void
295 // Fill nudging coefficients from constant values, then overwrite
296 // with coeffs read from file if using
299 for (int icomp = 0; icomp < ncons; ++icomp) {
301 }
305#ifdef REMORA_USE_NETCDF
307 // A coefficient file is optional. Without one every variable keeps the constant
308 // timescale set above, which is a reasonable setup for tracers nudged on the
309 // single remora.tnudg timescale.
310 if (nc_clim_coeff_file.empty()) {
311 amrex::Print() << "No remora.nc_clim_coeff_file given; climatology nudging will use "
312 "the constant timescales from remora.tnudg, m2nudg, and m3nudg"
313 << std::endl;
314 } else {
315 amrex::Print() << "Calling init_clim_nudg_coeff_from_netcdf \n " << std::endl;
317 amrex::Print() << "Climatology weights loaded from netcdf file \n " << std::endl;
318 }
319 }
320#endif
321}
322
323void
325 int nz = geom[0].Domain().length(2);
326 s_r.resize(nz);
327 s_w.resize(nz+1);
328 Cs_r.resize(nz);
329 Cs_w.resize(nz+1);
330
332}
333
334const DistributionMapping&
336{
337 if (dm_full_domain.empty()) {
338 BoxArray ba(makeSlab(geom[0].Domain(),2,0));
339 dm_full_domain.define(ba);
340 }
341 return dm_full_domain;
342}
343
345 // Make fake boxArray that covers the whole domain on level 0
346 BoxArray ba;
347 ba.define(makeSlab(geom[0].Domain(),2,0));
348 Box refined_domain = makeSlab(geom[0].Domain(),2,0);
349
350 // One box per level, so one map serves every level and every centering here.
351 const DistributionMapping& dm = full_domain_dmap();
352 vec_h_full_domain[0].reset(new MultiFab(ba, dm, 1, IntVect(1,1,0)));
353 vec_pm_full_domain[0].reset(new MultiFab(ba, dm, 1, IntVect(1,1,0)));
354 vec_pn_full_domain[0].reset(new MultiFab(ba, dm, 1, IntVect(1,1,0)));
355 vec_mskr_full_domain[0].reset(new MultiFab(ba, dm, 1, IntVect(1,1,0)));
356
357 auto h_growvect = vec_h[0]->nGrowVect();
358 auto pm_growvect = vec_pm[0]->nGrowVect();
359 auto pn_growvect = vec_pn[0]->nGrowVect();
360 auto mskr_growvect = vec_mskr[0]->nGrowVect();
361 for (int lev=1; lev <= hires_grid_level; lev++) {
362 ba = ba.refine(refRatio(lev-1));
363 refined_domain.refine(refRatio(lev-1));
364
365 // Always allocate at least as many grow cells as there are in the level's normal variable multifab
366 // This makes copying and boundary filling much easier
367 vec_h_full_domain[lev].reset(new MultiFab(ba, dm, 1, max(cum_ref_ratios[lev],h_growvect)));
368 vec_pm_full_domain[lev].reset(new MultiFab(ba, dm, 1, max(cum_ref_ratios[lev],pm_growvect)));
369 vec_pn_full_domain[lev].reset(new MultiFab(ba, dm, 1, max(cum_ref_ratios[lev],pn_growvect)));
370 vec_mskr_full_domain[lev].reset(new MultiFab(ba, dm, 1, max(cum_ref_ratios[lev],mskr_growvect)));
371 }
372 // A NetCDF read covers only as many grow cells as the file carries, and the analytic
373 // bathymetry hook fills h alone, so parts of these arrays can reach the average-down
374 // unwritten. Zero them so what lands at level 0 does not depend on the arena.
375 for (int lev = 0; lev <= hires_grid_level; lev++) {
376 vec_h_full_domain[lev]->setVal(0.0);
377 vec_pm_full_domain[lev]->setVal(0.0);
378 vec_pn_full_domain[lev]->setVal(0.0);
379 // Water, not zero: the mask readers and the analytic hook only ever write land, so
380 // anything they miss has to default the way the per-level masks do in init_masks.
381 vec_mskr_full_domain[lev]->setVal(1.0);
382 }
384}
385
386void
388{
389 // init_analytic_bathymetry needs to be able to handle the full number of grow cells that vec_h_full_domain has
391 // Coarsen to fill levels below hires_grid_level, grow cells included. Mask-weighted, so a
392 // coarse cell only partly covered by water takes the depth of that water.
393 for (int lev=hires_grid_level-1; lev >= 0; lev--) {
395 }
396}
397
398void
400{
401 // init_analytic_masks has to be able to handle the full number of grow cells that
402 // vec_mskr_full_domain has, and cannot reach for the per-level coordinate arrays, since
403 // this MultiFab is not on grids[hires_grid_level].
404 prob->init_analytic_masks(hires_grid_level, Geom(hires_grid_level), solverChoice, *this,
406 // Coarsen to fill the levels below hires_grid_level. Not average_down_with_grow_cells:
407 // a mask has to stay exactly 0 or 1, so this takes "wet if any fine cell is wet".
408 for (int lev=hires_grid_level-1; lev >= 0; lev--) {
410 }
411}
412
414 // Make fake boxArray that covers the whole domain on level 0
415 BoxArray ba;
416 ba.define(geom[0].Domain());
417 BoxArray ba2d;
418 ba2d.define(makeSlab(geom[0].Domain(),2,0));
419 Box refined_domain = geom[0].Domain();
420
421 const DistributionMapping& dm = full_domain_dmap();
422 vec_cons_full_domain[0].reset(new MultiFab(ba, dm, ncons, IntVect(1,1,0)));
423 vec_xvel_full_domain[0].reset(new MultiFab(convert(ba,IntVect(1,0,0)), dm, 1, IntVect(0,1,0)));
424 vec_yvel_full_domain[0].reset(new MultiFab(convert(ba,IntVect(0,1,0)), dm, 1, IntVect(1,0,0)));
425 vec_zeta_full_domain[0].reset(new MultiFab(ba2d, dm, 1, IntVect(1,1,0)));
426
427
428 auto cons_growvect = cons_new[0]->nGrowVect();
429 auto xvel_growvect = xvel_new[0]->nGrowVect();
430 auto yvel_growvect = yvel_new[0]->nGrowVect();
431 auto zeta_growvect = vec_zeta[0]->nGrowVect();
432 for (int lev=1; lev <= hires_init_level; lev++) {
433 ba = ba.refine(refRatio(lev-1));
434 ba2d = ba2d.refine(refRatio(lev-1));
435 refined_domain.refine(refRatio(lev-1));
436
437 // Always allocate at least as many grow cells as there are in the level's normal variable multifab
438 // This makes copying and boundary filling much easier
440 vec_xvel_full_domain[lev].reset(new MultiFab(convert(ba,IntVect(1,0,0)), dm, 1, max(cum_ref_ratios[lev],xvel_growvect) - IntVect(1,0,0)));
441 vec_yvel_full_domain[lev].reset(new MultiFab(convert(ba,IntVect(0,1,0)), dm, 1, max(cum_ref_ratios[lev],yvel_growvect) - IntVect(0,1,0)));
442 vec_zeta_full_domain[lev].reset(new MultiFab(ba2d, dm, 1, max(cum_ref_ratios[lev],zeta_growvect)));
443 }
444 // See the note in allocate_bathymetry_grid_vars_full_domain: the vertical grow cells in
445 // particular are never covered by the read, since cum_ref_ratios has no z component.
446 for (int lev = 0; lev <= hires_init_level; lev++) {
447 vec_cons_full_domain[lev]->setVal(0.0);
448 vec_xvel_full_domain[lev]->setVal(0.0);
449 vec_yvel_full_domain[lev]->setVal(0.0);
450 vec_zeta_full_domain[lev]->setVal(0.0);
451 }
453}
454
455/**
456 * Evaluate the analytic initial state, free surface, and biology on the full domain at
457 * hires_init_level and average them down to level 0.
458 *
459 * That level does not exist yet, so its coordinates are built here: x_r and y_r from the cell
460 * size (constant grid scale), z_r and z_w from the free surface and the bathymetry. The
461 * bathymetry is the hires grid data when hires_grid_level >= hires_init_level, and the
462 * analytic bathymetry evaluated at hires_init_level otherwise.
463 */
464void
466{
467 const int lev = hires_init_level;
468 const DistributionMapping& dm = vec_cons_full_domain[lev]->DistributionMap();
469 const BoxArray& ba2d = vec_zeta_full_domain[lev]->boxArray();
470 const IntVect ng2d = vec_zeta_full_domain[lev]->nGrowVect();
471
472 MultiFab mf_xr(ba2d, dm, 1, ng2d);
473 MultiFab mf_yr(ba2d, dm, 1, ng2d);
474 const auto dxi = Geom(lev).InvCellSize();
475 const Real pm = dxi[0];
476 const Real pn = dxi[1];
477 for (MFIter mfi(mf_xr, TilingIfNotGPU()); mfi.isValid(); ++mfi)
478 {
479 const Box& bx = mfi.growntilebox();
480 Array4<Real> const& xr = mf_xr.array(mfi);
481 Array4<Real> const& yr = mf_yr.array(mfi);
482 ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int)
483 {
484 xr(i,j,0) = (i + Real(0.5)) / pm;
485 yr(i,j,0) = (j + Real(0.5)) / pn;
486 });
487 }
488
490 coords.x_r = &mf_xr;
491 coords.y_r = &mf_yr;
492
493 prob->init_analytic_zeta(lev, geom[lev], solverChoice, *this, coords,
495
496 MultiFab mf_h(ba2d, dm, 1, ng2d);
497 mf_h.setVal(zero);
498 if (lev <= hires_grid_level) {
499 mf_h.ParallelCopy(*vec_h_full_domain[lev], 0, 0, 1, vec_h_full_domain[lev]->nGrowVect(),
500 ng2d);
501 } else {
502 prob->init_analytic_bathymetry(lev, geom[lev], solverChoice, *this, mf_h);
503 }
504
505 const BoxArray& ba3d = vec_cons_full_domain[lev]->boxArray();
506 const IntVect ng3d(ng2d[0], ng2d[1], 0);
507 MultiFab mf_z_r(ba3d, dm, 1, ng3d);
508 MultiFab mf_z_w(convert(ba3d, IntVect(0,0,1)), dm, 1, ng3d);
510 coords.z_r = &mf_z_r;
511 coords.z_w = &mf_z_w;
512
513 prob->init_analytic_prob(lev, geom[lev], solverChoice, *this, coords,
516 // The prob functions fill only the valid region, so the grow cells averaged down below
517 // are wrong. FillPatch overwrites them in set_init_data_averaged_down: filling these
518 // arrays with 1e10 instead of 0 leaves every plotfile bitwise unchanged.
519
520 // Biology must be filled on the hires level before the average-down loop
521 // below, or the biology components of vec_cons_full_domain are averaged
522 // down uninitialized.
524
525 for (int crse_lev = lev-1; crse_lev >= 0; crse_lev--) {
530 }
531}
constexpr amrex::Real zero
#define NGROW
#define NAT
mf_h setVal(geomdata.ProbHi(2))
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr_full_domain
Land/sea mask at cell centers on the whole domain at each potential level. Specified at hires_grid_le...
Definition REMORA.H:421
ProbCoords prob_coords(int lev) const
Coordinate arrays of level lev, for the prob functions.
int ncons
Number of conserved scalars in the state (temperature + salt + passive scalars + biology tracers)
Definition REMORA.H:1797
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta_full_domain
high resolution initial free surface height (2D)
Definition REMORA.H:581
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_fcor
coriolis factor (2D)
Definition REMORA.H:612
void allocate_init_full_domain()
Allocate multifabs for storing full-domain high resolution initial data.
void init_gls_vmix(int lev, SolverChoice solver_choice)
Initialize GLS variables.
void init_biology_from_netcdf(int lev)
Biology initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_xvel_full_domain
multilevel data container for high res initial x velocities (u in ROMS)
Definition REMORA.H:404
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_h
multilevel data container for current step's z velocities (largely unused; W stored separately)
Definition REMORA.H:413
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pm
horizontal scaling factor: 1 / dx (2D)
Definition REMORA.H:603
void init_biology_ic(int lev)
Initialize biology tracers from whichever source remora.biology_ic_type selects. Call after the physi...
amrex::Vector< amrex::MultiFab * > cons_new
multilevel data container for current step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:393
void init_biology_ic_full_domain()
Full-domain counterpart of init_biology_ic, for the hires_init_level average-down path.
amrex::Gpu::DeviceVector< amrex::Real > s_w
Scaled vertical coordinate (range [0,1]) that transforms to z, defined at w-points (cell faces)
Definition REMORA.H:460
REMORABiology::BiologyModel biology_model
Active biology package.
Definition REMORA.H:1799
std::unique_ptr< ProblemBase > prob
Pointer to container of analytical functions for problem definition.
Definition REMORA.H:1679
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_mskr
land/sea mask at cell centers (2D)
Definition REMORA.H:584
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_tke
Turbulent kinetic energy.
Definition REMORA.H:667
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_gls
Turbulent generic length scale.
Definition REMORA.H:669
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_xr
x_grid on rho points (2D)
Definition REMORA.H:615
void init_biology_full_domain_from_netcdf()
Full-domain high-res biology initialization from NetCDF file.
void set_grid_scale(int lev)
Set pm and pn arrays and x/y coords on level lev.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Lscale
Vertical mixing turbulent length scale.
Definition REMORA.H:671
amrex::DistributionMapping dm_full_domain
the DistributionMapping every full-domain multifab is built on. Each of those covers the domain in a ...
Definition REMORA.H:1413
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_pm_full_domain
horizontal scaling factor: 1 / dx (2D) on whole domain
Definition REMORA.H:607
amrex::Vector< amrex::MultiFab * > yvel_new
multilevel data container for current step's y velocities (v in ROMS)
Definition REMORA.H:397
amrex::Box nc_hires_init_box
Box for the full domain at nc_hires_init_level.
Definition REMORA.H:2023
amrex::Gpu::DeviceVector< amrex::Real > s_r
Scaled vertical coordinate (range [0,1]) that transforms to z, defined at rho points (cell centers)
Definition REMORA.H:458
amrex::Vector< amrex::IntVect > cum_ref_ratios
Cumulative refinement ratio between level 0 and level i.
Definition REMORA.H:2026
void stretch_transform_full_domain(int lev, const amrex::MultiFab &mf_h, const amrex::MultiFab &mf_zeta, amrex::MultiFab &mf_z_r, amrex::MultiFab &mf_z_w)
Calculate z_r and z_w on full-domain arrays at a level not yet created.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_r
z coordinates at rho points (cell centers)
Definition REMORA.H:453
void coarsen_bathymetry_with_grow_cells(int crse_lev)
Coarsen the full-domain bathymetry from crse_lev+1 onto crse_lev, grow cells included,...
Definition REMORA.cpp:1272
amrex::Vector< amrex::MultiFab * > xvel_new
multilevel data container for current step's x velocities (u in ROMS)
Definition REMORA.H:395
int bdy_zeta() const noexcept
Definition REMORA.H:1466
void init_beta_plane_coriolis(int lev)
Calculate Coriolis parameters from beta plane parametrization.
std::string nc_clim_coeff_file
NetCDF climatology coefficient file.
Definition REMORA.H:2036
void coarsen_masks_with_grow_cells(int crse_lev)
Coarsen the full-domain rho-mask from crse_lev+1 onto crse_lev, grow cells included,...
Definition REMORA.cpp:1014
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_yvel_full_domain
multilevel data container for high res initial y velocities (v in ROMS)
Definition REMORA.H:406
void calc_stretch_coeffs()
calculate vertical stretch coefficients
void set_zeta_average(int lev)
Set Zt_avg1 to zeta.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_h_full_domain
Bathymetry data on the whole domain at each potential level.
Definition REMORA.H:416
void init_full_domain_from_analytic()
Initialize high-resolution initial data, zeta included, from analytic functions.
int hires_init_level
Which level the high resolution initialization data is at.
Definition REMORA.H:2019
int bdy_vbar() const noexcept
Definition REMORA.H:1465
amrex::Gpu::DeviceVector< amrex::Real > Cs_r
Stretching coefficients at rho points.
Definition REMORA.H:468
amrex::Vector< amrex::Real > t_new
new time at each level, in seconds since start_time
Definition REMORA.H:1700
void init_stretch_coeffs()
initialize and calculate stretch coefficients
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1949
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akk
Turbulent kinetic energy vertical diffusion coefficient.
Definition REMORA.H:673
int bdy_ubar() const noexcept
Definition REMORA.H:1464
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta
free surface height (2D)
Definition REMORA.H:578
int ubar_bc() const noexcept
Definition REMORA.H:1451
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vbar
barotropic y velocity (2D)
Definition REMORA.H:576
amrex::Box nc_hires_grid_box
Box for the full domain at nc_hires_grid_level.
Definition REMORA.H:2016
amrex::Gpu::DeviceVector< amrex::Real > Cs_w
Stretching coefficients at w points.
Definition REMORA.H:470
void set_2darrays(int lev)
Set 2D momentum arrays from 3D momentum.
void init_analytic(int lev)
Initialize initial problem data from analytic functions.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_ubar
barotropic x velocity (2D)
Definition REMORA.H:574
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.
void init_clim_nudg_coeff_from_netcdf(int lev)
Climatology nudging coefficient initialization from NetCDF file.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_cons_full_domain
multilevel data container for high res initial data: temperature, salinity, passive tracer
Definition REMORA.H:402
int vbar_bc() const noexcept
Definition REMORA.H:1452
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_pn_full_domain
horizontal scaling factor: 1 / dy (2D) on whole domain
Definition REMORA.H:609
amrex::Vector< amrex::Vector< std::unique_ptr< amrex::MultiFab > > > vec_nudg_coeff
Climatology nudging coefficients.
Definition REMORA.H:678
const amrex::DistributionMapping & full_domain_dmap()
The shared full-domain DistributionMapping, built on first use.
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
void init_masks_full_domain_from_analytic()
Full domain land-sea mask initialization from analytic.
REMORABiology::FennelParameters fennel_params
Runtime parameters for the Fennel biology package.
Definition REMORA.H:1801
void allocate_bathymetry_grid_vars_full_domain()
Allocate multifabs for storing full-domain bathymetry and grid vars data.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Zt_avg1
Average of the free surface, zeta (2D)
Definition REMORA.H:476
void average_down_with_grow_cells(int lev, amrex::Vector< std::unique_ptr< amrex::MultiFab > > &mf, bool use_mask=false)
Average down from level lev+1 to lev in mf, including grow cells.
Definition REMORA.cpp:3217
void init_clim_nudg_coeff(int lev)
Wrapper to initialize climatology nudging coefficient.
void init_bathymetry_full_domain_from_analytic()
Full domain bathymetry data initialization from analytic.
int hires_grid_level
Which level the high resolution bathymetry is at.
Definition REMORA.H:2012
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_z_w
z coordinates at w points (faces between z-cells)
Definition REMORA.H:456
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_yr
y_grid on rho points (2D)
Definition REMORA.H:617
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Akp
Turbulent length scale vertical diffusion coefficient.
Definition REMORA.H:675
REMORABiology::BiologyICType biology_ic_type
Source of the biology tracer initial condition, independent of remora.ic_type. Default follows ic_typ...
Definition REMORA.H:1804
static constexpr int u
static constexpr int v
int cons(int icomp) noexcept
bool has_biology(BiologyModel model) noexcept
@ follow_ic_type
default: NetCDF when ic_type is netcdf, else analytic
Coordinates a prob function reads, on the BoxArray and DistributionMapping of the MultiFab it fills.
const amrex::MultiFab * x_r
amrex::Real coriolis_beta
amrex::Vector< amrex::Real > nudg_coeff
amrex::Real coriolis_f0