Please note that the recommended version of Scilab is 2025.0.0. This page might be outdated.
See the recommended documentation of this function
dae
программа решения дифференциальных алгебраических уравнений (ДАУ)
Синтаксис
y=dae(initial,t0,t,res) [y [,hd]]=dae(initial,t0,t [,rtol, [atol]],res [,jac] [,hd]) [y,rd]=dae("root",initial,t0,t,res,ng,surface) [y ,rd [,hd]]=dae("root",initial,t0,t [,rtol, [atol]],res [,jac], ng, surface [,hd])
Аргументы
- initial
вектор-столбец. Он может быть равен
x0
или[x0;xdot0]
, гдеx0
- это значение состояния в начальный момент времениt0
, аxdot0
- значение производной исходного состояния или его оценка (см. ниже).- t0
вещественное число, исходный момент времени.
- t
Вещественный скаляр или вектор. Указывает моменты времени для которых нужно найти решение. Заметьте, что вы можете получить решение в каждой точке шага ДАУ с помощью установки
%DAEOPTIONS(2)=1
.- rtol
вещественный скаляр или вектор-столбец того же размера, что и
x0
, допуск относительной ошибки. Еслиrtol
является вектором, то допуски определяются для каждой составляющей состояния.- atol
вещественный скаляр или вектор-столбец того же размера, что и
x0
, допуск абсолютной ошибки. Еслиatol
является вектором, то допуски определяются для каждой составляющей состояния.- res
внешняя функция, которая вычисляет значение
g(t,y,ydot)
. Она может быть:- функцией Scilab'а
В этом случае последовательность вызова должна быть
[r,ires]=res(t,x,xdot)
, аres
должна возвращать остатокr=g(t,x,xdot)
и флаг ошибкиires
.ires = 0
, еслиres
смогла вычислитьr
;ires = -1
, если остаток дляg(t,x,xdot)
локально не определён;ires =-2
, если параметры находятся вне допустимого диапазона.- списком
Эта форма внешней функции используется для передачи параметров в функцию. Она может иметь следующий вид:
list(res,p1,p2,...)
где последовательность вызова функции
res
теперьr=res(t,y,ydot,p1,p2,...)
Функция
res
по-прежнему возвращает значение остатка в виде функции от(t,x,xdot,x1,x2,...)
, аp1, p2,...
являются параметрами функции.- символьной строкой
она должна ссылаться на имя подпрограммы на языке C или fortran, в предположении, что <
r_name
> является заданным именем.Последовательность вызова Fortran должна быть
<r_name>(t, x, xdot, res, ires, rpar, ipar)
t, x(*), xdot(*), res(*), rpar(*)
имеют удвоенную точность;ires, ipar(*)
являются целочисленными.Последовательность вызова C должна быть
C2F(<r_name>)(double *t, double *x, double *xdot, double *res, integer *ires, double *rpar, integer *ipar)
,
где
t
- текущее значение времени;x
- массив состояния;xdot
- массив производных состояния;res
- массив остатков;ires
- индикатор выполнения;rpar
- массив целочисленных значений параметров с плавающей запятой, которые нужны, но не могут быть установлены с помощью функцииdae
.ipar
- массив целочисленных значений параметров с плавающей запятой, которые нужны, но не могут быть установлены с помощью функцииdae
.
- jac
Внешняя функция вычисляет значение
dg/dx+cj*dg/dxdot
для заданного значения параметраcj
. Она может быть- функцией Scilab'а
В этом случае последовательность вызова должна быть
r=jac(t,x,xdot,cj)
, аjac
должна возвращатьr=dg(t,x,xdot)/dy+cj*dg(t,x,xdot)/dxdot
, гдеcj
- вещественный скаляр.- списком
Эта форма внешней функции используется для передачи параметров в функцию. Она может иметь следующий вид:
list(jac,p1,p2,...)
где последовательность вызова функции
jac
теперьr=jac(t,x,xdot,p1,p2,...)
Функция
jac
по-прежнему возвращаетdg/dx+cj*dg/dxdot
как функцию от(t, x, xdot, cj, p1, p2,...)
.- символьной строкой
она должна ссылаться на имя подпрограммы на языке C или fortran, в предположении, что <
j_name
> является заданным именем.Последовательность вызова Fortran должна быть
<j_name>(t, x, xdot, r, cj, ires, rpar, ipar)
t, x(*), xdot(*), r(*), ci, rpar(*)
имеют удвоенную точность;ires, ipar(*)
являются целочисленными.Последовательность вызова C должна быть
C2F(<j_name>)(double *t, double *x, double *xdot, double *r, double *cj, integer *ires, double *rpar, integer *ipar)
,
где
t, x, xdot, ires, rpar, ipar
имеют аналогичное определение, что и выше,r
- массив результатов
- surface
Внешняя функция вычисляет значение вектор-столбца
surface(t,x)
с количеством элементовng
. Каждый элемент определяет поверхность.- функцией Scilab'а
В этом случае последовательность вызова должна быть
r=surface(t,x)
. Эта функция должна вернуть вектор сng
элементами.- списком
Эта форма внешней функции используется для передачи параметров в функцию. Она может иметь следующий вид:
list(surface,p1,p2,...)
где последовательность вызова функции
surface
теперь имеет вид:r=surface(t,x,p1,p2,...)
- символьной строкой
она должна ссылаться на имя подпрограммы на языке C или fortran, в предположении, что <
s_name
> является заданным именем.Последовательность вызова Fortran должна быть
<j_name>(t, x, xdot, r, cj, ires, rpar, ipar)
t, x(*), xdot(*), r(*), ci, rpar(*)
имеют удвоенную точность;ires, ipar(*)
являются целочисленными.Последовательность вызова C должна быть
C2F(<j_name>)(double *t, double *x, double *xdot, double *r, double *cj, integer *ires, double *rpar, integer *ipar)
,
где
t, x, xdot, ires, rpar, ipar
имеют аналогичное определение, что и выше,ng
- количество поверхностей,nx
- размерность состояния иr
- массив результатов.
- rd
вектор с двумя элементами
[times num]
, гдеtimes
- значение момента времени пересечения поверхности,num
- число пересечённых поверхностей- hd
вещественный вектор, в качестве аргумента на выходе он хранит контекст
dae
. Он может быть использован в качестве входного аргумента для возобновления интегрирования (горячий перезапуск).- y
вещественная матрица. Если
%DAEOPTIONS(2)=1
,то каждый столбец является вектором вида[t;x(t);xdot(t)]
, гдеt
- индекс времени для которого вычислено решение. В противном случаеy
- вектор вида[x(t);xdot(t)]
.
Описание
Функция dae
является шлюзом, построенным над
функциями dassl и dasrt, разработанными для явного интегрирования
дифференциальных уравнений.
g(t,x,xdot)=0 x(t0)=x0 and xdot(t0)=xdot0
Если xdot0
не указан в
исходном аргументе, то функция dae
пытается вычислить его решая уравнение
g(t,x0,xdot0)=0
/
Если xdot0
указан в исходном
аргументе, то он может быть либо совместимой производной (compatible
derivative), удовлетворяющей условию g(t,x0,xdot0)=0
,
либо приближённым значением. В последнем случае %DAEOPTIONS(7) должен быть установлен в
1.
Конкретные примеры использования внешних функций, написанных на
языке Scilab и C, представлены в
modules/differential_equations/tests/unit_tests/dassldasrt.tst
Примеры
//Пример с кодом 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); // возвращает запрошенные моменты времени наблюдения %DAEOPTIONS = list([], 1, [], [], [], 0, 0); // просит вернуть сетку точек dae y = dae([x0, xd0], 0, 4d10, chemres); // без якобиана y = dae([x0, xd0], 0, 4d10, chemres, chemjac); // с якобианом
//пример с кодом C (необходим C-компилятор) //-------------------------------------------------- bOK = haveacompiler(); if bOK <> %t [btn] = messagebox(["Для этого примера Вам необходим C-компилятор.";"Выполнение этого примера отменено."], "Проблема с программным обеспечением", 'info'); return end //-1- создать C-код в TMPDIR - Уравнение Вандерпола, неявная форма 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- скомпилировать и загрузить его ilib_for_link(['res22' 'jac22' 'gr22'], 't22.c', [], 'c', [], 't22loader.sce'); exec('t22loader.sce') //-3- запустить 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; //простое моделирование t = 0:0.003:300; yy = dae([y0, y0d], t0, t, atol, rtol, 'res22', 'jac22'); clf(); plot(yy(1, :), yy(2, :)) // Найти первую точку, где 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))); // горячий перезапуск для следующей точки 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);
Смотрите также
- ode — программа решения обыкновенных дифференциальных уравнений
- daeoptions — установка опций для dae (программа решения дифференциальных алгоритмических уравнений)
- dassl — дифференциальное алгебраическое уравнение
- impl — дифференциальное алгебраическое уравнение
- call — Fortran or C user routines call
- link — dynamic linker
- external — объект Scilab'а, внешняя функция или подпрограмма
Report an issue | ||
<< bvode | Дифференциальное счисление, интегрирование | daeoptions >> |