dae
Differential algebraic equations solver
Syntax
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])
Arguments
- y0
a column vector. It may be equal to
x0or[x0;xdot0]. Wherex0is the state value at initial timet0andxdot0is the initial state derivative value or an estimation of it (see below).- t0
a real number, the initial time.
- t
a real scalar or vector. Gives instants for which you want the solution. Note that you can get solution at each dae's step point by setting
%DAEOPTIONS(2)=1.- rtol
a real scalar or a column vector of same size as
x0, the relative error tolerance of solution. Ifrtolis a vector the tolerances are specified for each component of the state.- atol
a real scalar or a column vector of same size as
x0, the absolute error tolerance of solution. Ifatolis a vector the tolerances are specified for each component of the state.- res
an external function, computes the value of
g(t, y, ydot). It may be:- a Scilab function
In this case, the syntax must be
[r, ires] = res(t, x, xdot)andresmust return the residuer = g(t, x, xdot)and error flagires.ires = 0ifressucceeds to computer.ires = -1if residue is locally not defined forg(t, x, xdot).ires =-2if parameters are out of admissible range.- a list
This form of external is used to pass parameters to the function. It must be as follows:
list(res, p1, p2, ...)
where the syntax of the function
resis nowr = res(t, y, ydot, p1, p2, ...)
resstill returns the residual value as a function of(t, x, xdot, x1, x2, ...), andp1, p2,...are function parameters.- a character string
it must refer to the name of a C or Fortran routine. Assuming that <
r_name> is the given name,The Fortran calling sequence must be
<r_name>(t,x,xdot,res,ires,rpar,ipar)double precision t,x(*),xdot(*),res(*),rpar(*)integer ires,ipar(*)The C syntax must be
C2F(<r_name>)(double *t, double *x, double *xdot, double *res, integer *ires, double *rpar, integer *ipar)
where
tis the current time valuexthe state arrayxdotthe array of state derivativesresthe array of residualsiresthe execution indicatorrparis the array of floating point parameter values, needed but cannot be set by thedaefunctioniparis the array of floating integer parameter values, needed but cannot be set by thedaefunction
- jac
an external, computes the value of
dg/dx+cj*dg/dxdotfor a given value of parametercj. It may be- a Scilab function
Its syntax must be
r = jac(t, x, xdot, cj)and thejacfunction must returnr = dg(t, x, xdot)/dy + cj * dg(t, x, xdot)/dxdotwherecjis a real scalar.- a list
This form of external is used to pass parameters to the function. It must be as follows:
list(jac,p1,p2,...)
where the syntax of the function
jacis nowr = jac(t,x,xdot,p1,p2,...)
jacstill returnsdg/dx+cj*dg/dxdotas a function of(t,x,xdot,cj,p1,p2,...).- a character string
it must refer to the name of a C or Fortran routine. Assuming that <j_name> is the given name,
The Fortran calling sequence must be
<j_name>(t, x, xdot, r, cj, ires, rpar, ipar)double precision
t, x(*), xdot(*), r(*), ci, rpar(*)integer
ires, ipar(*)The C syntax must be
C2F(<j_name>)(double *t, double *x, double *xdot, double *r, double *cj, integer *ires, double *rpar, integer *ipar)
where
t, x, xdot, ires, rpar, iparhave similar definition as above,ris the results array
- surface
an external, computes the value of the column vector
surface(t,x)withngcomponents. Each component defines a surface.- a Scilab function
Its syntax must be
r=surface(t,x), this function must return a vector withngelements.- a list
This form of external is used to pass parameters to the function. It must be as follows:
list(surface,p1,p2,...)
where the syntax of the function
surfaceis nowr = surface(t,x,p1,p2,...)
- a character string
it must refer to the name of a C or Fortran routine. Assuming that <s_name> is the given name,
The Fortran calling sequence must be
<s_name>(nx, t, x, ng, r, rpar, ipar)double precision t, x(*), r(*), rpar(*)integer nx, ng,ipar(*)The C syntax must be
C2F(<s_name>)(double *t, double *x, double *xdot, double *r, double *cj, integer *ires, double *rpar, integer *ipar)
where
t, x, rpar, iparhave similar definition as above,ngis the number of surfaces,nxthe dimension of the state andris the results array.
- rd
a vector with two entries
[times num]wheretimesis the value of the time at which the surface is crossed,numis the number of the crossed surface- psol
external (function, list or string). Solves a linear system
P*x = b, with P being the factored preconditioner that routinepjaccomputed beforehand and stored inwpandiwp.A Scilab function.
Its syntax must be
[r, ier] = psol(wp, iwp, b)and must return the solution of the system inrand an error flagier.A list.
It must be as follows:
list(psol, x1, x2, ...)
where the syntax of
psolis nowpsol(wp, iwp, b, x1, x2, ...)
psolstill returns the solution inr.A character string.
It must refer to the name of a C function or a Fortran subroutine linked with Scilab
In C, the syntax must be:
where the arraysvoid psol (int*neq, double*t, double*y, double*ydot, double*savr, double*wk, double*cj, double*wght, double*wp, int*iwp, double*b, double*eplin, int*ier, double*rpar, int*ipar)
wpandiwpcontain matrix elements of LU-factored preconditionerP,wpbeing the values andiwpthe pivots used in the factorization.In Fortran, it must be:
subroutine psol (neq, t, y, ydot, savr, wk, cj, wght, wp, iwp, b, eplin, ier, rpar, ipar) double precision t,y(*), ydot(*), savr(*), wk(*), cj, wght(*), wp(*), b(*), eplin, rpar(*) integer neq, iwp(*), ier, ipar(*)
- pjac
external (function, list or string). Computes the value of
dg/dy + cj*dg/dydotfor a given value of parametercjand LU-factorizes it in two arrays, real and integer.A Scilab function.
Its syntax must be
[wp, iwp, ires] = pjac(neq, t, y, ydot, h, cj, rewt, savr)and in return, the arrayswpandiwpmust contain all factored preconditioner information.A list.
It must be as follows
list(pjac, x1, x2, ...)
where the syntax of
pjacispjac(neq, t, y, ydot, h, cj, rewt, savr, x1, x2,...)
pjacstill returns factorizeddg/dy + cj*dg/dydotas a function of(neq, t, y, ydot, h, cj, rewt, savr, x1, x2, ...).A character string.
It must refer to the name of a C function or a Fortran subroutine linked with Scilab
In C, the syntax must be:
void pjac (double*res, int*ires, int*neq, double*t, double*y, double*ydot, double*rewt, double*savr, double*wk, double*h, double*cj, double*wp, int*iwp, int*ier, double*rpar, int*ipar)
In Fortran, it must be:
subroutine pjac (res, ires, neq, t, y, ydot, rewt, savr, wk, h, cj, wp, iwp, ier, rpar, ipar) double precision res(*), t, y(*), ydot(*), rewt(*), savr(*), wk(*), h, cj, wp(*), rpar(*) integer ires, neq, iwp(*), ier, ipar(*)
- hd
a real vector, as an output it stores the
daecontext. It can be used as an input argument to resume integration (hot restart).- y
a real matrix. If
%DAEOPTIONS(2)=1, each column is the vector[t;x(t);xdot(t)]wheretis time index for which the solution has been computed. Elseyis the vector[x(t);xdot(t)].
Description
The dae function solves the differential algebraic equation and returns
the evolution of y a given time points
g(t, x, xdot) = 0 x(t0) = x0 and xdot(t0) = xdot0
If xdot0 is not given in the y0
argument, the dae function tries to compute it solving
g(t,x0,xdot0)=0.
If xdot0 is given in the y0
argument it may be either a compatible derivative
satisfying g(t,x0,xdot0)=0 or an approximate value. In the latter case
%DAEOPTIONS(7) must be set to 1.
The solvers
The type of problem solved and
the method used depend on the value of the first optional argument
type which can be one of the following strings:
Examples
Example #1: use dassl solver
// Example with Scilab code //-------------------------------------------------- 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); // Returns requested observation time points %DAEOPTIONS = list([], 1, [], [], [], 0, 0); // Ask dae mesh points to be returned y = dae([x0, xd0], 0, 4d10, chemres); // Without jacobian y = dae([x0, xd0], 0, 4d10, chemres, chemjac); // With jacobian
Example #2: use dasrt solver with "root"
// Example with C code (C compiler needed) //-------------------------------------------------- bOK = haveacompiler(); if bOK <> %t [btn] = messagebox(["You need a C compiler for this example."; "Execution of this example is canceled."], "Software problem", 'info'); return end //-1- Create the C codes in TMPDIR - Vanderpol equation, implicit form 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 and load them ilib_for_link(['res22' 'jac22' 'gr22'], 't22.c', [], 'c', [], 't22loader.sce'); exec('t22loader.sce') //-3- Run 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; // Simple simulation t = 0:0.003:300; yy = dae([y0, y0d], t0, t, atol, rtol, 'res22', 'jac22'); clf(); plot(yy(1, :), yy(2, :)) // Find first point where 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))); // Hot restart for next point 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);
Example #3: use daskr solver with "root2", using default 'psol' and 'pjac' routines
// Example with C code (C compiler needed) //-------------------------------------------------- bOK = haveacompiler(); if bOK <> %t [btn] = messagebox(["You need a C compiler for this example."; "Execution of this example is canceled."], "Software problem", 'info'); return end //-1- Create the C codes in TMPDIR - Vanderpol equation, implicit form 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 and load them ilib_for_link(['res22' 'jac22' 'gr22'], 't22.c', [], 'c', [], 't22loader.sce'); exec('t22loader.sce') //-3- Run 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; // Simple simulation t = 0:0.003:300; yy = dae([y0, y0d], t0, t, atol, rtol, 'res22', 'jac22'); clf(); plot(yy(1, :), yy(2, :)) // Find first point where 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))); // Hot restart for next point 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);

See also
- dae_root — differential algebraic equation solver with roots finding
- ode — программа решения обыкновенных дифференциальных уравнений
- daeoptions — установка опций для dae (программа решения дифференциальных алгоритмических уравнений)
- impl — дифференциальное алгебраическое уравнение
- call — Fortran or C user routines call
- link — dynamic linker
- external — объект Scilab'а, внешняя функция или подпрограмма
History
| Версия | Описание |
| 2024.1.0 | dassl, dasrt and daskr become internal. |
| Report an issue | ||
| << bvode | Дифференциальные уравнения | dae_root >> |