source: Sophya/trunk/SophyaLib/NTools/difeq.h@ 3730

Last change on this file since 3730 was 2808, checked in by ansari, 20 years ago

MAJ documentation - Reza 14/6/2005

File size: 7.0 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2// Simple differential equation solver
3// E. Aubourg 1996-
4// DAPNIA/SPP (Saclay) / CEA LAL - IN2P3/CNRS (Orsay)
5
6#ifndef DIFEQ_H_SEEN
7#define DIFEQ_H_SEEN
8
9#include "machdefs.h"
10#include "pexceptions.h"
11#include "tvector.h"
12
13namespace SOPHYA {
14
15class GeneralFunction;
16
17// <summary> fonction pour equadifs </summary>
18// Une fonction utilisee pour les equations differentielles.
19// On resoud de facon generale un systeme de n equations differentielles,
20// donnant les derivees fpi de n fonctions fi.
21class DiffEqFunction {
22public:
23 //! Constructeur. n = nombre de fonctions dans le systeme
24 DiffEqFunction(int n) : mNFunc(n), mNFuncApp(n) {}
25
26
27 // Constructeur. n = nombre reel de fonctions dans le systeme,
28 // m = nombre apparent (il y a dans certaines cas des fonctions a
29 // usage interne, par exemple la fonction constante valant 1....
30 DiffEqFunction(int n, int m) : mNFunc(n), mNFuncApp(m) {}
31
32 // Destructeur
33 virtual ~DiffEqFunction() {}
34
35 // Calcule les valeurs des derivees fpi a partir des valeurs des fonctions fi
36 virtual void ComputeV(Vector& fpi, Vector const& fi)
37 { Compute(fpi(0), fi(0)); }
38
39 // Dans le cas ou on a une seule fonction, calcule la valeur de la derivee fp
40 // a partir de la valeur de la fonction
41 virtual void Compute(double& /*fp*/, double /*f*/)
42 { ASSERT(mNFunc == 1); }
43
44 //! Nombre apparent de fonctions dans le systeme
45 int NFunc() {return mNFuncApp;}
46
47 //! Nombre reel de fonctions dans le systeme
48 int NFuncReal() {return mNFunc;}
49
50 //! Pour ajuster vecteur de depart quand il y a des fonctions a usage v interne...
51 virtual void AdjustStart(Vector& /*start*/, double /*tstart*/)
52 {}
53protected:
54 // Nombre de fonctions dans le systeme
55 int mNFunc;
56 // Nombre apparent de fonctions
57 int mNFuncApp;
58};
59
60
61// Cas y' = f(y)
62typedef double(*DIFEQFCN1)(double);
63
64// <summary> Cas y' = f(y) </summary>
65// Cas y' = f(y), on fournit la fonction f, sous la forme
66// double f(double), et ca construit la bonne DiffEqFunction
67class DiffEqFcn1 : public DiffEqFunction {
68public:
69 // Constructeur, on fournit une fonction double->double
70 // qui donne y' en fonction de y.
71 DiffEqFcn1(DIFEQFCN1);
72
73 // Implementation de Compute qui va utiliser la fonction
74 // fournie au constructeur.
75 virtual void Compute(double& fp, double f);
76protected:
77 DIFEQFCN1 mFcn;
78};
79
80// Cas y' = f(y,t)
81typedef double(*DIFEQFCNT1)(double, double);
82
83// <summary> y' = f(y,t) </summary>
84// Cas y' = f(y,t), on fournit la fonction f, sous la forme
85// double f(double, double), et ca construit la bonne DiffEqFunction
86class DiffEqFcnT1 : public DiffEqFunction {
87public:
88 // Constructeur, on fournit une fonction (double, double)->double
89 // qui donne y' en fonction de y et t.
90 DiffEqFcnT1(DIFEQFCNT1);
91
92 // Implementation de Compute qui va utiliser la fonction fournie
93 // au constructeur.
94 virtual void ComputeV(Vector& fpi, Vector const& fi);
95
96 // Implementation de AdjustStart qui gere la fonction a usage interne.
97 virtual void AdjustStart(Vector& start, double tstart);
98protected:
99 DIFEQFCNT1 mFcn;
100};
101
102// Cas y'' = f(y',y)
103typedef double(*DIFEQFCN2)(double, double);
104
105class DiffEqFcn2 : public DiffEqFunction {
106public:
107 DiffEqFcn2(DIFEQFCN2);
108
109 virtual void ComputeV(Vector& fpi, Vector const& fi);
110protected:
111 DIFEQFCN2 mFcn;
112};
113
114// Cas y'' = f(y',y,t)
115typedef double(*DIFEQFCNT2)(double, double, double);
116
117// <summary> y'' = f(y',y,t) </summary>
118// Cas y'' = f(y',y,t), on fournit la fonction f, sous la forme
119// double f(double, double, double), et ca construit la bonne DiffEqFunction
120class DiffEqFcnT2 : public DiffEqFunction {
121public:
122 // Constructeur, on fournit une fonction (double, double, double)->double
123 // qui donne y'' en fonction de y', y et t.
124 DiffEqFcnT2(DIFEQFCNT2);
125
126 // Implementation de Compute qui va utiliser la fonction fournie
127 // au constructeur.
128 virtual void ComputeV(Vector& fpi, Vector const& fi);
129
130 // Implementation de AdjustStart qui gere la fonction a usage interne.
131 virtual void AdjustStart(Vector& start, double tstart);
132protected:
133 DIFEQFCNT2 mFcn;
134};
135
136// Cas y'' = f(y',y) avec des 3-vecteurs
137typedef void(*DIFEQFCNV)(Vector&, Vector const&, Vector const&);
138
139// <summary> y'' = f(y',y,t) </summary>
140// Cas y'' = f(y',y,t), on fournit la fonction f, sous la forme
141// double f(Vector), et ca construit la bonne DiffEqFunction
142class DiffEqFcnV : public DiffEqFunction {
143public:
144 // Constructeur, on fournit une fonction (Vector)->double
145 // qui donne y'' en fonction du vecteur (t, y, y')
146 DiffEqFcnV(DIFEQFCNV);
147
148 // Implementation de Compute qui va utiliser la fonction fournie
149 // au constructeur.
150 virtual void ComputeV(Vector& fpi, Vector const& fi);
151protected:
152 DIFEQFCNV mFcn;
153 Vector tmp1, tmp2, tmp3;
154};
155
156// <summary> Classe abstraite de resolveur d'equadif </summary>
157// Classe abstraite de resolveur d'equadif
158// Beaucoup de fonctions renvoient l'objet pour pouvoir faire une
159// notation chainee s.Step(...).Start(...).Solve(...)
160class DiffEqSolver {
161public:
162 // Constructeurs. L'equadif est donnee sous forme de DiffEqFunction.
163 // On a prevu le cas particulier du premier degre directement
164 // <group>
165 DiffEqSolver();
166 DiffEqSolver(DiffEqFunction*);
167 DiffEqSolver(DIFEQFCN1);
168 // </group>
169
170 // Destructeur
171 virtual ~DiffEqSolver();
172
173 // Change la fonction. Notation chainee possible
174 // <group>
175 DiffEqSolver& Func(DiffEqFunction*);
176 DiffEqSolver& Func(DIFEQFCN1);
177 // </group>
178 // Change le pas d'integration. Notation chainee possible
179 DiffEqSolver& Step(double);
180
181 // Change les conditions initiales. Notation chainee possible.
182 // <group>
183 DiffEqSolver& StartV(Vector const& yi, double t);
184 // si NFunc == 1
185 DiffEqSolver& Start1(double yi, double t);
186 DiffEqSolver& Start(double const* yi, double t);
187 // </group>
188
189 // Lance la resolution, avec ou sans conservation de n valeurs intermediaires
190 // <group>
191 virtual void SolveV(Vector& yf, double tf);
192 // si NFunc == 1
193 virtual void Solve1(double& yf, double tf);
194 virtual void Solve(double* yf, double tf);
195 virtual void SolveArr(Matrix& y, double* t, double tf, int n)=0;
196 // si NFunc == 1
197 virtual void SolveArr1(double* y, double* t, double tf, int n);
198 virtual void SolveArr2(double** y, double* t, double tf, int n);
199 // </group>
200
201protected:
202 DiffEqFunction* mFunc;
203 bool mOwnFunc;
204
205 Vector mYStart;
206 double mXStart;
207 double mStep;
208};
209
210// <summary> Runge-Kutta ordre 4 </summary>
211// Runge-Kutta ordre 4
212class RK4DiffEq : public DiffEqSolver {
213public:
214 // Constructeurs. Voir <linkto class=DiffEqSolver>DiffEqSolver</linkto>
215 // <group>
216 RK4DiffEq();
217 RK4DiffEq(DiffEqFunction*);
218 RK4DiffEq(DIFEQFCN1);
219 // </group>
220
221 // Implementation de RK4
222 virtual void SolveArr(Matrix& y, double* t, double tf, int n);
223
224protected:
225 // Un pas RK4
226 void RKStep(Vector& newY, Vector const& y0, double dt);
227 // Vecteurs utilises en interne, pour ne pas les reallouer.
228 Vector k1, k2, k3, k4;
229};
230
231
232} // Fin du namespace
233
234#endif
Note: See TracBrowser for help on using the repository browser.