Skip to content

Commit f287f14

Browse files
authored
feat: restart (#278)
## Description This PR implements the restart feature. ## How has this been tested? - see `./tests/test_restart.cpp` - Most of the finite volume demos also have an example of how to use the restart. Three of them are tested during the CI: we restart from the init file and we check if the result is the same as the reference at the end of the computation. ## Code of Conduct By submitting this PR, you agree to follow our [Code of Conduct](https://github.com/hpc-maths/samurai/blob/master/docs/CODE_OF_CONDUCT.md) - [x] I agree to follow this project's Code of Conduct
1 parent 9958484 commit f287f14

File tree

75 files changed

+1708
-703
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1708
-703
lines changed

demos/FiniteVolume/AMR_Burgers_Hat.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
#include <samurai/bc.hpp>
1111
#include <samurai/box.hpp>
1212
#include <samurai/field.hpp>
13-
#include <samurai/hdf5.hpp>
13+
#include <samurai/io/hdf5.hpp>
14+
#include <samurai/io/restart.hpp>
1415
#include <samurai/samurai.hpp>
1516

1617
#include "stencil_field.hpp"
@@ -20,12 +21,13 @@
2021
#include <filesystem>
2122
namespace fs = std::filesystem;
2223

23-
template <class Mesh>
24-
auto init_solution(Mesh& mesh)
24+
template <class Field>
25+
void init_solution(Field& phi)
2526
{
26-
using mesh_id_t = typename Mesh::mesh_id_t;
27+
using mesh_id_t = typename Field::mesh_t::mesh_id_t;
2728

28-
auto phi = samurai::make_field<double, 1>("phi", mesh);
29+
auto& mesh = phi.mesh();
30+
phi.resize();
2931
phi.fill(0);
3032

3133
samurai::for_each_cell(mesh[mesh_id_t::cells],
@@ -47,8 +49,6 @@ auto init_solution(Mesh& mesh)
4749
// phi[cell] = u;
4850
phi[cell] = std::exp(-20. * x * x);
4951
});
50-
51-
return phi;
5252
}
5353

5454
template <class Field, class Tag>
@@ -140,6 +140,7 @@ void save(const fs::path& path, const std::string& filename, const Field& u, con
140140
});
141141

142142
samurai::save(path, fmt::format("{}{}", filename, suffix), mesh, u, level_);
143+
samurai::dump(path, fmt::format("{}_restart{}", filename, suffix), mesh, u);
143144
}
144145

145146
template <class Field>
@@ -203,6 +204,8 @@ int main(int argc, char* argv[])
203204
double right_box = 3;
204205
double Tf = 1.5; // We have blowup at t = 1
205206
double cfl = 0.99;
207+
double t = 0.;
208+
std::string restart_file;
206209

207210
// AMR parameters
208211
std::size_t start_level = 7;
@@ -218,7 +221,9 @@ int main(int argc, char* argv[])
218221
app.add_option("--left", left_box, "The left border of the box")->capture_default_str()->group("Simulation parameters");
219222
app.add_option("--right", right_box, "The right border of the box")->capture_default_str()->group("Simulation parameters");
220223
app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters");
224+
app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters");
221225
app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters");
226+
app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters");
222227
app.add_option("--start-level", start_level, "Start level of AMR")->capture_default_str()->group("AMR parameters");
223228
app.add_option("--min-level", min_level, "Minimum level of AMR")->capture_default_str()->group("AMR parameters");
224229
app.add_option("--max-level", max_level, "Maximum level of AMR")->capture_default_str()->group("AMR parameters");
@@ -231,9 +236,19 @@ int main(int argc, char* argv[])
231236
SAMURAI_PARSE(argc, argv);
232237

233238
const samurai::Box<double, dim> box({left_box}, {right_box});
234-
samurai::amr::Mesh<Config> mesh(box, start_level, min_level, max_level);
239+
samurai::amr::Mesh<Config> mesh;
240+
auto phi = samurai::make_field<double, 1>("phi", mesh);
241+
242+
if (restart_file.empty())
243+
{
244+
mesh = {box, start_level, min_level, max_level};
245+
init_solution(phi);
246+
}
247+
else
248+
{
249+
samurai::load(restart_file, mesh, phi);
250+
}
235251

