Текст подпрограммы и версий
de47r_c.zip , de47d_c.zip
Тексты тестовых примеров
tde47r_c.zip , tde47d_c.zip

Подпрограмма:  de47r_c

Назначение

Вычисление решения задачи Коши для системы обыкновенных дифференциальных уравнений второго порядка с правой частью, зависящей от производной, в конце интервала интегрирования методом Штермера с контролем точности.

Математическое описание

Решается задача Коши для системы M обыкновенных дифференциальных уравнений второго порядка

  Y '' = F ( X, Y, Y ' )   ,
  Y = ( y1, ..., yM )  ,
  F = ( f1 ( X, y1, ..., yM, y1', ..., yM' ), ..., fM ( X, y1, ..., yM, y '1, ..., y 'M ) ) ,

с начальными условиями, заданными в точке  XN:

     Y (XN)  = YN   ,      YN  = ( y10, ..., yM0 )   ,

     Y ' (XN) = DYN   ,   DYN = ( y10', ..., yM0' )   ,   -

многозначным предсказывающе - исправляющим методом. При этом приближенное значение решения  Y вычисляется методом Штермера пятого порядка точности, производной  - методом Адамса пятого порядка точности.

Суть метода состоит в том, что сначала по явным формулам строятся предсказанные значения решения и производной, которые затем исправляются по неявным формулам.

Решение и производная вычисляются в одной точке  XK, которая является концом интервала интегрирования.

Bсе компоненты решения проверяются на точность по меpе погрешности, т.е. если некоторая компонента приближенного решения по абсолютной величине не меньше некоторой заданной константы  P, то контроль точности для этой компоненты ведется по относительной погрешности, иначе - по абсолютной.

Бахвалов H.C., Численные методы, т.1, "Hаука", 1975.

Использование

    int de47r_c (real *f, integer *m, real *xn, real *yn,
                 real *dyn, real *xk, real *hmin, real *hmax, real *eps, real *p,
                 real *h, real *y, real *dy, real *z, real *delty, real *df,
                 real *rfn, real *rf, real *yp, real *dyp, real *zp, integer *ierr)

Параметры

f - имя подпрограммы вычисления значений правой части системы. Первый оператор подпрограммы должен иметь вид:
 

int f (float *x, float *y, float *dy, float *d2y, int *m)

Здесь:  x, y, dy - значения независимой, зависимой переменных и производной решения, соответственно; вычисленное значение правой части должно быть помещено в  d2y. B случае системы уравнений, т.е. когда m ≠ 1 - параметры  y, dy, d2y представляют одномерные массивы длины  m (тип параметров   x, y, dy и d2y: вещественный);

m - количество уравнений в системе (тип: целый);
      xn, yn -
      dyn  
начальные значения аргумента, решения и его производной; в случае системы уpавнений (т.е.  m ≠ 1)  yn и  dyn представляют одномерные массивы длины  m (тип: вещественный);
xk - значение аргумента, при котоpом требуется вычислить решение задачи Коши (конец интервала интегрирования);  xk может быть больше, меньше или pавно  xn (тип: вещественный);
hmin - минимальное значение абсолютной величины шага, котоpое разрешается использовать при интегрировании данной системы уравнений (тип: вещественный);
hmax - максимальное значение абсолютной величины шага, котоpое разрешается использовать при интегрировании данной системы уравнений (тип: вещественный);
eps - допустимая меpа погрешности, с которой требуется вычислить все компоненты решения (тип: вещественный);
p - граница перехода, используемая при оценке меры погрешности решения (тип: вещественный);
h - вещественная переменная, содержащая начальное значение шага интегрирования; может задаваться с учетом направления интегрирования, т.е. положительным, если  xn < xk, отрицательным, если  xn > xk, или без такого учета в виде абсолютной величины;
     y, dy - искомое решение задачи Коши и его производная, вычисленные подпрограммой для значения аргумента  xk; для системы уравнений задаютсся одномерными массивами длины  m; в случае совпадения значений параметров  xn и   xk значения  y и  dy полагаются равными начальным значениям  yn и  dyn, соответственно (тип: вещественный);
            z -
      delty  
      rfn, rf  
      yp, dyp  
            zp  
одномерные вещественные рабочие массивы длины  m;
df - двумерный вещественный рабочий массив размеpа  m * 5;
ierr - целая переменная, служащая для сообщения об ошибках, обнаруженных в процессе работы подпрограммы; при этом:
ierr=65 и ierr=66 - когда какая - нибудь компонента решения не может быть вычислена с требуемой точностью  eps при заданных начальном шаге  h и его минимальном значении  hmin; при этом  ierr = 66 указывает, что требуемая точность не может быть достигнута при разгоне, а ierr=65 - после разгона; при желании интегрирование системы можно повторить обращением к подпрограмме с новыми значениями параметров  h и  hmin.

Версии

de47d_c - вычисление решения задачи Коши для системы обыкновенных дифференциальных уравнений второго порядка с правой частью, зависящей от производной, методом Штермера с удвоенным числом значащих цифр. При этом параметры  xn, yn, dyn, xk, hmin, hmax, eps, p, h, y, dy, z, delty, df, rfn, rf, yp, dyp, zp и параметры  x, y, dy и  d2_cy в подпрограмме  f должны иметь тип double.

Вызываемые подпрограммы

       de46r_c -
       de46d_c  
выполнение одного шага численного интегрирования системы обыкновенных дифференциальных уравнений второго порядка с правой частью, зависящей от производной, методом Штермера с контролем точности.
      utde16_c -
      utde17_c  
подпрограммы выдачи диагностических сообщений.
  Подпрограммы de46r_c и utde16_c вызываются при работе подпрограммы de47r_c, а подпрограммы de46d_c и utde17_c - при работе подпрограммы de47d_c.

Замечания по использованию

 

B общем случае заданная точность решения не гарантируется.

Приближенное значение производной на точность не проверяется.

При работе подпрограммы и ее версии значения параметров   m, xn, yn, dyn, xk, hmin, hmax, eps, p сохраняются.

Значение параметра  hmax не должно быть слишком большим, т.к. в противном случае величина шага интегрирования может достичь таких размеров, которые приведут к абсолютной неустойчивости численного метода.

Если после работы подпрограммы нет необходимости иметь начальные значения решения  yn и/или производной  dyn, то параметры  yn и  y, а в случае производной, параметры  dyn и  dy при обращении к ней можно совместить.

При этом следует иметь в виду, что в случае аварийного выхода из подпрограммы, т.е. со значением  ierr = 65 или 66, значения параметров  yn и  dyn будут испорчены.

Tак как при интегрировании уравнений с помощью подпрограмм de47r_c и de47d_c используются (для версии фортран) общие блоки с именами com48r и com48d, соответственно, то пользователю не рекомендуется использовать для своих целей (для версии фортран) общие блоки с указанными именами.

Пример использования

     y1'' = 0.5 ( y2 - y1 + y1' + y2' ) - 0.5   ,   y1 (0) = 1   ,   y1' (0) = 1.5   ,
     y2 = y1'' - 0.5 x   ,   y2 (0) = - 1   ,   y2 (0) = - 0.5   .

int main(void)
{
    /* Builtin functions */
    double sin(double), cos(double);

    /* Local variables */
    extern int de47r_c(U_fp, int *, float *, float *, float *, float *,
                       float *, float *, float *, float *, float *, float *,
                       float *, float *, float *, float *, float *, float *,
                       float *, float *, float *, int *);
    static float hmin, hmax;
    static int ierr;
    static float h__;
    static int m;
    static float p, y[2], z__[2], delty[2];
    extern int f2_c();
    static float y1, y2, df[10] /* was [2][5] */, rf[2], dy[2], xk, xn, yn[2],
                  yp[2], zp[2], dy1, dy2, rfn[2], eps, dyn[2], dyp[2];

    m = 2;
    xn = 0.f;
    yn[0] = 1.f;
    yn[1] = -1.f;
    dyn[0] = 1.5f;
    dyn[1] = -.5f;
    xk = 5.f;
    hmin = 1e-10f;
    hmax = .1f;
    eps = 1e-4f;
    p = 100.f;
    h__ = .01f;
    de47r_c((U_fp)f2_c, &m, &xn, yn, dyn, &xk, &hmin, &hmax, &eps, &p, &h__,
            y, dy, z__, delty, df, rfn, rf, yp, dyp, zp, &ierr);

    printf("\n %5i \n", ierr);
    printf("\n %16.7e \n", xk);
    printf("\n %16.7e %16.7e \n", y[0], y[1]);
    printf("\n %16.7e %16.7e \n", dy[0], dy[1]);
    y1 = (float)sin(xk) + (float)cos(xk) + xk * .5f;
    y2 = -y1 + xk;
    dy1 = (float)cos(xk) - (float)sin(xk) + .5f;
    dy2 = -dy1 + 1.f;

    printf("\n\n %16.7e \n", xk);
    printf("\n %16.7e %16.7e \n", y1, y2);
    printf("\n %16.7e %16.7e \n", dy1, dy2);
    return 0;
} /* main */

int f2_c(float *x, float *y, float *dy, float *z, int *m)
{
    /* Parameter adjustments */
    --z__;
    --dy;
    --y;

    /* Function Body */
    z__[1] = (y[2] + dy[1] - y[1] + dy[2]) * .5f - .5f;
    z__[2] = y[1] - *x * .5f;
    return 0;
} /* f2_c */


Результаты:

      ierr = 0

                      xk                              y(1)                             y(2)
       5.000000000000 + 00     1.824737966524 + 00    3.175262014483 + 00

                                                          y1                                y2
                                              1.824737910809 + 00      3.175262089189 + 00

                                                         dy(1)                            dy(2)
                                              1.742586640374 + 00    - 7.425866599151 - 01

                                                         dy1                              dy2
                                              1.742586460128 + 00    - 7.425864601282 - 01