Object-oriented Scientific Computing Library: Version 0.910
nonadapt_step.h
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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.