/__w/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/timestepping/abstract_timestepper.hh Source File#

DiFfRG: /__w/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/timestepping/abstract_timestepper.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
abstract_timestepper.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
11#include <algorithm>
12#include <cmath>
13#include <limits>
14#include <optional>
15#include <unordered_map>
16
17namespace DiFfRG
18{
51 template <typename VectorType_, typename SparseMatrixType_, uint dim_> class AbstractTimestepper
52 {
53 protected:
54 static constexpr uint dim = dim_;
55 using VectorType = VectorType_;
57 using SparseMatrixType = SparseMatrixType_;
59 static_assert(std::is_same_v<VectorType, Vector<NumberType>>, "VectorType must not be Vector<double>!");
60 using BlockVectorType = dealii::BlockVector<NumberType>;
61
62 public:
74 start_time(std::chrono::high_resolution_clock::now())
75 {
76 verbosity = json.get_int("/output/verbosity");
77 output_dt = json.get_double("/timestepping/output_dt");
78
79 impl.dt = json.get_double("/timestepping/implicit/dt");
80 impl.minimal_dt = json.get_double("/timestepping/implicit/minimal_dt");
81 impl.maximal_dt = json.get_double("/timestepping/implicit/maximal_dt");
82 impl.abs_tol = json.get_double("/timestepping/implicit/abs_tol");
83 impl.rel_tol = json.get_double("/timestepping/implicit/rel_tol");
84 impl.max_steps = json.get_uint("/timestepping/implicit/max_steps", 1000000);
85
86 expl.dt = json.get_double("/timestepping/explicit/dt");
87 expl.minimal_dt = json.get_double("/timestepping/explicit/minimal_dt");
88 expl.maximal_dt = json.get_double("/timestepping/explicit/maximal_dt");
89 expl.abs_tol = json.get_double("/timestepping/explicit/abs_tol");
90 expl.rel_tol = json.get_double("/timestepping/explicit/rel_tol");
91
92 try {
93 Lambda = json.get_double("/physical/Lambda");
94 } catch (std::exception &e) {
95 Lambda = -1.0;
96 }
97 }
98
106 {
107 if (data_out == nullptr) {
108 data_out_default = std::make_shared<DataOutput<dim, VectorType>>(json);
109 return data_out_default.get();
110 }
111 return data_out;
112 }
113
121 {
122 if (adaptor == nullptr) {
123 adaptor_default = std::make_shared<NoAdaptivity<VectorType>>();
124 return adaptor_default.get();
125 }
126 return adaptor;
127 }
128
136 virtual void run(AbstractFlowingVariables<NumberType> *initial_condition, const double t_start,
137 const double t_stop) = 0;
138
139 protected:
144
145 const std::chrono::time_point<std::chrono::high_resolution_clock> start_time;
146
147 std::shared_ptr<NoAdaptivity<VectorType>> adaptor_default;
148 std::shared_ptr<DataOutput<dim, VectorType>> data_out_default;
149
150 double Lambda;
152 double output_dt;
161
163 double dt;
166 double abs_tol;
167 double rel_tol;
169
170 static constexpr size_t console_name_width = 21;
171
173 size_t first_ms = 0;
174 size_t last_ms = 0;
175 double latest_t = 0.;
176 size_t calls = 0;
177 size_t calc_dt_calls = 0;
178 double calc_dt_sum_ms = 0.;
179 double calc_dt_min_ms = std::numeric_limits<double>::max();
180 double calc_dt_max_ms = 0.;
181 bool has_calc_dt = false;
182
183 void add(const double t, const size_t milliseconds, const double calc_dt_ms)
184 {
185 if (calls == 0) first_ms = milliseconds;
186 last_ms = milliseconds;
187 latest_t = t;
188 ++calls;
189
190 if (calc_dt_ms < 0.) return;
191 has_calc_dt = true;
193 calc_dt_sum_ms += calc_dt_ms;
194 calc_dt_min_ms = std::min(calc_dt_min_ms, calc_dt_ms);
195 calc_dt_max_ms = std::max(calc_dt_max_ms, calc_dt_ms);
196 }
197
198 double mean_calc_dt_ms() const { return calc_dt_sum_ms / double(calc_dt_calls); }
199 double calc_dt_uncertainty_ms() const { return 0.5 * (calc_dt_max_ms - calc_dt_min_ms); }
200 };
201
202 mutable std::unordered_map<std::string, ConsoleOutStats> console_out_stats_by_category;
203
204 static std::string console_out_category(const std::string &name) { return name.substr(0, name.find(" (")); }
205
206 static std::string format_uncertain_ms(const double mean_ms, const double uncertainty_ms)
207 {
208 const double abs_uncertainty = std::abs(uncertainty_ms);
209 const bool has_uncertainty = abs_uncertainty > 0.;
210 int decimals = 0;
211 long rounded_uncertainty = 0;
212
213 if (has_uncertainty) {
214 double exponent = std::floor(std::log10(abs_uncertainty));
215 double scale = std::pow(10., -exponent);
216 rounded_uncertainty = long(std::round(abs_uncertainty * scale));
217 if (rounded_uncertainty >= 10) {
218 exponent += 1.;
219 scale = std::pow(10., -exponent);
220 rounded_uncertainty = long(std::round(abs_uncertainty * scale));
221 }
222 decimals = std::max(0, int(-exponent));
223 } else if (std::abs(mean_ms) < 1.) {
224 decimals = 2;
225 } else if (std::abs(mean_ms) < 100.) {
226 decimals = 1;
227 }
228
229 std::stringstream stream;
230 stream << std::fixed << std::setprecision(decimals) << mean_ms << "(" << rounded_uncertainty << ")ms";
231 return stream.str();
232 }
233
234 void print_console_out(const std::string &name, const double t, const size_t milliseconds,
235 const std::optional<std::string> calc_dt = std::nullopt, const size_t calls = 0) const
236 {
237 if (name.size() > console_name_width) throw std::runtime_error("console_out: log label is too long: " + name);
238
239 const std::ios_base::fmtflags oldflags = std::cout.flags();
240 const std::streamsize oldprecision = std::cout.precision();
241 std::cout << "[" << std::setw(console_name_width) << std::left << name << "]";
242 std::cout << " t: " << std::setw(10) << std::left << std::setprecision(4) << std::scientific << t;
243 if (Lambda > 0.0) {
244 std::cout << " | k: " << std::setw(10) << std::left << std::setprecision(4) << std::scientific
245 << exp(-t) * Lambda;
246 }
247 if (calc_dt.has_value()) {
248 std::cout << " | calc_dt: " << std::setw(11) << calc_dt.value();
249 }
250 if (calls > 0) {
251 std::cout << " | calls: " << std::setw(4) << calls;
252 }
253 std::cout << " | calc_t: " << time_format_ms(milliseconds);
254 std::cout << std::endl;
255 std::cout.flags(oldflags);
256 std::cout.precision(oldprecision);
257 }
258
267 void console_out(const double t, const std::string name, const int verbosity_level,
268 const double calc_dt_ms = -1.0) const
269 {
270 if (verbosity < verbosity_level) return;
271
272 const size_t milliseconds =
273 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start_time)
274 .count();
275 if (verbosity >= 4) {
276 const auto calc_dt =
277 calc_dt_ms >= 0.0 ? std::optional<std::string>(time_format_ms(size_t(calc_dt_ms))) : std::nullopt;
278 print_console_out(name, t, milliseconds, calc_dt);
279 return;
280 }
281
282 const std::string category = console_out_category(name);
283 auto &stats = console_out_stats_by_category[category];
284 stats.add(t, milliseconds, calc_dt_ms);
285 if (milliseconds - stats.first_ms < 1000) return;
286
287 const auto calc_dt =
288 stats.has_calc_dt
289 ? std::optional<std::string>(format_uncertain_ms(stats.mean_calc_dt_ms(), stats.calc_dt_uncertainty_ms()))
290 : std::nullopt;
291 print_console_out(category, stats.latest_t, stats.last_ms, calc_dt, stats.calls);
292 stats = {};
293 }
294 };
295} // namespace DiFfRG
Implement a simple interface to do all adaptivity tasks, i.e. solution transfer, reinit of dofHandler...
Definition abstract_adaptor.hh:11
This is the general assembler interface for any kind of discretization. An assembler is responsible f...
Definition abstract_assembler.hh:40
A class to set up initial data for whatever discretization we have chosen. Also used to switch/manage...
Definition abstract_data.hh:18
The abstract base class for all timestepping algorithms. It provides a standard constructor which pop...
Definition abstract_timestepper.hh:52
VectorType_ VectorType
Definition abstract_timestepper.hh:55
dealii::BlockVector< NumberType > BlockVectorType
Definition abstract_timestepper.hh:60
int verbosity
Definition abstract_timestepper.hh:151
AbstractAssembler< VectorType, SparseMatrixType, dim > * assembler
Definition abstract_timestepper.hh:141
struct DiFfRG::AbstractTimestepper::ExplicitParameters expl
std::shared_ptr< DataOutput< dim, VectorType > > data_out_default
Definition abstract_timestepper.hh:148
double Lambda
Definition abstract_timestepper.hh:150
static std::string format_uncertain_ms(const double mean_ms, const double uncertainty_ms)
Definition abstract_timestepper.hh:206
void console_out(const double t, const std::string name, const int verbosity_level, const double calc_dt_ms=-1.0) const
Pretty-print the status of the timestepping algorithm to the console.
Definition abstract_timestepper.hh:267
SparseMatrixType_ SparseMatrixType
Definition abstract_timestepper.hh:57
DataOutput< dim, VectorType > * data_out
Definition abstract_timestepper.hh:142
static std::string console_out_category(const std::string &name)
Definition abstract_timestepper.hh:204
const std::chrono::time_point< std::chrono::high_resolution_clock > start_time
Definition abstract_timestepper.hh:145
AbstractTimestepper(const JSONValue &json, AbstractAssembler< VectorType, SparseMatrixType, dim > *assembler, DataOutput< dim, VectorType > *data_out=nullptr, AbstractAdaptor< VectorType > *adaptor=nullptr)
Construct a new Abstract Timestepper object.
Definition abstract_timestepper.hh:71
AbstractAdaptor< VectorType > * adaptor
Definition abstract_timestepper.hh:143
std::shared_ptr< NoAdaptivity< VectorType > > adaptor_default
Definition abstract_timestepper.hh:147
virtual void run(AbstractFlowingVariables< NumberType > *initial_condition, const double t_start, const double t_stop)=0
Any derived class must implement this method to run the timestepping algorithm.
typename get_type::NumberType< VectorType > NumberType
Definition abstract_timestepper.hh:56
DataOutput< dim, VectorType > * get_data_out()
Utility function to obtain a DataOutput object. If no DataOutput object is provided,...
Definition abstract_timestepper.hh:105
typename get_type::InverseSparseMatrixType< SparseMatrixType > InverseSparseMatrixType
Definition abstract_timestepper.hh:58
AbstractAdaptor< VectorType > * get_adaptor()
Utility function to obtain an Adaptor object. If no Adaptor object is provided, a default one is crea...
Definition abstract_timestepper.hh:120
void print_console_out(const std::string &name, const double t, const size_t milliseconds, const std::optional< std::string > calc_dt=std::nullopt, const size_t calls=0) const
Definition abstract_timestepper.hh:234
const JSONValue json
Definition abstract_timestepper.hh:140
static constexpr size_t console_name_width
Definition abstract_timestepper.hh:170
struct DiFfRG::AbstractTimestepper::ImplicitParameters impl
static constexpr uint dim
Definition abstract_timestepper.hh:54
std::unordered_map< std::string, ConsoleOutStats > console_out_stats_by_category
Definition abstract_timestepper.hh:202
double output_dt
Definition abstract_timestepper.hh:152
Class to manage writing to files. FEM functions are written to vtk files and other data is written to...
Definition data_output.hh:20
A wrapper around the boost json value class.
Definition json.hh:19
double get_double(const std::string &key) const
Get the value of a key in the json object.
int get_int(const std::string &key) const
Get the value of a key in the json object.
uint get_uint(const std::string &key) const
Get the value of a key in the json object.
typename internal::_InverseSparseMatrixType< SparseMatrixType >::value InverseSparseMatrixType
Definition types.hh:92
typename internal::_NumberType< VectorType >::value NumberType
Definition types.hh:86
Definition complex_math.hh:10
std::string time_format_ms(size_t time_in_miliseconds)
Nice output from seconds to h/min/s style string.
unsigned int uint
Definition utils.hh:24
Definition abstract_timestepper.hh:172
void add(const double t, const size_t milliseconds, const double calc_dt_ms)
Definition abstract_timestepper.hh:183
double calc_dt_sum_ms
Definition abstract_timestepper.hh:178
double calc_dt_uncertainty_ms() const
Definition abstract_timestepper.hh:199
size_t first_ms
Definition abstract_timestepper.hh:173
size_t calls
Definition abstract_timestepper.hh:176
double calc_dt_min_ms
Definition abstract_timestepper.hh:179
double calc_dt_max_ms
Definition abstract_timestepper.hh:180
bool has_calc_dt
Definition abstract_timestepper.hh:181
size_t last_ms
Definition abstract_timestepper.hh:174
size_t calc_dt_calls
Definition abstract_timestepper.hh:177
double mean_calc_dt_ms() const
Definition abstract_timestepper.hh:198
double latest_t
Definition abstract_timestepper.hh:175
Definition abstract_timestepper.hh:162
double abs_tol
Definition abstract_timestepper.hh:166
double minimal_dt
Definition abstract_timestepper.hh:164
double dt
Definition abstract_timestepper.hh:163
double maximal_dt
Definition abstract_timestepper.hh:165
double rel_tol
Definition abstract_timestepper.hh:167
Definition abstract_timestepper.hh:153
double dt
Definition abstract_timestepper.hh:154
double maximal_dt
Definition abstract_timestepper.hh:156
double minimal_dt
Definition abstract_timestepper.hh:155
double rel_tol
Definition abstract_timestepper.hh:158
uint max_steps
Definition abstract_timestepper.hh:159
double abs_tol
Definition abstract_timestepper.hh:157