REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_TimeStepML.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4
5/**
6 * @param[in] time simulation time at start of step
7 * @param[in] iteration iteration in subcycling, if using
8 */
9void
10REMORA::timeStepML (Real time, int /*iteration*/)
11{
12#if 0
15 0, cons_new[0]->nComp(), refRatio(0));
17 }
18#endif
19
20 for (int lev=0; lev <= finest_level;lev++) {
21 if (regrid_int > 0) // We may need to regrid
22 {
23 // help keep track of whether a level was already regridded
24 // from a coarser level call to regrid
25 static Vector<int> last_regrid_step(max_level+1, 0);
26
27 // regrid changes level "lev+1" so we don't regrid on max_level
28 // also make sure we don't regrid fine levels again if
29 // it was taken care of during a coarser regrid
31 {
32 if (istep[lev] % regrid_int == 0)
33 {
34 // regrid could add newly refine levels (if finest_level < max_level)
35 // so we save the previous finest level index
37 regrid(lev, time);
38
39 // The refined footprint moved, so the level pairs are new
41
42 // Mark that we have regridded this level already
43 for (int k = lev; k <= finest_level; ++k) {
45 }
46
47 // If there are newly created levels, set the time step
48 for (int k = old_finest+1; k <= finest_level; ++k) {
49 dt[k] = dt[k-1] / nsubsteps[k];
50 }
51 }
52 }
53 }
54 }
55
56 for (int lev=0; lev <= finest_level; lev++) {
58 }
59
60 for (int lev=0; lev <= finest_level;lev++)
61 {
62 // Update what we call "old" and "new" time
63 t_old[lev] = t_new[lev];
64 t_new[lev] += dt[lev];
65
66 if (Verbose()) {
67 amrex::Print() << "[Level " << lev << " step " << istep[lev]+1 << "] ";
68 amrex::Print() << "ADVANCE from time = " << t_old[lev] << " to " << t_new[lev]
69 << " with dt = " << dt[lev] << std::endl;
70 }
71
72 // We must swap the pointers so the previous step's "new" is now this step's "old"
73 std::swap(cons_old[lev], cons_new[lev]);
74 std::swap(xvel_old[lev], xvel_new[lev]);
75 std::swap(yvel_old[lev], yvel_new[lev]);
76 std::swap(zvel_old[lev], zvel_new[lev]);
77
79
80 // **************************************************************************************
81 // Register old and new coarse data if we are at a level less than the finest level
82 // **************************************************************************************
83 if (lev < finest_level)
84 {
85 if (cf_width > 0) {
86 // We must fill the ghost cells of these so that the parallel copy works correctly
87 cons_old[lev]->FillBoundary(geom[lev].periodicity());
88 cons_new[lev]->FillBoundary(geom[lev].periodicity());
89 FPr_c[lev].RegisterCoarseData({cons_old[lev], cons_new[lev]}, {time, time + dt[lev]});
90 }
91
92 if (cf_width >= 0) {
93 // We must fill the ghost cells of these so that the parallel copy works correctly
94 xvel_old[lev]->FillBoundary(geom[lev].periodicity());
95 xvel_new[lev]->FillBoundary(geom[lev].periodicity());
96 FPr_u[lev].RegisterCoarseData({xvel_old[lev], xvel_new[lev]}, {time, time + dt[lev]});
97
98 yvel_old[lev]->FillBoundary(geom[lev].periodicity());
99 yvel_new[lev]->FillBoundary(geom[lev].periodicity());
100 FPr_v[lev].RegisterCoarseData({yvel_old[lev], yvel_new[lev]}, {time, time + dt[lev]});
101
102 zvel_old[lev]->FillBoundary(geom[lev].periodicity());
103 zvel_new[lev]->FillBoundary(geom[lev].periodicity());
104 FPr_w[lev].RegisterCoarseData({zvel_old[lev], zvel_new[lev]}, {time, time + dt[lev]});
105 }
106 }
107 }
108
109 int nfast_counter=nfast + 1;
110
111 for (int my_iif = 0; my_iif < nfast_counter; my_iif++) {
112 //Compute fast timestep from dt[lev] and ratio
113 for (int lev=0; lev <= finest_level; lev++)
114 {
115 Real dtfast_lev=dt[lev]/Real(ndtfast);
117 // **************************************************************************************
118 // Register old and new coarse data if we are at a level less than the finest level
119 // **************************************************************************************
120 if (lev < finest_level)
121 {
122 if (cf_width >= 0) {
123 // We must fill the ghost cells of these so that the parallel copy works correctly
124 vec_ubar[lev]->FillBoundary(geom[lev].periodicity());
125 FPr_ubar[lev].RegisterCoarseData({vec_ubar[lev].get(), vec_ubar[lev].get()}, {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()}, {time, time + dt[lev]});
129 }
130 }
131 } // lev
132 } // my_iif
133
134 for (int lev=0; lev <= finest_level; lev++) {
136 ++istep[lev];
137
138 if (Verbose())
139 {
140 amrex::Print() << "[Level " << lev << " step " << istep[lev] << "] ";
141 amrex::Print() << "Advanced " << CountCells(lev) << " cells" << std::endl;
142 }
143 // **************************************************************************************
144 // Register old and new coarse data if we are at a level less than the finest level
145 // **************************************************************************************
146 if (lev < finest_level)
147 {
148 if (cf_width > 0) {
149 // We must fill the ghost cells of these so that the parallel copy works correctly
150 cons_old[lev]->FillBoundary(geom[lev].periodicity());
151 cons_new[lev]->FillBoundary(geom[lev].periodicity());
152 FPr_c[lev].RegisterCoarseData({cons_old[lev], cons_new[lev]}, {time, time + dt[lev]});
153 }
154
155 if (cf_width >= 0) {
156 // We must fill the ghost cells of these so that the parallel copy works correctly
157 xvel_old[lev]->FillBoundary(geom[lev].periodicity());
158 xvel_new[lev]->FillBoundary(geom[lev].periodicity());
159 FPr_u[lev].RegisterCoarseData({xvel_old[lev], xvel_new[lev]}, {time, time + dt[lev]});
160
161 yvel_old[lev]->FillBoundary(geom[lev].periodicity());
162 yvel_new[lev]->FillBoundary(geom[lev].periodicity());
163 FPr_v[lev].RegisterCoarseData({yvel_old[lev], yvel_new[lev]}, {time, time + dt[lev]});
164
165 zvel_old[lev]->FillBoundary(geom[lev].periodicity());
166 zvel_new[lev]->FillBoundary(geom[lev].periodicity());
167 FPr_w[lev].RegisterCoarseData({zvel_old[lev], zvel_new[lev]}, {time, time + dt[lev]});
168 }
169 }
170 // Same as Advance after its step: nothing on level 0, and a child re-filled from its
171 // parent only under cf_fill_vel_after. A FillPatch of the level-0 velocity with the
172 // physical boundary conditions at t_new used to sit here; on the open-boundary
173 // dogbone it moved the answer 2e-8 away from ROMS, which the step otherwise matches
174 // to 1e-14.
175 if (cf_fill_vel_after && lev > 0) {
178 }
179 }
180
181 for (int lev=0; lev <= finest_level; lev++) {
183 }
184
186 for (int lev=0; lev <= finest_level-1; lev++) {
187 AverageDownTo(lev); // average lev+1 down to lev
188 }
189 }
190}
constexpr amrex::Real zero
mf_h setVal(geomdata.ProbHi(2))
int nfast
Number of fast steps to take.
Definition REMORA.H:1828
int xvel_bc() const noexcept
Definition REMORA.H:1448
amrex::Vector< REMORAFillPatcher > FPr_v
Vector over levels of FillPatchers for v (3D)
Definition REMORA.H:1646
amrex::Vector< amrex::MultiFab * > cons_new
multilevel data container for current step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:393
void check_mask_consistency()
Check every level pair's masks against each other, and every level's mask values, reporting according...
Definition REMORA.cpp:1047
int yvel_bc() const noexcept
Definition REMORA.H:1449
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< amrex::MultiFab * > yvel_new
multilevel data container for current step's y velocities (v in ROMS)
Definition REMORA.H:397
int regrid_int
how often each level regrids the higher levels of refinement (after a level advances that many time s...
Definition REMORA.H:1913
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
void AverageDownTo(int crse_lev)
more flexible version of AverageDown() that lets you average down across multiple levels
Definition REMORA.cpp:2840
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::Vector< int > nsubsteps
How many substeps on each level?
Definition REMORA.H:1691
amrex::Vector< int > istep
which step?
Definition REMORA.H:1689
void advance_3d_ml(int lev, amrex::Real dt_lev)
3D advance on a single level
amrex::Vector< amrex::MultiFab * > yvel_old
multilevel data container for last step's y velocities (v in ROMS)
Definition REMORA.H:388
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
amrex::Vector< amrex::Real > t_new
new time at each level, in seconds since start_time
Definition REMORA.H:1700
void scale_rhs_vars_inv(int lev)
Scale RHS momentum variables by cell area, needed after FillPatch to different levels.
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1949
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
void timeStepML(amrex::Real time, int iteration)
advance all levels by dt, loops over finer levels
void setup_step(int lev, amrex::Real time, amrex::Real dt_lev)
Set everything up for a step on a level.
void WritePlotFile(int istep)
main driver for writing AMReX plotfiles
int cf_width
Nudging width at coarse-fine interface.
Definition REMORA.H:1637
amrex::Vector< amrex::Real > t_old
old time at each level, in seconds since start_time
Definition REMORA.H:1702
void scale_rhs_vars(int lev)
Scale RHS momentum variables by 1/cell area, needed before FillPatch to different levels.
amrex::Vector< amrex::Real > dt
time step at each level
Definition REMORA.H:1704
static constexpr int u
static constexpr int v
CouplingType coupling_type