дифференциальное алгебраическое уравнение
[r [,hd]]=dassl(x0,t0,t [,atol,[rtol]],res [,jac] [,info] [,hd])
представляет собой либо y0
(ydot0
оценён с помощью dassl
с нулём в качестве первой оценки),
либо матрицу [y0 ydot0]
. g(t,y0,ydot0)
должна быть равной нулю. Если известна только оценка ydot0
,
то установите info(7)=1
.
вещественный вектор-столбец исходных условий.
вещественный вектор-столбец производной y
по
времени в момент t0
(может быть оценкой).
вещественное число, начальный момент времени.
вещественный скаляр или вектор. Указывает моменты времени для которых
необходимо найти решение. Заметьте, что вы можете получить решение в
каждой точке шага dassl установкой info(2)=1
.
вещественные скаляры или вектор-столбцы того же размера, что и
y
. atol, rtol
указывают допуски
абсолютной и относительной ошибок решения, соответственно. Если это
векторы, то допуски определены для каждого элемента y
.
внешняя функция, список или строка.
Вычисляет значение g(t,y,ydot)
. Это может быть:
Функция Scilab.
Её последовательность вызова должна быть
[r,ires]=res(t,y,ydot)
и
res
должна возвращать остаток
r=g(t,y,ydot)
и флаг ошибки
ires
. ires = 0
, если
res
удалось вычислить r
;
=-1
, если остаток локально не определён для
(t,y,ydot)
; =-2
, если
параметры находятся вне допустимого диапазона.
Список.
Эта форма позволяет передавать функции параметры, отличные от t
,
y
, ydot
. Это выполняется следующим способом:
list(res,x1,x2,...)
где последовательность вызова функции res
теперь имеет вид:
r=res(t,y,ydot,x1,x2,...)
res
по-прежнему возвращает
r=g(t,y,ydot
как функцию от
(t,y,ydot,x1,x2,...)
.
Строка.
Она должна ссылаться на имя подпрограммы на языке C или Fortran, связанной с Scilab'ом.
Последовательность вызова на языке C должна быть:
На языке Fortran она должна быть:
subroutine res(t,y,yd,r,ires,rpar,ipar) double precision t, y(*),yd(*),r(*),rpar(*) integer ires,ipar(*)
Массивы rpar
и ipar
должны быть,
но не должны использоваться.
внешняя функция, список или строка.
Вычисляет значение dg/dy+cj*dg/dydot
для заданной
величины параметра cj
.
Функция Scilab.
Её последовательность вызова должна быть
r=jac(t,y,ydot,cj)
и
jac
должна возвращать
r=dg(t,y,ydot)/dy+cj*dg(t,y,ydot)/dydot
, где
cj
-- вещественный скаляр.
Список.
Он должен иметь следующий вид:
list(jac,x1,x2,...)
где последовательность вызова функции
jac
теперь имеет вид:
r=jac(t,y,ydot,cj,x1,x2,...)
jac
по-прежнему возвращает
dg/dy+cj*dg/dydot
в виде функции от
(t,y,ydot,cj,x1,x2,...)
.
Символьная строка.
Она должна ссылаться на имя подпрограммы на языке C или Fortran, связанной с Scilab.
В C последовательность вызова должна быть следующего вида:
В Fortran она должна быть:
subroutine jac(t,y,yd,pd,cj,rpar,ipar) double precision t, y(*),yd(*),pd(*),cj,rpar(*) integer ipar(*)
необязательный список, содержащий 7
элементов.
Значение по умолчанию равно list([],0,[],[],[],0,0)
.
вещественный скаляр, который указывает максимальное время, для которого
g
может выполняться, либо пустая матрица
[]
, если время не ограничено.
флаг, который указывает возвращать ли dassl
её
вычисленные промежуточные значения (flag=1
) или только
пользователь определяет значения моментов времени
(flag=0
).
двухэлементный вектор, который указывает определение [ml,mu]
матрицы пределов, вычисленной с помощью jac
;
r(i - j + ml + mu + 1,j) = "dg(i)/dy(j)+cj*dg(i)/dydot(j)"
.
Если jac
возвращает полную матрицу, то
info(3)=[]
.
вещественный скаляр, который указывает максимальный размер шага. Установите
info(4)=[]
, если ограничений нет.
вещественный скаляр, который указывает исходный размер шага.
Установите info(5)=[]
, если он не определён.
info(6)=1
, если известно, что решение отрицательное, в
противном случае установите info(6)=0
.
info(7)=1
, если ydot0
является
просто оценкой; info(7)=0
, если
g(t0,y0,ydot0)=0
.
вещественный вектор, который позволяет хранить контекст
dassl
и продолжать интегрирование.
вещественная матрица. Каждый столбец является вектором [t;x(t);xdot(t)]
,
где t
-- индекс времени для которого требуется найти решение.
Функция dassl
интегрирует дифференциальное алгебраическое уравнение и возвращает изменение y
в заданные моменты времени.
g(t,y,ydot)=0 y(t0)=y0 and ydot(t0)=ydot0
function [r, ires]=chemres(t, y, yd) r=[-0.04*y(1)+1d4*y(2)*y(3)-yd(1) 0.04*y(1)-1d4*y(2)*y(3)-3d7*y(2)*y(2)-yd(2) 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 y0=[1;0;0]; yd0=[-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=dassl([y0,yd0],0,t,chemres); info=list([],0,[],[],[],0,0); info(2)=1; y1=dassl([y0,yd0],0,4d10,chemres,info); y2=dassl([y0,yd0],0,4d10,chemres,chemjac,info); //Использование дополнительного аргумента для параметров //----------------------------------- function [r, ires]=chemres(t, y, yd, a, b, c) r=[-a*y(1)+b*y(2)*y(3)-yd(1) a*y(1)-b*y(2)*y(3)-c*y(2)*y(2)-yd(2) y(1)+y(2)+y(3)-1]; ires=0 endfunction function pd=chemjac(x, y, yd, cj, a, b, c) pd=[-a-cj , b*y(3) , b*y(2); a ,-b*y(3)-2*c*y(2)-cj ,-b*y(2); 1 , 1 , 1 ] endfunction y3=dassl([y0,yd0],0,t,list(chemres,0.04,1d4,3d7),list(chemjac,0.04,1d4,3d7)); //использование C-кода //------------ // - создаём C-код cd TMPDIR rescode=['void chemres(double *t, double y[], double yd[], double r[], int *ires, double rpar[], int ipar[])' ' {' ' r[0] = -0.04*y[0]+1.0e4*y[1]*y[2] -yd[0];' ' r[1] = 0.04*y[0]-1.0e4*y[1]*y[2]-3.0e7*y[1]*y[1]-yd[1];' ' r[2] = y[0]+y[1]+y[2]-1;' ' *ires = 0;' ' }']; jaccode=['void chemjac(double *t, double y[], double yd[], double pd[], double *cj, double rpar[], int ipar[])' ' {' ' /* first column*/' ' pd[0] = -0.04-*cj;' ' pd[1] = 0.04;' ' pd[2] = 1.0;' ' /* second column*/' ' pd[3] = 1.0e4*y[2];' ' pd[4] = -1.0e4*y[2]-2*3.0e7*y[1]-*cj;' ' pd[5] = 1.0;' ' /* third column*/' ' pd[6] = 1.0e4*y[1];' ' pd[7] = -1.0e4*y[1];' ' pd[8] = 1.0;' ' }']; mputl([rescode;jaccode],'mycode.c') //создаём C-файл в директории TMPDIR // - компилируем ilib_for_link(['chemres','chemjac'],'mycode.c',[],'c','','loader.sce'); // - связываем его с Scilab'ом exec('loader.sce') // - вызов dassl y4=dassl([y0,yd0],0,t,'chemres','chemjac'); | ![]() | ![]() |