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

Last change on this file since 459 was 307, checked in by ansari, 26 years ago

FIO_... + grosses modifs cmv 19/5/99

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