Test-ODE.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 | Copyright (C) 2011-2013 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "argList.H"
29 #include "IOmanip.H"
30 #include "ODESystem.H"
31 #include "ODESolver.H"
32 
33 using namespace Foam;
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 class testODE
38 :
39  public ODESystem
40 {
41 
42 public:
43 
45  {}
46 
47  label nEqns() const
48  {
49  return 4;
50  }
51 
52  void derivatives
53  (
54  const scalar x,
55  const scalarField& y,
56  scalarField& dydx
57  ) const
58  {
59  dydx[0] = -y[1];
60  dydx[1] = y[0] - (1.0/x)*y[1];
61  dydx[2] = y[1] - (2.0/x)*y[2];
62  dydx[3] = y[2] - (3.0/x)*y[3];
63  }
64 
65  void jacobian
66  (
67  const scalar x,
68  const scalarField& y,
69  scalarField& dfdx,
70  scalarSquareMatrix& dfdy
71  ) const
72  {
73  dfdx[0] = 0.0;
74  dfdx[1] = (1.0/sqr(x))*y[1];
75  dfdx[2] = (2.0/sqr(x))*y[2];
76  dfdx[3] = (3.0/sqr(x))*y[3];
77 
78  dfdy[0][0] = 0.0;
79  dfdy[0][1] = -1.0;
80  dfdy[0][2] = 0.0;
81  dfdy[0][3] = 0.0;
82 
83  dfdy[1][0] = 1.0;
84  dfdy[1][1] = -1.0/x;
85  dfdy[1][2] = 0.0;
86  dfdy[1][3] = 0.0;
87 
88  dfdy[2][0] = 0.0;
89  dfdy[2][1] = 1.0;
90  dfdy[2][2] = -2.0/x;
91  dfdy[2][3] = 0.0;
92 
93  dfdy[3][0] = 0.0;
94  dfdy[3][1] = 0.0;
95  dfdy[3][2] = 1.0;
96  dfdy[3][3] = -3.0/x;
97  }
98 };
99 
100 
101 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
102 // Main program:
103 
104 int main(int argc, char *argv[])
105 {
106  argList::validArgs.append("ODESolver");
107  argList args(argc, argv);
108 
109  // Create the ODE system
110  testODE ode;
111 
113  dict.add("solver", args[1]);
114 
115  // Create the selected ODE system solver
117 
118  // Initialise the ODE system fields
119  scalar xStart = 1.0;
120  scalarField yStart(ode.nEqns());
121  yStart[0] = ::Foam::j0(xStart);
122  yStart[1] = ::Foam::j1(xStart);
123  yStart[2] = ::Foam::jn(2, xStart);
124  yStart[3] = ::Foam::jn(3, xStart);
125 
126  // Print the evolution of the solution and the time-step
127  scalarField dyStart(ode.nEqns());
128  ode.derivatives(xStart, yStart, dyStart);
129 
130  Info<< setw(10) << "relTol" << setw(12) << "dxEst";
131  Info<< setw(13) << "dxDid" << setw(14) << "dxNext" << endl;
132  Info<< setprecision(6);
133 
134  for (label i=0; i<15; i++)
135  {
136  scalar relTol = ::Foam::exp(-scalar(i + 1));
137 
138  scalar x = xStart;
139  scalarField y(yStart);
140 
141  scalar dxEst = 0.6;
142  scalar dxNext = dxEst;
143 
144  odeSolver->relTol() = relTol;
145  odeSolver->solve(x, y, dxNext);
146 
147  Info<< scientific << setw(13) << relTol;
148  Info<< fixed << setw(11) << dxEst;
149  Info<< setw(13) << x - xStart << setw(13) << dxNext
150  << setw(13) << y[0] << setw(13) << y[1]
151  << setw(13) << y[2] << setw(13) << y[3]
152  << endl;
153  }
154 
155  scalar x = xStart;
156  scalar xEnd = x + 1.0;
157  scalarField y(yStart);
158 
159  scalarField yEnd(ode.nEqns());
160  yEnd[0] = ::Foam::j0(xEnd);
161  yEnd[1] = ::Foam::j1(xEnd);
162  yEnd[2] = ::Foam::jn(2, xEnd);
163  yEnd[3] = ::Foam::jn(3, xEnd);
164 
165  scalar dxEst = 0.5;
166 
167  odeSolver->relTol() = 1e-4;
168  odeSolver->solve(x, xEnd, y, dxEst);
169 
170  Info<< nl << "Analytical: y(2.0) = " << yEnd << endl;
171  Info << "Numerical: y(2.0) = " << y << ", dxEst = " << dxEst << endl;
172 
173  Info<< "\nEnd\n" << endl;
174 
175  return 0;
176 }
177 
178 
179 // ************************************************************************* //
Foam::argList::validArgs
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:143
Foam::jn
dimensionedScalar jn(const int n, const dimensionedScalar &ds)
Definition: dimensionedScalar.C:296
Foam::ODESolver::New
static autoPtr< ODESolver > New(const ODESystem &ode, const dictionary &dict)
Select null constructed.
Definition: ODESolverNew.C:31
main
int main(int argc, char *argv[])
Definition: Test-ODE.C:104
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:97
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
ODESystem.H
Foam::exp
dimensionedScalar exp(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:252
testODE
Definition: Test-ODE.C:37
testODE::testODE
testODE()
Definition: Test-ODE.C:44
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
argList.H
IOmanip.H
Istream and Ostream manipulators taking arguments.
Foam::ode
An ODE solver for chemistry.
Definition: ode.H:50
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::fixed
IOstream & fixed(IOstream &io)
Definition: IOstream.H:576
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
ODESolver.H
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::scientific
IOstream & scientific(IOstream &io)
Definition: IOstream.H:582
Foam::setprecision
Omanip< int > setprecision(const int i)
Definition: IOmanip.H:205
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
Foam::SquareMatrix< scalar >
Foam::sqr
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Definition: dimensionedSymmTensor.C:49
Foam::ODESystem
Abstract base class for the systems of ordinary differential equations.
Definition: ODESystem.H:46
Foam::j0
dimensionedScalar j0(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:270
x
x
Definition: LISASMDCalcMethod2.H:52
testODE::nEqns
label nEqns() const
Return the number of equations in the system.
Definition: Test-ODE.C:47
args
Foam::argList args(argc, argv)
Foam::j1
dimensionedScalar j1(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:271
Foam::dictionary::add
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:729
y
scalar y
Definition: LISASMDCalcMethod1.H:14