Skip to content

Commit 421ca84

Browse files
mbkuhnjrood-nrel
andauthored
Framework for adaptive dt / independent dt specs in each solver input (#107)
* framework for adaptive dt / independent dt specs in each solver input * put adaptive dt into a reg test * change function call to go with amr-wind changes * get min dt across processors * check for fixed dt upon initialization; do other work for consistent dt only when needed * allow max_time as ending argument, modify reg test to include it * remove redundant mpi_barrier --------- Co-authored-by: Jon Rood <[email protected]>
1 parent 30f1a51 commit 421ca84

File tree

11 files changed

+154
-12
lines changed

11 files changed

+154
-12
lines changed

app/exawind/exawind.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,10 @@ int main(int argc, char** argv)
186186
sim.set_nw_start_rank(nalu_start_rank);
187187

188188
const auto nalu_vars = node["nalu_vars"].as<std::vector<std::string>>();
189-
const int num_timesteps = node["num_timesteps"].as<int>();
189+
const int num_timesteps =
190+
node["num_timesteps"] ? node["num_timesteps"].as<int>() : -1;
191+
const double max_time =
192+
node["max_time"] ? node["max_time"].as<double>() : -1.0;
190193
const int additional_picard_its =
191194
node["additional_picard_iterations"]
192195
? node["additional_picard_iterations"].as<int>()
@@ -199,6 +202,12 @@ int main(int argc, char** argv)
199202
: false;
200203
sim.set_holemap_alg(holemap_alg);
201204

205+
if (num_timesteps < 0 && max_time < 0.) {
206+
throw std::runtime_error(
207+
"max_timesteps or num_timesteps must be specified as positive "
208+
"values. These are both unspecified or specified as negative.");
209+
}
210+
202211
if (node["composite_body"]) {
203212
const YAML::Node& composite_mesh = node["composite_body"];
204213
const int num_composite = static_cast<int>(composite_mesh.size());
@@ -291,7 +300,8 @@ int main(int argc, char** argv)
291300
sim.echo("Initializing overset simulation");
292301
sim.initialize();
293302
sim.echo("Initialization successful");
294-
sim.run_timesteps(additional_picard_its, nonlinear_its, num_timesteps);
303+
sim.run_timesteps(
304+
additional_picard_its, nonlinear_its, num_timesteps, max_time);
295305
sim.delete_solvers();
296306

297307
if (amr_comm != MPI_COMM_NULL) {

src/AMRWind.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,18 @@ void AMRWind::prepare_solver_epilog()
7070
m_incflo.prepare_for_time_integration();
7171
}
7272

73-
void AMRWind::pre_advance_stage1(size_t inonlin)
73+
void AMRWind::pre_advance_stage0(size_t inonlin)
7474
{
7575
if (inonlin < 1) {
7676
m_incflo.sim().time().new_timestep();
7777
m_incflo.regrid_and_update();
78+
m_incflo.compute_dt();
79+
}
80+
}
81+
82+
void AMRWind::pre_advance_stage1(size_t inonlin)
83+
{
84+
if (inonlin < 1) {
7885
m_incflo.pre_advance_stage1();
7986
}
8087
}
@@ -84,6 +91,20 @@ void AMRWind::pre_advance_stage2(size_t inonlin)
8491
if (inonlin < 1) m_incflo.pre_advance_stage2();
8592
}
8693

94+
double AMRWind::get_time() { return m_incflo.time().new_time(); }
95+
96+
double AMRWind::get_timestep_size() { return m_incflo.time().delta_t(); }
97+
98+
void AMRWind::set_timestep_size(const double dt)
99+
{
100+
m_incflo.sim().time().delta_t() = dt;
101+
}
102+
103+
bool AMRWind::is_fixed_timestep_size()
104+
{
105+
return (!m_incflo.sim().time().adaptive_timestep());
106+
}
107+
87108
void AMRWind::advance_timestep(size_t inonlin) { m_incflo.do_advance(inonlin); }
88109

89110
void AMRWind::post_advance() { m_incflo.post_advance_work(); }

src/AMRWind.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class AMRWind : public ExawindSolver
2727
~AMRWind();
2828
bool is_unstructured() override { return false; }
2929
bool is_amr() override { return true; }
30+
bool is_fixed_timestep_size() override;
3031
int overset_update_interval() override;
3132
int time_index() override;
3233
std::string identifier() override { return "AMR-Wind"; }
@@ -37,8 +38,12 @@ class AMRWind : public ExawindSolver
3738
void init_epilog() override;
3839
void prepare_solver_prolog() override;
3940
void prepare_solver_epilog() override;
41+
void pre_advance_stage0(size_t inonlin) override;
4042
void pre_advance_stage1(size_t inonlin) override;
4143
void pre_advance_stage2(size_t inonlin) override;
44+
double get_time() override;
45+
double get_timestep_size() override;
46+
void set_timestep_size(const double) override;
4247
void advance_timestep(size_t inonlin) override;
4348
void additional_picard_iterations(const int) override {};
4449
void post_advance() override;

src/ExawindSolver.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ class ExawindSolver
1919
void call_init_epilog() { init_epilog(); };
2020
void call_prepare_solver_prolog() { prepare_solver_prolog(); };
2121
void call_prepare_solver_epilog() { prepare_solver_epilog(); };
22+
void call_pre_advance_stage0(size_t inonlin, const bool increment)
23+
{
24+
const std::string name = "Pre";
25+
m_timers.tick(name, increment);
26+
pre_advance_stage0(inonlin);
27+
m_timers.tock(name);
28+
}
2229
void call_pre_advance_stage1(size_t inonlin, const bool increment)
2330
{
2431
const std::string name = "Pre";
@@ -33,6 +40,29 @@ class ExawindSolver
3340
pre_advance_stage2(inonlin);
3441
m_timers.tock(name);
3542
};
43+
double call_get_time()
44+
{
45+
const std::string name = "Pre";
46+
m_timers.tick(name);
47+
double time = get_time();
48+
m_timers.tock(name);
49+
return time;
50+
}
51+
double call_get_timestep_size()
52+
{
53+
const std::string name = "Pre";
54+
m_timers.tick(name);
55+
double dt = get_timestep_size();
56+
m_timers.tock(name);
57+
return dt;
58+
};
59+
void call_set_timestep_size(double dt)
60+
{
61+
const std::string name = "Pre";
62+
m_timers.tick(name);
63+
set_timestep_size(dt);
64+
m_timers.tock(name);
65+
};
3666
void call_advance_timestep(size_t inonlin, const bool increment)
3767
{
3868
const std::string name = "Solve";
@@ -91,6 +121,7 @@ class ExawindSolver
91121

92122
virtual bool is_unstructured() { return false; };
93123
virtual bool is_amr() { return false; };
124+
virtual bool is_fixed_timestep_size() = 0;
94125
virtual int overset_update_interval() { return 100000000; };
95126
virtual int time_index() = 0;
96127
virtual std::string identifier() { return "ExawindSolver"; }
@@ -108,8 +139,12 @@ class ExawindSolver
108139
virtual void init_epilog() = 0;
109140
virtual void prepare_solver_prolog() = 0;
110141
virtual void prepare_solver_epilog() = 0;
142+
virtual void pre_advance_stage0(size_t inonlin) = 0;
111143
virtual void pre_advance_stage1(size_t inonlin) = 0;
112144
virtual void pre_advance_stage2(size_t inonlin) = 0;
145+
virtual double get_time() = 0;
146+
virtual double get_timestep_size() = 0;
147+
virtual void set_timestep_size(const double) = 0;
113148
virtual void advance_timestep(size_t inonlin) = 0;
114149
virtual void additional_picard_iterations(const int) = 0;
115150
virtual void post_advance() = 0;

src/NaluWind.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ void NaluWind::prepare_solver_epilog()
8282
realm->output_converged_results();
8383
}
8484

85+
void NaluWind::pre_advance_stage0(size_t inonlin)
86+
{
87+
m_sim.timeIntegrator_->prepare_time_step(inonlin);
88+
}
89+
8590
void NaluWind::pre_advance_stage1(size_t inonlin)
8691
{
8792
m_sim.timeIntegrator_->pre_realm_advance_stage1(inonlin);
@@ -92,6 +97,26 @@ void NaluWind::pre_advance_stage2(size_t inonlin)
9297
m_sim.timeIntegrator_->pre_realm_advance_stage2(inonlin);
9398
}
9499

100+
double NaluWind::get_time()
101+
{
102+
return m_sim.timeIntegrator_->get_current_time();
103+
}
104+
105+
double NaluWind::get_timestep_size()
106+
{
107+
return m_sim.timeIntegrator_->get_time_step();
108+
}
109+
110+
void NaluWind::set_timestep_size(const double dt)
111+
{
112+
m_sim.timeIntegrator_->set_time_step(dt);
113+
}
114+
115+
bool NaluWind::is_fixed_timestep_size()
116+
{
117+
return m_sim.timeIntegrator_->get_is_fixed_time_step();
118+
}
119+
95120
void NaluWind::advance_timestep(size_t /*inonlin*/)
96121
{
97122
for (auto* realm : m_sim.timeIntegrator_->realmVec_) {

src/NaluWind.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class NaluWind : public ExawindSolver
5050
~NaluWind();
5151
bool is_unstructured() override { return true; }
5252
bool is_amr() override { return false; }
53+
bool is_fixed_timestep_size() override;
5354
int overset_update_interval() override;
5455
int time_index() override;
5556
std::string identifier() override
@@ -64,8 +65,12 @@ class NaluWind : public ExawindSolver
6465
void init_epilog() override;
6566
void prepare_solver_prolog() override;
6667
void prepare_solver_epilog() override;
68+
void pre_advance_stage0(size_t inonlin) override;
6769
void pre_advance_stage1(size_t inonlin) override;
6870
void pre_advance_stage2(size_t inonlin) override;
71+
double get_time() override;
72+
double get_timestep_size() override;
73+
void set_timestep_size(const double) override;
6974
void advance_timestep(size_t inonlin) override;
7075
void additional_picard_iterations(const int) override;
7176
void post_advance() override;

src/OversetSimulation.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,12 @@ void OversetSimulation::initialize()
8282
}
8383
m_last_timestep = m_solvers.at(0)->time_index();
8484

85-
MPI_Barrier(m_comm);
85+
// Determine if any of the solvers have adaptive timestepping
86+
for (auto& ss : m_solvers) {
87+
m_fixed_dt = m_fixed_dt && ss->is_fixed_timestep_size();
88+
}
89+
MPI_Allreduce(MPI_IN_PLACE, &m_fixed_dt, 1, MPI_C_BOOL, MPI_LAND, m_comm);
90+
8691
m_initialized = true;
8792
}
8893

@@ -127,7 +132,10 @@ void OversetSimulation::exchange_solution(bool increment_time)
127132
}
128133

