version 3.11-dev
Loading...
Searching...
No Matches
multistagemethods.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6// SPDX-FileCopyrightText: Copyright © dune-pdelab developers, see LICENSE.md (permalink below)
7// SPDX-License-Identifier: GPL-3.0-or-later
8// The code is based on the implementation of time stepping method parameters
9// in dune-pdelab (https://archive.softwareheritage.org/swh:1:cnt:9c3d72412f8e4d48d84a0090b2bb4362b5a0d843)
10// licensed under GPL-3.0-or-later, see their LICENSE.md for a full list of copyright holders at
11// https://archive.softwareheritage.org/swh:1:cnt:b11b484e74eefe20c74f7043309b1b02853df2eb.
12// Modifications (different interface naming, comments, types) are licensed under GPL-3.0-or-later.
13//
20#ifndef DUMUX_TIMESTEPPING_MULTISTAGE_METHODS_HH
21#define DUMUX_TIMESTEPPING_MULTISTAGE_METHODS_HH
22
23#include <cmath>
24#include <string>
25#include <array>
26
27namespace Dumux::Experimental {
28
73template<class Scalar>
75{
76public:
77 virtual bool implicit () const = 0;
78
79 virtual std::size_t numStages () const = 0;
80
82 virtual Scalar temporalWeight (std::size_t i, std::size_t k) const = 0;
83
85 virtual Scalar spatialWeight (std::size_t i, std::size_t k) const = 0;
86
88 virtual Scalar timeStepWeight (std::size_t k) const = 0;
89
90 virtual std::string name () const = 0;
91
92 virtual ~MultiStageMethod() = default;
93};
94
96namespace MultiStage {
97
104template<class Scalar>
105class Theta : public MultiStageMethod<Scalar>
106{
107public:
108 explicit Theta(const Scalar theta)
109 : paramAlpha_{{-1.0, 1.0}}
110 , paramBeta_{{1.0-theta, theta}}
111 , paramD_{{0.0, 1.0}}
112 {}
113
114 bool implicit () const final
115 { return paramBeta_[1] > 0.0; }
116
117 std::size_t numStages () const final
118 { return 1; }
119
120 Scalar temporalWeight (std::size_t, std::size_t k) const final
121 { return paramAlpha_[k]; }
122
123 Scalar spatialWeight (std::size_t, std::size_t k) const final
124 { return paramBeta_[k]; }
125
126 Scalar timeStepWeight (std::size_t k) const final
127 { return paramD_[k]; }
128
129 std::string name () const override
130 { return "theta scheme"; }
131
132private:
133 std::array<Scalar, 2> paramAlpha_;
134 std::array<Scalar, 2> paramBeta_;
135 std::array<Scalar, 2> paramD_;
136};
137
141template<class Scalar>
142class ExplicitEuler final : public Theta<Scalar>
143{
144public:
145 ExplicitEuler() : Theta<Scalar>(0.0) {}
146
147 std::string name () const final
148 { return "explicit Euler"; }
149};
150
154template<class Scalar>
155class ImplicitEuler final : public Theta<Scalar>
156{
157public:
158 ImplicitEuler() : Theta<Scalar>(1.0) {}
159
160 std::string name () const final
161 { return "implicit Euler"; }
162};
163
167template<class Scalar>
169{
170public:
172 : paramAlpha_{{{-1.0, 1.0, 0.0},
173 {-1.0, 0.0, 1.0}}}
174 , paramBeta_{{{1.0, 0.0, 0.0},
175 {0.5, 0.5, 0.0}}}
176 , paramD_{{0.0, 1.0, 1.0}}
177 {}
178
179 bool implicit () const final
180 { return false; }
181
182 std::size_t numStages () const final
183 { return 2; }
184
185 Scalar temporalWeight (std::size_t i, std::size_t k) const final
186 { return paramAlpha_[i-1][k]; }
187
188 Scalar spatialWeight (std::size_t i, std::size_t k) const final
189 { return paramBeta_[i-1][k]; }
190
191 Scalar timeStepWeight (std::size_t k) const final
192 { return paramD_[k]; }
193
194 std::string name () const final
195 { return "explicit Runge-Kutta 2nd order (Heun)"; }
196
197private:
198 std::array<std::array<Scalar, 3>, 2> paramAlpha_;
199 std::array<std::array<Scalar, 3>, 2> paramBeta_;
200 std::array<Scalar, 3> paramD_;
201};
202
206template<class Scalar>
208{
209public:
211 : paramAlpha_{{{-1.0, 1.0, 0.0, 0.0},
212 {-1.0, 0.0, 1.0, 0.0},
213 {-1.0, 0.0, 0.0, 1.0}}}
214 , paramBeta_{{{0.5, 0.0, 0.0, 0.0},
215 {-1.0, 2.0, 0.0, 0.0},
216 {1.0/6.0, 2.0/3.0, 1.0/6.0, 0.0}}}
217 , paramD_{{0.0, 0.5, 1.0, 1.0}}
218 {}
219
220 bool implicit () const final
221 { return false; }
222
223 std::size_t numStages () const final
224 { return 3; }
225
226 Scalar temporalWeight (std::size_t i, std::size_t k) const final
227 { return paramAlpha_[i-1][k]; }
228
229 Scalar spatialWeight (std::size_t i, std::size_t k) const final
230 { return paramBeta_[i-1][k]; }
231
232 Scalar timeStepWeight (std::size_t k) const final
233 { return paramD_[k]; }
234
235 std::string name () const final
236 { return "explicit Runge-Kutta 3rd order"; }
237
238private:
239 std::array<std::array<Scalar, 4>, 3> paramAlpha_;
240 std::array<std::array<Scalar, 4>, 3> paramBeta_;
241 std::array<Scalar, 4> paramD_;
242};
243
247template<class Scalar>
249{
250public:
252 : paramAlpha_{{{-1.0, 1.0, 0.0, 0.0, 0.0},
253 {-1.0, 0.0, 1.0, 0.0, 0.0},
254 {-1.0, 0.0, 0.0, 1.0, 0.0},
255 {-1.0, 0.0, 0.0, 0.0, 1.0}}}
256 , paramBeta_{{{0.5, 0.0, 0.0, 0.0, 0.0},
257 {0.0, 0.5, 0.0, 0.0, 0.0},
258 {0.0, 0.0, 1.0, 0.0, 0.0},
259 {1.0/6.0, 1.0/3.0, 1.0/3.0, 1.0/6.0, 0.0}}}
260 , paramD_{{0.0, 0.5, 0.5, 1.0, 1.0}}
261 {}
262
263 bool implicit () const final
264 { return false; }
265
266 std::size_t numStages () const final
267 { return 4; }
268
269 Scalar temporalWeight (std::size_t i, std::size_t k) const final
270 { return paramAlpha_[i-1][k]; }
271
272 Scalar spatialWeight (std::size_t i, std::size_t k) const final
273 { return paramBeta_[i-1][k]; }
274
275 Scalar timeStepWeight (std::size_t k) const final
276 { return paramD_[k]; }
277
278 std::string name () const final
279 { return "explicit Runge-Kutta 4th order"; }
280
281private:
282 std::array<std::array<Scalar, 5>, 4> paramAlpha_;
283 std::array<std::array<Scalar, 5>, 4> paramBeta_;
284 std::array<Scalar, 5> paramD_;
285};
286
287
292template<class Scalar>
293class DIRKSecondOrderAlexander final : public MultiStageMethod<Scalar>
294{
295public:
297 {
298 using std::sqrt;
299 const Scalar gamma = 1.0 - 1.0/sqrt(2.0);
300
301 paramD_ = {{0.0, gamma, 1.0}};
302 paramAlpha_ = {{
303 {-1.0, 1.0, 0.0},
304 {-1.0, 0.0, 1.0}
305 }};
306 paramBeta_ = {{
307 {0.0, gamma, 0.0},
308 {0.0, 1.0-gamma, gamma}
309 }};
310 }
311
312 bool implicit () const final
313 { return true; }
314
315 std::size_t numStages () const final
316 { return 2; }
317
318 Scalar temporalWeight (std::size_t i, std::size_t k) const final
319 { return paramAlpha_[i-1][k]; }
320
321 Scalar spatialWeight (std::size_t i, std::size_t k) const final
322 { return paramBeta_[i-1][k]; }
323
324 Scalar timeStepWeight (std::size_t k) const final
325 { return paramD_[k]; }
326
327 std::string name () const final
328 { return "diagonally implicit Runge-Kutta 2nd order (Alexander)"; }
329
330private:
331 std::array<std::array<Scalar, 3>, 2> paramAlpha_;
332 std::array<std::array<Scalar, 3>, 2> paramBeta_;
333 std::array<Scalar, 3> paramD_;
334};
335
340template<class Scalar>
341class DIRKThirdOrderAlexander final : public MultiStageMethod<Scalar>
342{
343public:
345 {
346 constexpr Scalar alpha = []{
347 // Newton iteration for alpha
348 Scalar alpha = 0.4358665215; // initial guess
349 for (int i = 0; i < 10; ++i)
350 alpha = alpha - (alpha*(alpha*alpha-3.0*(alpha-0.5))-1.0/6.0)/(3.0*alpha*(alpha-2.0)+1.5);
351 return alpha;
352 }();
353
354 constexpr Scalar tau2 = (1.0+alpha)*0.5;
355 constexpr Scalar b1 = -(6.0*alpha*alpha -16.0*alpha + 1.0)*0.25;
356 constexpr Scalar b2 = (6*alpha*alpha - 20.0*alpha + 5.0)*0.25;
357
358 paramD_ = {{0.0, alpha, tau2, 1.0}};
359 paramAlpha_ = {{
360 {-1.0, 1.0, 0.0, 0.0},
361 {-1.0, 0.0, 1.0, 0.0},
362 {-1.0, 0.0, 0.0, 1.0}
363 }};
364 paramBeta_ = {{
365 {0.0, alpha, 0.0, 0.0},
366 {0.0, tau2-alpha, alpha, 0.0},
367 {0.0, b1, b2, alpha}
368 }};
369 }
370
371 bool implicit () const final
372 { return true; }
373
374 std::size_t numStages () const final
375 { return 3; }
376
377 Scalar temporalWeight (std::size_t i, std::size_t k) const final
378 { return paramAlpha_[i-1][k]; }
379
380 Scalar spatialWeight (std::size_t i, std::size_t k) const final
381 { return paramBeta_[i-1][k]; }
382
383 Scalar timeStepWeight (std::size_t k) const final
384 { return paramD_[k]; }
385
386 std::string name () const final
387 { return "diagonally implicit Runge-Kutta 3rd order (Alexander)"; }
388
389private:
390 std::array<std::array<Scalar, 4>, 3> paramAlpha_;
391 std::array<std::array<Scalar, 4>, 3> paramBeta_;
392 std::array<Scalar, 4> paramD_;
393};
394
416template<class Scalar>
417class QinZhangSymplecticDIRK final : public MultiStageMethod<Scalar>
418{
419public:
421 : paramAlpha_{{
422 {-1.0, 1.0, 0.0, 0.0},
423 {-1.0, 0.0, 1.0, 0.0},
424 {-1.0, 0.0, 0.0, 1.0}
425 }}
426 , paramBeta_{{
427 {0.0, 0.25, 0.0, 0.0}, // stage 1: a_11 = 1/4
428 {0.0, 0.5, 0.25, 0.0}, // stage 2: a_21 = 1/2, a_22 = 1/4
429 {0.0, 0.5, 0.5, 0.0} // update: b_1 = 1/2, b_2 = 1/2
430 }}
431 , paramD_{{0.0, 0.25, 0.75, 1.0}}
432 {}
433
434 bool implicit () const final
435 { return true; }
436
437 std::size_t numStages () const final
438 { return 3; }
439
440 Scalar temporalWeight (std::size_t i, std::size_t k) const final
441 { return paramAlpha_[i-1][k]; }
442
443 Scalar spatialWeight (std::size_t i, std::size_t k) const final
444 { return paramBeta_[i-1][k]; }
445
446 Scalar timeStepWeight (std::size_t k) const final
447 { return paramD_[k]; }
448
449 std::string name () const final
450 { return "symplectic diagonally implicit Runge-Kutta 2nd order (Qin-Zhang)"; }
451
452private:
453 std::array<std::array<Scalar, 4>, 3> paramAlpha_;
454 std::array<std::array<Scalar, 4>, 3> paramBeta_;
455 std::array<Scalar, 4> paramD_;
456};
457
458} // end namespace MultiStage
459} // end namespace Dumux::Experimental
460
461#endif
DIRKSecondOrderAlexander()
Definition multistagemethods.hh:296
Scalar timeStepWeight(std::size_t k) const final
time step weights for each stage ( )
Definition multistagemethods.hh:324
std::size_t numStages() const final
Definition multistagemethods.hh:315
bool implicit() const final
Definition multistagemethods.hh:312
std::string name() const final
Definition multistagemethods.hh:327
Scalar spatialWeight(std::size_t i, std::size_t k) const final
weights of the spatial operator residual ( )
Definition multistagemethods.hh:321
Scalar temporalWeight(std::size_t i, std::size_t k) const final
weights of the temporal operator residual ( )
Definition multistagemethods.hh:318
bool implicit() const final
Definition multistagemethods.hh:371
DIRKThirdOrderAlexander()
Definition multistagemethods.hh:344
Scalar temporalWeight(std::size_t i, std::size_t k) const final
weights of the temporal operator residual ( )
Definition multistagemethods.hh:377
Scalar spatialWeight(std::size_t i, std::size_t k) const final
weights of the spatial operator residual ( )
Definition multistagemethods.hh:380
Scalar timeStepWeight(std::size_t k) const final
time step weights for each stage ( )
Definition multistagemethods.hh:383
std::string name() const final
Definition multistagemethods.hh:386
std::size_t numStages() const final
Definition multistagemethods.hh:374
ExplicitEuler()
Definition multistagemethods.hh:145
std::string name() const final
Definition multistagemethods.hh:147
ImplicitEuler()
Definition multistagemethods.hh:158
std::string name() const final
Definition multistagemethods.hh:160
std::size_t numStages() const final
Definition multistagemethods.hh:437
Scalar timeStepWeight(std::size_t k) const final
time step weights for each stage ( )
Definition multistagemethods.hh:446
std::string name() const final
Definition multistagemethods.hh:449
QinZhangSymplecticDIRK()
Definition multistagemethods.hh:420
bool implicit() const final
Definition multistagemethods.hh:434
Scalar spatialWeight(std::size_t i, std::size_t k) const final
weights of the spatial operator residual ( )
Definition multistagemethods.hh:443
Scalar temporalWeight(std::size_t i, std::size_t k) const final
weights of the temporal operator residual ( )
Definition multistagemethods.hh:440
RungeKuttaExplicitFourthOrder()
Definition multistagemethods.hh:251
Scalar temporalWeight(std::size_t i, std::size_t k) const final
weights of the temporal operator residual ( )
Definition multistagemethods.hh:269
std::string name() const final
Definition multistagemethods.hh:278
bool implicit() const final
Definition multistagemethods.hh:263
std::size_t numStages() const final
Definition multistagemethods.hh:266
Scalar spatialWeight(std::size_t i, std::size_t k) const final
weights of the spatial operator residual ( )
Definition multistagemethods.hh:272
Scalar timeStepWeight(std::size_t k) const final
time step weights for each stage ( )
Definition multistagemethods.hh:275
std::size_t numStages() const final
Definition multistagemethods.hh:182
RungeKuttaExplicitSecondOrderHeun()
Definition multistagemethods.hh:171
bool implicit() const final
Definition multistagemethods.hh:179
std::string name() const final
Definition multistagemethods.hh:194
Scalar temporalWeight(std::size_t i, std::size_t k) const final
weights of the temporal operator residual ( )
Definition multistagemethods.hh:185
Scalar spatialWeight(std::size_t i, std::size_t k) const final
weights of the spatial operator residual ( )
Definition multistagemethods.hh:188
Scalar timeStepWeight(std::size_t k) const final
time step weights for each stage ( )
Definition multistagemethods.hh:191
bool implicit() const final
Definition multistagemethods.hh:220
Scalar timeStepWeight(std::size_t k) const final
time step weights for each stage ( )
Definition multistagemethods.hh:232
Scalar spatialWeight(std::size_t i, std::size_t k) const final
weights of the spatial operator residual ( )
Definition multistagemethods.hh:229
std::size_t numStages() const final
Definition multistagemethods.hh:223
Scalar temporalWeight(std::size_t i, std::size_t k) const final
weights of the temporal operator residual ( )
Definition multistagemethods.hh:226
std::string name() const final
Definition multistagemethods.hh:235
RungeKuttaExplicitThirdOrder()
Definition multistagemethods.hh:210
std::size_t numStages() const final
Definition multistagemethods.hh:117
bool implicit() const final
Definition multistagemethods.hh:114
std::string name() const override
Definition multistagemethods.hh:129
Theta(const Scalar theta)
Definition multistagemethods.hh:108
Scalar spatialWeight(std::size_t, std::size_t k) const final
weights of the spatial operator residual ( )
Definition multistagemethods.hh:123
Scalar temporalWeight(std::size_t, std::size_t k) const final
weights of the temporal operator residual ( )
Definition multistagemethods.hh:120
Scalar timeStepWeight(std::size_t k) const final
time step weights for each stage ( )
Definition multistagemethods.hh:126
Abstract interface for one-step multi-stage method parameters in Shu/Osher form.
Definition multistagemethods.hh:75
virtual std::string name() const =0
virtual std::size_t numStages() const =0
virtual Scalar timeStepWeight(std::size_t k) const =0
time step weights for each stage ( )
virtual Scalar temporalWeight(std::size_t i, std::size_t k) const =0
weights of the temporal operator residual ( )
virtual bool implicit() const =0
virtual Scalar spatialWeight(std::size_t i, std::size_t k) const =0
weights of the spatial operator residual ( )
Multi-stage time stepping scheme implementations.
Definition multistagemethods.hh:96
Definition assembly/assembler.hh:44