RKDP45.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2013-2016 OpenFOAM Foundation
9 Copyright (C) 2019 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "RKDP45.H"
31
32// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33
34namespace Foam
35{
38
39const scalar
40 RKDP45::c2 = 1.0/5.0,
41 RKDP45::c3 = 3.0/10.0,
42 RKDP45::c4 = 4.0/5.0,
43 RKDP45::c5 = 8.0/9.0,
44
45 RKDP45::a21 = 1.0/5.0,
46
47 RKDP45::a31 = 3.0/40.0,
48 RKDP45::a32 = 9.0/40.0,
49
50 RKDP45::a41 = 44.0/45.0,
51 RKDP45::a42 = -56.0/15.0,
52 RKDP45::a43 = 32.0/9.0,
53
54 RKDP45::a51 = 19372.0/6561.0,
55 RKDP45::a52 = -25360.0/2187.0,
56 RKDP45::a53 = 64448.0/6561.0,
57 RKDP45::a54 = -212.0/729.0,
58
59 RKDP45::a61 = 9017.0/3168.0,
60 RKDP45::a62 = -355.0/33.0,
61 RKDP45::a63 = 46732.0/5247.0,
62 RKDP45::a64 = 49.0/176.0,
63 RKDP45::a65 = -5103.0/18656.0,
64
65 RKDP45::b1 = 35.0/384.0,
66 RKDP45::b3 = 500.0/1113.0,
67 RKDP45::b4 = 125.0/192.0,
68 RKDP45::b5 = -2187.0/6784.0,
69 RKDP45::b6 = 11.0/84.0,
70
71 RKDP45::e1 = 5179.0/57600.0 - RKDP45::b1,
72 RKDP45::e3 = 7571.0/16695.0 - RKDP45::b3,
73 RKDP45::e4 = 393.0/640.0 - RKDP45::b4,
74 RKDP45::e5 = -92097.0/339200.0 - RKDP45::b5,
75 RKDP45::e6 = 187.0/2100.0 - RKDP45::b6,
76 RKDP45::e7 = 1.0/40.0;
77}
78
79
80// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
81
83:
86 yTemp_(n_),
87 k2_(n_),
88 k3_(n_),
89 k4_(n_),
90 k5_(n_),
91 k6_(n_),
92 err_(n_)
93{}
94
95
96// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
97
99{
100 if (ODESolver::resize())
101 {
103
104 resizeField(yTemp_);
105 resizeField(k2_);
106 resizeField(k3_);
107 resizeField(k4_);
108 resizeField(k5_);
109 resizeField(k6_);
110 resizeField(err_);
111
112 return true;
113 }
114
115 return false;
116}
117
118
120(
121 const scalar x0,
122 const scalarField& y0,
123 const scalarField& dydx0,
124 const scalar dx,
126) const
127{
128 forAll(yTemp_, i)
129 {
130 yTemp_[i] = y0[i] + a21*dx*dydx0[i];
131 }
132
133 odes_.derivatives(x0 + c2*dx, yTemp_, k2_);
134
135 forAll(yTemp_, i)
136 {
137 yTemp_[i] = y0[i] + dx*(a31*dydx0[i] + a32*k2_[i]);
138 }
139
140 odes_.derivatives(x0 + c3*dx, yTemp_, k3_);
141
142 forAll(yTemp_, i)
143 {
144 yTemp_[i] = y0[i] + dx*(a41*dydx0[i] + a42*k2_[i] + a43*k3_[i]);
145 }
146
147 odes_.derivatives(x0 + c4*dx, yTemp_, k4_);
148
149 forAll(yTemp_, i)
150 {
151 yTemp_[i] = y0[i]
152 + dx*(a51*dydx0[i] + a52*k2_[i] + a53*k3_[i] + a54*k4_[i]);
153 }
154
155 odes_.derivatives(x0 + c5*dx, yTemp_, k5_);
156
157 forAll(yTemp_, i)
158 {
159 yTemp_[i] = y0[i]
160 + dx
161 *(a61*dydx0[i] + a62*k2_[i] + a63*k3_[i] + a64*k4_[i] + a65*k5_[i]);
162 }
163
164 odes_.derivatives(x0 + dx, yTemp_, k6_);
165
166 forAll(y, i)
167 {
168 y[i] = y0[i]
169 + dx*(b1*dydx0[i] + b3*k3_[i] + b4*k4_[i] + b5*k5_[i] + b6*k6_[i]);
170 }
171
172 // Reuse k2_ for the derivative of the new state
173 odes_.derivatives(x0 + dx, y, k2_);
174
175 forAll(err_, i)
176 {
177 err_[i] =
178 dx
179 *(e1*dydx0[i] + e3*k3_[i] + e4*k4_[i] + e5*k5_[i] + e6*k6_[i]
180 + e7*k2_[i]);
181 }
182
183 return normalizeError(y0, y, err_);
184}
185
186
188(
189 scalar& x,
190 scalarField& y,
191 scalar& dxTry
192) const
193{
194 adaptiveSolver::solve(odes_, x, y, dxTry);
195}
196
197
198// ************************************************************************* //
scalar y
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
virtual bool resize()
Resize the ODE solver.
Definition: Euler.C:53
Abstract base-class for ODE system solvers.
Definition: ODESolver.H:57
virtual bool resize()=0
Resize the ODE solver.
Definition: ODESolver.C:92
Abstract base class for the systems of ordinary differential equations.
Definition: ODESystem.H:50
4/5th Order Dormand-Prince Runge-Kutta ODE solver.
Definition: RKDP45.H:75
virtual bool resize()
Resize the ODE solver.
Definition: RKDP45.C:98
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
An ODE solver for chemistry.
Definition: ode.H:55
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
Namespace for OpenFOAM.
dimensionedScalar y0(const dimensionedScalar &ds)
dictionary dict
CEqn solve()
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333