129134
void OversetSimulation::run_timesteps(
130-
const int add_pic_its, const int nonlinear_its, const int nsteps)
135+
const int add_pic_its,
136+
const int nonlinear_its,
137+
const int nsteps,
138+
const double max_time)
131139
{
132140

133141
if (!m_initialized) {
@@ -140,7 +148,12 @@ void OversetSimulation::run_timesteps(
140148
"Running " + std::to_string(nsteps) + " timesteps starting from " +
141149
std::to_string(tstart));
142150

143-
for (int nt = tstart; nt < tend; ++nt) {
151+
int nt = tstart;
152+
double time = max_time < 0. ? 0. : m_solvers[0]->call_get_time();
153+
bool step_check = nsteps > 0 ? nt < tend : true;
154+
bool time_check = max_time > 0. ? time < max_time : true;
155+
bool do_step = step_check && time_check;
156+
while (do_step) {
144157
m_printer.echo_time_header();
145158

146159
m_timers_exa.tick("TimeStep");
@@ -150,6 +163,20 @@ void OversetSimulation::run_timesteps(
150163

151164
bool increment_timer = inonlin > 0 ? true : false;
152165

166+
double dt{1e8};
167+
for (auto& ss : m_solvers) {
168+
ss->call_pre_advance_stage0(inonlin, increment_timer);
169+
if (inonlin < 1 && !m_fixed_dt) {
170+
dt = std::min(dt, ss->call_get_timestep_size());
171+
}
172+
}
173+
174+
if (inonlin < 1 && !m_fixed_dt) {
175+
MPI_Allreduce(
176+
MPI_IN_PLACE, &dt, 1, MPI_DOUBLE, MPI_MIN, m_comm);
177+
for (auto& ss : m_solvers) ss->call_set_timestep_size(dt);
178+
}
179+
153180
for (auto& ss : m_solvers)
154181
ss->call_pre_advance_stage1(inonlin, increment_timer);
155182

@@ -183,6 +210,12 @@ void OversetSimulation::run_timesteps(
183210
MPI_Barrier(m_comm);
184211

185212
mem_usage_all(nt);
213+
214+
++nt;
215+
if (max_time > 0.) time = m_solvers[0]->call_get_time();
216+
step_check = nsteps > 0 ? nt < tend : true;
217+
time_check = max_time > 0. ? time < max_time : true;
218+
do_step = step_check && time_check;
186219
}
187220
for (auto& ss : m_solvers) ss->call_dump_simulation_time();
188221
m_last_timestep = tend;

src/OversetSimulation.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ class OversetSimulation
3030
int m_overset_update_interval{100000000};
3131
//! Last timestep run during this simulation
3232
int m_last_timestep{0};
33+
//! Flag indicating whether all solvers use fixed dt. If any solver uses
34+
//! adaptive dt, then this flag will be false
35+
bool m_fixed_dt{true};
3336
//! Flag indicating whether initialization tasks have been performed
3437
bool m_initialized{false};
3538
//! Flag indicating if complementary comms have been initialized
@@ -88,7 +91,8 @@ class OversetSimulation
8891
void run_timesteps(
8992
const int add_pic_its,
9093
const int nonlinear_its = 1,
91-
const int nsteps = 1);
94+
const int nsteps = 1,
95+
const double max_time = -1.);
9296

9397
//! Print something
9498
void echo(const std::string& out) { m_printer.echo(out); }

test/test_files/dam-break-block/dam-break-block-amr.inp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
time.stop_time = 2 # Max (simulated) time to evolve
22
time.max_step = 2000 # Max number of time steps
33

4-
time.fixed_dt = 0.005 # Use this constant dt if > 0
5-
time.cfl = 1.0 # CFL factor
4+
time.initial_dt = 0.01 # Use this constant dt if > 0
5+
time.cfl = 0.95 # CFL factor
66
time.use_force_cfl = false
77

88
time.plot_interval = 10 # Steps between plot files

test/test_files/dam-break-block/dam-break-block-nalu.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ realms:
3333
automatic_decomposition_type: rcb
3434
check_for_missing_bcs: yes
3535

36+
time_step_control:
37+
target_courant: 2.0
38+
time_step_change_factor: 1.2
39+
3640
equation_systems:
3741
name: theEqSys
3842
max_iterations: 3
@@ -132,8 +136,8 @@ Time_Integrators:
132136
name: ti_1
133137
start_time: 0.0
134138
termination_time: 2.0
135-
time_step: 0.005
136-
time_stepping_type: fixed
139+
time_step: 0.01
140+
time_stepping_type: adaptive
137141
time_step_count: 0
138142
second_order_accuracy: yes
139143

0 commit comments

Comments
 (0)