首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用gsl编写Runge-Kutta ODE求解器

使用gsl编写Runge-Kutta ODE求解器
EN

Stack Overflow用户
提问于 2012-10-25 00:44:36
回答 1查看 2.3K关注 0票数 1

我已经有一段时间没有做任何C/c++了,但是我想使用gsl库编写一个ODE解算器来求解下面的ODE集

代码语言:javascript
复制
$$ 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=u、y1==up和上面的RHS定义了f和f1。根据这些定义,可以计算雅可比矩阵和dfdr (通常将它们的'time‘变量称为't’而不是'r')。这样做的原因是因为我在使用Mathematica时遇到了速度问题。我在ODE解算器上的文档末尾采用了gsl示例代码,并尝试将其调整为适合我的问题,如下所示:

代码语言:javascript
复制
 #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给出的数字,即使我有一个较低的WorkingPrecision和PrecisionGoal。我做的事有错吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-10-25 01:21:47

我认为您只是在r*(r-2)中缺少了一个括号

代码语言:javascript
复制
((r*r/((r-2)*(r-2)))-(2/r*(r-2)))*y[0];

(也是在up'(r)=-(2*(r-1)/(r*(r-2)))*up(r)-((r*r/((r-2)*(r-2)))-(2/r*(r-2)))*u(r)中),在jac中有相应的圆括号。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13053768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档