⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rose.c

📁 multipleshooting to find the roots of the non-linear functions
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <stdio.h>#include <math.h>#include <stdlib.h>#include "math_util.h"#define MAXIT 200#define NEW_ITT_1 20#define NEW_ITT_2 20#define MACH_EPS 1.0e-19#define GAMMA2 (7.0/24.0)#define DELTA1 (1.0)#define DELTA2 (7.0/24.0)#define gdeli00 (0.0)#define gdeli10 (19.0/7.0)#define gdeli11 (1.0)#define gdeli20 (53.0/14.0)#define gdeli21 (0.0)#define gdeli22 (0.0)#define gdeli30 (3.0/98.0)#define gdeli31 (0.0)#define gdeli32 (1.0/7.0)#define gdeli33 (1.0)#define deli00 (1.0)#define deli10 (55.0/7.0)#define deli11 (24.0/7.0)#define deli20 (71.0/7.0)#define deli21 (39.0/7.0)#define deli22 (1.0)#define deli30 (-15.0/49.0)#define deli31 (129.0/49.0)#define deli32 (23.0/7.0)#define deli33 (24.0/7.0)#define mudeli0 (71.0/39.0)#define mudeli1 (1.0)#define mudeli2 (23.0/39.0)#define mudeli3 (24.0/39.0)#define max_num(x,y) ((x)>(y)?(x):(y))#define sgn_num(x) (((x)<0.0)?-1.0:1.0)#define dmax(x,y) (((x)>(y))?(x):(y))#define dmin(x,y) (((x)>(y))?(y):(x))/**/int rose_mod_a( t0, t1, y, z, u_fun, u_dfun, n, m, tol )/*      This function uses the 4th order Runge-Kutta (ROW) method to integrate a system      of (n,m) differential-algebraic equations. The integration goes from t0 to t1.      The result is put in y, z. On input, y = y(t0), z = z(t0).      Method adapted from Schneider, C., Rosenbrock-type Methods Adapted to Differential-      Algebraic Systems, Mathematics of Computation, Vol. 56, pp. 201-213, 1989.        Return code -> 0 : Normal completion.      Return code -> 1 : Error, invalid number of differential and algebraic equations.      Return code -> 2 : Error, out of memory.      Return code -> 4 : Error, too many iterations required.      Return code -> 5 : Error, required stepsize too small.*/int n, m;long double t0, t1, *y, *z, tol;    void (*u_fun)( long double *, long double *, long double *, long double * );void (*u_dfun)( long double *, long double *, long double **, long double **, long double **, long double ** );/**/{   long double **big_jac1, **big_jac2, *rhs, *lhs, *y0, *z0, *y1, *z1;   long double **fy, **fz, **gy, **gz, **kapa, **lambda, *f, *g, *g0;   long double h, hnew, sum, t, error, err_2, fac;   int i, j, k, p, err, itt;   int *pivot1, *pivot2;  /*   Some simple checks*/   if( (n < 1) || (m < 0) ) {      printf("*** ERROR in ROSE -> Invalid number of differential and algebraic equations\n");      return( 1 );   }   /*   Allocate storage*/   p = m+n;      big_jac1 = a2d_allo_dbl( p, p );   big_jac2 = a2d_allo_dbl( p, p );   fy = a2d_allo_dbl( n, n );   fz = a2d_allo_dbl( n, m );   gz = a2d_allo_dbl( m, m );   gy = a2d_allo_dbl( m, n );   kapa = a2d_allo_dbl( 4, n );   lambda = a2d_allo_dbl( 4, m );   pivot1 = a1d_allo_int( p );   pivot2 = a1d_allo_int( p );   rhs = a1d_allo_dbl( p );   lhs = a1d_allo_dbl( p );   f = a1d_allo_dbl( n );   g = a1d_allo_dbl( m );   g0 = a1d_allo_dbl( m );   y1 = a1d_allo_dbl( n );   z1 = a1d_allo_dbl( m );   y0 = a1d_allo_dbl( n );   z0 = a1d_allo_dbl( m );   if ( big_jac1 == NULL || big_jac2 == NULL || fy == NULL || pivot1 == NULL || pivot2 == NULL ||         rhs == NULL || lhs == NULL || y0 == NULL || y1 == NULL || f == NULL || kapa == NULL  ) {      printf("*** ERROR in ROSE -> Out of memory\n");      a2d_free_dbl( big_jac1, p );      a2d_free_dbl( big_jac2, p );      a2d_free_dbl( kapa, 4 );      a2d_free_dbl( fy, n );      a1d_free_int( pivot1 );      a1d_free_int( pivot2 );      a1d_free_dbl( rhs );      a1d_free_dbl( lhs );      a1d_free_dbl( f );      a1d_free_dbl( y0 );      a1d_free_dbl( y1 );      return( 2 );   }   if( (m > 0) && ( fz == NULL || gz == NULL || gy == NULL || z0 == NULL || z1 == NULL || g == NULL ||        g0 == NULL || lambda == NULL) ){      printf("*** ERROR in ROSE -> Out of memory\n");      a2d_free_dbl( fz, n );      a2d_free_dbl( gz, m );      a2d_free_dbl( gy, m );      a1d_free_dbl( g );      a1d_free_dbl( g0 );      a1d_free_dbl( z0 );      a1d_free_dbl( z1 );      a2d_free_dbl( lambda, 4 );      return( 2 );   }/*   Make initial conditions consistent   */        (*u_fun)( y, z, f, g );   vec_copy( g0, g, m );   /* Initial step size */   h = pow(tol,0.25);   if( h > fabs((double)(t1-t0)) )       h = dmax(t1,t0)-dmin(t1,t0);   if( (t0+h) > t1 )      h = t1-t0;         t = t0;         for( itt = 0; itt < MAXIT; itt++ ) {         t += h;         vec_copy( y0, y, n );      vec_copy( z0, z, m );   /*   Step 1*/            /*Form big_jac_1*/                  mat_null( big_jac1, p, p );         (*u_fun)( y0, z0, f, g );      (*u_dfun)( y0, z0, fy, fz, gy, gz );         for( i = 0; i < p; i++ )         for( j = 0; j < p; j++ ) {            if( i < n ) {               if( i == j )                  big_jac1[i][j] = 1.0;            }            if( i >= n ) {               if( j < n )                  big_jac1[i][j] = gy[i-n][j];               else                  big_jac1[i][j] = gz[i-n][j-n];            }         }      err = factor1( big_jac1, p, pivot1 );      if( err == 0 || err == 2 ) {         printf("*** ERROR in ROSE -> Jacobian matrix singular\n");         printf("                     DAE is not index 1\n");                  return( 3 );      }      vec_null( rhs, p );         for( i = 0; i < p; i++ ) {         if( i < n )            rhs[i] = DELTA1*h*f[i];         else            rhs[i] = -(g[i-n]-g0[i-n]);      }      solve1( big_jac1, pivot1, rhs, p, lhs );         for( i = 0; i < p; i++ ) {         if( i < n ) {            kapa[0][i] = lhs[i];            y0[i] += lhs[i];            /* Update y0 and z0 for the next step */         }         else {            lambda[0][i-n] = lhs[i];            z0[i-n] += lhs[i];         }      }/*   Step 2*/            /*Form big_jac_2*/                  mat_null( big_jac2, p, p );         (*u_fun)( y0, z0, f, g );         (*u_dfun)( y0, z0, fy, fz, gy, gz );         for( i = 0; i < p; i++ )         for( j = 0; j < p; j++ ) {            if( i < n ) {               if( i == j )                  big_jac2[i][j] = 1.0;               if( j < n )                  big_jac2[i][j] += -h*GAMMA2*fy[i][j];               if( j >= n )                   big_jac2[i][j] = -h*GAMMA2*fz[i][j-n];            }            if( i >= n ) {               if( j < n )                  big_jac2[i][j] = gy[i-n][j];               else                  big_jac2[i][j] = gz[i-n][j-n];            }         }         err = factor1( big_jac2, p, pivot2 );      if( err == 0 || err == 2 ) {         printf("*** ERROR in ROSE -> Jacobian matrix singular\n");         printf("                     DAE is not index 1\n");                  return( 3 );      }         for( i = 0; i < n; i++ ) {         sum = h*f[i];         for( k = 0; k < n; k++ ) {            sum += fy[i][k]*kapa[0][k]*h*gdeli10;         /*for( k = 0; k < m; k++ )*/            if( k < m ) sum += fz[i][k]*lambda[0][k]*h*gdeli10;         }         rhs[i] = DELTA2*(sum - deli10*kapa[0][i]);      }      for( i = n; i < p; i++ )         rhs[i] = -(g[i-n]-g0[i-n]);      solve1( big_jac2, pivot2, rhs, p, lhs );         for( i = 0; i < p; i++ ) {         if( i < n ) {            kapa[1][i] = lhs[i];            y0[i] += lhs[i];            /* Update y0 and z0 for the next step */         }         else {            lambda[1][i-n] = lhs[i];            z0[i-n] += lhs[i];         }      }/*   Step 3*/            /*Form big_jac_1*/                  mat_null( big_jac1, p, p );         (*u_fun)( y0, z0, f, g );      (*u_dfun)( y0, z0, fy, fz, gy, gz );         for( i = 0; i < p; i++ )         for( j = 0; j < p; j++ ) {            if( i < n ) {               if( i == j )                  big_jac1[i][j] = 1.0;            }            if( i >= n ) {               if( j < n )                  big_jac1[i][j] = gy[i-n][j];               else                  big_jac1[i][j] = gz[i-n][j-n];            }         }      err = factor1( big_jac1, p, pivot1 );      if( err == 0 || err == 2 ) {         printf("*** ERROR in ROSE -> Jacobian matrix singular\n");         printf("                     DAE is not index 1\n");                  return( 3 );      }         for( i = 0; i < n; i++ ) {         sum = h*f[i];         for( k = 0; k < n; k++ ) {            sum += h*fy[i][k]*(gdeli20*kapa[0][k] + gdeli21*kapa[1][k]);         /*for( k = 0; k < m; k++ )*/            if( k < m ) sum += h*fz[i][k]*(gdeli20*lambda[0][k] + gdeli21*lambda[1][k]);         }         rhs[i] = DELTA1*(sum - (deli20*kapa[0][i] + deli21*kapa[1][i]));      }      for( i = n; i < p; i++ )         rhs[i] = -(g[i-n]-g0[i-n]);      solve1( big_jac1, pivot1, rhs, p, lhs );         for( i = 0; i < p; i++ ) {         if( i < n ) {            kapa[2][i] = lhs[i];            y0[i] += lhs[i];            /* Update y0 and z0 for the next step */         }         else {            lambda[2][i-n] = lhs[i];            z0[i-n] += lhs[i];         }      }/*   Step 4*/            /*Form big_jac_2*/                  mat_null( big_jac2, p, p );         (*u_fun)( y0, z0, f, g );         (*u_dfun)( y0, z0, fy, fz, gy, gz );         for( i = 0; i < p; i++ )         for( j = 0; j < p; j++ ) {            if( i < n ) {               if( i == j )                  big_jac2[i][j] = 1.0;               if( j < n )                  big_jac2[i][j] += -h*GAMMA2*fy[i][j];               if( j >= n )                   big_jac2[i][j] = -h*GAMMA2*fz[i][j-n];            }            if( i >= n ) {               if( j < n )                  big_jac2[i][j] = gy[i-n][j];               else                  big_jac2[i][j] = gz[i-n][j-n];            }         }         err = factor1( big_jac2, p, pivot2 );      if( err == 0 || err == 2 ) {         printf("*** ERROR in ROSE -> Jacobian matrix singular\n");         printf("                         DAE is not index 1\n");                  return( 3 );      }         for( i = 0; i < n; i++ ) {         sum = h*f[i];         for( k = 0; k < n; k++ ) {            sum += h*fy[i][k]*(gdeli30*kapa[0][k] + gdeli31*kapa[1][k] + gdeli32*kapa[2][k]);         /*for( k = 0; k < m; k++ )*/            if( k < m ) sum += h*fz[i][k]*(gdeli30*lambda[0][k] + gdeli31*lambda[1][k] + gdeli32*lambda[2][k]);         }         rhs[i] = DELTA2*(sum - (deli30*kapa[0][i] + deli31*kapa[1][i] + deli32*kapa[2][i]));      }      for( i = n; i < p; i++ )         rhs[i] = -(g[i-n]-g0[i-n]);      solve1( big_jac2, pivot2, rhs, p, lhs );         for( i = 0; i < p; i++ ) {         if( i < n ) {            kapa[3][i] = lhs[i];            y0[i] += lhs[i];            /* Get the solution */                 }         else {            lambda[3][i-n] = lhs[i];            z0[i-n] += lhs[i];         }      }/*    Compute the error estimate */            error = 0.0;      for( i = 0; i < n; i++ ) {                 y1[i] = y[i] + mudeli0*kapa[0][i] + mudeli1*kapa[1][i]+ mudeli2*kapa[2][i]+ mudeli3*kapa[3][i];         if(i==0) error = (y0[i]-y1[i])*(y0[i]-y1[i]);         else error = dmax(error,(y0[i]-y1[i])*(y0[i]-y1[i]));      }/*      To speed things up comment out the next four lines      *//*           for( i = 0; i < m; i++ ) {         z1[i] = z[i] + mudeli0*lambda[0][i] + mudeli1*lambda[1][i] + mudeli2*lambda[2][i] + mudeli3*lambda[3][i];         error += (z0[i]-z1[i])*(z0[i]-z1[i]);      }*/      error = sqrt( (double) error);   /*   Compute a new step size*/      if( error == 0.0 )         error = tol/100.0;            hnew = h*dmin(6.0,dmax(0.2,0.9*(sqrt(sqrt(tol/error)))));            if( error <= tol ) {          vec_copy( y, y0, n);         vec_copy( z, z0, m);      }      else   /* repeat this iteration with a new step size */         t = t - h;      if( (t+hnew) > t1 )         hnew = t1-t;      if( t == t1 || itt >= (MAXIT-1) || h < MACH_EPS ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -