REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_ComputeTimestep.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4
5void
7{
8 Vector<Real> dt_tmp(finest_level+1);
9
10 for (int lev = 0; lev <= finest_level; ++lev)
11 {
12 dt_tmp[lev] = estTimeStep(lev);
13 }
14
15 ParallelDescriptor::ReduceRealMin(&dt_tmp[0], dt_tmp.size());
16
17 Real dt_0 = dt_tmp[0];
18 int n_factor = 1;
19 for (int lev = 0; lev <= finest_level; ++lev) {
20 dt_tmp[lev] = amrex::min(dt_tmp[lev], change_max*dt[lev]);
21 n_factor *= nsubsteps[lev];
22 dt_0 = amrex::min(dt_0, n_factor*dt_tmp[lev]);
23 }
24
25 // Limit dt's by the value of stop_time.
26 const Real eps = 1.e-3_rt*dt_0;
27 if (t_new[0] + dt_0 > stop_time - eps) {
28 dt_0 = stop_time - t_new[0];
29 }
30
31 dt[0] = dt_0;
32 for (int lev = 1; lev <= finest_level; ++lev) {
33 dt[lev] = dt[lev-1] / nsubsteps[lev];
34 }
35}
36
37/**
38 * @param[in] level level of refinement
39 */
40Real
41REMORA::estTimeStep(int level) const
42{
43 BL_PROFILE("REMORA::estTimeStep()");
44
45 amrex::Real estdt_lowM = 1.e20_rt;
46
47 auto const dxinv = geom[level].InvCellSizeArray();
48
49 MultiFab ccvel(grids[level],dmap[level],3,0);
50
51 average_face_to_cellcenter(ccvel,0,
52 Array<const MultiFab*,3>{xvel_new[level], yvel_new[level], zvel_new[level]});
53
54 Real estdt_lowM_inv = amrex::ReduceMax(ccvel, 0,
55 [=] AMREX_GPU_HOST_DEVICE (Box const& b,
56 Array4<Real const> const& u) -> Real
57 {
58 Real new_lm_dt = -1.e100_rt;
59 amrex::Loop(b, [=,&new_lm_dt] (int i, int j, int k) noexcept
60 {
61 new_lm_dt = amrex::max(((amrex::Math::abs(u(i,j,k,0)))*dxinv[0]),
62 ((amrex::Math::abs(u(i,j,k,1)))*dxinv[1]),
63 ((amrex::Math::abs(u(i,j,k,2)))*dxinv[2]), new_lm_dt);
64 });
65 return new_lm_dt;
66 });
67
68 ParallelDescriptor::ReduceRealMax(estdt_lowM_inv);
69 if (estdt_lowM_inv > 0.0_rt)
70 estdt_lowM = cfl / estdt_lowM_inv;;
71
72 if (verbose) {
73 if (fixed_dt <= 0.0_rt) {
74 amrex::Print() << "Using cfl = " << cfl << std::endl;
75 if (estdt_lowM_inv > 0.0_rt) {
76 amrex::Print() << "Slow dt at level " << level << ": " << estdt_lowM << std::endl;
77 } else {
78 amrex::Print() << "Slow dt at level " << level << ": undefined " << std::endl;
79 }
80 }
81 if (fixed_dt > 0.0_rt) {
82 amrex::Print() << "Based on cfl of 1.0_rt " << std::endl;
83 if (estdt_lowM_inv > 0.0_rt) {
84 amrex::Print() << "Slow dt at level " << level << " would be: " << estdt_lowM/cfl << std::endl;
85 } else {
86 amrex::Print() << "Slow dt at level " << level << " would be undefined " << std::endl;
87 }
88 amrex::Print() << "Fixed dt at level " << level << " is: " << fixed_dt << std::endl;
89 }
90 }
91
92 if (fixed_dt > 0.0_rt) {
93 return fixed_dt;
94 } else {
95 return estdt_lowM;
96 }
97}
static amrex::Real fixed_dt
User specified fixed baroclinic time step.
Definition REMORA.H:1174
amrex::Real stop_time
Time to stop.
Definition REMORA.H:1160
amrex::Vector< amrex::MultiFab * > zvel_new
multilevel data container for current step's z velocities (largely unused; W stored separately)
Definition REMORA.H:223
amrex::Vector< amrex::MultiFab * > yvel_new
multilevel data container for current step's y velocities (v in ROMS)
Definition REMORA.H:221
amrex::Vector< amrex::MultiFab * > xvel_new
multilevel data container for current step's x velocities (u in ROMS)
Definition REMORA.H:219
amrex::Vector< int > nsubsteps
How many substeps on each level?
Definition REMORA.H:1096
void ComputeDt()
a wrapper for estTimeStep()
static amrex::Real change_max
Fraction maximum change in subsequent time steps.
Definition REMORA.H:1172
amrex::Vector< amrex::Real > t_new
new time at each level
Definition REMORA.H:1098
amrex::Real estTimeStep(int lev) const
compute dt from CFL considerations
static amrex::Real cfl
CFL condition.
Definition REMORA.H:1170
static int verbose
Verbosity level of output.
Definition REMORA.H:1248
amrex::Vector< amrex::Real > dt
time step at each level
Definition REMORA.H:1102