宇宙学背景方程的数值求解

计算科学 数字 计算物理学 微分方程 C
2021-12-05 12:01:15

我正在尝试使用具有简化假设的 Runge-Kutta Dormand Prince 方法以数值方式求解宇宙学的背景方程。方程是 8πG=1c=1

a¨=16(ρ+3p)a

ρ˙=3a˙a(ρ+p)

对于物质和辐射(p=0)(p=13ρ)

我应该得到一个关于物质但是在这两种情况下,我都得到了相同的比例因子变化。我是初学者。我无法弄清楚我哪里出错了。请帮我。at2/3at1/2a

我传递给我的代码的方程式如下

就事论事

       void fcn(double t, double *y, double *f){

                double p,hub;
                p=0;
                hub=y[1]/y[0];
                f[0] = y[1];
                f[1] = -(y[0]*y[2]+3*p*y[0])/6.0;
                f[2] = -3*hub*y[2]-3*hub*p;

             }

对于辐射

           void fcn(double t, double *y, double *f){
           /* a=y[0],adot=y[1],rho=y[2]  */
                     double p,hub;
                     hub=y[1]/y[0];
                     p= (2.0/3.0)*y[2];
                     f[0] = y[1];
                     f[1] = -(y[0]*y[2]+3*p*y[0])/6.0;
                     f[2] = -3*hub*y[2]-3*hub*p;
                 }

我为 vs图是 vs图" />at<跨度类=at

我只是想看看我们得到的函数依赖类型是什么,而不是按照宇宙学来设置初始条件。这可能是因为初始条件错误吗?

另一件事是随时间的变化在两种情况下应该是相同的()但我也得到了不同的结果。ρρt2

vs情节如下ρt

<跨度类=ρ vs图" />t

我的代码在求解其他耦合微分方程方面表现出色。

         #include<stdio.h>
         #include<math.h>
         #include<stdbool.h>
         #include  <stdlib.h>

         #define N 3

         double ddopri5(void fcn(double, double *, double *), 
                        double *y);
         double alpha;
         void fcn(double t, double *y, double *f);
         double eps;

         int main(void){

               double y[N];
               //eps = 1.e-9;
               printf("Enter epsilon:\n"); 
               scanf("%lg", &eps);
               y[0]=1.0;
               y[1]=12.00;
               y[2]=30.00000567845; 
               ddopri5(fcn, y);

          }


         void fcn(double t, double *y, double *f){
                double p,hub;
                 p=0;
                 hub=y[1]/y[0];
                 f[0] = y[1];
                 f[1] = -(y[0]*y[2]+3*p*y[0])/6.0;
                 f[2] = -3*hub*y[2]-3*hub*p;

          }

           double ddopri5(void fcn(double, double *, double *), 
                         double *y){
                 double t, h, a, b, tw, chi;
                 double w[N], k1[N], k2[N], k3[N], k4[N], k5[N], 
                        k6[N],k7[N], err[N], dy[N];
                 int i;
                 double errabs;
                 int iteration;
                 FILE *fpw;
                 fpw=fopen("case1.dat", "w");


                 iteration = 0;
                 //eps = 1.e-9;
                  h = 1.0e-6;
                  a = 0.0;
                  b = 30;
                  t = a;
                 while(t < b -eps){
                      fcn(t, y, k1);
                      tw = t+ (1.0/5.0)*h;
                      for(i = 0; i < N; i++){
                         w[i] = y[i] + h*(1.0/5.0)*k1[i];    
                       }
                     fcn(tw, w, k2);
                      tw = t+ (3.0/10.0)*h;
                      for(i = 0; i < N; i++){
                       w[i] = y[i] + h*((3.0/40.0)*k1[i]+ 
                              (9.0/40.0)*k2[i]);  
                            }

                         fcn(tw, w, k3);
                         tw = t+ (4.0/5.0)*h;
                         for(i = 0; i < N; i++){
                           w[i] = y[i] + h*((44.0/45.0)*k1[i] -n 
                                 (56.0/15.0)*k2[i] + 
                                 (32.0/9.0)*k3[i]); 
                              }
                    fcn(tw, w, k4);
                    tw = t+ (8.0/9.0)*h;
                     for(i = 0; i < N; i++){
                       w[i] = y[i] + h*((19372.0/6561.0)*k1[i] - 
                             (25360.0/2187.0)*k2[i] + 
                                (64448.0/6561.0)*k3[i] - 
                                   (212.0/729.0)*k4[i]);   
                         }
                   fcn(tw, w, k5);
                   tw = t + h;
                   for(i = 0; i < N; i++){
                         w[i] = y[i] + h*((9017.0/3168.0)*k1[i] - 
                                (355.0/33.0)*k2[i] + 
                                 (46732.0/5247.0)*k3[i] + 
                                  (49.0/176.0)*k4[i] - 
                                   (5103.0/18656.0)*k5[i]) ;   
                            }
                  fcn(tw, w, k6);
                  tw = t + h;
                  for(i = 0; i < N; i++){
                     w[i] = y[i] + h*((35.0/384.0)*k1[i] + 
                     (500.0/1113.0)*k3[i] + (125.0/192.0)*k4[i] - 
                      (2187.0/6784.0)*k5[i] + (11.0/84.0)*k6[i]);  
                    }
                  fcn(tw, w, k7);
                  errabs = 0;

                 for(i = 0; i < N; i++){
                   dy[i] = h*((35.0/384.0)*k1[i] + 
                         (500.0/1113.0)*k3[i] + 
                         (125.0/192.0)*k4[i] - 
                          (2187.0/6784.0)*k5[i] + 
                           (11.0/84.0)*k6[i]);
        
                    err[i] =  h*((71.0/57600.0)*k1[i]  - 
                            (71.0/16695.0)*k3[i] 
                            + (71.0/1920.0)*k4[i] - 
                            (17253.0/339200.0)*k5[i] + 
                        (22.0/525.0)*k6[i] - (1.0/40.0)*k7[i]);
                   errabs+=err[i]*err[i];
                }


               errabs = sqrt(errabs);
               if( errabs < eps){
                    t+= h;
                    for(i = 0; i < N; i++){
                         y[i]+=dy[i];            
                    }
                 } 
              chi=errabs/eps;
              chi = pow(chi, (1.0/6.0));
              if(chi > 10)    chi = 10;
              if(chi < 0.1)   chi = 0.1;
              h*=  0.95/chi;
              if( t + h > b ) h = b - t;      
              iteration++;

             fprintf(fpw ,"%.25lf %.25lf %.25lf %.25lf \n", 
                      t,y[0],y[1],y[2]);
             if(iteration > 30000) break;
            }

             fclose(fpw);
             return 0;
           }

我也试过 Scipy 。我在下面分享我的 Scipy 代码

      from scipy.integrate import odeint
      import numpy as np
      import matplotlib.pyplot as plt
      
      def odes(x,t):
      #assign each ode to a vector
      A=x[0]
      B=x[1]
      C=x[2]

      #define each ODE
      dAdt=B
      dBdt=-(1/6)*A*C
      dCdt=-(3*C*B)/A

      return [dAdt,dBdt,dCdt]

      #define initialcondition
      x0=[1,5,13]

      #declare a time vector
      t=np.linspace(0,30,1000)
      x=odeint(odes,x0,t)

      A=x[:,0]
      B=x[:,1]
      C=x[:,2]

      #plot the results
      plt.semilogy(t,A)
      plt.semilogy(t,B)
      plt.semilogy(t,C)
      plt.show()
0个回答
没有发现任何回复~