1 <?xml version="1.0" encoding="UTF-8"?>
2 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns5="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="ode" xml:lang="fr">
5 <refpurpose>solveur d'équations différentielles ordinaires</refpurpose>
8 <title>Séquence d'appel</title>
9 <synopsis>y=ode(y0,t0,t,f)
10 [y,w,iw]=ode([type],y0,t0,t [,rtol [,atol]],f [,jac] [,w,iw])
11 [y,rd,w,iw]=ode("root",y0,t0,t [,rtol [,atol]],f [,jac],ng,g [,w,iw])
12 y=ode("discrete",y0,k0,kvect,f)
16 <title>Paramètres</title>
21 <para>vecteur ou matrice réelle (conditions initiales).</para>
27 <para>réel (instant initial).</para>
33 <para>vecteur réel (instants où la solution est renvoyée).</para>
39 <para>fonction externe (fonction Scilab ou chaîne de caractères ou
48 une des chaînes de caractères : <literal>"adams"</literal>,
49 <literal>"stiff"</literal>, <literal>"rk"</literal>,
50 <literal>"rkf"</literal>, <literal>"fix"</literal>,
51 <literal>"discrete"</literal>, <literal>"roots"</literal>
56 <term>rtol, atol</term>
58 <para>constantes ou vecteurs réels de même taille que
66 <para>fonction externe (fonction Scilab, chaîne de caractères ou
74 <para>vecteurs réels</para>
86 <para>fonction externe (fonction Scilab, chaîne de caractères ou
94 <para>entier (instant initial).</para>
100 <para>vecteur d'entiers.</para>
106 <title>Description</title>
108 <literal>ode</literal> est la fonction utilisée pour approcher la
109 solution d'une équation différentielle ordinaire (EDO) explicite du
110 premier ordre en temps, définie par : dy/dt=f(t,y) , y(t0)=y0. Il s'agit
111 d'une interface vers diverses bibliothèques, en particulier ODEPACK. Le type
112 du problème et la méthode utilisée dépendent de la valeur du premier
113 argument optionnel <literal>type</literal> qui peut être égal à :
117 <term><aucun> :</term>
120 le solveur <literal>lsoda</literal> du package ODEPACK est
121 utilisé par défaut. Il choisit automatiquement entre un schéma
122 prédicteur-correcteur d'Adams et un schéma adapté au systèmes raides
123 (stiff) de type "Backward Differentiation Formula" (BDF).
124 Initialement le schéma adapté aux système non raides est choisi puis
125 la méthode adaptée est ensuite choisie dynamiquement.
130 <term>"adams" :</term>
133 Problèmes non raides. Le solveur <literal>lsode</literal> du
134 package ODEPACK est utilisé (schéma d'Adams).
139 <term>"stiff" :</term>
142 Pour les systèmes raides. Le solveur <literal>lsode</literal>
143 du package ODEPACK est utilisé avec le schéma BDF.
150 <para>Schéma de Runge-Kutta adaptatif d'ordre 4 (RK4).</para>
156 <para>Formules de Shampine et Watts basées sur les paires de
157 Runge-Kutta Fehlberg d'ordre 4 et 5 (RKF45). Bien pour les problèmes
158 non raides ou moyennement raides, lorsque le calcul du second membre
159 n'est pas trop coûteux. Cette méthode est à éviter si l'on recherche
160 une très grande précision.
168 Identique à <literal>"rkf"</literal>, mais l'interface est
170 uniquement <literal>rtol</literal> et <literal>atol</literal> sont
171 communiqués au solveur.
178 <para>Solveur d'EDO avec recherche de racines. Le solveur
179 <literal>lsodar</literal> du package ODEPACK est utilisé. C'est une
180 variante de <literal>lsoda</literal> permettant la recherche d'une
181 racine d'une fonction vectorielle donnée. Voir <link linkend="ode_root">ode_root</link> pour plus de
187 <term>"discrete":</term>
190 Simulation en temps discret. Voir <link linkend="ode_discrete">ode_discrete</link> pour plus de
197 Ici on ne décrit l'usage de <literal>ode</literal> que pour des EDO
203 L'appel le plus simple de <literal>ode</literal> est du type :
204 <literal>y=ode(y0,t0,t,f)</literal> où <literal>y0</literal> est le
205 vecteur des conditions initiales, <literal>t0</literal> est le temps
206 initial, et <literal>t</literal> est le vecteur des instants où l'on
207 veut une approximation de la solution. <literal>y</literal> est
208 calculée et <literal>y</literal> est la matrice
209 <literal>y=[y(t(1)),y(t(2)),...]</literal>.
212 Le paramètre d'entrée <literal>f</literal> de
213 <literal>ode</literal> définit le membre de droite de l'équation
214 différentielle du premier ordre dy/dt=f(t,y). C'est un external qui
220 Soit une fonction Scilab, sa syntaxe doit être <literal>ydot
223 où <literal>t</literal> est un scalaire (le
224 temps), <literal>y</literal> un vecteur (l'état). Cette fonction
225 renvoie le second membre de l'équation différentielle
230 <para>Soit une chaîne de caractères, elle désigne le nom d'une
231 subroutine Fortran ou une procédure C, i.e. si
232 <literal>ode(y0,t0,t,"fex")</literal> est la commande, alors la
233 procedure <literal>fex</literal> est appelée.
235 <para>Si c'est une subroutine Fortran, sa liste d'appel doit
238 <programlisting role=""><![CDATA[
239 subroutine fex(n,t,y,ydot)
241 double precision t,y(*),ydot(*)
243 <para>Si c'est une fonction C son prototype doit être:</para>
244 <programlisting role=""><![CDATA[
245 void fex(int *n,double *t,double *y,double *ydot)
248 Cet external peut être compilé par l'utilitaire <link linkend="ilib_for_link">ilib_for_link</link> et chargé
249 dynamiquement par la fonction <link linkend="link">link</link>.
253 <para>Soit une liste avec la structure suivante
254 <literal>list(vrai_f,u1,u2,...un)</literal> où
255 <literal>vrai_f</literal> est une fonction avec la syntaxe
256 <literal>ydot = vrai_f(t,y,u1,u2,...,un)</literal>
258 <para>Cette syntaxe permet de passer des paramètres sous forme
259 d'arguments supplémentaires de <literal>vrai_f</literal>.
264 La fonction <literal>f</literal> peut renvoyer une matrice
265 <literal>p x q</literal> au lieu d'un vecteur. Dans ce cas, on résout
266 le système d'EDO <literal>n=p+q</literal>
267 <literal>dY/dt=F(t,Y)</literal> où <literal>Y</literal> est une
268 matrice <literal>p x q</literal>. La condition initiale
269 <literal>Y0</literal> doit aussi être une matrice <literal>p x
272 matrix et le résultat renvoyé par <literal>ode</literal>
273 est la matrice: <literal>p x q(T+1)</literal> égale à
274 <literal>[Y(t_0),Y(t_1),...,Y(t_T)]</literal>.
278 <para>Des paramètres optionnels contrôlent la tolérance du schéma :
279 <literal>rtol</literal> et <literal>atol</literal> sont des valeurs
280 seuil sur les erreurs estimées (relative et absolue) L'erreur estimée
281 sur <literal>y(i)</literal> est
282 <literal>rtol(i)*abs(y(i))+atol(i)</literal>
285 Si <literal>rtol</literal> et/ou <literal>atol</literal> sont
286 des constantes <literal>rtol(i)</literal> et/ou
287 <literal>atol(i)</literal> prennent ces valeurs. Les valeurs par
288 défaut de <literal>rtol</literal> et <literal>atol</literal> sont
289 respectivement <literal>rtol=1.d-5</literal> et
290 <literal>atol=1.d-7</literal> pour la plupart des solveurs et
291 <literal>rtol=1.d-3</literal> et <literal>atol=1.d-4</literal> pour
292 <literal>"rfk"</literal> et <literal>"fix"</literal>.
296 <para>Pour les problèmes raides, il est recommandé de fournir la
297 jacobienne du second membre sous forme de l'argument optionnel
298 <literal>jac</literal>. Le paramètre <literal>jac</literal> de
299 <literal>ode</literal> est par exemple une fonction Scilab, dont la
300 syntaxe est imposée, ou le nom d'une subroutine Fortran ou C (chaîne
301 de caractères) ou une liste.
304 Si <literal>jac</literal> est une fonction Scilab sa syntaxe
305 doit être <literal>J=jac(t,y)</literal>
308 où <literal>t</literal> est un scalaire (le temps) et
309 <literal>y</literal> un vecteur (l'état). La matrice
310 <literal>J</literal> doit renvoyer df/dx i.e. <literal>J(k,i) = dfk
313 avec <literal>fk</literal> = k-ième composante de
317 Si <literal>f</literal> est une chaîne de caractères, elle
318 désigne le nom d'une subroutine Fortran ou C.
320 <para>En Fortran, Cette routine doit avoir la liste d'appel suivante
323 <programlisting role=""><![CDATA[
324 subroutine fex(n,t,y,ml,mu,J,nrpd)
326 double precision t,y(*),J(*)
328 <para>Si c'est une fonction C son prototype doit être:</para>
329 <programlisting role=""><![CDATA[
330 void fex(int *n,double *t,double *y,int *ml,int *mu,double *J,int *nrpd,)
332 <para>Dans la plupart des cas il n'est pas nécessaire d'utiliser
333 <literal>ml</literal>, <literal>mu</literal> et
334 <literal>nrpd</literal>, qui sont relatifs à la possibilité de
335 stockage "bande" du Jacobien
338 Si <literal>jac</literal> est une liste, les mêmes conventions
339 que pour <literal>f</literal> s'appliquent.
344 Les arguments optionnels <literal>w</literal> et
345 <literal>iw</literal> sont des vecteurs dans lesquels le solveur stocke des
346 informations sur son état (voir <link linkend="ode_optional_output">ode_optional_output</link> pour plus de
347 détails) . Lorsque ces paramêtres sont utilisés comme argument
348 d'entrée, ils permettent de redémarrer l'intégration au point où elle
349 s'était arrêtée à la sortie d'un appel précédent à
350 <literal>ode</literal>.
354 <para>Plus d'options peuvent être passées aux solveurs d'ODEPACK en
355 utilisant la variable <literal>%ODEOPTIONS</literal>. Voir <link linkend="odeoptions">odeoptions</link>.
361 <title>Exemples</title>
362 <programlisting role="example"><![CDATA[
363 // ---------- EDO Simple (external : fonction Scilab)
364 // dy/dt=y^2-y sin(t)+cos(t), y(0)=0
365 function ydot=f(t,y),ydot=y^2-y*sin(t)+cos(t),endfunction
366 y0=0;t0=0;t=0:0.1:%pi;
370 // ---------- EDO Simple (external : code C)
371 ccode=['#include <math.h>'
372 'void myode(int *n,double *t,double *y,double *ydot)'
374 ' ydot[0]=y[0]*y[0]-y[0]*sin(*t)+cos(*t);'
376 mputl(ccode,TMPDIR+'/myode.c') //create the C file
377 ilib_for_link('myode','myode.c',[],'c',[],TMPDIR+'/loader.sce');//compile
378 exec(TMPDIR+'/loader.sce') //incremental linking
379 y0=0;t0=0;t=0:0.1:%pi;
380 y=ode(y0,t0,t,'myode');
382 // ---------- Simulation de dx/dt = A x(t) + B u(t) avec u(t)=sin(omega*t),
384 // solution x(t) desired at t=0.1, 0.2, 0.5 ,1.
385 // A and u function are passed to RHS function in a list.
386 // B and omega are passed as global variables
387 function xdot=linear(t,x,A,u),xdot=A*x+B*u(t),endfunction
388 function ut=u(t),ut=sin(omega*t),endfunction
389 A=[1 1;0 2];B=[1;1];omega=5;
390 ode([1;0],0,[0.1,0.2,0.5,1],list(linear,A,u))
392 // ----------Integration de l'équation différentielle de Riccati (état matriciel)
393 // Xdot=A'*X + X*A - X'*B*X + C , X(0)=Identity
394 // Solution at t=[1,2]
395 function Xdot=ric(t,X),Xdot=A'*X+X*A-X'*B*X+C,endfunction
396 A=[1,1;0,2]; B=[1,0;0,1]; C=[1,0;0,1];
398 X=ode(eye(A),0,t,ric)
400 // ---------- Calcul de exp(A) (état matriciel)
402 function xdot=f(t,x),xdot=A*x;,endfunction
404 ode("adams",eye(A),0,1,f)
406 // ---------- Calcul de exp(A) (état matriciel, cas raide, jacobien fourni)
408 function xdot=f(t,x),xdot=A*x,endfunction
409 function J=Jacobian(t,y),J=A,endfunction
410 ode("stiff",[0;1],0,1,f,Jacobian)
413 <refsection role="see also">
414 <title>Voir aussi</title>
415 <simplelist type="inline">
417 <link linkend="ode_discrete">ode_discrete</link>
420 <link linkend="ode_root">ode_root</link>
423 <link linkend="dassl">dassl</link>
426 <link linkend="impl">impl</link>
429 <link linkend="odedc">odedc</link>
432 <link linkend="odeoptions">odeoptions</link>
435 <link linkend="csim">csim</link>
438 <link linkend="ltitr">ltitr</link>
441 <link linkend="rtitr">rtitr</link>
444 <link linkend="intg">intg</link>
449 <title>Bibliographie</title>
450 <para>Alan C. Hindmarsh, lsode and lsodi, two new initial value ordinary
451 differential equation solvers, acm-signum newsletter, vol. 15, no. 4
456 <title>Fonctions Utilisées</title>
457 <para>Les sous-programmes associés se trouvent dans le répertoire
458 SCI/modules/differential_equations/src/fortran/: lsode.f lsoda.f lsodar.f