236-
auto phi = init_solution(mesh);
237252
samurai::make_bc<samurai::Neumann<1>>(phi, 0.);
238253

239254
auto phinp1 = samurai::make_field<double, 1>("phi", mesh);
@@ -244,7 +259,6 @@ int main(int argc, char* argv[])
244259
const double dx = mesh.cell_length(max_level);
245260
double dt = 0.99 * dx;
246261
const double dt_save = Tf / static_cast<double>(nfiles);
247-
double t = 0.;
248262

249263
std::size_t nsave = 1;
250264
std::size_t nt = 0;

demos/FiniteVolume/BZ/bz_2d.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include <math.h>
77
#include <samurai/algorithm.hpp>
88
#include <samurai/field.hpp>
9-
#include <samurai/hdf5.hpp>
9+
#include <samurai/io/hdf5.hpp>
1010
#include <samurai/mr/adapt.hpp>
1111
#include <samurai/mr/mesh.hpp>
1212
#include <samurai/stencil_field.hpp>

demos/FiniteVolume/BZ/bz_2d_AMR.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <samurai/algorithm.hpp>
55
#include <samurai/cell_flag.hpp>
66
#include <samurai/field.hpp>
7-
#include <samurai/hdf5.hpp>
7+
#include <samurai/io/hdf5.hpp>
88
#include <samurai/mesh.hpp>
99
#include <samurai/mr/adapt.hpp>
1010
#include <samurai/mr/operators.hpp>

demos/FiniteVolume/advection_1d.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
#include <samurai/algorithm.hpp>
66
#include <samurai/bc.hpp>
77
#include <samurai/field.hpp>
8-
#include <samurai/hdf5.hpp>
8+
#include <samurai/io/hdf5.hpp>
9+
#include <samurai/io/restart.hpp>
910
#include <samurai/mr/adapt.hpp>
1011
#include <samurai/mr/mesh.hpp>
1112
#include <samurai/samurai.hpp>
@@ -15,11 +16,11 @@
1516
#include <filesystem>
1617
namespace fs = std::filesystem;
1718

18-
template <class Mesh>
19-
auto init(Mesh& mesh)
19+
template <class Field>
20+
void init(Field& u)
2021
{
21-
auto u = samurai::make_field<double, 1>("u", mesh);
22-
u.fill(0.);
22+
auto& mesh = u.mesh();
23+
u.resize();
2324

2425
samurai::for_each_cell(mesh,
2526
[&](auto& cell)
@@ -33,8 +34,6 @@ auto init(Mesh& mesh)
3334
u[cell] = 1;
3435
}
3536
});
36-
37-
return u;
3837
}
3938

4039
template <class Field>
@@ -105,6 +104,7 @@ void save(const fs::path& path, const std::string& filename, const Field& u, con
105104
});
106105

107106
samurai::save(path, fmt::format("{}{}", filename, suffix), mesh, u, level_);
107+
samurai::dump(path, fmt::format("{}_restart{}", filename, suffix), mesh, u);
108108
}
109109

110110
int main(int argc, char* argv[])
@@ -121,6 +121,8 @@ int main(int argc, char* argv[])
121121
double a = 1.;
122122
double Tf = 1.;
123123
double cfl = 0.95;
124+
double t = 0.;
125+
std::string restart_file;
124126

125127
// Multiresolution parameters
126128
std::size_t min_level = 6;
@@ -139,7 +141,9 @@ int main(int argc, char* argv[])
139141
app.add_flag("--periodic", is_periodic, "Set the domain periodic")->capture_default_str()->group("Simulation parameters");
140142
app.add_option("--velocity", a, "The velocity of the advection equation")->capture_default_str()->group("Simulation parameters");
141143
app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters");
144+
app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters");
142145
app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters");
146+
app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters");
143147
app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution");
144148
app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution");
145149
app.add_option("--mr-eps", mr_epsilon, "The epsilon used by the multiresolution to adapt the mesh")
@@ -160,14 +164,22 @@ int main(int argc, char* argv[])
160164
SAMURAI_PARSE(argc, argv);
161165

162166
const samurai::Box<double, dim> box({left_box}, {right_box});
167+
samurai::MRMesh<Config> mesh;
168+
auto u = samurai::make_field<double, 1>("u", mesh);
163169

