14
14
<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns3="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" version="5.0-subset Scilab" xml:id="dae" xml:lang="ru">
16
<refname>dae</refname>
17
<refpurpose>программа решения дифференциальных алгебраических уравнений
22
<title>Последовательность вызова</title>
24
y=dae(initial,t0,t,res)
25
[y [,hd]]=dae(initial,t0,t [,rtol, [atol]],res [,jac] [,hd])
26
[y,rd]=dae("root",initial,t0,t,res,ng,surface)
27
[y ,rd [,hd]]=dae("root",initial,t0,t [,rtol, [atol]],res [,jac], ng, surface [,hd])
31
<title>Аргументы</title>
37
вектор-столбец. Он может быть равен <literal>x0</literal> или
38
<literal>[x0;xdot0]</literal>, где <literal>x0</literal> -- это
39
значение состояния в начальный момент времени <literal>t0</literal>,
40
а <literal>xdot0</literal> -- значение производной исходного
41
состояния или его оценка (см. ниже).
48
<para>вещественное число, исходный момент времени.</para>
54
<para>Вещественный скаляр или вектор. Указывает моменты времени для
55
которых нужно найти решение. Заметьте, что вы можете получить
56
решение в каждой точке шага ДАУ с помощью установки
58
<link linkend="daeoptions">%DAEOPTIONS</link>(2)=1
67
<para>вещественный скаляр или вектор-столбец того же размера, что и
68
<literal>x0</literal>, допуск относительной ошибки. Если
69
<literal>rtol</literal> является вектором, то допуски определяются
70
для каждой составляющей состояния.
77
<para>вещественный скаляр или вектор-столбец того же размера, что и
78
<literal>x0</literal>, допуск абсолютной ошибки. Если
79
<literal>atol</literal> является вектором, то допуски определяются
80
для каждой составляющей состояния.
88
<link linkend="external">внешняя</link> функция, которая
89
вычисляет значение <literal>g(t,y,ydot)</literal>. Она может
94
<term>функцией Scilab'а</term>
96
<para>В этом случае последовательность вызова должна быть
97
<literal>[r,ires]=res(t,x,xdot)</literal>, а
98
<literal>res</literal> должна возвращать остаток
99
<literal>r=g(t,x,xdot)</literal> и флаг ошибки
100
<literal>ires</literal>.
103
<literal>ires = 0</literal>, если <literal>res</literal>
104
смогла вычислить <literal>r</literal>;
107
<literal>ires = -1</literal>, если остаток для
108
<literal>g(t,x,xdot)</literal> локально не определён;
111
<literal>ires =-2</literal>, если параметры находятся
112
вне допустимого диапазона.
119
<para>Эта форма внешней функции используется для передачи
120
параметров в функцию. Она может иметь следующий вид:
122
<programlisting role="no-scilab-exec">
125
<para>где последовательность вызова функции
126
<literal>res</literal> теперь
128
<programlisting role="no-scilab-exec">
129
r=res(t,y,ydot,p1,p2,...)
132
Функция <literal>res</literal> по-прежнему возвращает
133
значение остатка в виде функции от
134
<literal>(t,x,xdot,x1,x2,...)</literal>, а <literal>p1,
137
являются параметрами функции.
142
<term>символьной строкой</term>
144
<para>она должна ссылаться на имя подпрограммы на языке C или
145
fortran, в предположении, что
146
<<literal>r_name</literal>> является заданным
151
<para>Последовательность вызова Fortran должна быть</para>
153
<literal><r_name>(t, x, xdot, res, ires, rpar,
158
<literal>t, x(*), xdot(*), res(*), rpar(*)</literal>
159
имеют удвоенную точность;
162
<literal>ires, ipar(*)</literal> являются
167
<para>Последовательность вызова C должна быть</para>
169
<literal>C2F(<r_name>)(double *t, double *x,
170
double *xdot, double *res, integer *ires, double *rpar,
181
<literal>t</literal> -- текущее значение
187
<literal>x</literal> -- массив состояния;
192
<literal>xdot</literal> -- массив производных
198
<literal>res</literal> -- массив остатков;
203
<literal>ires</literal> -- индикатор
209
<literal>rpar</literal> -- массив целочисленных
210
значений параметров с плавающей запятой, которые нужны, но
211
не могут быть установлены с помощью функции
212
<literal>dae</literal>.
217
<literal>ipar</literal> -- массив целочисленных
218
значений параметров с плавающей запятой, которые нужны, но
219
не могут быть установлены с помощью функции
220
<literal>dae</literal>.
233
<link linkend="external">Внешняя</link> функция вычисляет
234
значение <literal>dg/dx+cj*dg/dxdot</literal> для заданного значения
235
параметра <literal>cj</literal>. Она может быть
239
<term>функцией Scilab'а</term>
241
<para>В этом случае последовательность вызова должна быть
242
<literal>r=jac(t,x,xdot,cj)</literal>, а
243
<literal>jac</literal> должна возвращать
244
<literal>r=dg(t,x,xdot)/dy+cj*dg(t,x,xdot)/dxdot</literal>,
245
где <literal>cj</literal> -- вещественный скаляр.
252
<para>Эта форма внешней функции используется для передачи
253
параметров в функцию. Она может иметь следующий вид:
255
<programlisting role="no-scilab-exec">
258
<para>где последовательность вызова функции
259
<literal>jac</literal> теперь
261
<programlisting role="no-scilab-exec">
262
r=jac(t,x,xdot,p1,p2,...)
265
Функция <literal>jac</literal> по-прежнему возвращает
266
<literal>dg/dx+cj*dg/dxdot</literal> как функцию от
267
<literal>(t, x, xdot, cj, p1, p2,...)</literal>.
272
<term>символьной строкой</term>
274
<para>она должна ссылаться на имя подпрограммы на языке C или
275
fortran, в предположении, что
276
<<literal>j_name</literal>> является заданным
281
<para>Последовательность вызова Fortran должна быть</para>
283
<literal><j_name>(t, x, xdot, r, cj, ires,
288
<literal>t, x(*), xdot(*), r(*), ci,
291
имеют удвоенную точность;
294
<literal>ires, ipar(*)</literal> являются
299
<para>Последовательность вызова C должна быть</para>
301
<literal>C2F(<j_name>)(double *t, double *x,
302
double *xdot, double *r, double *cj, integer *ires, double
303
*rpar, integer *ipar)
310
где <literal>t, x, xdot, ires, rpar, ipar</literal>
311
имеют аналогичное определение, что и выше,
312
<literal>r</literal> -- массив результатов
323
<link linkend="external">Внешняя</link> функция вычисляет
324
значение вектор-столбца <literal>surface(t,x)</literal> с
325
количеством элементов <literal>ng</literal>. Каждый элемент
326
определяет поверхность.
330
<term>функцией Scilab'а</term>
332
<para>В этом случае последовательность вызова должна быть
333
<literal>r=surface(t,x)</literal>. Эта функция должна вернуть
334
вектор с <literal>ng</literal> элементами.
341
<para>Эта форма внешней функции используется для передачи
342
параметров в функцию. Она может иметь следующий вид:
344
<programlisting role="no-scilab-exec">
345
list(surface,p1,p2,...)
347
<para>где последовательность вызова функции
348
<literal>surface</literal> теперь имеет вид:
350
<programlisting role="no-scilab-exec">
351
r=surface(t,x,p1,p2,...)
356
<term>символьной строкой</term>
358
<para>она должна ссылаться на имя подпрограммы на языке C или
359
fortran, в предположении, что
360
<<literal>s_name</literal>> является заданным
365
<para>Последовательность вызова Fortran должна быть</para>
367
<literal><j_name>(t, x, xdot, r, cj, ires,
372
<literal>t, x(*), xdot(*), r(*), ci,
375
имеют удвоенную точность;
378
<literal>ires, ipar(*)</literal> являются
383
<para>Последовательность вызова C должна быть</para>
385
<literal>C2F(<j_name>)(double *t, double *x,
386
double *xdot, double *r, double *cj, integer *ires, double
387
*rpar, integer *ipar)
394
где <literal>t, x, xdot, ires, rpar, ipar</literal>
395
имеют аналогичное определение, что и выше,
396
<literal>ng</literal> -- количество поверхностей,
397
<literal>nx</literal> -- размерность состояния и
398
<literal>r</literal> -- массив результатов.
409
вектор с двумя элементами <literal>[times num]</literal>, где
410
<literal>times</literal> -- значение момента времени пересечения
411
поверхности, <literal>num</literal> -- число пересечённых
419
<para>вещественный вектор, в качестве аргумента на выходе он хранит
420
контекст <literal>dae</literal>. Он может быть использован в
421
качестве входного аргумента для возобновления интегрирования
422
(горячий перезапуск).
430
вещественная матрица. Если
432
<link linkend="daeoptions">%DAEOPTIONS</link>(2)=1
435
столбец является вектором вида <literal>[t;x(t);xdot(t)]</literal>,
436
где <literal>t</literal> -- индекс времени для которого вычислено
437
решение. В противном случае <literal>y</literal> -- вектор вида
438
<literal>[x(t);xdot(t)]</literal>.
445
<title>Описание</title>
447
Функция <literal>dae</literal> является шлюзом, построенным над
448
функциями <link linkend="dassl">dassl</link> и <link linkend="dasrt">dasrt</link>, разработанными для явного интегрирования
449
дифференциальных уравнений.
451
<programlisting role="no-scilab-exec">
453
x(t0)=x0 and xdot(t0)=xdot0
456
Если <literal>xdot0</literal> не указан в
457
<emphasis>исходном</emphasis> аргументе, то функция <literal>dae</literal>
458
пытается вычислить его решая уравнение
459
<literal>g(t,x0,xdot0)=0</literal>/
462
Если <literal>xdot0</literal> указан в <emphasis>исходном</emphasis>
463
аргументе, то он может быть либо совместимой производной (compatible
464
derivative), удовлетворяющей условию <literal>g(t,x0,xdot0)=0</literal>,
465
либо приближённым значением. В последнем случае <link linkend="daeoptions">%DAEOPTIONS</link>(7) должен быть установлен в
468
<para>Конкретные примеры использования внешних функций, написанных на
469
языке Scilab и C, представлены в
470
<literal>modules/differential_equations/tests/unit_tests/dassldasrt.tst</literal>
474
<title>Примеры</title>
475
<programlisting role="example">
476
//Пример с кодом Scilab
477
function [r,ires]=chemres(t,y,yd)
478
r(1) = -0.04*y(1) + 1d4*y(2)*y(3) - yd(1);
479
r(2) = 0.04*y(1) - 1d4*y(2)*y(3) - 3d7*y(2)*y(2) - yd(2);
480
r(3) = y(1) + y(2) + y(3)-1;
483
function pd=chemjac(x,y,yd,cj)
484
pd=[-0.04-cj , 1d4*y(3) , 1d4*y(2);
485
0.04 ,-1d4*y(3)-2*3d7*y(2)-cj ,-1d4*y(2);
490
xd0=[-0.04; 0.04; 0];
491
t=[1.d-5:0.02:.4, 0.41:.1:4, 40, 400, 4000, 40000, 4d5, 4d6, 4d7, 4d8, 4d9, 4d10];
493
y=dae([x0,xd0],0,t,chemres);// возвращает запрошенные моменты времени наблюдения
495
%DAEOPTIONS=list([],1,[],[],[],0,0); // просит вернуть сетку точек dae
496
y=dae([x0,xd0],0,4d10,chemres); // без якобиана
497
y=dae([x0,xd0],0,4d10,chemres,chemjac); // с якобианом
499
//пример с кодом C (необходим C-компилятор) --------------------------------------------------
500
//-1- создать C-код в TMPDIR - Уравнение Вандерпола, неявная форма
501
code=['#include <math.h>'
502
'void res22(double *t,double *y,double *yd,double *res,int *ires,double *rpar,int *ipar)'
503
'{res[0] = yd[0] - y[1];'
504
' res[1] = yd[1] - (100.0*(1.0 - y[0]*y[0])*y[1] - y[0]);}'
506
'void jac22(double *t,double *y,double *yd,double *pd,double *cj,double *rpar,int *ipar)'
508
' pd[1]= - (-200.0*y[0]*y[1] - 1.0);'
510
' pd[3]=*cj - (100.0*(1.0 - y[0]*y[0]));}'
512
'void gr22(int *neq, double *t, double *y, int *ng, double *groot, double *rpar, int *ipar)'
513
'{ groot[0] = y[0];}']
514
mputl(code,TMPDIR+'/t22.c')
516
//-2- скомпилировать и загрузить его
517
ilib_for_link(['res22' 'jac22' 'gr22'],'t22.c',[],'c',TMPDIR+'/Makefile',TMPDIR+'/t22loader.sce');
518
exec(TMPDIR+'/t22loader.sce')
521
rtol=[1.d-6;1.d-6];atol=[1.d-6;1.d-4];
522
t0=0;y0=[2;0];y0d=[0;-2];t=[20:20:200];ng=1;
524
//простое моделирование
526
yy=dae([y0,y0d],t0,t,atol,rtol,'res22','jac22');
527
clf();plot(yy(1,:),yy(2,:))
529
// найти первую точку, где yy(1)=0
530
[yy,nn,hotd]=dae("root",[y0,y0d],t0,300,atol,rtol,'res22','jac22',ng,'gr22');
531
plot(yy(1,1),yy(2,1),'r+')
532
xstring(yy(1,1)+0.1,yy(2,1),string(nn(1)))
534
// горячий перезапуск для следующей точки
535
t01=nn(1);[pp,qq]=size(yy);y01=yy(2:3,qq);y0d1=yy(3:4,qq);
536
[yy,nn,hotd]=dae("root",[y01,y0d1],t01,300,atol,rtol,'res22','jac22',ng,'gr22',hotd);
537
plot(yy(1,1),yy(2,1),'r+')
538
xstring(yy(1,1)+0.1,yy(2,1),string(nn(1)))
541
<refsection role="see also">
542
<title>Смотрите также</title>
543
<simplelist type="inline">
545
<link linkend="ode">ode</link>
548
<link linkend="daeoptions">daeoptions</link>
551
<link linkend="dassl">dassl</link>
554
<link linkend="impl">impl</link>
557
<link linkend="fort">fort</link>
560
<link linkend="link">link</link>
563
<link linkend="external">external</link>
16
<refname>dae</refname>
17
<refpurpose>программа решения дифференциальных алгебраических уравнений
22
<title>Последовательность вызова</title>
24
y=dae(initial,t0,t,res)
25
[y [,hd]]=dae(initial,t0,t [,rtol, [atol]],res [,jac] [,hd])
26
[y,rd]=dae("root",initial,t0,t,res,ng,surface)
27
[y ,rd [,hd]]=dae("root",initial,t0,t [,rtol, [atol]],res [,jac], ng, surface [,hd])
31
<title>Аргументы</title>
37
вектор-столбец. Он может быть равен <literal>x0</literal> или
38
<literal>[x0;xdot0]</literal>, где <literal>x0</literal> -- это
39
значение состояния в начальный момент времени <literal>t0</literal>,
40
а <literal>xdot0</literal> -- значение производной исходного
41
состояния или его оценка (см. ниже).
48
<para>вещественное число, исходный момент времени.</para>
54
<para>Вещественный скаляр или вектор. Указывает моменты времени для
55
которых нужно найти решение. Заметьте, что вы можете получить
56
решение в каждой точке шага ДАУ с помощью установки
58
<link linkend="daeoptions">%DAEOPTIONS</link>(2)=1
67
<para>вещественный скаляр или вектор-столбец того же размера, что и
68
<literal>x0</literal>, допуск относительной ошибки. Если
69
<literal>rtol</literal> является вектором, то допуски определяются
70
для каждой составляющей состояния.
77
<para>вещественный скаляр или вектор-столбец того же размера, что и
78
<literal>x0</literal>, допуск абсолютной ошибки. Если
79
<literal>atol</literal> является вектором, то допуски определяются
80
для каждой составляющей состояния.
88
<link linkend="external">внешняя</link> функция, которая
89
вычисляет значение <literal>g(t,y,ydot)</literal>. Она может
94
<term>функцией Scilab'а</term>
96
<para>В этом случае последовательность вызова должна быть
97
<literal>[r,ires]=res(t,x,xdot)</literal>, а
98
<literal>res</literal> должна возвращать остаток
99
<literal>r=g(t,x,xdot)</literal> и флаг ошибки
100
<literal>ires</literal>.
103
<literal>ires = 0</literal>, если <literal>res</literal>
104
смогла вычислить <literal>r</literal>;
107
<literal>ires = -1</literal>, если остаток для
108
<literal>g(t,x,xdot)</literal> локально не определён;
111
<literal>ires =-2</literal>, если параметры находятся
112
вне допустимого диапазона.
119
<para>Эта форма внешней функции используется для передачи
120
параметров в функцию. Она может иметь следующий вид:
122
<programlisting role="no-scilab-exec">
125
<para>где последовательность вызова функции
126
<literal>res</literal> теперь
128
<programlisting role="no-scilab-exec">
129
r=res(t,y,ydot,p1,p2,...)
132
Функция <literal>res</literal> по-прежнему возвращает
133
значение остатка в виде функции от
134
<literal>(t,x,xdot,x1,x2,...)</literal>, а <literal>p1,
137
являются параметрами функции.
142
<term>символьной строкой</term>
144
<para>она должна ссылаться на имя подпрограммы на языке C или
145
fortran, в предположении, что
146
<<literal>r_name</literal>> является заданным
151
<para>Последовательность вызова Fortran должна быть</para>
153
<literal><r_name>(t, x, xdot, res, ires, rpar,
158
<literal>t, x(*), xdot(*), res(*), rpar(*)</literal>
159
имеют удвоенную точность;
162
<literal>ires, ipar(*)</literal> являются
167
<para>Последовательность вызова C должна быть</para>
169
<literal>C2F(<r_name>)(double *t, double *x,
170
double *xdot, double *res, integer *ires, double *rpar,
181
<literal>t</literal> -- текущее значение
187
<literal>x</literal> -- массив состояния;
192
<literal>xdot</literal> -- массив производных
198
<literal>res</literal> -- массив остатков;
203
<literal>ires</literal> -- индикатор
209
<literal>rpar</literal> -- массив целочисленных
210
значений параметров с плавающей запятой, которые нужны, но
211
не могут быть установлены с помощью функции
212
<literal>dae</literal>.
217
<literal>ipar</literal> -- массив целочисленных
218
значений параметров с плавающей запятой, которые нужны, но
219
не могут быть установлены с помощью функции
220
<literal>dae</literal>.
233
<link linkend="external">Внешняя</link> функция вычисляет
234
значение <literal>dg/dx+cj*dg/dxdot</literal> для заданного значения
235
параметра <literal>cj</literal>. Она может быть
239
<term>функцией Scilab'а</term>
241
<para>В этом случае последовательность вызова должна быть
242
<literal>r=jac(t,x,xdot,cj)</literal>, а
243
<literal>jac</literal> должна возвращать
244
<literal>r=dg(t,x,xdot)/dy+cj*dg(t,x,xdot)/dxdot</literal>,
245
где <literal>cj</literal> -- вещественный скаляр.
252
<para>Эта форма внешней функции используется для передачи
253
параметров в функцию. Она может иметь следующий вид:
255
<programlisting role="no-scilab-exec">
258
<para>где последовательность вызова функции
259
<literal>jac</literal> теперь
261
<programlisting role="no-scilab-exec">
262
r=jac(t,x,xdot,p1,p2,...)
265
Функция <literal>jac</literal> по-прежнему возвращает
266
<literal>dg/dx+cj*dg/dxdot</literal> как функцию от
267
<literal>(t, x, xdot, cj, p1, p2,...)</literal>.
272
<term>символьной строкой</term>
274
<para>она должна ссылаться на имя подпрограммы на языке C или
275
fortran, в предположении, что
276
<<literal>j_name</literal>> является заданным
281
<para>Последовательность вызова Fortran должна быть</para>
283
<literal><j_name>(t, x, xdot, r, cj, ires,
288
<literal>t, x(*), xdot(*), r(*), ci,
291
имеют удвоенную точность;
294
<literal>ires, ipar(*)</literal> являются
299
<para>Последовательность вызова C должна быть</para>
301
<literal>C2F(<j_name>)(double *t, double *x,
302
double *xdot, double *r, double *cj, integer *ires, double
303
*rpar, integer *ipar)
310
где <literal>t, x, xdot, ires, rpar, ipar</literal>
311
имеют аналогичное определение, что и выше,
312
<literal>r</literal> -- массив результатов
323
<link linkend="external">Внешняя</link> функция вычисляет
324
значение вектор-столбца <literal>surface(t,x)</literal> с
325
количеством элементов <literal>ng</literal>. Каждый элемент
326
определяет поверхность.
330
<term>функцией Scilab'а</term>
332
<para>В этом случае последовательность вызова должна быть
333
<literal>r=surface(t,x)</literal>. Эта функция должна вернуть
334
вектор с <literal>ng</literal> элементами.
341
<para>Эта форма внешней функции используется для передачи
342
параметров в функцию. Она может иметь следующий вид:
344
<programlisting role="no-scilab-exec">
345
list(surface,p1,p2,...)
347
<para>где последовательность вызова функции
348
<literal>surface</literal> теперь имеет вид:
350
<programlisting role="no-scilab-exec">
351
r=surface(t,x,p1,p2,...)
356
<term>символьной строкой</term>
358
<para>она должна ссылаться на имя подпрограммы на языке C или
359
fortran, в предположении, что
360
<<literal>s_name</literal>> является заданным
365
<para>Последовательность вызова Fortran должна быть</para>
367
<literal><j_name>(t, x, xdot, r, cj, ires,
372
<literal>t, x(*), xdot(*), r(*), ci,
375
имеют удвоенную точность;
378
<literal>ires, ipar(*)</literal> являются
383
<para>Последовательность вызова C должна быть</para>
385
<literal>C2F(<j_name>)(double *t, double *x,
386
double *xdot, double *r, double *cj, integer *ires, double
387
*rpar, integer *ipar)
394
где <literal>t, x, xdot, ires, rpar, ipar</literal>
395
имеют аналогичное определение, что и выше,
396
<literal>ng</literal> -- количество поверхностей,
397
<literal>nx</literal> -- размерность состояния и
398
<literal>r</literal> -- массив результатов.
409
вектор с двумя элементами <literal>[times num]</literal>, где
410
<literal>times</literal> -- значение момента времени пересечения
411
поверхности, <literal>num</literal> -- число пересечённых
419
<para>вещественный вектор, в качестве аргумента на выходе он хранит
420
контекст <literal>dae</literal>. Он может быть использован в
421
качестве входного аргумента для возобновления интегрирования
422
(горячий перезапуск).
430
вещественная матрица. Если
432
<link linkend="daeoptions">%DAEOPTIONS</link>(2)=1
435
столбец является вектором вида <literal>[t;x(t);xdot(t)]</literal>,
436
где <literal>t</literal> -- индекс времени для которого вычислено
437
решение. В противном случае <literal>y</literal> -- вектор вида
438
<literal>[x(t);xdot(t)]</literal>.
445
<title>Описание</title>
447
Функция <literal>dae</literal> является шлюзом, построенным над
448
функциями <link linkend="dassl">dassl</link> и <link linkend="dasrt">dasrt</link>, разработанными для явного интегрирования
449
дифференциальных уравнений.
451
<programlisting role="no-scilab-exec">
453
x(t0)=x0 and xdot(t0)=xdot0
456
Если <literal>xdot0</literal> не указан в
457
<emphasis>исходном</emphasis> аргументе, то функция <literal>dae</literal>
458
пытается вычислить его решая уравнение
459
<literal>g(t,x0,xdot0)=0</literal>/
462
Если <literal>xdot0</literal> указан в <emphasis>исходном</emphasis>
463
аргументе, то он может быть либо совместимой производной (compatible
464
derivative), удовлетворяющей условию <literal>g(t,x0,xdot0)=0</literal>,
465
либо приближённым значением. В последнем случае <link linkend="daeoptions">%DAEOPTIONS</link>(7) должен быть установлен в
468
<para>Конкретные примеры использования внешних функций, написанных на
469
языке Scilab и C, представлены в
470
<literal>modules/differential_equations/tests/unit_tests/dassldasrt.tst</literal>
474
<title>Примеры</title>
475
<programlisting role="example">
476
//Пример с кодом Scilab
477
function [r,ires]=chemres(t,y,yd)
478
r(1) = -0.04*y(1) + 1d4*y(2)*y(3) - yd(1);
479
r(2) = 0.04*y(1) - 1d4*y(2)*y(3) - 3d7*y(2)*y(2) - yd(2);
480
r(3) = y(1) + y(2) + y(3)-1;
483
function pd=chemjac(x,y,yd,cj)
484
pd=[-0.04-cj , 1d4*y(3) , 1d4*y(2);
485
0.04 ,-1d4*y(3)-2*3d7*y(2)-cj ,-1d4*y(2);
490
xd0=[-0.04; 0.04; 0];
491
t=[1.d-5:0.02:.4, 0.41:.1:4, 40, 400, 4000, 40000, 4d5, 4d6, 4d7, 4d8, 4d9, 4d10];
493
y=dae([x0,xd0],0,t,chemres);// возвращает запрошенные моменты времени наблюдения
495
%DAEOPTIONS=list([],1,[],[],[],0,0); // просит вернуть сетку точек dae
496
y=dae([x0,xd0],0,4d10,chemres); // без якобиана
497
y=dae([x0,xd0],0,4d10,chemres,chemjac); // с якобианом
499
//пример с кодом C (необходим C-компилятор) --------------------------------------------------
500
//-1- создать C-код в TMPDIR - Уравнение Вандерпола, неявная форма
501
code=['#include <math.h>'
502
'void res22(double *t,double *y,double *yd,double *res,int *ires,double *rpar,int *ipar)'
503
'{res[0] = yd[0] - y[1];'
504
' res[1] = yd[1] - (100.0*(1.0 - y[0]*y[0])*y[1] - y[0]);}'
506
'void jac22(double *t,double *y,double *yd,double *pd,double *cj,double *rpar,int *ipar)'
508
' pd[1]= - (-200.0*y[0]*y[1] - 1.0);'
510
' pd[3]=*cj - (100.0*(1.0 - y[0]*y[0]));}'
512
'void gr22(int *neq, double *t, double *y, int *ng, double *groot, double *rpar, int *ipar)'
513
'{ groot[0] = y[0];}']
514
mputl(code,TMPDIR+'/t22.c')
516
//-2- скомпилировать и загрузить его
517
ilib_for_link(['res22' 'jac22' 'gr22'],'t22.c',[],'c',TMPDIR+'/Makefile',TMPDIR+'/t22loader.sce');
518
exec(TMPDIR+'/t22loader.sce')
521
rtol=[1.d-6;1.d-6];atol=[1.d-6;1.d-4];
522
t0=0;y0=[2;0];y0d=[0;-2];t=[20:20:200];ng=1;
524
//простое моделирование
526
yy=dae([y0,y0d],t0,t,atol,rtol,'res22','jac22');
527
clf();plot(yy(1,:),yy(2,:))
529
// найти первую точку, где yy(1)=0
530
[yy,nn,hotd]=dae("root",[y0,y0d],t0,300,atol,rtol,'res22','jac22',ng,'gr22');
531
plot(yy(1,1),yy(2,1),'r+')
532
xstring(yy(1,1)+0.1,yy(2,1),string(nn(1)))
534
// горячий перезапуск для следующей точки
535
t01=nn(1);[pp,qq]=size(yy);y01=yy(2:3,qq);y0d1=yy(3:4,qq);
536
[yy,nn,hotd]=dae("root",[y01,y0d1],t01,300,atol,rtol,'res22','jac22',ng,'gr22',hotd);
537
plot(yy(1,1),yy(2,1),'r+')
538
xstring(yy(1,1)+0.1,yy(2,1),string(nn(1)))
541
<refsection role="see also">
542
<title>Смотрите также</title>
543
<simplelist type="inline">
545
<link linkend="ode">ode</link>
548
<link linkend="daeoptions">daeoptions</link>
551
<link linkend="dassl">dassl</link>
554
<link linkend="impl">impl</link>
557
<link linkend="fort">fort</link>
560
<link linkend="link">link</link>
563
<link linkend="external">external</link>