本文介绍了编写使用GSL龙格 - 库塔ODE求解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

它已经有一段时间,因为我做的任何C / C ++,但我想用GSL库来解决以下ODE设置写一个ODE求解

It's been some time since I did any C/c++, but I wanted to write an ODE solver using the gsl library to solve the following ODE set

$$ u'(r)=up(r)$$
$$ up'(r)=-(2*(r-1)/(r*(r-2)))*up(r)-((r*r/((r-2)*(r-2)))-(2/r*(r-2)))*u(r) $$

所以在GSL符号我的Y [0] = U,Y [1] ==起来,上述在RHS定义F [0]和F [1]。从这些定义可以然后计算雅可比和DFDR(通常是他们的'时间'变量称为'T'不'R')。这样做的原因,这是因为我有数学速度问题。我接过GSL例如code。在他们对ODE解算器文档的末尾,并试图以适应我的问题如下:

so in the gsl notation my y[0]=u, y[1]==up, and the RHS of the above defines f[0] and f[1]. From these definitions one can then compute the Jacobian and dfdr (usually their 'time' variable is called 't' not 'r'). The reason for doing this is because I am having speed issues with Mathematica. I took the gsl example code at the end of their documentation on the ODE solver, and tried to adapt it to my problem as follows:

 #include <stdio.h>
 #include <gsl/gsl_errno.h>
 #include <gsl/gsl_matrix.h>
 #include <gsl/gsl_odeiv2.h>
 #include <complex.h>


 int
 func (double r, const double y[], double f[],
       void *params)
 {
   double mu = *(double *)params;
   f[0] = y[1];
   f[1] = -(2*(r-1)/(r*(r-2)))*y[1]-((r*r/((r-2)*(r-2)))-(2/r*(r-2)))*y[0];
   return GSL_SUCCESS;
 }

/* void tester (double r) {  double outer=-((r*r/((r-2)*(r-2)))-(2/(r*(r-2))));  printf ("%.5e \n", outer); } */      

 int
 jac (double r, const double y[], double *dfdy, 
      double dfdt[], void *params)
 {
   double mu = *(double *)params;
   gsl_matrix_view dfdy_mat 
     = gsl_matrix_view_array (dfdy, 2, 2);
   gsl_matrix * m = &dfdy_mat.matrix; 
   gsl_matrix_set (m, 0, 0, 0.0);
   gsl_matrix_set (m, 0, 1, 1.0);
   gsl_matrix_set (m, 1, 0,-((r*r/((r-2)*(r-2)))-(2/(r*(r-2)))));
   gsl_matrix_set (m, 1, 1, -(2*(r-1)/(r*(r-2))));
   dfdt[0] = 0.0;
   dfdt[1] =((1/(r*r))+(1/((r-2)*(r-2))))*y[1]-((4*(1-r)/(r*r*(r-2)*(r-2)))+(4*r/((r-2)*(r-2)*(r-2))))*y[0];
   return GSL_SUCCESS;
 }

 int
 main (void)
 {
   /* tester(5);*/
   double om = 2;
   gsl_odeiv2_system sys = {func, jac, 2, &om};

   gsl_odeiv2_driver * d = 
     gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rk8pd,
                  1e-6, 1e-6, 0.0);
   int i;
   double r = 10, r1 = 100;
   double y[2] = { 0.0000341936, -0.0000572397 };

   for (i = 1; i <= 90; i++)
     {
       double ri = 10 + i;
       int status = gsl_odeiv2_driver_apply (d, &r, ri, y);

       if (status != GSL_SUCCESS)
    {
      printf ("error, return value=%d\n", status);
      break;
    }

       printf ("%.5e %.5e %.5e\n", r, y[0], y[1]);
     }

   gsl_odeiv2_driver_free (d);
   return 0;
 }

这是给的数字,但作为数学NDSolve给出了他们不一样的数字,甚至当我有一个低的工作precision和precisionGoal。有没有在我做了什么错误?

This is giving numbers but they are not the same numbers as Mathematica NDSolve gives, even when I have a low WorkingPrecision and PrecisionGoal. Is there an error in what I've done?

推荐答案

依我看你只是缺乏围绕括号 R *(R-2)

Methinks you're just lacking a parenthesis around r*(r-2) in

((r*r/((r-2)*(r-2)))-(2/r*(r-2)))*y[0];

(也向上'(R)= - (2 *(R-1)/(R *(R-2)))*向上(R) - ((R * R / ((R-2)*(R-2))) - (2 / R *(R-2)))* U(R)),您必须在相应的括号 JAC

(also in up'(r)=-(2*(r-1)/(r*(r-2)))*up(r)-((r*r/((r-2)*(r-2)))-(2/r*(r-2)))*u(r)), you have the corresponding parentheses in jac.

这篇关于编写使用GSL龙格 - 库塔ODE求解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 06:16