164-
samurai::MRMesh<Config> mesh(box, min_level, max_level, std::array<bool, dim>{is_periodic});
170+
if (restart_file.empty())
171+
{
172+
mesh = {box, min_level, max_level, std::array<bool, dim>{is_periodic}};
173+
init(u);
174+
}
175+
else
176+
{
177+
samurai::load(restart_file, mesh, u);
178+
}
165179

166180
double dt = cfl * mesh.cell_length(max_level);
167181
const double dt_save = Tf / static_cast<double>(nfiles);
168-
double t = 0.;
169182

170-
auto u = init(mesh);
171183
if (!is_periodic)
172184
{
173185
const xt::xtensor_fixed<int, xt::xshape<1>> left{-1};

demos/FiniteVolume/advection_2d.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#include <samurai/algorithm.hpp>
99
#include <samurai/bc.hpp>
1010
#include <samurai/field.hpp>
11-
#include <samurai/hdf5.hpp>
11+
#include <samurai/io/hdf5.hpp>
12+
#include <samurai/io/restart.hpp>
1213
#include <samurai/mr/adapt.hpp>
1314
#include <samurai/mr/mesh.hpp>
1415
#include <samurai/samurai.hpp>
@@ -18,10 +19,11 @@
1819
#include <filesystem>
1920
namespace fs = std::filesystem;
2021

21-
template <class Mesh>
22-
auto init(Mesh& mesh)
22+
template <class Field>
23+
void init(Field& u)
2324
{
24-
auto u = samurai::make_field<double, 1>("u", mesh);
25+
auto& mesh = u.mesh();
26+
u.resize();
2527

2628
samurai::for_each_cell(
2729
mesh,
@@ -40,8 +42,6 @@ auto init(Mesh& mesh)
4042
u[cell] = 0;
4143
}
4244
});
43-
44-
return u;
4545
}
4646

4747
template <class Field>
@@ -164,6 +164,7 @@ void save(const fs::path& path, const std::string& filename, const Field& u, con
164164
samurai::save(path, fmt::format("{}_size_{}{}", filename, world.size(), suffix), mesh, u, level_);
165165
#else
166166
samurai::save(path, fmt::format("{}{}", filename, suffix), mesh, u, level_);
167+
samurai::dump(path, fmt::format("{}_restart{}", filename, suffix), mesh, u);
167168
#endif
168169
}
169170

@@ -182,6 +183,8 @@ int main(int argc, char* argv[])
182183
};
183184
double Tf = .1;
184185
double cfl = 0.5;
186+
double t = 0.;
187+
std::string restart_file;
185188

186189
// Multiresolution parameters
187190
std::size_t min_level = 4;
@@ -199,7 +202,9 @@ int main(int argc, char* argv[])
199202
app.add_option("--max-corner", max_corner, "The max corner of the box")->capture_default_str()->group("Simulation parameters");
200203
app.add_option("--velocity", a, "The velocity of the advection equation")->capture_default_str()->group("Simulation parameters");
201204
app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters");
205+
app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters");
202206
app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters");
207+
app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters");
203208
app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution");
204209
app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution");
205210
app.add_option("--mr-eps", mr_epsilon, "The epsilon used by the multiresolution to adapt the mesh")
@@ -220,14 +225,23 @@ int main(int argc, char* argv[])
220225
SAMURAI_PARSE(argc, argv);
221226

222227
const samurai::Box<double, dim> box(min_corner, max_corner);
223-
samurai::MRMesh<Config> mesh{box, min_level, max_level};
228+
samurai::MRMesh<Config> mesh;
229+
auto u = samurai::make_field<double, 1>("u", mesh);
230+
231+
if (restart_file.empty())
232+
{
233+
mesh = {box, min_level, max_level};
234+
init(u);
235+
}
236+
else
237+
{
238+
samurai::load(restart_file, mesh, u);
239+
}
240+
samurai::make_bc<samurai::Dirichlet<1>>(u, 0.);
224241

225242
double dt = cfl * mesh.cell_length(max_level);
226243
const double dt_save = Tf / static_cast<double>(nfiles);
227-
double t = 0.;
228244

229-
auto u = init(mesh);
230-
samurai::make_bc<samurai::Dirichlet<1>>(u, 0.);
231245
auto unp1 = samurai::make_field<double, 1>("unp1", mesh);
232246

