![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, 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 /** \brief An non-adaptive stepper implementation of \ref adapt_step. 00036 00037 This class simply calls the specified ODE stepper without any 00038 attempt to modify the size of the step. It is primarily useful 00039 to allow for simple comparisons between adaptive and 00040 non-adaptive solution or to proceed with a solution in places 00041 where an adaptive stepper is failing. 00042 00043 To modify the ODE stepper which is used, use the function 00044 adapt_step::set_step(). 00045 */ 00046 template<class func_t=ode_funct<>, 00047 class vec_t=ovector_base, class alloc_vec_t=ovector, 00048 class alloc_t=ovector_alloc> class nonadapt_step : 00049 public adapt_step<func_t,vec_t,alloc_vec_t,alloc_t> { 00050 00051 #ifndef DOXYGEN_INTERNAL 00052 00053 protected: 00054 00055 /// The allocated vector size 00056 size_t msize; 00057 00058 /** \brief Internal storage for dydx 00059 00060 \comment 00061 This isn't named dydx so that we can name function arguments 00062 dydx in astep_derivs(). 00063 \endcomment 00064 */ 00065 alloc_vec_t dydx_int; 00066 00067 /// Memory allocator for objects of type \c alloc_vec_t 00068 alloc_t ao; 00069 00070 #endif 00071 00072 public: 00073 00074 nonadapt_step() { 00075 msize=0; 00076 } 00077 00078 virtual ~nonadapt_step() { 00079 if (msize>0) { 00080 ao.free(dydx_int); 00081 } 00082 } 00083 00084 /** \brief Make an adaptive integration step of the system 00085 \c derivs 00086 00087 This attempts to take a step of size \c h from the point \c x of 00088 an \c n-dimensional system \c derivs starting with \c y. On 00089 exit, \c x and \c y contain the new values at the end of the 00090 step, \c h contains the size of the step, \c dydx_out contains 00091 the derivative at the end of the step, and \c yerr contains the 00092 estimated error at the end of the step. 00093 00094 If the base stepper returns a non-zero value, that value is 00095 passed on as the return value of <tt>astep()</tt>, though the 00096 input \c y may still have been modified by the base stepper. 00097 00098 */ 00099 virtual int astep(double &x, double xlimit, double &h, 00100 size_t n, vec_t &y, vec_t &dydx_out, 00101 vec_t &yerr, func_t &derivs) { 00102 00103 if (n!=msize) { 00104 ao.allocate(dydx_int,n); 00105 } 00106 00107 derivs(x,n,y,dydx_int); 00108 if (h>0) { 00109 if (x+h>xlimit) h=xlimit-x; 00110 } else { 00111 if (x+h<xlimit) h=xlimit-x; 00112 } 00113 int ret=this->stepp->step(x,h,n,y,dydx_int,y,yerr,dydx_out,derivs); 00114 x+=h; 00115 00116 return ret; 00117 } 00118 00119 /** \brief Make an adaptive integration step of the system 00120 \c derivs with derivatives 00121 00122 This attempts to take a step of size \c h from the point \c x of 00123 an \c n-dimensional system \c derivs starting with \c y and 00124 given the initial derivatives \c dydx. On exit, \c x, \c y and 00125 \c dydx contain the new values at the end of the step, \c h 00126 contains the size of the step, \c dydx contains the derivative 00127 at the end of the step, and \c yerr contains the estimated error 00128 at the end of the step. 00129 00130 If the base stepper returns a non-zero value, that value is 00131 passed on as the return value of <tt>astep()</tt>, though the 00132 inputs \c y and \c dydx may still have been modified by the 00133 base stepper. 00134 */ 00135 virtual int astep_derivs(double &x, double xlimit, double &h, 00136 size_t n, vec_t &y, vec_t &dydx, 00137 vec_t &yerr, func_t &derivs) { 00138 00139 if (h>0) { 00140 if (x+h>xlimit) h=xlimit-x; 00141 } else { 00142 if (x+h<xlimit) h=xlimit-x; 00143 } 00144 int ret=this->stepp->step(x,h,n,y,dydx,y,yerr,dydx,derivs); 00145 x+=h; 00146 00147 return ret; 00148 } 00149 00150 /** \brief Make an adaptive integration step of the system 00151 \c derivs 00152 00153 This function performs an adaptive integration step with the 00154 \c n-dimensional system \c derivs and parameter \c pa. It 00155 Begins at \c x with initial stepsize \c h, ensuring that the 00156 step goes no farther than \c xlimit. At the end of the step, 00157 the size of the step taken is \c h and the new value of \c x 00158 is in \c x_out. Initially, the function values and 00159 derivatives should be specified in \c y and \c dydx. The 00160 function values, derivatives, and the error at the end of 00161 the step are given in \c yout, \c yerr, and \c dydx_out. 00162 Unlike in \c ode_step objects, the objects \c y, \c yout, 00163 \c dydx, and \c dydx_out must all be distinct. 00164 00165 If the base stepper returns a non-zero value, that value is 00166 passed on as the return value of <tt>astep()</tt>, though the 00167 output parameters may still have been modified by the 00168 base stepper. 00169 */ 00170 virtual int astep_full(double x, double xlimit, double &x_out, double &h, 00171 size_t n, vec_t &y, vec_t &dydx, 00172 vec_t &yout, vec_t &yerr, vec_t &dydx_out, 00173 func_t &derivs) { 00174 00175 if (h>0) { 00176 if (x+h>xlimit) h=xlimit-x; 00177 } else { 00178 if (x+h<xlimit) h=xlimit-x; 00179 } 00180 int ret=this->stepp->step(x,h,n,y,dydx,yout,yerr,dydx_out,derivs); 00181 x_out=x+h; 00182 00183 return ret; 00184 } 00185 00186 }; 00187 00188 #ifndef DOXYGENP 00189 } 00190 #endif 00191 00192 #endif
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).