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

Last change on this file since 262 was 244, checked in by ansari, 26 years ago

beaucoup modifs rz+cmv 22/4/99

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