00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 00024 #ifndef O2SCL_NONADAPT_STEP_H 00025 #define O2SCL_NONADAPT_STEP_H 00026 00027 #include <o2scl/adapt_step.h> 00028 #include <gsl/gsl_math.h> 00029 #include <gsl/gsl_odeiv.h> 00030 00031 #ifndef DOXYGENP 00032 namespace o2scl { 00033 #endif 00034 00035 /** 00036 \brief An non-adaptive stepper implementation of \ref adapt_step. 00037 00038 This class simply calls the specified ODE stepper without any 00039 attempt to modify the size of the step. It is primarily useful 00040 to allow for simple comparisons between adaptive and 00041 non-adaptive solution or to proceed with a solution in places 00042 where an adaptive stepper is failing. 00043 00044 To modify the ODE stepper which is used, use the function 00045 adapt_step::set_step(). 00046 */ 00047 template<class param_t, class func_t=ode_funct<param_t>, 00048 class vec_t=ovector_base, class alloc_vec_t=ovector, 00049 class alloc_t=ovector_alloc> class nonadapt_step : 00050 public adapt_step<param_t,func_t,vec_t,alloc_vec_t,alloc_t> { 00051 00052 #ifndef DOXYGEN_INTERNAL 00053 00054 protected: 00055 00056 /// The allocated vector size 00057 size_t msize; 00058 00059 /** 00060 \brief Internal storage for dydx 00061 00062 \comment 00063 This isn't named dydx so that we can name function arguments 00064 dydx in astep_derivs(). 00065 \endcomment 00066 */ 00067 alloc_vec_t dydx_int; 00068 00069 /// Memory allocator for objects of type \c alloc_vec_t 00070 alloc_t ao; 00071 00072 #endif 00073 00074 public: 00075 00076 nonadapt_step() { 00077 msize=0; 00078 } 00079 00080 virtual ~nonadapt_step() { 00081 if (msize>0) { 00082 ao.free(dydx_int); 00083 } 00084 } 00085 00086 /** 00087 \brief Make an adaptive integration step of the system 00088 \c derivs 00089 00090 This attempts to take a step of size \c h from the point \c x of 00091 an \c n-dimensional system \c derivs starting with \c y. On 00092 exit, \c x and \c y contain the new values at the end of the 00093 step, \c h contains the size of the step, \c dydx_out contains 00094 the derivative at the end of the step, and \c yerr contains the 00095 estimated error at the end of the step. 00096 00097 If the base stepper returns a non-zero value, that value is 00098 passed on as the return value of <tt>astep()</tt>, though the 00099 input \c y may still have been modified by the base stepper. 00100 00101 */ 00102 virtual int astep(double &x, double &h, double xlimit, 00103 size_t n, vec_t &y, vec_t &u_dydx_out, 00104 vec_t &yerr, param_t &pa, 00105 func_t &derivs) { 00106 00107 if (n!=msize) { 00108 ao.allocate(dydx_int,n); 00109 } 00110 00111 derivs(x,n,y,dydx_int,pa); 00112 if (h>0) { 00113 if (x+h>xlimit) h=xlimit-x; 00114 } else { 00115 if (x+h<xlimit) h=xlimit-x; 00116 } 00117 int ret=this->stepp->step(x,h,n,y,dydx_int,y,yerr, 00118 u_dydx_out,pa,derivs); 00119 x+=h; 00120 00121 return ret; 00122 } 00123 00124 /** \brief Make an adaptive integration step of the system 00125 \c derivs 00126 00127 This function performs an adaptive integration step with the 00128 \c n-dimensional system \c derivs and parameter \c pa. It 00129 Begins at \c x with initial stepsize \c h, ensuring that the 00130 step goes no farther than \c xlimit. At the end of the step, 00131 the size of the step taken is \c h and the new value of \c x 00132 is in \c x_out. Initially, the function values and 00133 derivatives should be specified in \c y and \c dydx. The 00134 function values, derivatives, and the error at the end of 00135 the step are given in \c yout, \c yerr, and \c dydx_out. 00136 Unlike in \c odestep objects, the objects \c y, \c yout, 00137 \c dydx, and \c dydx_out must all be distinct. 00138 00139 If the base stepper returns a non-zero value, that value is 00140 passed on as the return value of <tt>astep()</tt>, though the 00141 output parameters may still have been modified by the 00142 base stepper. 00143 */ 00144 virtual int astep_full(double x, double &h, double xlimit, double &x_out, 00145 size_t n, vec_t &y, vec_t &dydx, 00146 vec_t &yout2, vec_t &yerr, vec_t &dydx_out, 00147 param_t &pa, func_t &derivs) { 00148 00149 if (h>0) { 00150 if (x+h>xlimit) h=xlimit-x; 00151 } else { 00152 if (x+h<xlimit) h=xlimit-x; 00153 } 00154 int ret=this->stepp->step(x,h,n,y,dydx,yout2,yerr,dydx_out,pa,derivs); 00155 x_out=x+h; 00156 00157 return ret; 00158 } 00159 00160 /** 00161 \brief Make an adaptive integration step of the system 00162 \c derivs with derivatives 00163 00164 This attempts to take a step of size \c h from the point \c x of 00165 an \c n-dimensional system \c derivs starting with \c y and 00166 given the initial derivatives \c dydx. On exit, \c x, \c y and 00167 \c dydx contain the new values at the end of the step, \c h 00168 contains the size of the step, \c dydx contains the derivative 00169 at the end of the step, and \c yerr contains the estimated error 00170 at the end of the step. 00171 00172 If the base stepper returns a non-zero value, that value is 00173 passed on as the return value of <tt>astep()</tt>, though the 00174 inputs \c y and \c dydx may still have been modified by the 00175 base stepper. 00176 */ 00177 virtual int astep_derivs(double &x, double &h, double xlimit, 00178 size_t n, vec_t &y, vec_t &dydx, 00179 vec_t &yerr, param_t &pa, 00180 func_t &derivs) { 00181 00182 if (h>0) { 00183 if (x+h>xlimit) h=xlimit-x; 00184 } else { 00185 if (x+h<xlimit) h=xlimit-x; 00186 } 00187 int ret=this->stepp->step(x,h,n,y,dydx,y,yerr,dydx,pa,derivs); 00188 x+=h; 00189 00190 return ret; 00191 } 00192 00193 }; 00194 00195 #ifndef DOXYGENP 00196 } 00197 #endif 00198 00199 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page