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

Last change on this file since 757 was 552, checked in by ansari, 26 years ago

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