233247
auto MRadaptation = samurai::make_MRAdapt(u);

demos/FiniteVolume/advection_2d_user_bc.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
#include <samurai/algorithm.hpp>
1010
#include <samurai/bc.hpp>
1111
#include <samurai/field.hpp>
12-
#include <samurai/hdf5.hpp>
12+
#include <samurai/io/hdf5.hpp>
13+
#include <samurai/io/restart.hpp>
1314
#include <samurai/mr/adapt.hpp>
1415
#include <samurai/mr/mesh.hpp>
1516
#include <samurai/samurai.hpp>
@@ -43,10 +44,11 @@ struct Mybc : public samurai::Bc<Field>
4344
}
4445
};
4546

46-
template <class Mesh>
47-
auto init(Mesh& mesh)
47+
template <class Field>
48+
void init(Field& u)
4849
{
49-
auto u = samurai::make_field<double, 1>("u", mesh);
50+
auto& mesh = u.mesh();
51+
u.resize();
5052

5153
samurai::for_each_cell(
5254
mesh,
@@ -65,8 +67,6 @@ auto init(Mesh& mesh)
6567
u[cell] = 0;
6668
}
6769
});
68-
69-
return u;
7070
}
7171

7272
template <class Field>
@@ -186,6 +186,7 @@ void save(const fs::path& path, const std::string& filename, const Field& u, con
186186
});
187187

188188
samurai::save(path, fmt::format("{}{}", filename, suffix), mesh, u, level_);
189+
samurai::dump(path, fmt::format("{}_restart{}", filename, suffix), mesh, u);
189190
}
190191

191192
int main(int argc, char* argv[])
@@ -203,6 +204,8 @@ int main(int argc, char* argv[])
203204
};
204205
double Tf = .1;
205206
double cfl = 0.5;
207+
double t = 0.;
208+
std::string restart_file;
206209

207210
// Multiresolution parameters
208211
std::size_t min_level = 4;
@@ -220,7 +223,9 @@ int main(int argc, char* argv[])
220223
app.add_option("--max-corner", max_corner, "The max corner of the box")->capture_default_str()->group("Simulation parameters");
221224
app.add_option("--velocity", a, "The velocity of the advection equation")->capture_default_str()->group("Simulation parameters");
222225
app.add_option("--cfl", cfl, "The CFL")->capture_default_str()->group("Simulation parameters");
226+
app.add_option("--Ti", t, "Initial time")->capture_default_str()->group("Simulation parameters");
223227
app.add_option("--Tf", Tf, "Final time")->capture_default_str()->group("Simulation parameters");
228+
app.add_option("--restart-file", restart_file, "Restart file")->capture_default_str()->group("Simulation parameters");
224229
app.add_option("--min-level", min_level, "Minimum level of the multiresolution")->capture_default_str()->group("Multiresolution");
225230
app.add_option("--max-level", max_level, "Maximum level of the multiresolution")->capture_default_str()->group("Multiresolution");
226231
app.add_option("--mr-eps", mr_epsilon, "The epsilon used by the multiresolution to adapt the mesh")
@@ -241,14 +246,23 @@ int main(int argc, char* argv[])
241246
SAMURAI_PARSE(argc, argv);
242247

243248
const samurai::Box<double, dim> box(min_corner, max_corner);
244-
samurai::MRMesh<Config> mesh{box, min_level, max_level};
249+
samurai::MRMesh<Config> mesh;
250+
auto u = samurai::make_field<double, 1>("u", mesh);
251+
252+
if (restart_file.empty())
253+
{
254+
mesh = {box, min_level, max_level};
255+
init(u);
256+
}
257+
else
258+
{
259+
samurai::load(restart_file, mesh, u);
260+
}
261+
samurai::make_bc<Mybc>(u, 0.);
245262

246263
double dt = cfl * mesh.cell_length(max_level);
247264
const double dt_save = Tf / static_cast<double>(nfiles);
248-
double t = 0.;
249265

250-
auto u = init(mesh);
251-
samurai::make_bc<Mybc>(u, 0.);
252266
auto unp1 = samurai::make_field<double, 1>("unp1", mesh);
253267

254268
auto MRadaptation = samurai::make_MRAdapt(u);

0 commit comments

Comments
 (0)