REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_Advance.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4
5#ifdef REMORA_USE_FUNWAVE_FORT
7#endif
8
9/**
10 * @param[in] lev level of refinement
11 * @param[in] time simulation time at start of step
12 * @param[in] dt_lev baroclinic time step at level
13 * @param[in] iteration iteration in subcycling, if using
14 * @param[in] ncycle total number of subcycles, if using
15 */
16 void
17REMORA::Advance (int lev, Real time, Real dt_lev, int /*iteration*/, int /*ncycle*/)
18{
19 BL_PROFILE("REMORA::Advance()");
20
21 // Start the correction lev+1 will contribute to, before any flux is added to it.
24 getAdvFluxReg(lev+1)->reset();
25 }
26
28
29 int nfast_counter=nfast + 1;
30
31 //***************************************************
32 //Compute fast timestep from dt_lev and ratio
33 //***************************************************
34 Real dtfast_lev=dt_lev/Real(ndtfast);
35
36 //***************************************************
37 //Advance nfast_counter steps of the 2d integrator
38 //***************************************************
39 for (int my_iif = 0; my_iif < nfast_counter; my_iif++) {
41 }
42
43#ifdef REMORA_USE_FUNWAVE_FORT
44 MultiFab* mf_rhoS = vec_rhoS[lev].get();
45 for ( MFIter mfi(*mf_rhoS, TilingIfNotGPU()); mfi.isValid(); ++mfi )
46 {
47 Box bx = mfi.validbox();
48 int ims = bx.smallEnd(0);
49 int jms = bx.smallEnd(1);
50 int kms = bx.smallEnd(2);
51 int ime = bx.bigEnd(0);
52 int jme = bx.bigEnd(1);
53 int kme = bx.bigEnd(2);
54
55 Array4<Real> const& rho_salt = mf_rhoS->array(mfi);
56
57 funwave_advance_c(rho_salt.dataPtr(), ims, ime, jms, jme, kms, kme);
58 }
59#endif
60
61 //***************************************************
62 //Advance one step of the 3d integrator
63 //***************************************************
65
66 // vert_mean_3d has just replaced the depth mean of the fine 3D velocity with the
67 // barotropic transport the parent imposed, while its shear is still the profile the
68 // parent handed over at the start of the step. Nothing reconciles the two, so the
69 // interface carries a depth-uniform offset that AverageDownTo then pushes onto the
70 // parent. Neither driver reconciles them unless this knob is set.
71 if (cf_fill_vel_after && lev > 0) {
73 BdyVars::u, 0, true, true);
75 BdyVars::v, 0, true, true);
76 }
77
78 //***************************************************
79 //Hand the completed step to a finer level. Only timeStep reaches this;
80 //timeStepML registers its own coarse data inline.
81 //***************************************************
83}
84
85/**
86 * Store this level's old and new state in the coarse/fine fill patchers so the next finer
87 * level can interpolate its contact points to its own sub-times.
88 *
89 * @param[in] lev level of refinement
90 * @param[in] time simulation time at start of the step just taken
91 * @param[in] dt_lev baroclinic time step at level
92 */
93void
95{
96 // At the end of Advance, once the new state is valid. The parent completes its whole
97 // step before any child substep, so {t_old, t_new} brackets every time the child asks for.
98 if (lev >= finest_level) { return; }
99
100 if (cf_width > 0) {
101 // The parallel copy inside RegisterCoarseData needs filled ghost cells
102 cons_old[lev]->FillBoundary(geom[lev].periodicity());
103 cons_new[lev]->FillBoundary(geom[lev].periodicity());
104 FPr_c[lev].RegisterCoarseData({cons_old[lev], cons_new[lev]}, {time, time + dt_lev});
105 }
106
107 if (cf_width >= 0) {
108 xvel_old[lev]->FillBoundary(geom[lev].periodicity());
109 xvel_new[lev]->FillBoundary(geom[lev].periodicity());
110 FPr_u[lev].RegisterCoarseData({xvel_old[lev], xvel_new[lev]}, {time, time + dt_lev});
111
112 yvel_old[lev]->FillBoundary(geom[lev].periodicity());
113 yvel_new[lev]->FillBoundary(geom[lev].periodicity());
114 FPr_v[lev].RegisterCoarseData({yvel_old[lev], yvel_new[lev]}, {time, time + dt_lev});
115
116 zvel_old[lev]->FillBoundary(geom[lev].periodicity());
117 zvel_new[lev]->FillBoundary(geom[lev].periodicity());
118 FPr_w[lev].RegisterCoarseData({zvel_old[lev], zvel_new[lev]}, {time, time + dt_lev});
119
120 // ubar and vbar carry their time levels as components of one MultiFab, so there is
121 // no old/new pair. These serve the tangential and interior contact points; the
122 // normal ones on the interface come from the mass flux below.
123 vec_ubar[lev]->FillBoundary(geom[lev].periodicity());
124 FPr_ubar[lev].RegisterCoarseData({vec_ubar[lev].get(), vec_ubar[lev].get()},
125 {time, time + dt_lev});
126
127 vec_vbar[lev]->FillBoundary(geom[lev].periodicity());
128 FPr_vbar[lev].RegisterCoarseData({vec_vbar[lev].get(), vec_vbar[lev].get()},
129 {time, time + dt_lev});
130
131 // ROMS uses only the newest flux record unless TIME_INTERP_FLUX is defined
132 // (nesting.F): holding the step average constant over the child's substeps conserves
133 // mass across the parent interval, interpolating between two averages does not.
135
136 MultiFab* Du_old = time_interp_flux ? vec_Dubar_old[lev].get() : vec_Dubar_new[lev].get();
137 MultiFab* Dv_old = time_interp_flux ? vec_Dvbar_old[lev].get() : vec_Dvbar_new[lev].get();
138
139 vec_Dubar_new[lev]->FillBoundary(geom[lev].periodicity());
140 Du_old->FillBoundary(geom[lev].periodicity());
141 FPr_Dubar[lev].RegisterCoarseData({Du_old, vec_Dubar_new[lev].get()},
142 {time, time + dt_lev});
143
144 vec_Dvbar_new[lev]->FillBoundary(geom[lev].periodicity());
145 Dv_old->FillBoundary(geom[lev].periodicity());
146 FPr_Dvbar[lev].RegisterCoarseData({Dv_old, vec_Dvbar_new[lev].get()},
147 {time, time + dt_lev});
148
149 // The free surface has no old/new pair above, so the generic FillPatch hands a
150 // subcycled child this level's state frozen at the end of the step, for every substep.
151 // ROMS's put_refine2d interpolates the donor between two stored snapshots onto the
152 // child's own time, so keep the pair it needs. Zt_avg1 is the end-of-step surface and
153 // set_zeta_to_Ztavg puts it in every leapfrog component, so broadcasting it to all
154 // three matches both what ROMS stores and what the child reads, whichever component
155 // its own knew names.
159 }
160 }
161}
162
163/**
164 * Roll a two-snapshot history of one level's end-of-step 2D state: the previous "new" becomes
165 * "old" and src becomes the new one, so the pair brackets [t_old, t_new] of the step just
166 * taken. src has one component and is broadcast to all of them. On the first call, and
167 * whenever the level's layout changes, both snapshots are set to src, making the child's time
168 * interpolation a no-op for that step rather than reading uninitialised data -- the same
169 * special case ROMS takes when RollingIndex is still zero.
170 *
171 * @param[inout] old_v the older snapshot, one entry per level
172 * @param[inout] new_v the newer snapshot, one entry per level
173 * @param[in] lev level of refinement
174 * @param[in] src end-of-step value to store, single component
175 * @param[in] like MultiFab whose layout, component count and ghost width to match
176 */
177void
178REMORA::roll_2d_snapshot (Vector<std::unique_ptr<MultiFab>>& old_v,
179 Vector<std::unique_ptr<MultiFab>>& new_v,
180 int lev, const MultiFab& src, const MultiFab& like)
181{
182 if (int(old_v.size()) <= lev) { old_v.resize(lev+1); }
183 if (int(new_v.size()) <= lev) { new_v.resize(lev+1); }
184
185 const int ncomp = like.nComp();
186 const IntVect ng = like.nGrowVect();
187 const bool fresh = !new_v[lev] || new_v[lev]->boxArray() != like.boxArray()
188 || new_v[lev]->DistributionMap() != like.DistributionMap();
189
190 if (fresh) {
191 old_v[lev].reset(new MultiFab(like.boxArray(), like.DistributionMap(), ncomp, ng));
192 new_v[lev].reset(new MultiFab(like.boxArray(), like.DistributionMap(), ncomp, ng));
193 } else {
194 MultiFab::Copy(*old_v[lev], *new_v[lev], 0, 0, ncomp, ng);
195 }
196
197 // src carries one component; every component of the snapshot gets it
198 for (int n = 0; n < ncomp; ++n) {
199 MultiFab::Copy(*new_v[lev], src, 0, n, 1, amrex::min(ng, src.nGrowVect()));
200 }
201 new_v[lev]->FillBoundary(geom[lev].periodicity());
202
203 if (fresh) {
204 MultiFab::Copy(*old_v[lev], *new_v[lev], 0, 0, ncomp, ng);
205 }
206}
mf_h setVal(geomdata.ProbHi(2))
void funwave_advance_c(double *salt, int ims, int ime, int jms, int jme, int kms, int kme)
int nfast
Number of fast steps to take.
Definition REMORA.H:1828
int xvel_bc() const noexcept
Definition REMORA.H:1448
bool time_interp_flux
interpolate the parent's barotropic mass flux in time at the coarse-fine interface,...
Definition REMORA.H:1836
amrex::Vector< REMORAFillPatcher > FPr_v
Vector over levels of FillPatchers for v (3D)
Definition REMORA.H:1646
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta_crse_new
see vec_zeta_crse_old (2D)
Definition REMORA.H:566
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta_crse_old
free surface at the start and end of this level's step, every leapfrog component holding the same val...
Definition REMORA.H:564
amrex::Vector< amrex::MultiFab * > cons_new
multilevel data container for current step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:393
int do_substep
Whether to substep fine levels in time.
Definition REMORA.H:1831
int yvel_bc() const noexcept
Definition REMORA.H:1449
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Dvbar_new
see vec_Dvbar_old (2D)
Definition REMORA.H:560
amrex::Vector< amrex::MultiFab * > zvel_new
multilevel data container for current step's z velocities (largely unused; W stored separately)
Definition REMORA.H:399
amrex::Vector< REMORAFillPatcher > FPr_u
Vector over levels of FillPatchers for u (3D)
Definition REMORA.H:1644
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_Dubar_old
DU_avg2 per unit cell edge length, at the start and end of this level's step. What a subcycled finer ...
Definition REMORA.H:554
void register_coarse_data(int lev, amrex::Real time, amrex::Real dt_lev)
register this level's completed step as the coarse bracket the next finer level interpolates within
amrex::Vector< amrex::MultiFab * > yvel_new
multilevel data container for current step's y velocities (v in ROMS)
Definition REMORA.H:397
void advance_2d_onestep(int lev, amrex::Real dt_lev, amrex::Real dtfast_lev, int my_iif, int nfast_counter)
2D advance, one predictor/corrector step
amrex::Vector< REMORAFillPatcher > FPr_vbar
Vector over levels of FillPatchers for vbar (2D)
Definition REMORA.H:1654
amrex::Vector< amrex::MultiFab * > zvel_old
multilevel data container for last step's z velocities (largely unused; W stored separately)
Definition REMORA.H:390
amrex::Vector< amrex::MultiFab * > xvel_new
multilevel data container for current step's x velocities (u in ROMS)
Definition REMORA.H:395
amrex::YAFluxRegister * getAdvFluxReg(int lev)
flux register between lev and lev-1
Definition REMORA.H:1716
void advance_3d_ml(int lev, amrex::Real dt_lev)
3D advance on a single level
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_rhoS
density perturbation
Definition REMORA.H:650
amrex::Vector< REMORAFillPatcher > FPr_Dubar
Vector over levels of FillPatchers for Dubar (2D)
Definition REMORA.H:1656
void store_2d_flux(int lev)
store this level's barotropic mass flux per unit cell edge length
amrex::Vector< REMORAFillPatcher > FPr_Dvbar
Vector over levels of FillPatchers for Dvbar (2D)
Definition REMORA.H:1658
amrex::Vector< amrex::MultiFab * > yvel_old
multilevel data container for last step's y velocities (v in ROMS)
Definition REMORA.H:388
void Advance(int lev, amrex::Real time, amrex::Real dt_lev, int iteration, int ncycle)
advance a single level for a single time step
amrex::Vector< REMORAFillPatcher > FPr_c
Vector over levels of FillPatchers for scalars.
Definition REMORA.H:1642
amrex::Vector< REMORAFillPatcher > FPr_w
Vector over levels of FillPatchers for w.
Definition REMORA.H:1648
int cf_fill_vel_after
re-fill the child's 3D velocity from the parent after the step, so the coarse-fine boundary carries t...
Definition REMORA.H:1859
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1949
int do_reflux
correct the coarse tracer with the finer level's accumulated advective flux at their interface....
Definition REMORA.H:1847
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_zeta
free surface height (2D)
Definition REMORA.H:578
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vbar
barotropic y velocity (2D)
Definition REMORA.H:576
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.
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< REMORAFillPatcher > FPr_ubar
Vector over levels of FillPatchers for ubar (2D)
Definition REMORA.H:1652
static int ndtfast
User specified, number of barotropic steps per baroclinic step.
Definition REMORA.H:1826
int cf_time_interp_zeta
interpolate the parent in time onto the child's own sub-time, as put_refine2d does,...
Definition REMORA.H:1881
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Dvbar_old
DV_avg2 per unit cell edge length, see vec_Dubar_old (2D)
Definition REMORA.H:558
void setup_step(int lev, amrex::Real time, amrex::Real dt_lev)
Set everything up for a step on a level.
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Dubar_new
see vec_Dubar_old (2D)
Definition REMORA.H:556
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_Zt_avg1
Average of the free surface, zeta (2D)
Definition REMORA.H:476
int cf_width
Nudging width at coarse-fine interface.
Definition REMORA.H:1637
void roll_2d_snapshot(amrex::Vector< std::unique_ptr< amrex::MultiFab > > &old_v, amrex::Vector< std::unique_ptr< amrex::MultiFab > > &new_v, int lev, const amrex::MultiFab &src, const amrex::MultiFab &like)
roll a two-snapshot history of a level's end-of-step 2D state
static constexpr int u
static constexpr int v
CouplingType coupling_type