Advertisement
Guest User

Untitled

a guest
Mar 20th, 2011
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.62 KB | None | 0 0
  1. /*
  2. AUTHOR : Shrikanth Ranganadham
  3. Based on asc_lsode and asc_dopri5
  4. */
  5.  
  6. #include <ascend/general/platform.h>
  7. #include <ascend/general/panic.h>
  8. #include <ascend/utilities/ascSignal.h>
  9. #include <ascend/utilities/error.h>
  10. #include <ascend/general/ospath.h>
  11. #include <ascend/integrator/integrator.h>
  12. #include <ascend/system/slv_stdcalls.h>
  13. #include <ascend/solver/solver.h>
  14. #include "radau.h"
  15.  
  16. #define INTEG_RADAU5 6  // Guess this is solver id for ascend purpose
  17.             // Since dopri5 had 5 i used 6 here
  18.  
  19. /* REGISTERING THE SOLVER */
  20.  
  21. static IntegratorCreateFn integrator_radau5_create;
  22. static IntegratorParamsDefaultFn integrator_radau5_params_default;
  23. static IntegratorSolveFn integrator_radau5_solve;
  24. static IntegratorFreeFn integrator_radau5_free;
  25. static IntegratorWriteMatrixFn integrator_radau5_write_matrix;
  26.  
  27. static const IntegratorInternals integrator_radau5_internals = {
  28.     integrator_radau5_create
  29.     ,integrator_radau5_params_default
  30.     ,integrator_analyse_ode /* note, this routine is back in integrator.c */
  31.     ,integrator_radau5_solve
  32.     ,NULL /*integrator_radau5_write_matrix not implemented */
  33.     ,NULL /* debugfn */
  34.     ,integrator_radau5_free
  35.     ,INTEG_LSODE
  36.     ,"RADAU5"
  37. };
  38.  
  39. extern ASC_EXPORT int radau5_register(void){
  40.     CONSOLE_DEBUG("Registering RADAU5...");
  41.     return integrator_register(&integrator_radau5_internals);
  42. }
  43.  
  44. /*END REGISTERATION*/
  45. /**
  46. FORTRAN REFERENCE
  47.      IDID        REPORTS ON SUCCESSFULNESS UPON RETURN:
  48.                    IDID= 1  COMPUTATION SUCCESSFUL,
  49.                    IDID= 2  COMPUT. SUCCESSFUL (INTERRUPTED BY SOLOUT)
  50.                    IDID=-1  INPUT IS NOT CONSISTENT,
  51.                    IDID=-2  LARGER NMAX IS NEEDED,
  52.                    IDID=-3  STEP SIZE BECOMES TOO SMALL,
  53.                    IDID=-4  MATRIX IS REPEATEDLY SINGULAR
  54. */
  55.  
  56. enum radau5_status{
  57.     RADAU5_SUCCESS=1
  58.     ,RADAU5_INRPT=2
  59.     ,RADAU5_BADINPUT=-1
  60.     ,RADAU5_ITERLIMIT=-2
  61.     ,RADAU5_STEPSMALL=-3
  62.     ,RADAU5_SINGULAR=-4
  63. };
  64.  
  65. typedef struct IntegratorRadau5DataStruct
  66. {
  67.     long n_eqns;                     /**< dimension of state vector */
  68.     int *input_indices;              /**< vector of state vars indexes */
  69.     int *output_indices;             /**< vector of derivative var indexes */
  70.     struct var_variable **y_vars;    /**< NULL-terminated list of states vars */
  71.     struct var_variable **ydot_vars; /**< NULL-terminated list of derivative vars*/
  72.     struct rel_relation **rlist;     /**< NULL-terminated list of relevant rels
  73.                     to be differentiated */
  74.     long currentsample;
  75.     char stop;          /* stop requested? */
  76.     int partitioned;                /* partioned func evals or not */
  77.     double *yinter;         /* interpolated y values */
  78.  
  79.     clock_t lastwrite;       /* time of last call to the reporter 'write' function */
  80. }
  81. IntegratorRadau5Data;
  82.  
  83. /** DONT KNOW IF THIS STUFF IS NEEDED*/
  84. /** Macro to declare a local var and fetch the 'enginedata' stuff into it from l_radau5_blsys. */
  85. #define RADAU5DATA_GET(N) \
  86.     IntegratorRadau5Data *N; \
  87.     asc_assert(l_radau5_blsys!=NULL); \
  88.     N = (IntegratorRadau5Data *)l_radau5_blsys->enginedata; \
  89.     asc_assert(N!=NULL)
  90.  
  91. /** Macro to set the global l_radau5_blsys to the currently blsys ptr. */
  92. #define RADAU5DATA_SET(N) \
  93.     asc_assert(l_radau5_blsys==NULL); \
  94.     asc_assert(N!=NULL); \
  95.     l_radau5_blsys = N
  96.  
  97. #define RADAU5DATA_RELEASE() \
  98.     asc_assert(l_radau5_blsys!=NULL); \
  99.     l_radau5_blsys = NULL;
  100.  
  101. /** END DONT KNOW STUFF :p */
  102.  
  103. /**
  104. ALLOCATE AND FREE MEMORY
  105. */
  106. void integrator_radau5_create(struct IntegratorSystemStruct *blsys){
  107.     IntegratorRadau5Data *d;
  108.     d = ASC_NEW_CLEAR(IntegratorRadau5Data);
  109.     d->n_eqns=0;
  110.     d->input_indices=NULL;
  111.     d->output_indices=NULL;
  112.     d->y_vars=NULL;
  113.     d->ydot_vars=NULL;
  114.     d->rlist=NULL;
  115.     blsys->enginedata=(void*)d;
  116.     integrator_radau5_params_default(blsys);
  117.     CONSOLE_DEBUG("CREATED RADAU5");
  118. }
  119.  
  120. /**
  121. END MEMORY ALLOCATION
  122. */
  123.  
  124. /**
  125. Cleanup the data struct that belongs to RADAU5
  126. */
  127. static void integrator_radau5_free(void *enginedata){
  128.     IntegratorRadau5Data d;
  129.     d = *((IntegratorRadau5Data *)enginedata);
  130.  
  131.     if(d.input_indices)ASC_FREE(d.input_indices);
  132.     d.input_indices = NULL;
  133.  
  134.     if(d.output_indices)ASC_FREE(d.output_indices);
  135.     d.output_indices = NULL;
  136.  
  137.     if(d.y_vars)ASC_FREE(d.y_vars);
  138.     d.y_vars = NULL;
  139.  
  140.     if(d.ydot_vars)ASC_FREE(d.ydot_vars);
  141.     d.ydot_vars = NULL;
  142.  
  143.     if(d.rlist)ASC_FREE(d.rlist);
  144.     d.rlist =  NULL;
  145.  
  146.     if(d.yinter)ASC_FREE(d.yinter);
  147.     d.yinter = NULL;
  148.  
  149.     d.n_eqns = 0L;
  150. }
  151. /**
  152. PARAMETERS REQUIRED FOR RADAU5 CODE
  153. REF: FORTRAN code
  154.      RTOL,ATOL   RELATIVE AND ABSOLUTE ERROR TOLERANCES. THEY
  155.                  CAN BE BOTH SCALARS OR ELSE BOTH VECTORS OF LENGTH N.
  156.      ITOL        SWITCH FOR RTOL AND ATOL:
  157.                    ITOL=0: BOTH RTOL AND ATOL ARE SCALARS.
  158.                      THE CODE KEEPS, ROUGHLY, THE LOCAL ERROR OF
  159.                      Y(I) BELOW RTOL*ABS(Y(I))+ATOL
  160.                    ITOL=1: BOTH RTOL AND ATOL ARE VECTORS.
  161.                      THE CODE KEEPS THE LOCAL ERROR OF Y(I) BELOW
  162.                      RTOL(I)*ABS(Y(I))+ATOL(I).
  163.      IJAC        SWITCH FOR THE COMPUTATION OF THE JACOBIAN:
  164.                     IJAC=0: JACOBIAN IS COMPUTED INTERNALLY BY FINITE
  165.                        DIFFERENCES, SUBROUTINE "JAC" IS NEVER CALLED.
  166.                     IJAC=1: JACOBIAN IS SUPPLIED BY SUBROUTINE JAC.
  167.  
  168.      MLJAC       SWITCH FOR THE BANDED STRUCTURE OF THE JACOBIAN:
  169.                     MLJAC=N: JACOBIAN IS A FULL MATRIX. THE LINEAR
  170.                        ALGEBRA IS DONE BY FULL-MATRIX GAUSS-ELIMINATION.
  171.                     0<=MLJAC<N: MLJAC IS THE LOWER BANDWITH OF JACOBIAN
  172.                        MATRIX (>= NUMBER OF NON-ZERO DIAGONALS BELOW
  173.                        THE MAIN DIAGONAL).
  174.  
  175.      MUJAC       UPPER BANDWITH OF JACOBIAN  MATRIX (>= NUMBER OF NON-
  176.                  ZERO DIAGONALS ABOVE THE MAIN DIAGONAL).
  177.                  NEED NOT BE DEFINED IF MLJAC=N.
  178.  
  179. C     IMAS       GIVES INFORMATION ON THE MASS-MATRIX:
  180. C                    IMAS=0: M IS SUPPOSED TO BE THE IDENTITY
  181. C                       MATRIX, MAS IS NEVER CALLED.
  182. C                    IMAS=1: MASS-MATRIX  IS SUPPLIED.
  183. C
  184. C     MLMAS       SWITCH FOR THE BANDED STRUCTURE OF THE MASS-MATRIX:
  185. C                    MLMAS=N: THE FULL MATRIX CASE. THE LINEAR
  186. C                       ALGEBRA IS DONE BY FULL-MATRIX GAUSS-ELIMINATION.
  187. C                    0<=MLMAS<N: MLMAS IS THE LOWER BANDWITH OF THE
  188. C                       MATRIX (>= NUMBER OF NON-ZERO DIAGONALS BELOW
  189. C                       THE MAIN DIAGONAL).
  190. C                 MLMAS IS SUPPOSED TO BE .LE. MLJAC.
  191. C
  192. C     MUMAS       UPPER BANDWITH OF MASS-MATRIX (>= NUMBER OF NON-
  193. C                 ZERO DIAGONALS ABOVE THE MAIN DIAGONAL).
  194. C                 NEED NOT BE DEFINED IF MLMAS=N.
  195. C                 MUMAS IS SUPPOSED TO BE .LE. MUJAC.
  196.  
  197. */
  198.  
  199.  
  200. enum radau5_parameters{
  201.     RADAU5_PARAM_RTOL
  202.     ,RADAU5_PARAM_ATOL
  203.     ,RADAU5_PARAM_ITOL
  204.     ,RADAU5_PARAM_IJAC
  205.     ,RADAU5_PARAM_IMAS
  206.     /* FIXME add NSTIFF here... */
  207.     ,RADAU5_PARAMS_SIZE // DONT KNOW USE OF THIS
  208.         /*^^^  (this automatically takes on the next number in the sequence, hence, by declaring it, we automatically calculates the required size of the parameters array) -- JP */
  209. };
  210.  
  211.  
  212. /**
  213.     Here the full set of parameters is defined, along with upper/lower bounds,
  214.     etc. The values are stuck into the blsys->params structure.
  215.  
  216.     @return 0 on success
  217. */
  218. static int integrator_radau5_params_default(IntegratorSystem *blsys){
  219.  
  220.     asc_assert(blsys!=NULL);
  221.     asc_assert(blsys->engine==INTEG_RADAU5);
  222.     slv_parameters_t *p;
  223.     p = &(blsys->params);
  224.  
  225.     slv_destroy_parms(p);
  226.  
  227.     if(p->parms==NULL){
  228.         p->parms = ASC_NEW_ARRAY(struct slv_parameter, RADAU5_PARAMS_SIZE);
  229.         if(p->parms==NULL)return -1;
  230.         p->dynamic_parms = 1;
  231.     }else{
  232.         asc_assert(p->num_parms == RADAU5_PARAMS_SIZE);
  233.     }
  234.  
  235.     /* reset the number of parameters to zero so that we can check it at the end */
  236.     p->num_parms = 0;
  237.  
  238.  
  239.     slv_param_real(p,RADAU5_PARAM_ATOL
  240.             ,(SlvParameterInitReal){{"atol"
  241.             ,"Scalar absolute error tolerance",1
  242.             ,"Default value of the scalar absolute error tolerance (for cases"
  243.             " where not specified in oda_atol var property. See 'radau5.f' for"
  244.             " details"
  245.         }, 1e-6, 1e-15, 1e10 }
  246.     );
  247.  
  248.     slv_param_real(p,RADAU5_PARAM_RTOL
  249.             ,(SlvParameterInitReal){{"rtol"
  250.             ,"Scalar relative error tolerance",1
  251.             ,"Default value of the scalar relative error tolerance (for cases"
  252.             " where not specified in oda_rtol var property. See 'radau5.f' for"
  253.             " details"
  254.         }, 1e-6, 1e-15, 1 }
  255.     );
  256.  
  257.  
  258.     slv_param_real(p,RADAU5_PARAM_ITOL
  259.             ,(SlvParameterInitReal){{"itol"
  260.             ,"Switch for rtol and atol",1
  261.             ,"ITOL=0: BOTH RTOL AND ATOL ARE SCALARS."
  262.                         "THE CODE KEEPS, ROUGHLY, THE LOCAL ERROR OF "
  263.                         " Y(I) BELOW RTOL*ABS(Y(I))+ATOL"
  264.         },0,1,0}
  265.     );
  266.  
  267.  
  268.     slv_param_real(p,RADAU5_PARAM_IJAC
  269.             ,(SlvParameterInitReal){{"ijac"
  270.             ,"GIVES INFORMATION ON THE MASS-MATRIX",1
  271.             ,"IJAC=0: JACOBIAN IS NOT SUPPLIED"
  272.             "MATRIX, JACOBIAN IS COMPUTED INTERNALLY"
  273.             "IJAC=1: JACOBIAN IS SUPPLIED."
  274.             "See 'radau5.f' for details"
  275.         },0,1,0}
  276.     );
  277.  
  278.     slv_param_real(p,RADAU5_PARAM_IMAS
  279.             ,(SlvParameterInitReal){{"imas"
  280.             ,"GIVES INFORMATION ON THE MASS-MATRIX",1
  281.             ,"IMAS=0: M IS SUPPOSED TO BE THE IDENTITY"
  282.             "MATRIX, MAS IS NEVER CALLED"
  283.             "IMAS=1: MASS-MATRIX  IS SUPPLIED."
  284.             "See 'radau5.f' for details"
  285.         },0,1,0}
  286.     );
  287.  
  288. // SOME MORE WORK NEEDS TO BE DONE HERE >>> ADD MORE OPTIONS
  289.  
  290.     asc_assert(p->num_parms == RADAU5_PARAMS_SIZE);
  291.     return 0;
  292. }
  293.  
  294.  
  295. /** DEFINING FUNCTIONS FOR SOLVER USAGE */
  296. // FUNCTION
  297. //FCN(int*,double*,double*,double*,double*,int*)
  298. static void integrator_radau5_fex(
  299.         unsigned* n_eq, double* t, double *y, double *ydot,
  300.         double *rpar, int* ipar)
  301. {
  302.     slv_status_t status;
  303.     IntegratorSystem *blsys;
  304.  
  305.     int i;
  306.     unsigned long res;
  307.  
  308.     //CONSOLE_DEBUG("Calling for a function evaluation");
  309.  
  310.     /* pass the time and the unknowns back to the System */
  311.     integrator_set_t(blsys, t);
  312.     integrator_set_y(blsys, y);
  313.     //CONSOLE_DEBUG("t = %f: y[0] = %f",t,y[0]);
  314.  
  315.     asc_assert(blsys->system);
  316.  
  317.     slv_resolve(blsys->system);
  318.  
  319.     if((res = slv_solve(blsys->system))){
  320.         CONSOLE_DEBUG("solver returns error %ld",res);
  321.     }
  322.  
  323.     slv_get_status(blsys->system, &status);
  324.  
  325.  
  326.     if(slv_check_bounds(blsys->system,0,-1,"")){
  327.         ERROR_REPORTER_HERE(ASC_PROG_ERR,"Variables went outside boundaries...");
  328.         // TODO relay that system has gone out of bounds
  329.     }
  330.  
  331.     /* pass the NLA solver status to the integrator */
  332.     res = integrator_checkstatus(status);
  333.  
  334.     integrator_output_write(blsys);
  335.  
  336.     if(res){
  337.         ERROR_REPORTER_HERE(ASC_PROG_ERR,"Failed to solve for derivatives (%d)",res);
  338. #if 1
  339.         ERROR_REPORTER_START_HERE(ASC_PROG_ERR);
  340.         FPRINTF(ASCERR,"Unable to compute the vector of derivatives with the following values for the state variables:\n");
  341.         for (i = 0; i< *n_eq; i++) {
  342.             FPRINTF(ASCERR,"y[%4d] = %g\n",i, y[i]);
  343.         }
  344.         error_reporter_end_flush();
  345. #endif
  346. #ifdef ASC_SIGNAL_TRAPS
  347.         raise(SIGINT);
  348. #endif
  349.     }else{
  350.         /* ERROR_REPORTER_HERE(ASC_PROG_NOTE,"lsodedata->status = %d",lsodedata->status); */
  351.     }
  352.  
  353.     integrator_get_ydot(blsys, ydot);
  354.  
  355. #ifdef DOPRI5_DEBUG
  356.     CONSOLE_DEBUG("y[0]=%e,y[1]=%e --> ydot[0]=%e,ydot[1]=%e",y[0],y[1],ydot[0],ydot[1]);
  357. #endif
  358.     //CONSOLE_DEBUG("ydot[0] = %f",ydot[0]);
  359.     // DONE, OK
  360. }
  361. // JACOBIAN ....
  362. /**
  363. Dummy Jacobian ... more work needs to be done here
  364. compatible with default settings
  365. */
  366. static void integrator_radau5_jex(int *n, double *x, double *y, double *dfy,
  367.            int *ldfy, double *rpar, double *ipar){
  368.     /* TODO implement this */
  369.     abort();
  370. }
  371.  
  372. // MASS FUNCTION
  373. /**
  374. Dummy Mass function ... more work needs to be done
  375. compatible with default settings
  376. */
  377. static void mass_dummy(int *n,double *am, int *lmas,int *rpar, int *ipar){
  378.  
  379.     /* TODO implement this */
  380.     abort();
  381.  
  382. }
  383. /** END DEFINING*/
  384.  
  385.  
  386. /**
  387.   STATS
  388. */
  389.  
  390. /**
  391.     Several functions provide access to different values :
  392.  
  393.     nstepRead   Number of used steps.
  394.     naccptRead  Number of accepted steps.
  395.     nrejctRead  Number of rejected steps.
  396.     nfcnRead    Number of function calls.
  397. */
  398. typedef struct IntegratorRadau5StatsStruct{
  399.     long nfcn;
  400.     long nstep;
  401.     long naccpt;
  402.     long nrejct;
  403.     double h;
  404.     double x;
  405. } IntegratorRadau5Stats;
  406.  
  407.  
  408. /**
  409.     SOLVE
  410.     (work in progress)
  411. */
  412.  
  413. #define RADAU5_FREE CONSOLE_DEBUG("FREE RADAU5")
  414.  
  415. int integrator_radau5_solve(IntegratorSystem *blsys
  416. ,unsigned long start_index, unsigned long finish_index
  417. ){
  418.     IntegratorRadau5Data *d;
  419.     slv_status_t status;
  420.    
  421.     unsigned long nsamples, neq;
  422.     long nobs;
  423.     int my_neq;
  424.  
  425.     d = (IntegratorRadau5Data *)(blsys->enginedata);
  426.  
  427.     /* the numer of equations must be equal to blsys->n_y, the number of states */
  428.     d->n_eqns = blsys->n_y;
  429.     assert(d->n_eqns>0);
  430.  
  431.     d->input_indices = ASC_NEW_ARRAY_CLEAR(int, d->n_eqns);
  432.     d->output_indices = ASC_NEW_ARRAY_CLEAR(int, d->n_eqns);
  433.  
  434.     d->y_vars = ASC_NEW_ARRAY(struct var_variable *,d->n_eqns+1);
  435.     d->ydot_vars = ASC_NEW_ARRAY(struct var_variable *, d->n_eqns+1);
  436.  
  437.     d->yinter = ASC_NEW_ARRAY(double,d->n_eqns);
  438.  
  439.     /**
  440.     set up the NLA solver here
  441.      */
  442.     // THIS STUFF IS NOT CLEAR
  443.     if(strcmp(slv_solver_name(slv_get_selected_solver(blsys->system)),"QRSlv") != 0) {
  444.         ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"QRSlv must be selected before integration.");
  445.         return 1;
  446.     }
  447.  
  448.     CONSOLE_DEBUG("Solver selected is '%s'",slv_solver_name(slv_get_selected_solver(blsys->system)));
  449.  
  450.     slv_get_status(blsys->system, &status);
  451.  
  452.     if(status.struct_singular){
  453.         ERROR_REPORTER_HERE(ASC_USER_WARNING
  454.             ,"The system (according to QRSlv) is structurally singular."
  455.             " The ODE system may also be singular, but not necessarily."
  456.         );
  457.     }
  458.  
  459.     /* here we assume integrators.c is in charge of dynamic loading */
  460.  
  461.     /* set up parameters for sending to RADAU5 */
  462.  
  463.     nsamples = integrator_getnsamples(blsys);
  464.     if (nsamples <2) {
  465.         ERROR_REPORTER_HERE(ASC_USER_ERROR,"Integration will not be performed. The system has no end sample time defined.");
  466.         //d->status = dopri5_nok;
  467.         return 3;
  468.     }
  469.     neq = blsys->n_y;
  470.     nobs = blsys->n_obs;
  471.     my_neq = (int)neq;
  472. /**
  473.     #define ND     2 //no. equations
  474.     #define NS     7 //
  475.     #define LWORK  (NS+1)*ND*ND+(3*NS+3)*ND+20
  476.     #define LIWORK (2+(NS-1)/2)*ND+20
  477.     double y[ND],work[LWORK];
  478.     int iwork[LIWORK];
  479.     double x,xend;
  480.     int i,idid;
  481.     double   rpar=1e-6;
  482.     int  n=2;
  483.     int ijac=1;
  484.     int mljac=n;
  485.     int mujac=0;
  486.     int imas=0;
  487.     int mlmas=0;
  488.     int mumas;
  489.     int ipar=0;
  490.     int iout=1;
  491. */
  492. /**
  493.     SOME PARAMETERS
  494. */
  495.     int lwork;
  496.     lwork = 4*my_neq*my_neq + 8*my_neq + 20; //full jacobian setting
  497.     int liwork;
  498.     liwork = 3*my_neq + 7; // full jacobian setting
  499.     double work[lwork];
  500.     int iwork[liwork];
  501.     int i,idid;
  502.     double x,xend;
  503.     double h;
  504.     double rpar=0.0;
  505.     int mujac = my_neq;
  506.     //int mujac=0;
  507.     int mlmas=0;
  508.     int mumas;
  509.     int ipar=0;
  510.     int iout=1;
  511.     double *y, atol, rtol, *obs;
  512.     //int my_neq;
  513.     enum radau5_status res;
  514.  
  515.     atol = SLV_PARAM_REAL(&(blsys->params),RADAU5_PARAM_ATOL);
  516.     rtol = SLV_PARAM_REAL(&(blsys->params),RADAU5_PARAM_RTOL); 
  517.     int ijac = SLV_PARAM_REAL(&(blsys->params),RADAU5_PARAM_IJAC);
  518.     int imas = SLV_PARAM_REAL(&(blsys->params),RADAU5_PARAM_IMAS);
  519.     int itol = SLV_PARAM_REAL(&(blsys->params),RADAU5_PARAM_ITOL); 
  520.  
  521.     /* samplelist_debug(blsys->samples); */
  522.  
  523.     x = integrator_getsample(blsys, 0);
  524.     d->currentsample = 1;
  525.  
  526.     y = integrator_get_y(blsys, NULL);
  527.     obs = integrator_get_observations(blsys, NULL);
  528.  
  529.     // TODO check memory allocations
  530.  
  531.     h = integrator_get_stepzero(blsys);
  532.     hmax = integrator_get_maxstep(blsys);
  533.     CONSOLE_DEBUG("init step = %f, max step = %f", h, hmax);
  534.  
  535.     /* rwork[6] = integrator_get_minstep(blsys); */ /* ignored */
  536.     nmax = integrator_get_maxsubsteps(blsys);
  537.  
  538.     nstiff = SLV_PARAM_INT(&(blsys->params),DOPRI5_PARAM_NSTIFF);
  539.  
  540.     if(x > integrator_getsample(blsys, 2)) {
  541.         ERROR_REPORTER_HERE(ASC_USER_ERROR,"Invalid initialisation time: exceeds second timestep value");
  542.         return 5;
  543.     }
  544.  
  545.     /* put the values from derivative system into the record */
  546.     integrator_setsample(blsys, start_index, x);
  547.  
  548.     integrator_output_init(blsys);
  549.  
  550.     /* -- store the initial values of all the stuff */
  551.     integrator_output_write(blsys);
  552.     integrator_output_write_obs(blsys);
  553.  
  554.  
  555.  
  556.     blsys->currentstep = 0;
  557.  
  558.     xend = integrator_getsample(blsys, finish_index);
  559.  
  560. # ifdef ASC_SIGNAL_TRAPS
  561.  
  562.         Asc_SignalHandlerPushDefault(SIGFPE);
  563.         Asc_SignalHandlerPushDefault(SIGINT);
  564.  
  565.         if(SETJMP(g_fpe_env)==0) {
  566. # endif /* ASC_SIGNAL_TRAPS */
  567.  
  568.             d->lastwrite = clock();
  569. /**
  570. HERE IS INTEGRATOR CALL
  571. REF CODE :
  572. void radau5_(int *N,
  573.    void FCN(int*,double*,double*,double*,double*,int*),
  574.    double *X, double *Y, double *XEND, double *H,
  575.            double *RTOL, double *ATOL, int *ITOL,
  576.    void JAC(int*, double*, double*, double*, int*, double*, double*),
  577.     int *IJAC, int *MLJAC, int *MUJAC,
  578.    void MAS(int *n,double *am, int *lmas,int *rpar, int *ipar),
  579.     int *IMAS, int *MLMAS, int *MUMAS,
  580.    void SOLOUT(int*,double*,double*,double*,double*,int*,int*,double*,int*,int*),
  581.     int *IOUT,
  582.    double *WORK, int *LWORK,int *IWORK, int *LIWORK,
  583.    double *RPAR, int *IPAR, int *IDID);
  584. */
  585.             radau5(&my_neq,
  586.                 integrator_radau5_fex,  // Function
  587.                 &x, &y, &xend,&h,  
  588.                 &rtol,&atol,&itol,
  589.                 integrator_radau5_jex,  // jacobian
  590.                 &ijac, &mljac, &mujac, 
  591.                 integrator_radau5_mex,  // mass matrix
  592.                 &imas,&mlmas,&mumas,
  593.                 integrator_radau5_solout,
  594.                 &iout,
  595.                 &work,&lwork,&iwork,&liwork,
  596.                 &rpar,&ipar,&idid
  597.             );
  598.         res = idid // res takes idid value
  599. # ifdef ASC_SIGNAL_TRAPS
  600.         }else{
  601.             ERROR_REPORTER_HERE(ASC_PROG_ERR,"Integration terminated due to float error in RADAU5 call.");
  602.             //DOPRI5_FREE; /* FIXME what's this for? */
  603.             return 6;
  604.         }
  605.         Asc_SignalHandlerPopDefault(SIGFPE);
  606.         Asc_SignalHandlerPopDefault(SIGINT);
  607.  
  608. # endif
  609.  
  610.     switch(res){
  611.         case RADAU5_SUCCESS:
  612.             break;
  613.         case RADAU5_INRPT:
  614.             ERROR_REPORTER_HERE(ASC_USER_ERROR,"RADAU5 interrupted by user");
  615.             break;
  616.         case RADAU5_BADINPUT:
  617.             ERROR_REPORTER_HERE(ASC_PROG_ERR,"Bad input to RADAU5");
  618.             break;
  619.         case RADAU5_ITERLIMIT:
  620.             ERROR_REPORTER_HERE(ASC_USER_ERROR,"Iteration limit exceeded in RADAU5");
  621.             break;
  622.         case RADAU5_STEPSMALL:
  623.             ERROR_REPORTER_HERE(ASC_USER_ERROR,"Step size became too small in RADAU5");
  624.             break;
  625.         case RADAU5_SINGULAR:
  626.             ERROR_REPORTER_HERE(ASC_USER_ERROR,"singular matrix encountered in RADAU5");
  627.             break;
  628.     }
  629.  
  630.     if(res<0){
  631.         ERROR_REPORTER_HERE(ASC_PROG_ERR,"Furthest point reached was t = %g.\n",x);
  632.         RADAU5_FREE;
  633.         return 7;
  634.     }
  635.  
  636.     /* write final step output */
  637.     integrator_output_write_obs(blsys);
  638.     integrator_output_close(blsys);
  639.  
  640. #ifdef STATS_DEBUG
  641.     IntegratorRadau5Stats stats;
  642.     if(0 == integrator_radau5_stats(blsys, &stats)){
  643.         integrator_radau5_write_stats(&stats);
  644.     }else{
  645.         ERROR_REPORTER_HERE(ASC_PROG_ERR,"Unable to fetch stats!?!?");
  646.     }
  647. #endif
  648.  
  649.     CONSOLE_DEBUG("--- RADAU5 done ---");
  650.     return 0; /* success */
  651. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement