MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
ode.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_ODE
13#define MFEM_ODE
14
16#include "../config/config.hpp"
17#include "operator.hpp"
18#include <vector>
19#include <memory>
20
21namespace mfem
22{
23
24/// An interface for storing state of previous timesteps
26{
27public:
28 /// Get the maximum number of stored stages
29 virtual int MaxSize() const = 0;
30
31 /// Get the current number of stored stages
32 virtual int Size() const = 0;
33
34 /// Get the ith state vector
35 virtual const Vector &Get(int i) const = 0;
36
37 /// Get the ith state vector - non-const version
38 virtual Vector &Get(int i) = 0;
39
40 /// Get the ith state vector - with a copy
41 virtual void Get(int i, Vector &vec) const = 0;
42
43 /// Set the ith state vector
44 virtual void Set(int i, Vector &state) = 0;
45
46 /// Add state vector and increment state size
47 virtual void Append(Vector &state) = 0;
48
49 /// Virtual destructor
50 virtual ~ODEStateData() = default;
51};
52
53/// An implementation of ODEStateData that stores states in an std::vector<Vector>
55{
56private:
57 MemoryType mem_type;
58 int ss, smax;
59 std::vector<Vector> data;
60 Array<int> idx;
61
62public:
63 ODEStateDataVector (int smax): smax(smax)
64 {
65 data.resize(smax);
66 idx.SetSize(smax);
67 ss = 0;
68 };
69
70 /// Set the number of stages and the size of the vectors
71 void SetSize(int vsize, MemoryType mem_type);
72
73 /// Shift the stage counter for the next timestep
74 inline void ShiftStages()
75 {
76 for (int i = 0; i < smax; i++) { idx[i] = (++idx[i])%smax; }
77 };
78
79 /// Increment the stage counter
80 void Increment() { ss++; ss = std::min(ss,smax); };
81
82 /// Reset the stage counter
83 void Reset() { ss = 0; };
84
85 /// Reference access to the ith vector.
86 inline Vector & operator[](int i) { return data[idx[i]]; };
87
88 /// Const reference access to the ith vector.
89 inline const Vector &operator[](int i) const { return data[idx[i]]; };
90
91 /// Print state data
92 void Print(std::ostream &os = mfem::out) const ;
93
94 int MaxSize() const override { return smax; };
95
96 int Size() const override { return ss; };
97
98 const Vector &Get(int i) const override;
99 Vector &Get(int i) override;
100 void Get(int i, Vector &vec) const override;
101
102 void Set(int i, Vector &state) override;
103
104 void Append(Vector &state) override;
105};
106
107
108/// Abstract class for solving systems of ODEs: dx/dt = f(x,t)
110{
111protected:
112 /// Pointer to the associated TimeDependentOperator.
113 TimeDependentOperator *f; // f(.,t) : R^n --> R^n
115
116public:
118
119 /// Associate a TimeDependentOperator with the ODE solver.
120 /** This method has to be called:
121 - Before the first call to Step().
122 - When the dimensions of the associated TimeDependentOperator change.
123 - When a time stepping sequence has to be restarted.
124 - To change the associated TimeDependentOperator. */
125 virtual void Init(TimeDependentOperator &f_);
126
127 /** @brief Perform a time step from time @a t [in] to time @a t [out] based
128 on the requested step size @a dt [in]. */
129 /** @param[in,out] x Approximate solution.
130 @param[in,out] t Time associated with the approximate solution @a x.
131 @param[in,out] dt Time step size.
132
133 The following rules describe the common behavior of the method:
134 - The input @a x [in] is the approximate solution for the input time
135 @a t [in].
136 - The input @a dt [in] is the desired time step size, defining the desired
137 target time: t [target] = @a t [in] + @a dt [in].
138 - The output @a x [out] is the approximate solution for the output time
139 @a t [out].
140 - The output @a dt [out] is the last time step taken by the method which
141 may be smaller or larger than the input @a dt [in] value, e.g. because
142 of time step control.
143 - The method may perform more than one time step internally; in this case
144 @a dt [out] is the last internal time step size.
145 - The output value of @a t [out] may be smaller or larger than
146 t [target], however, it is not smaller than @a t [in] + @a dt [out], if
147 at least one internal time step was performed.
148 - The value @a x [out] may be obtained by interpolation using internally
149 stored data.
150 - In some cases, the contents of @a x [in] may not be used, e.g. when
151 @a x [out] from a previous Step() call was obtained by interpolation.
152 - In consecutive calls to this method, the output @a t [out] of one
153 Step() call has to be the same as the input @a t [in] to the next
154 Step() call.
155 - If the previous rule has to be broken, e.g. to restart a time stepping
156 sequence, then the ODE solver must be re-initialized by calling Init()
157 between the two Step() calls. */
158 virtual void Step(Vector &x, real_t &t, real_t &dt) = 0;
159
160 /// Perform time integration from time @a t [in] to time @a tf [in].
161 /** @param[in,out] x Approximate solution.
162 @param[in,out] t Time associated with the approximate solution @a x.
163 @param[in,out] dt Time step size.
164 @param[in] tf Requested final time.
165
166 The default implementation makes consecutive calls to Step() until
167 reaching @a tf.
168 The following rules describe the common behavior of the method:
169 - The input @a x [in] is the approximate solution for the input time
170 @a t [in].
171 - The input @a dt [in] is the initial time step size.
172 - The output @a dt [out] is the last time step taken by the method which
173 may be smaller or larger than the input @a dt [in] value, e.g. because
174 of time step control.
175 - The output value of @a t [out] is not smaller than @a tf [in]. */
176 virtual void Run(Vector &x, real_t &t, real_t &dt, real_t tf)
177 {
178 while (t < tf) { Step(x, t, dt); }
179 }
180
181 /// Returns how many State vectors the ODE requires
182 virtual int GetStateSize() { return 0; };
183
184 // Help info for ODESolver options
185 static MFEM_EXPORT std::string ExplicitTypes;
186 static MFEM_EXPORT std::string ImplicitTypes;
187 static MFEM_EXPORT std::string Types;
188
189 /// Function for selecting the desired ODESolver (Explicit and Implicit)
190 /// Returns an ODESolver pointer based on an type
191 /// Caller gets ownership of the object and is responsible for its deletion
192 static MFEM_EXPORT std::unique_ptr<ODESolver> Select(const int ode_solver_type);
193
194 /// Function for selecting the desired Explicit ODESolver
195 /// Returns an ODESolver pointer based on an type
196 /// Caller gets ownership of the object and is responsible for its deletion
197 static MFEM_EXPORT std::unique_ptr<ODESolver> SelectExplicit(
198 const int ode_solver_type);
199
200 /// Function for selecting the desired Implicit ODESolver
201 /// Returns an ODESolver pointer based on an type
202 /// Caller gets ownership of the object and is responsible for its deletion
203 static MFEM_EXPORT std::unique_ptr<ODESolver> SelectImplicit(
204 const int ode_solver_type);
205
206 virtual ~ODESolver() { }
207};
208
209/// Abstract class for an ODESolver that has state history implemented as ODEStateData
211{
212public:
213 /// Returns the StateData
214 virtual ODEStateData& GetState() = 0;
215
216 /// Returns the StateData
217 virtual const ODEStateData& GetState() const = 0;
218
219 /// Returns how many State vectors the ODE requires
220 virtual int GetStateSize() { return GetState().MaxSize(); };
221};
222
223
224/// The classical forward Euler method
226{
227private:
228 Vector dxdt;
229
230public:
231 void Init(TimeDependentOperator &f_) override;
232
233 void Step(Vector &x, real_t &t, real_t &dt) override;
234};
235
236
237/** A family of explicit second-order RK2 methods. Some choices for the
238 parameter 'a' are:
239 a = 1/2 - the midpoint method
240 a = 1 - Heun's method
241 a = 2/3 - default, has minimal truncation error. */
242class RK2Solver : public ODESolver
243{
244private:
245 real_t a;
246 Vector dxdt, x1;
247
248public:
249 RK2Solver(const real_t a_ = 2./3.) : a(a_) { }
250
251 void Init(TimeDependentOperator &f_) override;
252
253 void Step(Vector &x, real_t &t, real_t &dt) override;
254};
255
256
257/// Third-order, strong stability preserving (SSP) Runge-Kutta method
259{
260private:
261 Vector y, k;
262
263public:
264 void Init(TimeDependentOperator &f_) override;
265
266 void Step(Vector &x, real_t &t, real_t &dt) override;
267};
268
269
270/// The classical explicit forth-order Runge-Kutta method, RK4
271class RK4Solver : public ODESolver
272{
273private:
274 Vector y, k, z;
275
276public:
277 void Init(TimeDependentOperator &f_) override;
278
279 void Step(Vector &x, real_t &t, real_t &dt) override;
280};
281
282
283/** An explicit Runge-Kutta method corresponding to a general Butcher tableau
284 +--------+----------------------+
285 | c[0] | a[0] |
286 | c[1] | a[1] a[2] |
287 | ... | ... |
288 | c[s-2] | ... a[s(s-1)/2-1] |
289 +--------+----------------------+
290 | | b[0] b[1] ... b[s-1] |
291 +--------+----------------------+ */
293{
294private:
295 int s;
296 const real_t *a, *b, *c;
297 Vector y, *k;
298
299public:
300 ExplicitRKSolver(int s_, const real_t *a_, const real_t *b_,
301 const real_t *c_);
302
303 void Init(TimeDependentOperator &f_) override;
304
305 void Step(Vector &x, real_t &t, real_t &dt) override;
306
307 virtual ~ExplicitRKSolver();
308};
309
310
311/** An 8-stage, 6th order RK method. From Verner's "efficient" 9-stage 6(5)
312 pair. */
314{
315private:
316 static MFEM_EXPORT const real_t a[28], b[8], c[7];
317
318public:
320};
321
322
323/** A 12-stage, 8th order RK method. From Verner's "efficient" 13-stage 8(7)
324 pair. */
326{
327private:
328 static MFEM_EXPORT const real_t a[66], b[12], c[11];
329
330public:
331 RK8Solver() : ExplicitRKSolver(12, a, b, c) { }
332};
333
334
335/// Backward Euler ODE solver. L-stable.
337{
338protected:
340
341public:
342 void Init(TimeDependentOperator &f_) override;
343
344 void Step(Vector &x, real_t &t, real_t &dt) override;
345};
346
347
348/// Implicit midpoint method. A-stable, not L-stable.
350{
351protected:
353
354public:
355 void Init(TimeDependentOperator &f_) override;
356
357 void Step(Vector &x, real_t &t, real_t &dt) override;
358};
359
360
361/** Two stage, singly diagonal implicit Runge-Kutta (SDIRK) methods;
362 the choices for gamma_opt are:
363 0 - 3rd order method, not A-stable
364 1 - 3rd order method, A-stable, not L-stable (default)
365 2 - 2nd order method, L-stable
366 3 - 2nd order method, L-stable (has solves outside [t,t+dt]). */
368{
369protected:
372
373public:
374 SDIRK23Solver(int gamma_opt = 1);
375
376 void Init(TimeDependentOperator &f_) override;
377
378 void Step(Vector &x, real_t &t, real_t &dt) override;
379};
380
381
382/** Three stage, singly diagonal implicit Runge-Kutta (SDIRK) method of
383 order 4. A-stable, not L-stable. */
385{
386protected:
388
389public:
390 void Init(TimeDependentOperator &f_) override;
391
392 void Step(Vector &x, real_t &t, real_t &dt) override;
393};
394
395
396/** Three stage, singly diagonal implicit Runge-Kutta (SDIRK) method of
397 order 3. L-stable. */
399{
400protected:
402
403public:
404 void Init(TimeDependentOperator &f_) override;
405
406 void Step(Vector &x, real_t &t, real_t &dt) override;
407};
408
409
410/** Two stage, explicit singly diagonal implicit Runge-Kutta (ESDIRK) method
411 of order 2. A-stable. */
413{
414protected:
416
417public:
418 void Init(TimeDependentOperator &f_) override;
419
420 void Step(Vector &x, real_t &t, real_t &dt) override;
421};
422
423
424/** Three stage, explicit singly diagonal implicit Runge-Kutta (ESDIRK) method
425 of order 2. L-stable. */
427{
428protected:
430
431public:
432 void Init(TimeDependentOperator &f_) override;
433
434 void Step(Vector &x, real_t &t, real_t &dt) override;
435};
436
437
438/** Three stage, explicit singly diagonal implicit Runge-Kutta (ESDIRK) method
439 of order 3. A-stable. */
441{
442protected:
444
445public:
446 void Init(TimeDependentOperator &f_) override;
447
448 void Step(Vector &x, real_t &t, real_t &dt) override;
449};
450
451
452/// Generalized-alpha ODE solver from "A generalized-α method for integrating
453/// the filtered Navier-Stokes equations with a stabilized finite element
454/// method" by K.E. Jansen, C.H. Whiting and G.M. Hulbert.
456{
457 ODEStateDataVector state;
458
459protected:
460
461 mutable Vector k,y;
463
464 void SetRhoInf(real_t rho_inf);
465 void PrintProperties(std::ostream &os = mfem::out);
466public:
467
468 GeneralizedAlphaSolver(real_t rho = 1.0) : state(1) { SetRhoInf(rho); };
469 void Init(TimeDependentOperator &f_) override;
470 void Step(Vector &x, real_t &t, real_t &dt) override;
471
472 ODEStateData& GetState() override { return state; }
473 const ODEStateData& GetState() const override { return state; }
474};
475
476
477/** An explicit Adams-Bashforth method. */
479{
480private:
481 const real_t *a;
482 const int stages;
483 real_t dt_;
484 ODEStateDataVector state;
485
486protected:
487 std::unique_ptr<ODESolver> RKsolver;
488
489 inline bool print()
490 {
491#ifdef MFEM_USE_MPI
492 return Mpi::IsInitialized() ? Mpi::Root() : true;
493#else
494 return true;
495#endif
496 }
497
498 void CheckTimestep(real_t dt);
499
500public:
501 AdamsBashforthSolver(int s_, const real_t *a_);
502 void Init(TimeDependentOperator &f_) override;
503 void Step(Vector &x, real_t &t, real_t &dt) override;
504
505 ODEStateData& GetState() override { return state; }
506 const ODEStateData& GetState() const override { return state; }
507};
508
509/** A 1-stage, 1st order AB method. */
511{
512private:
513 static MFEM_EXPORT const real_t a[1];
514
515public:
517};
518
519/** A 2-stage, 2nd order AB method. */
521{
522private:
523 static MFEM_EXPORT const real_t a[2];
524
525public:
527};
528
529/** A 3-stage, 3rd order AB method. */
531{
532private:
533 static MFEM_EXPORT const real_t a[3];
534
535public:
537};
538
539/** A 4-stage, 4th order AB method. */
541{
542private:
543 static MFEM_EXPORT const real_t a[4];
544
545public:
547};
548
549/** A 5-stage, 5th order AB method. */
551{
552private:
553 static MFEM_EXPORT const real_t a[5];
554
555public:
557};
558
559
560/** An implicit Adams-Moulton method. */
562{
563private:
564 const real_t *a;
565 const int stages;
566 real_t dt_;
567 ODEStateDataVector state;
568
569protected:
570 std::unique_ptr<ODESolver> RKsolver;
571
572 inline bool print()
573 {
574#ifdef MFEM_USE_MPI
575 return Mpi::IsInitialized() ? Mpi::Root() : true;
576#else
577 return true;
578#endif
579 }
580
582
583public:
584 AdamsMoultonSolver(int s_, const real_t *a_);
585 void Init(TimeDependentOperator &f_) override;
586 void Step(Vector &x, real_t &t, real_t &dt) override;
587
588 ODEStateData& GetState() override { return state; }
589 const ODEStateData& GetState() const override { return state; }
590};
591
592/** A 1-stage, 2nd order AM method. */
594{
595private:
596 static MFEM_EXPORT const real_t a[2];
597
598public:
600};
601
602/** A 2-stage, 3rd order AM method. */
604{
605private:
606 static MFEM_EXPORT const real_t a[3];
607
608public:
610};
611
612/** A 3-stage, 4th order AM method. */
614{
615private:
616 static MFEM_EXPORT const real_t a[4];
617
618public:
620};
621
622/** A 4-stage, 5th order AM method. */
624{
625private:
626 static MFEM_EXPORT const real_t a[5];
627
628public:
630};
631
632/// The SIASolver class is based on the Symplectic Integration Algorithm
633/// described in "A Symplectic Integration Algorithm for Separable Hamiltonian
634/// Functions" by J. Candy and W. Rozmus, Journal of Computational Physics,
635/// Vol. 92, pages 230-256 (1991).
636
637/** The Symplectic Integration Algorithm (SIA) is designed for systems of first
638 order ODEs derived from a Hamiltonian.
639 H(q,p,t) = T(p) + V(q,t)
640 Which leads to the equations:
641 dq/dt = dT/dp
642 dp/dt = -dV/dq
643 In the integrator the operators P and F are defined to be:
644 P = dT/dp
645 F = -dV/dq
646 */
648{
649public:
650 SIASolver() : F_(NULL), P_(NULL) {}
651
652 virtual void Init(Operator &P, TimeDependentOperator & F);
653
654 virtual void Step(Vector &q, Vector &p, real_t &t, real_t &dt) = 0;
655
656 virtual void Run(Vector &q, Vector &p, real_t &t, real_t &dt, real_t tf)
657 {
658 while (t < tf) { Step(q, p, t, dt); }
659 }
660
661 virtual ~SIASolver() {}
662
663protected:
664 TimeDependentOperator * F_; // p_{i+1} = p_{i} + dt F(q_{i})
665 Operator * P_; // q_{i+1} = q_{i} + dt P(p_{i+1})
666
667 mutable Vector dp_;
668 mutable Vector dq_;
669};
670
671/// First Order Symplectic Integration Algorithm
672class SIA1Solver : public SIASolver
673{
674public:
676 void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override;
677};
678
679/// Second Order Symplectic Integration Algorithm
680class SIA2Solver : public SIASolver
681{
682public:
684 void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override;
685};
686
687/// Variable order Symplectic Integration Algorithm (orders 1-4)
688class SIAVSolver : public SIASolver
689{
690public:
691 SIAVSolver(int order);
692 void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override;
693
694private:
695 int order_;
696
697 Array<real_t> a_;
698 Array<real_t> b_;
699};
700
701
702
703/// Abstract class for solving systems of ODEs: d2x/dt2 = f(x,dx/dt,t)
705{
706protected:
707 /// Pointer to the associated TimeDependentOperator.
708 SecondOrderTimeDependentOperator *f; // f(.,.,t) : R^n x R^n --> R^n
711
712public:
714
715 /// Associate a TimeDependentOperator with the ODE solver.
716 /** This method has to be called:
717 - Before the first call to Step().
718 - When the dimensions of the associated TimeDependentOperator change.
719 - When a time stepping sequence has to be restarted.
720 - To change the associated TimeDependentOperator. */
722
723 /** @brief Perform a time step from time @a t [in] to time @a t [out] based
724 on the requested step size @a dt [in]. */
725 /** @param[in,out] x Approximate solution.
726 @param[in,out] dxdt Approximate rate.
727 @param[in,out] t Time associated with the
728 approximate solution @a x and rate @ dxdt
729 @param[in,out] dt Time step size.
730
731 The following rules describe the common behavior of the method:
732 - The input @a x [in] is the approximate solution for the input time
733 @a t [in].
734 - The input @a dxdt [in] is the approximate rate for the input time
735 @a t [in].
736 - The input @a dt [in] is the desired time step size, defining the desired
737 target time: t [target] = @a t [in] + @a dt [in].
738 - The output @a x [out] is the approximate solution for the output time
739 @a t [out].
740 - The output @a dxdt [out] is the approximate rate for the output time
741 @a t [out].
742 - The output @a dt [out] is the last time step taken by the method which
743 may be smaller or larger than the input @a dt [in] value, e.g. because
744 of time step control.
745 - The method may perform more than one time step internally; in this case
746 @a dt [out] is the last internal time step size.
747 - The output value of @a t [out] may be smaller or larger than
748 t [target], however, it is not smaller than @a t [in] + @a dt [out], if
749 at least one internal time step was performed.
750 - The value @a x [out] may be obtained by interpolation using internally
751 stored data.
752 - In some cases, the contents of @a x [in] may not be used, e.g. when
753 @a x [out] from a previous Step() call was obtained by interpolation.
754 - In consecutive calls to this method, the output @a t [out] of one
755 Step() call has to be the same as the input @a t [in] to the next
756 Step() call.
757 - If the previous rule has to be broken, e.g. to restart a time stepping
758 sequence, then the ODE solver must be re-initialized by calling Init()
759 between the two Step() calls. */
760 virtual void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) = 0;
761 void EulerStep(Vector &x, Vector &dxdt, real_t &t, real_t &dt);
762 void MidPointStep(Vector &x, Vector &dxdt, real_t &t, real_t &dt);
763
764 /// Perform time integration from time @a t [in] to time @a tf [in].
765 /** @param[in,out] x Approximate solution.
766 @param[in,out] dxdt Approximate rate.
767 @param[in,out] t Time associated with the approximate solution @a x.
768 @param[in,out] dt Time step size.
769 @param[in] tf Requested final time.
770
771 The default implementation makes consecutive calls to Step() until
772 reaching @a tf.
773 The following rules describe the common behavior of the method:
774 - The input @a x [in] is the approximate solution for the input time
775 @a t [in].
776 - The input @a dxdt [in] is the approximate rate for the input time
777 @a t [in].
778 - The input @a dt [in] is the initial time step size.
779 - The output @a dt [out] is the last time step taken by the method which
780 may be smaller or larger than the input @a dt [in] value, e.g. because
781 of time step control.
782 - The output value of @a t [out] is not smaller than @a tf [in]. */
783 virtual void Run(Vector &x, Vector &dxdt, real_t &t, real_t &dt, real_t tf)
784 {
785 while (t < tf) { Step(x, dxdt, t, dt); }
786 }
787
788 /// Functions for getting the state vectors
790 const ODEStateData& GetState() const { return state; }
791
792 /// Returns how many State vectors the ODE requires
793 int GetStateSize() { return GetState().MaxSize(); };
794
795 /// Help info for SecondOrderODESolver options
796 static MFEM_EXPORT std::string Types;
797
798 /// Function selecting the desired SecondOrderODESolver
799 static MFEM_EXPORT SecondOrderODESolver *Select(const int ode_solver_type);
800
802};
803
804/// The classical newmark method.
805/// Newmark, N. M. (1959) A method of computation for structural dynamics.
806/// Journal of Engineering Mechanics, ASCE, 85 (EM3) 67-94.
808{
809private:
810 real_t beta, gamma;
811 bool no_mult;
812
813public:
814 NewmarkSolver(real_t beta_ = 0.25, real_t gamma_ = 0.5, bool no_mult_ = false)
815 {
816 beta = beta_;
817 gamma = gamma_;
818 no_mult = no_mult_;
819 };
820
821 void PrintProperties(std::ostream &os = mfem::out);
822
823 void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) override;
824};
825
827{
828public:
830};
831
833{
834public:
836};
837
839{
840public:
841 FoxGoodwinSolver() : NewmarkSolver(1.0/12.0, 0.5) { };
842};
843
844/// Generalized-alpha ODE solver
845/// A Time Integration Algorithm for Structural Dynamics With Improved
846/// Numerical Dissipation: The Generalized-α Method
847/// J.Chung and G.M. Hulbert, J. Appl. Mech 60(2), 371-375, 1993
848/// https://doi.org/10.1115/1.2900803
849/// rho_inf in [0,1]
851{
852protected:
856
857public:
858 GeneralizedAlpha2Solver(real_t rho_inf = 1.0, bool no_mult_ = false)
859 {
860 no_mult = no_mult_;
861 rho_inf = (rho_inf > 1.0) ? 1.0 : rho_inf;
862 rho_inf = (rho_inf < 0.0) ? 0.0 : rho_inf;
863
864 alpha_m = (2.0 - rho_inf)/(1.0 + rho_inf);
865 alpha_f = 1.0/(1.0 + rho_inf);
866 beta = 0.25*pow(1.0 + alpha_m - alpha_f,2);
867 gamma = 0.5 + alpha_m - alpha_f;
868 };
869
870 void PrintProperties(std::ostream &os = mfem::out);
871
872 void Init(SecondOrderTimeDependentOperator &f_) override;
873
874 void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) override;
875
876};
877
878/// The classical midpoint method.
880{
881public:
883 {
884 alpha_m = 0.5;
885 alpha_f = 0.5;
886 beta = 0.25;
887 gamma = 0.5;
888 };
889};
890
891/// HHT-alpha ODE solver
892/// Improved numerical dissipation for time integration algorithms
893/// in structural dynamics
894/// H.M. Hilber, T.J.R. Hughes and R.L. Taylor 1977
895/// https://doi.org/10.1002/eqe.4290050306
896/// alpha in [2/3,1] --> Defined differently than in paper.
898{
899public:
901 {
902 alpha = (alpha > 1.0) ? 1.0 : alpha;
903 alpha = (alpha < 2.0/3.0) ? 2.0/3.0 : alpha;
904
905 alpha_m = 1.0;
906 alpha_f = alpha;
907 beta = (2-alpha)*(2-alpha)/4;
908 gamma = 0.5 + alpha_m - alpha_f;
909 };
910
911};
912
913/// WBZ-alpha ODE solver
914/// An alpha modification of Newmark's method
915/// W.L. Wood, M. Bossak and O.C. Zienkiewicz 1980
916/// https://doi.org/10.1002/nme.1620151011
917/// rho_inf in [0,1]
919{
920public:
921 WBZAlphaSolver(real_t rho_inf = 1.0)
922 {
923 rho_inf = (rho_inf > 1.0) ? 1.0 : rho_inf;
924 rho_inf = (rho_inf < 0.0) ? 0.0 : rho_inf;
925
926 alpha_f = 1.0;
927 alpha_m = 2.0/(1.0 + rho_inf);
928 beta = 0.25*pow(1.0 + alpha_m - alpha_f,2);
929 gamma = 0.5 + alpha_m - alpha_f;
930 };
931
932};
933
934}
935
936#endif
ODEStateData & GetState() override
Returns the StateData.
Definition ode.hpp:505
const ODEStateData & GetState() const override
Returns the StateData.
Definition ode.hpp:506
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:496
void CheckTimestep(real_t dt)
Definition ode.cpp:529
AdamsBashforthSolver(int s_, const real_t *a_)
Definition ode.cpp:490
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:504
std::unique_ptr< ODESolver > RKsolver
Definition ode.hpp:487
const ODEStateData & GetState() const override
Returns the StateData.
Definition ode.hpp:589
std::unique_ptr< ODESolver > RKsolver
Definition ode.hpp:570
ODEStateData & GetState() override
Returns the StateData.
Definition ode.hpp:588
void CheckTimestep(real_t dt)
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:577
AdamsMoultonSolver(int s_, const real_t *a_)
Definition ode.cpp:563
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:569
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:758
The classical midpoint method.
Definition ode.hpp:880
Backward Euler ODE solver. L-stable.
Definition ode.hpp:337
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:634
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:640
static MemoryType GetHostMemoryType()
Get the current Host MemoryType. This is the MemoryType used by most MFEM classes when allocating mem...
Definition device.hpp:265
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:805
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:813
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:840
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:848
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:302
virtual ~ExplicitRKSolver()
Definition ode.cpp:332
ExplicitRKSolver(int s_, const real_t *a_, const real_t *b_, const real_t *c_)
Definition ode.cpp:281
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:291
The classical forward Euler method.
Definition ode.hpp:226
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:173
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:167
void PrintProperties(std::ostream &os=mfem::out)
Definition ode.cpp:1199
void Init(SecondOrderTimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:1191
void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1229
GeneralizedAlpha2Solver(real_t rho_inf=1.0, bool no_mult_=false)
Definition ode.hpp:858
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:877
void SetRhoInf(real_t rho_inf)
Definition ode.cpp:885
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:923
GeneralizedAlphaSolver(real_t rho=1.0)
Definition ode.hpp:468
ODEStateData & GetState() override
Returns the StateData.
Definition ode.hpp:472
void PrintProperties(std::ostream &os=mfem::out)
Definition ode.cpp:896
const ODEStateData & GetState() const override
Returns the StateData.
Definition ode.hpp:473
HHTAlphaSolver(real_t alpha=1.0)
Definition ode.hpp:900
Implicit midpoint method. A-stable, not L-stable.
Definition ode.hpp:350
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:655
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:649
static bool Root()
Return true if the rank in MPI_COMM_WORLD is zero.
static bool IsInitialized()
Return true if MPI has been initialized.
NewmarkSolver(real_t beta_=0.25, real_t gamma_=0.5, bool no_mult_=false)
Definition ode.hpp:814
void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:1156
void PrintProperties(std::ostream &os=mfem::out)
Definition ode.cpp:1126
Abstract class for an ODESolver that has state history implemented as ODEStateData.
Definition ode.hpp:211
virtual const ODEStateData & GetState() const =0
Returns the StateData.
virtual int GetStateSize()
Returns how many State vectors the ODE requires.
Definition ode.hpp:220
virtual ODEStateData & GetState()=0
Returns the StateData.
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
Definition ode.hpp:110
TimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
Definition ode.hpp:113
virtual void Init(TimeDependentOperator &f_)
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:161
virtual void Step(Vector &x, real_t &t, real_t &dt)=0
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
virtual ~ODESolver()
Definition ode.hpp:206
static MFEM_EXPORT std::unique_ptr< ODESolver > SelectImplicit(const int ode_solver_type)
Definition ode.cpp:70
static MFEM_EXPORT std::string Types
Definition ode.hpp:187
static MFEM_EXPORT std::unique_ptr< ODESolver > Select(const int ode_solver_type)
Definition ode.cpp:34
MemoryType mem_type
Definition ode.hpp:114
static MFEM_EXPORT std::string ImplicitTypes
Definition ode.hpp:186
virtual void Run(Vector &x, real_t &t, real_t &dt, real_t tf)
Perform time integration from time t [in] to time tf [in].
Definition ode.hpp:176
static MFEM_EXPORT std::string ExplicitTypes
Definition ode.hpp:185
virtual int GetStateSize()
Returns how many State vectors the ODE requires.
Definition ode.hpp:182
static MFEM_EXPORT std::unique_ptr< ODESolver > SelectExplicit(const int ode_solver_type)
Definition ode.cpp:46
An implementation of ODEStateData that stores states in an std::vector<Vector>
Definition ode.hpp:55
void Increment()
Increment the stage counter.
Definition ode.hpp:80
const Vector & Get(int i) const override
Get the ith state vector.
Definition ode.cpp:122
void Set(int i, Vector &state) override
Set the ith state vector.
Definition ode.cpp:140
void SetSize(int vsize, MemoryType mem_type)
Set the number of stages and the size of the vectors.
Definition ode.cpp:110
ODEStateDataVector(int smax)
Definition ode.hpp:63
void Append(Vector &state) override
Add state vector and increment state size.
Definition ode.cpp:146
void ShiftStages()
Shift the stage counter for the next timestep.
Definition ode.hpp:74
void Print(std::ostream &os=mfem::out) const
Print state data.
Definition ode.cpp:153
Vector & operator[](int i)
Reference access to the ith vector.
Definition ode.hpp:86
const Vector & operator[](int i) const
Const reference access to the ith vector.
Definition ode.hpp:89
int Size() const override
Get the current number of stored stages.
Definition ode.hpp:96
int MaxSize() const override
Get the maximum number of stored stages.
Definition ode.hpp:94
void Reset()
Reset the stage counter.
Definition ode.hpp:83
An interface for storing state of previous timesteps.
Definition ode.hpp:26
virtual void Get(int i, Vector &vec) const =0
Get the ith state vector - with a copy.
virtual int MaxSize() const =0
Get the maximum number of stored stages.
virtual Vector & Get(int i)=0
Get the ith state vector - non-const version.
virtual const Vector & Get(int i) const =0
Get the ith state vector.
virtual void Set(int i, Vector &state)=0
Set the ith state vector.
virtual void Append(Vector &state)=0
Add state vector and increment state size.
virtual int Size() const =0
Get the current number of stored stages.
virtual ~ODEStateData()=default
Virtual destructor.
Abstract operator.
Definition operator.hpp:25
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:182
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:190
RK2Solver(const real_t a_=2./3.)
Definition ode.hpp:249
Third-order, strong stability preserving (SSP) Runge-Kutta method.
Definition ode.hpp:259
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:211
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:219
The classical explicit forth-order Runge-Kutta method, RK4.
Definition ode.hpp:272
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:243
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:252
SDIRK23Solver(int gamma_opt=1)
Definition ode.cpp:664
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:691
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:684
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:755
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:748
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:719
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:711
First Order Symplectic Integration Algorithm.
Definition ode.hpp:673
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
Definition ode.cpp:960
Second Order Symplectic Integration Algorithm.
Definition ode.hpp:681
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
Definition ode.cpp:973
TimeDependentOperator * F_
Definition ode.hpp:664
Vector dq_
Definition ode.hpp:668
Vector dp_
Definition ode.hpp:667
virtual void Init(Operator &P, TimeDependentOperator &F)
Definition ode.cpp:951
virtual void Step(Vector &q, Vector &p, real_t &t, real_t &dt)=0
virtual ~SIASolver()
Definition ode.hpp:661
virtual void Run(Vector &q, Vector &p, real_t &t, real_t &dt, real_t tf)
Definition ode.hpp:656
Operator * P_
Definition ode.hpp:665
Variable order Symplectic Integration Algorithm (orders 1-4)
Definition ode.hpp:689
void Step(Vector &q, Vector &p, real_t &t, real_t &dt) override
Definition ode.cpp:1030
SIAVSolver(int order)
Definition ode.cpp:988
Abstract class for solving systems of ODEs: d2x/dt2 = f(x,dx/dt,t)
Definition ode.hpp:705
SecondOrderTimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
Definition ode.hpp:708
ODEStateData & GetState()
Functions for getting the state vectors.
Definition ode.hpp:789
void MidPointStep(Vector &x, Vector &dxdt, real_t &t, real_t &dt)
Definition ode.cpp:1105
virtual ~SecondOrderODESolver()
Definition ode.hpp:801
const ODEStateData & GetState() const
Definition ode.hpp:790
ODEStateDataVector state
Definition ode.hpp:710
int GetStateSize()
Returns how many State vectors the ODE requires.
Definition ode.hpp:793
static MFEM_EXPORT std::string Types
Help info for SecondOrderODESolver options.
Definition ode.hpp:796
void EulerStep(Vector &x, Vector &dxdt, real_t &t, real_t &dt)
Definition ode.cpp:1091
static MFEM_EXPORT SecondOrderODESolver * Select(const int ode_solver_type)
Function selecting the desired SecondOrderODESolver.
Definition ode.cpp:1061
virtual void Run(Vector &x, Vector &dxdt, real_t &t, real_t &dt, real_t tf)
Perform time integration from time t [in] to time tf [in].
Definition ode.hpp:783
virtual void Init(SecondOrderTimeDependentOperator &f)
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:1119
virtual void Step(Vector &x, Vector &dxdt, real_t &t, real_t &dt)=0
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Base abstract class for second order time dependent operators.
Definition operator.hpp:732
Base abstract class for first order time dependent operators.
Definition operator.hpp:332
void Step(Vector &x, real_t &t, real_t &dt) override
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
Definition ode.cpp:788
void Init(TimeDependentOperator &f_) override
Associate a TimeDependentOperator with the ODE solver.
Definition ode.cpp:781
Vector data type.
Definition vector.hpp:82
WBZAlphaSolver(real_t rho_inf=1.0)
Definition ode.hpp:921
Vector beta
const real_t alpha
Definition ex15.cpp:369
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
float real_t
Definition config.hpp:43
MemoryType
Memory types supported by MFEM.
@ HOST
Host memory; using new[] and delete[].
real_t p(const Vector &x, real_t t)