00001 #ifndef ODESYSTEM_H_
00002 #define ODESYSTEM_H_
00003
00004 #include <gsl/gsl_errno.h>
00005 #include <gsl/gsl_matrix.h>
00006 #include <gsl/gsl_odeiv.h>
00007
00008 #include <string>
00009 using std::string;
00010
00011 #include <iostream>
00012 using std::cerr;
00013 using std::endl;
00014
00015 namespace odeiv {
00016
00017 class ODESystem {
00018
00019 public:
00020 ODESystem( size_t dim ) {
00021 gsl_sys.function = __int__dydt__;
00022 gsl_sys.jacobian = NULL;
00023 gsl_sys.dimension = dim;
00024 gsl_sys.params = (void *)this;
00025 };
00026
00027 void setSystem( ODESystem *sys ) {
00028 gsl_sys.params = (void *)sys;
00029 };
00030
00031 virtual ~ODESystem() { }
00032 ;
00033
00034 virtual void derivatives( double t, const double y[], double f[] ) = 0;
00035
00036 int dimension() const {
00037 return gsl_sys.dimension;
00038 };
00039
00040 private:
00041 friend class GslStepper;
00042 friend class AdaptiveStepSolver;
00043 gsl_odeiv_system gsl_sys;
00044 static int __int__dydt__( double t, const double y[], double f[], void *params ) {
00045 (( ODESystem* )( params ))->derivatives( t, y, f );
00046 return GSL_SUCCESS;
00047 }
00048 };
00049
00050
00051 class Stepper {
00052
00053 public:
00054
00055 Stepper( ) {
00056
00057 };
00058
00059 virtual ~Stepper( ) {
00060
00061 };
00062
00063
00064 virtual void reset( ) = 0;
00065 virtual string name() = 0;
00066 virtual int order() = 0;
00067 virtual void apply( double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], ODESystem & sys ) = 0;
00068
00069 };
00070
00071 class GslStepperType {
00072 public:
00073 virtual ~GslStepperType() {}
00074 ;
00075 virtual const gsl_odeiv_step_type *gsl_type() const =0;
00076 };
00077
00078 class RungeKutta2 : public GslStepperType {
00079 public:
00080 virtual const gsl_odeiv_step_type *gsl_type() const {
00081 return gsl_odeiv_step_rk2;
00082 };
00083 };
00084
00085 class RungeKutta4 : public GslStepperType {
00086 public:
00087 virtual const gsl_odeiv_step_type *gsl_type() const {
00088 return gsl_odeiv_step_rk4;
00089 };
00090 };
00091
00092 class GslStepper : public Stepper {
00093
00094 public:
00095 GslStepper( ODESystem & sys, GslStepperType const& step ) : int_step( NULL ) {
00096 int_step = gsl_odeiv_step_alloc( step.gsl_type(), sys.dimension() );
00097 };
00098
00099 virtual ~GslStepper( ) {
00100 if( int_step )
00101 gsl_odeiv_step_free( int_step );
00102 };
00103
00104 virtual void reset( ) {
00105 gsl_odeiv_step_reset( int_step );
00106 };
00107
00108 virtual string name() {
00109 return string( gsl_odeiv_step_name( int_step ) );
00110 };
00111
00112 virtual int order() {
00113 return gsl_odeiv_step_order( int_step );
00114 };
00115
00116 virtual void apply( double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], ODESystem & sys ) {
00117 gsl_odeiv_step_apply( int_step, t, h, y, yerr, dydt_in, dydt_out, &sys.gsl_sys );
00118 };
00119
00120 protected:
00121 friend class AdaptiveStepSolver;
00122 gsl_odeiv_step *int_step;
00123
00124 };
00125
00126
00127 class Solver {
00128
00129 public:
00130
00131 Solver( ODESystem & sys, GslStepperType const& step ) : stepper( sys, step ) {
00132 _y_ = new double[sys.dimension()];
00133 };
00134
00135 virtual ~Solver() {
00136 if ( _y_ )
00137 delete _y_;
00138 };
00139
00140 virtual void reset( double dt, ODESystem & sys, const double y0[] ) = 0;
00141
00142 virtual void advance( double t, double dt, ODESystem & sys ) = 0;
00143
00144 double y( size_t i ) {
00145 return _y_[ i ];
00146 };
00147
00148 protected:
00149 GslStepper stepper;
00150 double *_y_;
00151 };
00152
00153 class FixedStepSolver : public Solver {
00154
00155 public:
00156 FixedStepSolver( ODESystem & sys, GslStepperType const& step );
00157 virtual ~FixedStepSolver();
00158
00159 virtual void reset( double dt, ODESystem & sys, const double y0[] );
00160 virtual void advance( double t, double dt, ODESystem & sys );
00161
00162 private:
00163 double *dydt_in, *dydt_out, *y_err;
00164 };
00165
00166
00167 class AdaptiveStepSolver : public Solver {
00168
00169 public:
00170 AdaptiveStepSolver( ODESystem & sys, GslStepperType const& step );
00171 virtual ~AdaptiveStepSolver();
00172
00173 virtual void reset( double dt, ODESystem & sys, const double y0[] );
00174 virtual void advance( double t, double dt, ODESystem & sys );
00175
00176 private:
00177 gsl_odeiv_control *int_control;
00178 gsl_odeiv_evolve *int_evolve;
00179 double h;
00180 };
00181
00182
00183 }
00184 #endif