00001 #include "ODESystem.h"
00002 using namespace odeiv;
00003 
00004 #include "PCSIMException.h"
00005 
00006 #include <iostream>
00007 using std::cerr;
00008 using std::endl;
00009 
00010 FixedStepSolver::FixedStepSolver( ODESystem & sys, GslStepperType const& step ) : Solver( sys, step ) {
00011     dydt_in = new double[ sys.dimension() ];
00012     dydt_out = new double[ sys.dimension() ];
00013     y_err = new double[ sys.dimension() ];
00014 }
00015 
00016 FixedStepSolver::~FixedStepSolver() {
00017     if ( dydt_in )
00018         delete dydt_in;
00019     if ( dydt_out )
00020         delete dydt_out;
00021     if ( y_err )
00022         delete y_err;
00023 }
00024 
00025 void FixedStepSolver::reset( double dt, ODESystem & sys, const double y0[] ) {
00026     for ( int i = 0; i < sys.dimension(); i++ ) {
00027         _y_[ i ] = y0[ i ];
00028     }
00029     sys.derivatives( 0.0, _y_, dydt_in );
00030     stepper.reset( );
00031 }
00032 
00033 void FixedStepSolver::advance( double t, double dt, ODESystem & sys ) {
00034     
00035     stepper.apply( t, dt, _y_, y_err, dydt_in, dydt_out, sys );
00036     for ( int i = 0; i < sys.dimension(); i++ )
00037         dydt_in[ i ] = dydt_out[ i ];
00038     
00039 }
00040 
00042 
00043 AdaptiveStepSolver::AdaptiveStepSolver( ODESystem & sys, GslStepperType const& step ) : Solver( sys, step ) {
00044     int_control = gsl_odeiv_control_y_new( 1e-6, 1e-6 );
00045     int_evolve = gsl_odeiv_evolve_alloc( sys.dimension() );
00046     h = 1e-6;
00047     
00048 }
00049 
00050 
00051 AdaptiveStepSolver::~AdaptiveStepSolver() {
00052   
00053     if ( int_control != NULL )
00054         gsl_odeiv_control_free( int_control );
00055     if ( int_evolve != NULL )
00056         gsl_odeiv_evolve_free( int_evolve );
00057 }
00058 
00059 void AdaptiveStepSolver::reset( double dt, ODESystem & sys, const double y0[] ) {
00060     
00061     for ( int i = 0; i < sys.dimension(); i++ ) {
00062         _y_[ i ] = y0[ i ];
00063     }
00064     stepper.reset( );
00065     gsl_odeiv_evolve_reset( int_evolve );
00066     h = dt / 100.0;
00067     
00068 }
00069 
00070 void AdaptiveStepSolver::advance( double t, double dt, ODESystem & sys ) {
00071     
00072     double t1 = t + dt;
00073     
00074     
00075     
00076     
00077     while ( t < t1 ) { 
00078         
00079         if ( gsl_odeiv_evolve_apply( int_evolve, int_control, stepper.int_step, &sys.gsl_sys, &t, t1, &h, _y_ ) != GSL_SUCCESS ) {
00080             throw( PCSIM::Exception( "AdaptiveStepSolver::advance", "ODE Solver error!" ) );
00081         }
00082         
00083     }
00084     
00085 }
00086