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

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

MAJ documentation - Reza 14/6/2005

File size: 7.0 KB
RevLine 
[220]1// This may look like C code, but it is really -*- C++ -*-
[1371]2// Simple differential equation solver
3// E. Aubourg 1996-
4// DAPNIA/SPP (Saclay) / CEA LAL - IN2P3/CNRS (Orsay)
5
[220]6#ifndef DIFEQ_H_SEEN
7#define DIFEQ_H_SEEN
8
[244]9#include "machdefs.h"
10#include "pexceptions.h"
[514]11#include "tvector.h"
[220]12
[552]13namespace SOPHYA {
[220]14
[514]15class GeneralFunction;
16
[220]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.
[1371]21class DiffEqFunction {
[220]22public:
[2808]23 //! Constructeur. n = nombre de fonctions dans le systeme
[220]24 DiffEqFunction(int n) : mNFunc(n), mNFuncApp(n) {}
25
[2808]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....
[220]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
[514]36 virtual void ComputeV(Vector& fpi, Vector const& fi)
[220]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
[2808]44 //! Nombre apparent de fonctions dans le systeme
[220]45 int NFunc() {return mNFuncApp;}
46
[2808]47 //! Nombre reel de fonctions dans le systeme
[220]48 int NFuncReal() {return mNFunc;}
49
[2808]50 //! Pour ajuster vecteur de depart quand il y a des fonctions a usage v interne...
[514]51 virtual void AdjustStart(Vector& /*start*/, double /*tstart*/)
[220]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:
[2808]69 // Constructeur, on fournit une fonction double->double
[220]70 // qui donne y' en fonction de y.
71 DiffEqFcn1(DIFEQFCN1);
72
[2808]73 // Implementation de Compute qui va utiliser la fonction
74 // fournie au constructeur.
[220]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.
[514]94 virtual void ComputeV(Vector& fpi, Vector const& fi);
[220]95
96 // Implementation de AdjustStart qui gere la fonction a usage interne.
[514]97 virtual void AdjustStart(Vector& start, double tstart);
[220]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
[514]109 virtual void ComputeV(Vector& fpi, Vector const& fi);
[220]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.
[514]128 virtual void ComputeV(Vector& fpi, Vector const& fi);
[220]129
130 // Implementation de AdjustStart qui gere la fonction a usage interne.
[514]131 virtual void AdjustStart(Vector& start, double tstart);
[220]132protected:
133 DIFEQFCNT2 mFcn;
134};
135
136// Cas y'' = f(y',y) avec des 3-vecteurs
[514]137typedef void(*DIFEQFCNV)(Vector&, Vector const&, Vector const&);
[220]138
139// <summary> y'' = f(y',y,t) </summary>
140// Cas y'' = f(y',y,t), on fournit la fonction f, sous la forme
[514]141// double f(Vector), et ca construit la bonne DiffEqFunction
[220]142class DiffEqFcnV : public DiffEqFunction {
143public:
[514]144 // Constructeur, on fournit une fonction (Vector)->double
[220]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.
[514]150 virtual void ComputeV(Vector& fpi, Vector const& fi);
[220]151protected:
152 DIFEQFCNV mFcn;
[514]153 Vector tmp1, tmp2, tmp3;
[220]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(...)
[1371]160class DiffEqSolver {
[220]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>
[514]183 DiffEqSolver& StartV(Vector const& yi, double t);
[220]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>
[514]191 virtual void SolveV(Vector& yf, double tf);
[220]192 // si NFunc == 1
193 virtual void Solve1(double& yf, double tf);
194 virtual void Solve(double* yf, double tf);
[514]195 virtual void SolveArr(Matrix& y, double* t, double tf, int n)=0;
[220]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
[514]205 Vector mYStart;
[220]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
[514]222 virtual void SolveArr(Matrix& y, double* t, double tf, int n);
[220]223
224protected:
225 // Un pas RK4
[514]226 void RKStep(Vector& newY, Vector const& y0, double dt);
[220]227 // Vecteurs utilises en interne, pour ne pas les reallouer.
[514]228 Vector k1, k2, k3, k4;
[220]229};
230
231
[514]232} // Fin du namespace
[220]233
234#endif
Note: See TracBrowser for help on using the repository browser.