1 <?xml version="1.0" encoding="UTF-8"?>
3 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4 * Copyright (C) 2008 - INRIA
7 * This file must be used under the terms of the CeCILL.
8 * This source file is licensed as described in the file COPYING, which
9 * you should have received as part of this distribution. The terms
10 * are also available at
11 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
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" xmlns:scilab="http://www.scilab.org" 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"><![CDATA[
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;
484 function pd=chemjac(x,y,yd,cj)
485 pd=[-0.04-cj , 1d4*y(3) , 1d4*y(2);
486 0.04 ,-1d4*y(3)-2*3d7*y(2)-cj ,-1d4*y(2);
491 xd0=[-0.04; 0.04; 0];
492 t=[1.d-5:0.02:.4, 0.41:.1:4, 40, 400, 4000, 40000, 4d5, 4d6, 4d7, 4d8, 4d9, 4d10];
494 y=dae([x0,xd0],0,t,chemres);// возвращает запрошенные моменты времени наблюдения
496 %DAEOPTIONS=list([],1,[],[],[],0,0); // просит вернуть сетку точек dae
497 y=dae([x0,xd0],0,4d10,chemres); // без якобиана
498 y=dae([x0,xd0],0,4d10,chemres,chemjac); // с якобианом
500 <programlisting role="example"><![CDATA[
501 //пример с кодом C (необходим C-компилятор)
502 --------------------------------------------------
505 [btn] = messagebox(["Для этого примера Вам необходим C-компилятор.";"Выполнение этого примера отменено."], "Проблема с программным обеспечением", 'info');
509 //-1- создать C-код в TMPDIR - Уравнение Вандерпола, неявная форма
510 code=['#include <math.h>'
511 'void res22(double *t,double *y,double *yd,double *res,int *ires,double *rpar,int *ipar)'
512 '{res[0] = yd[0] - y[1];'
513 ' res[1] = yd[1] - (100.0*(1.0 - y[0]*y[0])*y[1] - y[0]);}'
515 'void jac22(double *t,double *y,double *yd,double *pd,double *cj,double *rpar,int *ipar)'
517 ' pd[1]= - (-200.0*y[0]*y[1] - 1.0);'
519 ' pd[3]=*cj - (100.0*(1.0 - y[0]*y[0]));}'
521 'void gr22(int *neq, double *t, double *y, int *ng, double *groot, double *rpar, int *ipar)'
522 '{ groot[0] = y[0];}']
523 previous_dir = pwd();
527 //-2- скомпилировать и загрузить его
528 ilib_for_link(['res22' 'jac22' 'gr22'],'t22.c',[],'c','Makefile','t22loader.sce');
529 exec('t22loader.sce')
539 //простое моделирование
541 yy=dae([y0,y0d],t0,t,atol,rtol,'res22','jac22');
542 clf();plot(yy(1,:),yy(2,:))
544 // найти первую точку, где yy(1)=0
545 [yy,nn,hotd]=dae("root",[y0,y0d],t0,300,atol,rtol,'res22','jac22',ng,'gr22');
546 plot(yy(1,1),yy(2,1),'r+')
547 xstring(yy(1,1)+0.1,yy(2,1),string(nn(1)))
549 yy=dae([y0,y0d],t0,t,atol,rtol,'res22','jac22');
550 clf();plot(yy(1,:),yy(2,:))
552 // горячий перезапуск для следующей точки
557 [yy,nn,hotd]=dae("root",[y01,y0d1],t01,300,atol,rtol,'res22','jac22',ng,'gr22',hotd);
558 plot(yy(1,1),yy(2,1),'r+')
559 xstring(yy(1,1)+0.1,yy(2,1),string(nn(1)))
562 <scilab:image><![CDATA[
563 code=['#include <math.h>'
564 'void res22(double *t,double *y,double *yd,double *res,int *ires,double *rpar,int *ipar)'
565 '{res[0] = yd[0] - y[1];'
566 ' res[1] = yd[1] - (100.0*(1.0 - y[0]*y[0])*y[1] - y[0]);}'
568 'void jac22(double *t,double *y,double *yd,double *pd,double *cj,double *rpar,int *ipar)'
570 ' pd[1]= - (-200.0*y[0]*y[1] - 1.0);'
572 ' pd[3]=*cj - (100.0*(1.0 - y[0]*y[0]));}'
574 'void gr22(int *neq, double *t, double *y, int *ng, double *groot, double *rpar, int *ipar)'
575 '{ groot[0] = y[0];}']
576 previous_dir = pwd();
579 ilib_for_link(['res22' 'jac22' 'gr22'],'t22.c',[],'c','Makefile','t22loader.sce');
580 exec('t22loader.sce')
588 yy=dae([y0,y0d],t0,t,atol,rtol,'res22','jac22');
589 clf();plot(yy(1,:),yy(2,:))
590 [yy,nn,hotd]=dae("root",[y0,y0d],t0,300,atol,rtol,'res22','jac22',ng,'gr22');
591 plot(yy(1,1),yy(2,1),'r+')
592 xstring(yy(1,1)+0.1,yy(2,1),string(nn(1)))
597 [yy,nn,hotd]=dae("root",[y01,y0d1],t01,300,atol,rtol,'res22','jac22',ng,'gr22',hotd);
598 plot(yy(1,1),yy(2,1),'r+')
599 xstring(yy(1,1)+0.1,yy(2,1),string(nn(1)));
603 <refsection role="see also">
604 <title>Смотрите также</title>
605 <simplelist type="inline">
607 <link linkend="ode">ode</link>
610 <link linkend="daeoptions">daeoptions</link>
613 <link linkend="dassl">dassl</link>
616 <link linkend="impl">impl</link>
619 <link linkend="fort">fort</link>
622 <link linkend="link">link</link>
625 <link linkend="external">external</link>