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

Last change on this file since 2384 was 1371, checked in by ansari, 25 years ago

MAJ documentation, Makefile, ... - Reza 5/1/2001

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 // Constructeur. n = nombre reel de fonctions dans le systeme,
27 // m = nombre apparent (il y a dans certaines cas des fonctions a
28 // usage interne, par exemple la fonction constante valant 1...)
29
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
51 // interne...
52 virtual void AdjustStart(Vector& /*start*/, double /*tstart*/)
53 {}
54protected:
55 // Nombre de fonctions dans le systeme
56 int mNFunc;
57 // Nombre apparent de fonctions
58 int mNFuncApp;
59};
60
61
62// Cas y' = f(y)
63typedef double(*DIFEQFCN1)(double);
64
65// <summary> Cas y' = f(y) </summary>
66// Cas y' = f(y), on fournit la fonction f, sous la forme
67// double f(double), et ca construit la bonne DiffEqFunction
68class DiffEqFcn1 : public DiffEqFunction {
69public:
70 // Constructeur, on fournit une fonction double->double
71 // qui donne y' en fonction de y.
72 DiffEqFcn1(DIFEQFCN1);
73
74 // Implementation de Compute qui va utiliser la fonction fournie
75 // au constructeur.
76 virtual void Compute(double& fp, double f);
77protected:
78 DIFEQFCN1 mFcn;
79};
80
81// Cas y' = f(y,t)
82typedef double(*DIFEQFCNT1)(double, double);
83
84// <summary> y' = f(y,t) </summary>
85// Cas y' = f(y,t), on fournit la fonction f, sous la forme
86// double f(double, double), et ca construit la bonne DiffEqFunction
87class DiffEqFcnT1 : public DiffEqFunction {
88public:
89 // Constructeur, on fournit une fonction (double, double)->double
90 // qui donne y' en fonction de y et t.
91 DiffEqFcnT1(DIFEQFCNT1);
92
93 // Implementation de Compute qui va utiliser la fonction fournie
94 // au constructeur.
95 virtual void ComputeV(Vector& fpi, Vector const& fi);
96
97 // Implementation de AdjustStart qui gere la fonction a usage interne.
98 virtual void AdjustStart(Vector& start, double tstart);
99protected:
100 DIFEQFCNT1 mFcn;
101};
102
103// Cas y'' = f(y',y)
104typedef double(*DIFEQFCN2)(double, double);
105
106class DiffEqFcn2 : public DiffEqFunction {
107public:
108 DiffEqFcn2(DIFEQFCN2);
109
110 virtual void ComputeV(Vector& fpi, Vector const& fi);
111protected:
112 DIFEQFCN2 mFcn;
113};
114
115// Cas y'' = f(y',y,t)
116typedef double(*DIFEQFCNT2)(double, double, double);
117
118// <summary> y'' = f(y',y,t) </summary>
119// Cas y'' = f(y',y,t), on fournit la fonction f, sous la forme
120// double f(double, double, double), et ca construit la bonne DiffEqFunction
121class DiffEqFcnT2 : public DiffEqFunction {
122public:
123 // Constructeur, on fournit une fonction (double, double, double)->double
124 // qui donne y'' en fonction de y', y et t.
125 DiffEqFcnT2(DIFEQFCNT2);
126
127 // Implementation de Compute qui va utiliser la fonction fournie
128 // au constructeur.
129 virtual void ComputeV(Vector& fpi, Vector const& fi);
130
131 // Implementation de AdjustStart qui gere la fonction a usage interne.
132 virtual void AdjustStart(Vector& start, double tstart);
133protected:
134 DIFEQFCNT2 mFcn;
135};
136
137// Cas y'' = f(y',y) avec des 3-vecteurs
138typedef void(*DIFEQFCNV)(Vector&, Vector const&, Vector const&);
139
140// <summary> y'' = f(y',y,t) </summary>
141// Cas y'' = f(y',y,t), on fournit la fonction f, sous la forme
142// double f(Vector), et ca construit la bonne DiffEqFunction
143class DiffEqFcnV : public DiffEqFunction {
144public:
145 // Constructeur, on fournit une fonction (Vector)->double
146 // qui donne y'' en fonction du vecteur (t, y, y')
147 DiffEqFcnV(DIFEQFCNV);
148
149 // Implementation de Compute qui va utiliser la fonction fournie
150 // au constructeur.
151 virtual void ComputeV(Vector& fpi, Vector const& fi);
152protected:
153 DIFEQFCNV mFcn;
154 Vector tmp1, tmp2, tmp3;
155};
156
157// <summary> Classe abstraite de resolveur d'equadif </summary>
158// Classe abstraite de resolveur d'equadif
159// Beaucoup de fonctions renvoient l'objet pour pouvoir faire une
160// notation chainee s.Step(...).Start(...).Solve(...)
161class DiffEqSolver {
162public:
163 // Constructeurs. L'equadif est donnee sous forme de DiffEqFunction.
164 // On a prevu le cas particulier du premier degre directement
165 // <group>
166 DiffEqSolver();
167 DiffEqSolver(DiffEqFunction*);
168 DiffEqSolver(DIFEQFCN1);
169 // </group>
170
171 // Destructeur
172 virtual ~DiffEqSolver();
173
174 // Change la fonction. Notation chainee possible
175 // <group>
176 DiffEqSolver& Func(DiffEqFunction*);
177 DiffEqSolver& Func(DIFEQFCN1);
178 // </group>
179 // Change le pas d'integration. Notation chainee possible
180 DiffEqSolver& Step(double);
181
182 // Change les conditions initiales. Notation chainee possible.
183 // <group>
184 DiffEqSolver& StartV(Vector const& yi, double t);
185 // si NFunc == 1
186 DiffEqSolver& Start1(double yi, double t);
187 DiffEqSolver& Start(double const* yi, double t);
188 // </group>
189
190 // Lance la resolution, avec ou sans conservation de n valeurs intermediaires
191 // <group>
192 virtual void SolveV(Vector& yf, double tf);
193 // si NFunc == 1
194 virtual void Solve1(double& yf, double tf);
195 virtual void Solve(double* yf, double tf);
196 virtual void SolveArr(Matrix& y, double* t, double tf, int n)=0;
197 // si NFunc == 1
198 virtual void SolveArr1(double* y, double* t, double tf, int n);
199 virtual void SolveArr2(double** y, double* t, double tf, int n);
200 // </group>
201
202protected:
203 DiffEqFunction* mFunc;
204 bool mOwnFunc;
205
206 Vector mYStart;
207 double mXStart;
208 double mStep;
209};
210
211// <summary> Runge-Kutta ordre 4 </summary>
212// Runge-Kutta ordre 4
213class RK4DiffEq : public DiffEqSolver {
214public:
215 // Constructeurs. Voir <linkto class=DiffEqSolver>DiffEqSolver</linkto>
216 // <group>
217 RK4DiffEq();
218 RK4DiffEq(DiffEqFunction*);
219 RK4DiffEq(DIFEQFCN1);
220 // </group>
221
222 // Implementation de RK4
223 virtual void SolveArr(Matrix& y, double* t, double tf, int n);
224
225protected:
226 // Un pas RK4
227 void RKStep(Vector& newY, Vector const& y0, double dt);
228 // Vecteurs utilises en interne, pour ne pas les reallouer.
229 Vector k1, k2, k3, k4;
230};
231
232
233} // Fin du namespace
234
235#endif
Note: See TracBrowser for help on using the repository browser.