dae
Solveur de système d'Equations Différentielles Algébriques
Séquence d'appel
y = dae(y0, t0, t, res) [y [,hd]] = dae(y0, t0, t [[,rtol], atol], res [,jac] [,hd]) [y, rd] = dae("root", y0, t0, t, res, ng, surface) [y, rd [,hd]] = dae("root", y0, t0, t [[,rtol], atol], res [,jac], ng, surface [,hd]) [y, rd] = dae("root2", y0, t0, t, res, ng, surface) [y, rd [,hd]] = dae("root2", y0, t0, t [[,rtol], atol], res [,jac], ng, surface [, psol, pjac] [, hd])
Paramètres
- y0
vecteur colonne. Peut valoir
x0ou[x0;xdot0], oùx0est la valeur de l'état au temps initialt0etxdot0est la valeur (ou une estimation) de l'état dérivé au temps initial (voir ci-après).- t0
réel, le temps initial.
- t
scalaire ou vecteur réel. Les instants auxquels la solution est voulue. La solution peut s'obtenir à chaque étape de dae en initialisant
%DAEOPTIONS(2)=1.- rtol
un scalaire ou vecteur colonne réel de même taille que
x0, la tolérance relative de la solution. Siatolest un vecteur, les tolérances sont spécifiées pour chaque composante de l'état.- atol
un scalaire ou vecteur colonne réel de même taille que
x0, la tolérance absolue de la solution. Siatolest un vecteur, les tolérances sont spécifiées pour chaque composante de l'état.- res
une fonction external, calcule la valeur de
g(t, y, ydot). Peut être- une fonction Scilab
Dans ce cas, sa séquence d'appel doit être
[r, ires] = res(t, x, xdot)etresdoit retourner le résidur = g(t, x, xdot)et un drapeau d'erreurires.ires = 0siresest bien parvenu à calculerr.ires = -1si le résidu est localement non-défini pourg(t, x, xdot).ires = -2si le paramètres ne sont pas admissibles.- une liste
Cette forme d'external sert à passer des paramètres à la fonction. Elle doit se présenter comme suit:
list(res, p1, p2,...)
où la séquence d'appel de la fonction
resestr = res(t, y, ydot, p1, p2,...)
resretourne toujours le résidu comme fonction de(t, x, xdot, x1, x2, ...), etp1, p2,...sont des paramètres de la fonction.- une chaîne de caractères
Elle doit se référer au nom d'une routine C ou Fortran. Supposant que <
r_name> est le nom donné,La séquence d'appel en Fortran doit être
<r_name>(t, x, xdot, res, ires, rpar, ipar)double precision t,x(*),xdot(*),res(*),rpar(*)integer ires,ipar(*)La séquence d'appel en C doit être
C2F(<r_name>)(double *t, double *x, double *xdot, double *res, integer *ires, double *rpar, integer *ipar)
où
test la valeur actuelle du tempsxest la valeur de l'étatxdotest la valeur de l'état dérivéresla valeur du résiduiresindicateur de complétionrparest un vecteur de paramètres nécéssaires mais non initialisables pardae.iparest un vecteur de paramètres entiers nécéssaires mais non initialisables pardae
- jac
une fonction external, calcule la valeur de
dg/dx+cj*dg/dxdotpour un paramètrecjdonné. Elle peut être:- une fonction Scilab
Sa séquence d'appel doit être
r = jac(t, x, xdot, cj)et la fonctionjacdoit retournerr = dg(t, x, xdot)/dy + cj * dg(t, x, xdot)/dxdotoùcjest un scalaire réel.- une liste
Cette forme d'external est utilisée pour passer des paramètres à la fonction. Elle doit se présenter comme suit :
list(jac,p1,p2,...)
où la séquence d'appel de la fonction
jacestr = jac(t,x,xdot,p1,p2,...)
jacretourne toujoursdg/dx+cj*dg/dxdotcomme fonction de(t, x, xdot, cj, p1, p2,...).- une chaîne de caractères
elle doit se référer au nom d'une routine C ou Fortran. Supposant que <j_name> est le nom donné,
La séquence d'appel en Fortran doit être
<j_name>(t, x, xdot, r, cj, ires, rpar, ipar)double precision
t, x(*), xdot(*), r(*), ci, rpar(*)integer
ires, ipar(*)La séquence d'appel en C doit être
C2F(<j_name>)(double *t, double *x, double *xdot, double *r, double *cj, integer *ires, double *rpar, integer *ipar)
où
t, x, xdot, ires, rpar, iparont la même définition qu'au-dessus,rest la valeur du résultat
- surface
une fonction external, calcule a valeur du vecteur colonne
surface(t,x)àngéléments. Chaque élément définit une surface. Elle peut être- une fonction Scilab
Sa séquence d'appel doit être
r = surface(t, x), cette fonction doit retourner un vecteur colonne àngéléments.- une liste
Cette forme d'external est utilisé pour passer des paramètres à la fonction. Elle doit se présenter comme suit :
list(surface, p1, p2,...)
où la qéquence d'appel de la fonction
surfaceestr = surface(t, x, p1, p2,...)
- une chaîne de caractères
elle doit se référer au nom d'une routine C ou Fortran. Supposant que <s_name> est le nom donné,
La séquence d'appel en Fortran doit être
<s_name>(nx, t, x, ng, r, rpar, ipar)double precision t, x(*), r(*), rpar(*)integer nx, ng, ipar(*)La séquence d'appel en C doit être
C2F(<s_name>)(double *t, double *x, double *xdot, double *r, double *cj, integer *ires, double *rpar, integer *ipar)
où
t, x, rpar, iparont les mêmes définitions qu'au-dessus,ngest le nombre de surfaces,nxest la dimension de l'état etrest le vecteur résultat.
- rd
un vecteur à deux entrées
[times num]oùtimesest la valeur des temps auquel les surfaces sont traversées,numest le nombre de surfaces traversées.- psol
external (fonction, liste or chaîne de caractères).
- pjac
external (fonction, liste or chaîne de caractères).
- hd
vecteur réel, stocke en sortie le contexte de
dae. Peut être utilisé comme paramètre d'entrée pour reprendre l'intégration (reprise à chaud).- y
matrice réelle. Si
%DAEOPTIONS(2)=1, chaque colonne est le vecteur[t;x(t);xdot(t)]oùtest le temps auquel la solution à été calculée. Sinonyest le vecteur[x(t);xdot(t)].
Description
La fonction dae résout l'équation différentielle algébrique et renvoie l'évolution
de y à des moments donnés
g(t, x, xdot) = 0 x(t0) = x0 and xdot(t0) = xdot0
Si xdot0 n'est pas donné en paramètre initial,
dae tente de la calculer en résolvant
g(t,x0,xdot0)=0.
Si xdot0 est donné en paramètre initial, il peut soit
satifaire g(t,x0,xdot0)=0, soit en être une approximation.
Dans le dernier cas,
%DAEOPTIONS(7) doit être initialisé à 1.
Des exemples détaillés utilisant des externals codées en C et en Scilab se trouvent dans
modules/differential_equations/tests/unit_tests/dassldasrt.tst et
modules/differential_equations/tests/unit_tests/daskr.tst
Exemples
Exemple #1: dassl (pas de traversée de surface)
// Exemple avec du code Scilab //-------------------------------------------------- function [r, ires]=chemres(t, y, yd) r(1) = -0.04*y(1) + 1d4*y(2)*y(3) - yd(1); r(2) = 0.04*y(1) - 1d4*y(2)*y(3) - 3d7*y(2)*y(2) - yd(2); r(3) = y(1) + y(2) + y(3)-1; ires = 0; endfunction function pd=chemjac(x, y, yd, cj) pd = [-0.04-cj , 1d4*y(3) , 1d4*y(2); 0.04 ,-1d4*y(3)-2*3d7*y(2)-cj ,-1d4*y(2); 1 , 1 , 1 ] endfunction x0 = [1; 0; 0]; xd0 = [-0.04; 0.04; 0]; t = [1.d-5:0.02:.4, 0.41:.1:4, 40, 400, 4000, 40000, 4d5, 4d6, 4d7, 4d8, 4d9, 4d10]; y = dae([x0, xd0], 0, t, chemres); // Retourne les points d'observation demandés %DAEOPTIONS = list([], 1, [], [], [], 0, 0); // Demande à dae les points à retourner y = dae([x0, xd0], 0, 4d10, chemres); // Sans jacobian y = dae([x0, xd0], 0, 4d10, chemres, chemjac); // Avec jacobien
Exemple #2: utilise le solveur dasrt avec "root"
// Exemple avec du code C (compilateur C requis) //-------------------------------------------------- bOK = haveacompiler(); if bOK <> %t [btn] = messagebox(["Vous avez besoin d''un compilateur C pour cet exemple."; "Arrêt de l''exécution."], "Problème de Software", "info"); return end //-1- Crée les codes C dans TMPDIR - équation de Vanderpol, forme implicite code = ['#include <math.h>' 'void res22(double *t, double *y, double *yd, double *res, int *ires, double *rpar, int *ipar)' '{res[0] = yd[0] - y[1];' ' res[1] = yd[1] - (100.0*(1.0 - y[0]*y[0])*y[1] - y[0]);}' ' ' 'void jac22(double *t, double *y, double *yd, double *pd, double *cj, double *rpar, int *ipar)' '{pd[0] = *cj - 0.0;' ' pd[1] = - (-200.0*y[0]*y[1] - 1.0);' ' pd[2] = - 1.0;' ' pd[3] = *cj - (100.0*(1.0 - y[0]*y[0]));}' ' ' 'void gr22(int *neq, double *t, double *y, int *ng, double *groot, double *rpar, int *ipar)' '{ groot[0] = y[0];}'] previous_dir = pwd(); cd TMPDIR; mputl(code, 't22.c') //-2- Compile et charge ilib_for_link(['res22' 'jac22' 'gr22'], 't22.c', [], 'c', [], 't22loader.sce'); exec('t22loader.sce') //-3- Exécute rtol = [1.d-6; 1.d-6]; atol = [1.d-6; 1.d-4]; t0 = 0; t = [20:20:200]; y0 = [2; 0]; y0d = [0; -2]; ng = 1; // Simulation simple t = 0:0.003:300; yy = dae([y0, y0d], t0, t, atol, rtol, 'res22', 'jac22'); clf(); plot(yy(1, :), yy(2, :)) // Trouve le premier point où yy(1) = 0 [yy, nn, hotd] = dae("root", [y0, y0d], t0, 300, atol, rtol, 'res22', 'jac22', ng, 'gr22'); plot(yy(1, 1), yy(2, 1), 'r+') xstring(yy(1, 1)+0.1, yy(2, 1), string(nn(1))); // Reprise à chaud pour le point suivant t01 = nn(1); [pp, qq] = size(yy); y01 = yy(2:3, qq); y0d1 = yy(3:4, qq); [yy, nn, hotd] = dae("root", [y01, y0d1], t01, 300, atol, rtol, 'res22', 'jac22', ng, 'gr22', hotd); plot(yy(1, 1), yy(2, 1), 'r+') xstring(yy(1, 1)+0.1, yy(2, 1), string(nn(1))); cd(previous_dir);
Exemple #3: utilise le solveur daskr avec le mot-clé "root2", avec les routines 'psol' et 'pjac' par défaut
// Exemple avec du code C (compilateur C requis) //-------------------------------------------------- bOK = haveacompiler(); if bOK <> %t [btn] = messagebox(["Vous avez besoin d''un compilateur C pour cet exemple."; "Arrêt de l''exécution."], "Problème de Software", "info"); return end //-1- Crée les codes C dans TMPDIR - équation de Vanderpol, forme implicite code = ['#include <math.h>' 'void res22(double *t, double *y, double *yd, double *res, int *ires, double *rpar, int *ipar)' '{res[0] = yd[0] - y[1];' ' res[1] = yd[1] - (100.0*(1.0 - y[0]*y[0])*y[1] - y[0]);}' ' ' 'void jac22(double *t, double *y, double *yd, double *pd, double *cj, double *rpar, int *ipar)' '{pd[0] = *cj - 0.0;' ' pd[1] = - (-200.0*y[0]*y[1] - 1.0);' ' pd[2] = - 1.0;' ' pd[3] = *cj - (100.0*(1.0 - y[0]*y[0]));}' ' ' 'void gr22(int *neq, double *t, double *y, int *ng, double *groot, double *rpar, int *ipar)' '{ groot[0] = y[0];}'] previous_dir = pwd(); cd TMPDIR; mputl(code, 't22.c') //-2- Compile et charge ilib_for_link(['res22' 'jac22' 'gr22'], 't22.c', [], 'c', [], 't22loader.sce'); exec('t22loader.sce') //-3- Exécute rtol = [1.d-6; 1.d-6]; atol = [1.d-6; 1.d-4]; t0 = 0; t = [20:20:200]; y0 = [2; 0]; y0d = [0; -2]; ng = 1; // Simulation simple t = 0:0.003:300; yy = dae([y0, y0d], t0, t, atol, rtol, 'res22', 'jac22'); clf(); plot(yy(1, :), yy(2, :)) // Trouve le premier point où yy(1) = 0 %DAEOPTIONS = list([] , 0, [], [], [], 0, [], 1, [], 0, 1, [], [], 1); [yy, nn, hotd] = dae("root2", [y0, y0d], t0, 300, atol, rtol, 'res22', 'jac22', ng, 'gr22', 'psol1', 'pjac1'); plot(yy(1, 1), yy(2, 1), 'r+') xstring(yy(1, 1)+0.1, yy(2, 1), string(nn(1))); // Reprise à chaud pour le point suivant t01 = nn(1); [pp, qq] = size(yy); y01 = yy(2:3, qq); y0d1 = yy(3:4, qq); [yy, nn, hotd] = dae("root2", [y01, y0d1], t01, 300, atol, rtol, 'res22', 'jac22', ng, 'gr22', 'psol1', 'pjac1', hotd); plot(yy(1, 1), yy(2, 1), 'r+') xstring(yy(1, 1)+0.1, yy(2, 1), string(nn(1))); cd(previous_dir);

Voir aussi
- dae_root — differential algebraic equation solver with roots finding
- ode — solveur d'équations différentielles ordinaires
- daeoptions — set options for dae solver
- impl — differential algebraic equation
- call — Fortran or C user routines call
- link — dynamic linker
- external — Objet Scilab, fonction externe ou routine
History
| Version | Description |
| 2024.1.0 | dassl, dasrt and daskr deviennent des fonctions internes. |
| Report an issue | ||
| << bvode | Equations différentielles | dae_root >> |