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
13 if (time == 0.0_rt && solverChoice.init_l1ad_T) {
14 average_down(*cons_new[1], *cons_new[0],
15 0, cons_new[0]->nComp(), refRatio(0));
17 }
18#endif
19
20 // HACK HACK so lev is defined and compiler won't complain, but always say regrid_int=-1
21 for (int lev=0; lev <= finest_level;lev++) {
22 if (regrid_int > 0) // We may need to regrid
23 {
24 // help keep track of whether a level was already regridded
25 // from a coarser level call to regrid
26 static Vector<int> last_regrid_step(max_level+1, 0);
27
28 // regrid changes level "lev+1" so we don't regrid on max_level
29 // also make sure we don't regrid fine levels again if
30 // it was taken care of during a coarser regrid
31 if (lev < max_level && istep[lev] > last_regrid_step[lev])
32 {
33 if (istep[lev] % regrid_int == 0)
34 {
35 // regrid could add newly refine levels (if finest_level < max_level)
36 // so we save the previous finest level index
37 int old_finest = finest_level;
38 regrid(lev, time);
39
40 // Mark that we have regridded this level already
41 for (int k = lev; k <= finest_level; ++k) {
42 last_regrid_step[k] = istep[k];
43 }
44
45 // If there are newly created levels, set the time step
46 for (int k = old_finest+1; k <= finest_level; ++k) {
47 dt[k] = dt[k-1] / nsubsteps[lev];
48 }
49 }
50 }
51 }
52 }
53
55
56 for (int lev=0; lev <= finest_level;lev++)
57 {
58 // Update what we call "old" and "new" time
59 t_old[lev] = t_new[lev];
60 t_new[lev] += dt[lev];
61
62 if (Verbose()) {
63 amrex::Print() << "[Level " << lev << " step " << istep[lev]+1 << "] ";
64 amrex::Print() << "ADVANCE from time = " << t_old[lev] << " to " << t_new[lev]
65 << " with dt = " << dt[lev] << std::endl;
66 }
67
68 // We must swap the pointers so the previous step's "new" is now this step's "old"
69 std::swap(cons_old[lev], cons_new[lev]);
70 std::swap(xvel_old[lev], xvel_new[lev]);
71 std::swap(yvel_old[lev], yvel_new[lev]);
72 std::swap(zvel_old[lev], zvel_new[lev]);
73
74 setup_step(lev, time, dt[lev]);
75
76 // **************************************************************************************
77 // Register old and new coarse data if we are at a level less than the finest level
78 // **************************************************************************************
79 if (lev < finest_level)
80 {
81 if (cf_width > 0) {
82 // We must fill the ghost cells of these so that the parallel copy works correctly
83 cons_old[lev]->FillBoundary(geom[lev].periodicity());
84 cons_new[lev]->FillBoundary(geom[lev].periodicity());
85 FPr_c[lev].RegisterCoarseData({cons_old[lev], cons_new[lev]}, {time, time + dt[lev]});
86 }
87
88 if (cf_width >= 0) {
89 // We must fill the ghost cells of these so that the parallel copy works correctly
90 xvel_old[lev]->FillBoundary(geom[lev].periodicity());
91 xvel_new[lev]->FillBoundary(geom[lev].periodicity());
92 FPr_u[lev].RegisterCoarseData({xvel_old[lev], xvel_new[lev]}, {time, time + dt[lev]});
93
94 yvel_old[lev]->FillBoundary(geom[lev].periodicity());
95 yvel_new[lev]->FillBoundary(geom[lev].periodicity());
96 FPr_v[lev].RegisterCoarseData({yvel_old[lev], yvel_new[lev]}, {time, time + dt[lev]});
97
98 zvel_old[lev]->FillBoundary(geom[lev].periodicity());
99 zvel_new[lev]->FillBoundary(geom[lev].periodicity());
100 FPr_w[lev].RegisterCoarseData({zvel_old[lev], zvel_new[lev]}, {time, time + dt[lev]});
101 }
102 }
103 }
104
106 {
107 int nfast_counter=nfast + 1;
108
109 for (int my_iif = 0; my_iif < nfast_counter; my_iif++) {
110 //Compute fast timestep from dt[lev] and ratio
111 for (int lev=0; lev <= finest_level; lev++)
112 {
113 Real dtfast_lev=dt[lev]/Real(fixed_ndtfast_ratio);
114 advance_2d_onestep(lev, dt[lev], dtfast_lev, my_iif, nfast_counter);
115 // **************************************************************************************
116 // Register old and new coarse data if we are at a level less than the finest level
117 // **************************************************************************************
118 if (lev < finest_level)
119 {
120 if (cf_width >= 0) {
121 // We must fill the ghost cells of these so that the parallel copy works correctly
122 vec_ubar[lev]->FillBoundary(geom[lev].periodicity());
123 FPr_ubar[lev].RegisterCoarseData({vec_ubar[lev].get(), vec_ubar[lev].get()}, {time, time + dt[lev]});
124
125 vec_vbar[lev]->FillBoundary(geom[lev].periodicity());
126 FPr_vbar[lev].RegisterCoarseData({vec_vbar[lev].get(), vec_vbar[lev].get()}, {time, time + dt[lev]});
127 }
128 }
129 } // my_iif
130 } // lev
131 } // use_barotropic
132
133 for (int lev=0; lev <= finest_level; lev++) {
134 advance_3d_ml(lev, dt[lev]);
135 ++istep[lev];
136
137 if (Verbose())
138 {
139 amrex::Print() << "[Level " << lev << " step " << istep[lev] << "] ";
140 amrex::Print() << "Advanced " << CountCells(lev) << " cells" << std::endl;
141 }
142 // **************************************************************************************
143 // Register old and new coarse data if we are at a level less than the finest level
144 // **************************************************************************************
145 if (lev < finest_level)
146 {
147 if (cf_width > 0) {
148 // We must fill the ghost cells of these so that the parallel copy works correctly
149 cons_old[lev]->FillBoundary(geom[lev].periodicity());
150 cons_new[lev]->FillBoundary(geom[lev].periodicity());
151 FPr_c[lev].RegisterCoarseData({cons_old[lev], cons_new[lev]}, {time, time + dt[lev]});
152 }
153
154 if (cf_width >= 0) {
155 // We must fill the ghost cells of these so that the parallel copy works correctly
156 xvel_old[lev]->FillBoundary(geom[lev].periodicity());
157 xvel_new[lev]->FillBoundary(geom[lev].periodicity());
158 FPr_u[lev].RegisterCoarseData({xvel_old[lev], xvel_new[lev]}, {time, time + dt[lev]});
159
160 yvel_old[lev]->FillBoundary(geom[lev].periodicity());
161 yvel_new[lev]->FillBoundary(geom[lev].periodicity());
162 FPr_v[lev].RegisterCoarseData({yvel_old[lev], yvel_new[lev]}, {time, time + dt[lev]});
163
164 zvel_old[lev]->FillBoundary(geom[lev].periodicity());
165 zvel_new[lev]->FillBoundary(geom[lev].periodicity());
166 FPr_w[lev].RegisterCoarseData({zvel_old[lev], zvel_new[lev]}, {time, time + dt[lev]});
167 }
168 }
169 if ( (solverChoice.boundary_from_netcdf) && (lev==0) ) {
170 // We might need to go back to normal FillPatch once the refined patches are allowed to intersect the boundary in NetCDF
171 FillPatchNoBC(lev, t_new[lev], *xvel_new[lev], xvel_new, BdyVars::u,0,true,true);
172 FillPatchNoBC(lev, t_new[lev], *yvel_new[lev], yvel_new, BdyVars::v,0,true,true);
173 FillPatchNoBC(lev, t_new[lev], *zvel_new[lev], zvel_new, BdyVars::null,0,true,true);
174 } else {
175 FillPatch(lev, t_new[lev], *xvel_new[lev], xvel_new, BCVars::xvel_bc, BdyVars::u,0,true,true);
176 FillPatch(lev, t_new[lev], *yvel_new[lev], yvel_new, BCVars::yvel_bc, BdyVars::v,0,true,true);
177 FillPatch(lev, t_new[lev], *zvel_new[lev], zvel_new, BCVars::zvel_bc, BdyVars::null,0,true,true);
178 }
179 }
180
182
184 for (int lev=0; lev <= finest_level-1; lev++) {
185 AverageDownTo(lev); // average lev+1 down to lev
186 }
187 }
188}
int nfast
Number of fast steps to take.
Definition REMORA.H:1293
void scale_rhs_vars()
Scale RHS momentum variables by 1/cell area, needed before FillPatch to different levels.
amrex::Vector< REMORAFillPatcher > FPr_v
Vector over levels of FillPatchers for v (3D)
Definition REMORA.H:1168
amrex::Vector< amrex::MultiFab * > cons_new
multilevel data container for current step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:241
amrex::Vector< amrex::MultiFab * > zvel_new
multilevel data container for current step's z velocities (largely unused; W stored separately)
Definition REMORA.H:247
amrex::Vector< REMORAFillPatcher > FPr_u
Vector over levels of FillPatchers for u (3D)
Definition REMORA.H:1166
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...
amrex::Vector< amrex::MultiFab * > xvel_old
multilevel data container for last step's x velocities (u in ROMS)
Definition REMORA.H:234
amrex::Vector< amrex::MultiFab * > yvel_new
multilevel data container for current step's y velocities (v in ROMS)
Definition REMORA.H:245
int regrid_int
how often each level regrids the higher levels of refinement (after a level advances that many time s...
Definition REMORA.H:1299
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:1176
void AverageDownTo(int crse_lev)
more flexible version of AverageDown() that lets you average down across multiple levels
Definition REMORA.cpp:1276
amrex::Vector< amrex::MultiFab * > zvel_old
multilevel data container for last step's z velocities (largely unused; W stored separately)
Definition REMORA.H:238
amrex::Vector< amrex::MultiFab * > xvel_new
multilevel data container for current step's x velocities (u in ROMS)
Definition REMORA.H:243
amrex::Vector< int > nsubsteps
How many substeps on each level?
Definition REMORA.H:1209
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:1207
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:236
amrex::Vector< REMORAFillPatcher > FPr_c
Vector over levels of FillPatchers for scalars.
Definition REMORA.H:1164
void scale_rhs_vars_inv()
Scale RHS momentum variables by cell area, needed after FillPatch to different levels.
amrex::Vector< REMORAFillPatcher > FPr_w
Vector over levels of FillPatchers for w.
Definition REMORA.H:1170
amrex::Vector< amrex::Real > t_new
new time at each level
Definition REMORA.H:1211
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1336
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_vbar
barotropic y velocity (2D)
Definition REMORA.H:384
amrex::Vector< std::unique_ptr< amrex::MultiFab > > vec_ubar
barotropic x velocity (2D)
Definition REMORA.H:382
amrex::Vector< amrex::MultiFab * > cons_old
multilevel data container for last step's scalar data: temperature, salinity, passive tracer
Definition REMORA.H:232
amrex::Vector< REMORAFillPatcher > FPr_ubar
Vector over levels of FillPatchers for ubar (2D)
Definition REMORA.H:1174
static int fixed_ndtfast_ratio
User specified, number of barotropic steps per baroclinic step.
Definition REMORA.H:1291
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:1159
amrex::Vector< amrex::Real > t_old
old time at each level
Definition REMORA.H:1213
amrex::Vector< amrex::Real > dt
time step at each level
Definition REMORA.H:1215
CouplingType coupling_type