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

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

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

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:
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
[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
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...
[514]52 virtual void AdjustStart(Vector& /*start*/, double /*tstart*/)
[220]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.
[514]95 virtual void ComputeV(Vector& fpi, Vector const& fi);
[220]96
97 // Implementation de AdjustStart qui gere la fonction a usage interne.
[514]98 virtual void AdjustStart(Vector& start, double tstart);
[220]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
[514]110 virtual void ComputeV(Vector& fpi, Vector const& fi);
[220]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.
[514]129 virtual void ComputeV(Vector& fpi, Vector const& fi);
[220]130
131 // Implementation de AdjustStart qui gere la fonction a usage interne.
[514]132 virtual void AdjustStart(Vector& start, double tstart);
[220]133protected:
134 DIFEQFCNT2 mFcn;
135};
136
137// Cas y'' = f(y',y) avec des 3-vecteurs
[514]138typedef void(*DIFEQFCNV)(Vector&, Vector const&, Vector const&);
[220]139
140// <summary> y'' = f(y',y,t) </summary>
141// Cas y'' = f(y',y,t), on fournit la fonction f, sous la forme
[514]142// double f(Vector), et ca construit la bonne DiffEqFunction
[220]143class DiffEqFcnV : public DiffEqFunction {
144public:
[514]145 // Constructeur, on fournit une fonction (Vector)->double
[220]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.
[514]151 virtual void ComputeV(Vector& fpi, Vector const& fi);
[220]152protected:
153 DIFEQFCNV mFcn;
[514]154 Vector tmp1, tmp2, tmp3;
[220]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(...)
[1371]161class DiffEqSolver {
[220]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>
[514]184 DiffEqSolver& StartV(Vector const& yi, double t);
[220]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>
[514]192 virtual void SolveV(Vector& yf, double tf);
[220]193 // si NFunc == 1
194 virtual void Solve1(double& yf, double tf);
195 virtual void Solve(double* yf, double tf);
[514]196 virtual void SolveArr(Matrix& y, double* t, double tf, int n)=0;
[220]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
[514]206 Vector mYStart;
[220]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
[514]223 virtual void SolveArr(Matrix& y, double* t, double tf, int n);
[220]224
225protected:
226 // Un pas RK4
[514]227 void RKStep(Vector& newY, Vector const& y0, double dt);
[220]228 // Vecteurs utilises en interne, pour ne pas les reallouer.
[514]229 Vector k1, k2, k3, k4;
[220]230};
231
232
[514]233} // Fin du namespace
[220]234
235#endif
Note: See TracBrowser for help on using the repository browser.