1 /* This file is part of StepCore library. 2 Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com> 3 4 StepCore library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 StepCore library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with StepCore; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 /** \file gslsolver.h 20 * \brief GslGenericSolver, GslSolver and GslAdaptiveSolver classes 21 */ 22 23 #ifndef STEPCORE_GSLSOLVER_H 24 #define STEPCORE_GSLSOLVER_H 25 26 // HACK: CMake does not passes definitions to moc 27 #if defined(STEPCORE_WITH_GSL) || defined(Q_MOC_RUN) 28 29 #include "solver.h" 30 #include "object.h" 31 32 #include <gsl/gsl_odeiv.h> 33 34 namespace StepCore 35 { 36 37 /** \ingroup solvers 38 * \brief Adaptive and non-adaptive solvers from GSL library 39 * 40 * See https://www.gnu.org/software/gsl/manual/html_node/Ordinary-Differential-Equations.html#Ordinary-Differential-Equations 41 * and https://en.wikipedia.org/wiki/Numerical_ordinary_differential_equations 42 * 43 */ 44 class GslGenericSolver: public Solver 45 { STEPCORE_OBJECT(GslGenericSolver)46 STEPCORE_OBJECT(GslGenericSolver) 47 48 public: 49 /** Constructs GslSolver */ 50 GslGenericSolver(double stepSize, bool adaptive, const gsl_odeiv_step_type* gslStepType) 51 : Solver(stepSize), _adaptive(adaptive), _gslStepType(gslStepType) { init(); } 52 /** Constructs GslSolver */ GslGenericSolver(int dimension,Function function,void * params,double stepSize,bool adaptive,const gsl_odeiv_step_type * gslStepType)53 GslGenericSolver(int dimension, Function function, void* params, double stepSize, 54 bool adaptive, const gsl_odeiv_step_type* gslStepType) 55 : Solver(dimension, function, params, stepSize), 56 _adaptive(adaptive), _gslStepType(gslStepType) { init(); } 57 /** Copy constructor */ GslGenericSolver(const GslGenericSolver & gslSolver)58 GslGenericSolver(const GslGenericSolver& gslSolver) 59 : Solver(gslSolver), _adaptive(gslSolver._adaptive), 60 _gslStepType(gslSolver._gslStepType) { init(); } 61 ~GslGenericSolver()62 ~GslGenericSolver() { fini(); } 63 setDimension(int dimension)64 void setDimension(int dimension) { fini(); _dimension = dimension; init(); } setToleranceAbs(double toleranceAbs)65 void setToleranceAbs(double toleranceAbs) { fini(); _toleranceAbs = toleranceAbs; init(); } setToleranceRel(double toleranceRel)66 void setToleranceRel(double toleranceRel) { fini(); _toleranceRel = toleranceRel; init(); } 67 68 int doCalcFn(double* t, const VectorXd* y, const VectorXd* yvar, 69 VectorXd* f = 0, VectorXd* fvar = 0); 70 int doEvolve(double* t, double t1, VectorXd* y, VectorXd* yvar); 71 72 protected: 73 static int gslFunction(double t, const double* y, double* f, void* params); 74 void init(); 75 void fini(); 76 77 bool _adaptive; 78 79 //gsl_odeiv_control* _gslControl; 80 //gsl_odeiv_evolve* _gslEvolve; 81 VectorXd _yerr; 82 VectorXd _ytemp; 83 VectorXd _ydiff; 84 VectorXd _dydt_in; 85 VectorXd _dydt_out; 86 87 const gsl_odeiv_step_type* _gslStepType; 88 gsl_odeiv_system _gslSystem; 89 gsl_odeiv_step* _gslStep; 90 gsl_odeiv_control* _gslControl; 91 gsl_odeiv_evolve* _gslEvolve; 92 }; 93 94 /** \ingroup solvers 95 * \brief Non-adaptive solvers from GSL library 96 */ 97 class GslSolver: public GslGenericSolver 98 { STEPCORE_OBJECT(GslSolver)99 STEPCORE_OBJECT(GslSolver) 100 public: 101 GslSolver(double stepSize, const gsl_odeiv_step_type* gslStepType): 102 GslGenericSolver(stepSize, false, gslStepType) {} GslSolver(int dimension,Function function,void * params,double stepSize,const gsl_odeiv_step_type * gslStepType)103 GslSolver(int dimension, Function function, void* params, double stepSize, 104 const gsl_odeiv_step_type* gslStepType) 105 : GslGenericSolver(dimension, function, params, stepSize, false, gslStepType) {} GslSolver(const GslSolver & gslSolver)106 GslSolver(const GslSolver& gslSolver): GslGenericSolver(gslSolver) {} 107 }; 108 109 /** \ingroup solvers 110 * \brief Adaptive solvers from GSL library 111 */ 112 class GslAdaptiveSolver: public GslGenericSolver 113 { STEPCORE_OBJECT(GslAdaptiveSolver)114 STEPCORE_OBJECT(GslAdaptiveSolver) 115 public: 116 explicit GslAdaptiveSolver(const gsl_odeiv_step_type* gslStepType): 117 GslGenericSolver(1, true, gslStepType) {} GslAdaptiveSolver(int dimension,Function function,void * params,const gsl_odeiv_step_type * gslStepType)118 GslAdaptiveSolver(int dimension, Function function, void* params, 119 const gsl_odeiv_step_type* gslStepType) 120 : GslGenericSolver(dimension, function, params, 1, true, gslStepType) {} GslAdaptiveSolver(const GslAdaptiveSolver & gslSolver)121 GslAdaptiveSolver(const GslAdaptiveSolver& gslSolver): GslGenericSolver(gslSolver) {} 122 }; 123 124 #define STEPCORE_DECLARE_GSLSOLVER(Class, type) \ 125 class Gsl##Class##Solver: public GslSolver { \ 126 STEPCORE_OBJECT(Gsl##Class##Solver) \ 127 public: \ 128 Gsl##Class##Solver(double stepSize = 0.01): GslSolver(stepSize, gsl_odeiv_step_##type) {} \ 129 Gsl##Class##Solver(int dimension, Function function, void* params, double stepSize) \ 130 : GslSolver(dimension, function, params, stepSize, gsl_odeiv_step_##type) {} \ 131 Gsl##Class##Solver(const Gsl##Class##Solver& gslSolver): GslSolver(gslSolver) {} \ 132 }; 133 134 #define STEPCORE_DECLARE_GSLASOLVER(Class, type) \ 135 class GslAdaptive##Class##Solver: public GslAdaptiveSolver { \ 136 STEPCORE_OBJECT(GslAdaptive##Class##Solver) \ 137 public: \ 138 GslAdaptive##Class##Solver(): GslAdaptiveSolver(gsl_odeiv_step_##type) {} \ 139 GslAdaptive##Class##Solver(int dimension, Function function, void* params) \ 140 : GslAdaptiveSolver(dimension, function, params, gsl_odeiv_step_##type) {} \ 141 GslAdaptive##Class##Solver(const GslAdaptive##Class##Solver& gslSolver): GslAdaptiveSolver(gslSolver) {} \ 142 }; 143 144 /** \ingroup solvers 145 * \class GslRK2Solver 146 * \brief Runge-Kutta second-order solver from GSL library 147 */ 148 STEPCORE_DECLARE_GSLSOLVER(RK2, rk2) 149 150 /** \ingroup solvers 151 * \class GslAdaptiveRK2Solver 152 * \brief Adaptive Runge-Kutta second-order solver from GSL library 153 */ 154 STEPCORE_DECLARE_GSLASOLVER(RK2, rk2) 155 156 /** \ingroup solvers 157 * \class GslRK4Solver 158 * \brief Runge-Kutta classical fourth-order solver from GSL library 159 */ 160 STEPCORE_DECLARE_GSLSOLVER(RK4, rk4) 161 162 /** \ingroup solvers 163 * \class GslAdaptiveRK4Solver 164 * \brief Adaptive Runge-Kutta classical fourth-order solver from GSL library 165 */ 166 STEPCORE_DECLARE_GSLASOLVER(RK4, rk4) 167 168 /** \ingroup solvers 169 * \class GslRKF45Solver 170 * \brief Runge-Kutta-Fehlberg (4,5) solver from GSL library 171 */ 172 STEPCORE_DECLARE_GSLSOLVER(RKF45, rkf45) 173 174 /** \ingroup solvers 175 * \class AdaptiveGslRKF45Solver 176 * \brief Adaptive Runge-Kutta-Fehlberg (4,5) solver from GSL library 177 */ 178 STEPCORE_DECLARE_GSLASOLVER(RKF45, rkf45) 179 180 /** \ingroup solvers 181 * \class GslRKCKSolver 182 * \brief Runge-Kutta Cash-Karp (4,5) solver from GSL library 183 */ 184 STEPCORE_DECLARE_GSLSOLVER(RKCK, rkck) 185 186 /** \ingroup solvers 187 * \class AdaptiveGslRKCKSolver 188 * \brief Adaptive Runge-Kutta Cash-Karp (4,5) solver from GSL library 189 */ 190 STEPCORE_DECLARE_GSLASOLVER(RKCK, rkck) 191 192 /** \ingroup solvers 193 * \class GslRK8PDSolver 194 * \brief Runge-Kutta Prince-Dormand (8,9) solver from GSL library 195 */ 196 STEPCORE_DECLARE_GSLSOLVER(RK8PD, rk8pd) 197 198 /** \ingroup solvers 199 * \class GslAdaptiveRK8PDSolver 200 * \brief Adaptive Runge-Kutta Prince-Dormand (8,9) solver from GSL library 201 */ 202 STEPCORE_DECLARE_GSLASOLVER(RK8PD, rk8pd) 203 204 /** \ingroup solvers 205 * \class GslRK2IMPSolver 206 * \brief Runge-Kutta implicit second-order solver from GSL library 207 */ 208 STEPCORE_DECLARE_GSLSOLVER(RK2IMP, rk2imp) 209 210 /** \ingroup solvers 211 * \class GslAdaptiveRK2IMPSolver 212 * \brief Adaptive Runge-Kutta Prince-Dormand (8,9) solver from GSL library 213 */ 214 STEPCORE_DECLARE_GSLASOLVER(RK2IMP, rk2imp) 215 216 /** \ingroup solvers 217 * \class GslRK4IMPSolver 218 * \brief Runge-Kutta implicit fourth-order solver from GSL library 219 */ 220 STEPCORE_DECLARE_GSLSOLVER(RK4IMP, rk4imp) 221 222 /** \ingroup solvers 223 * \class GslAdaptiveRK4IMPSolver 224 * \brief Runge-Kutta implicit fourth-order solver from GSL library 225 */ 226 STEPCORE_DECLARE_GSLASOLVER(RK4IMP, rk4imp) 227 228 } // namespace StepCore 229 230 #endif // defined(STEPCORE_WITH_GSL) || defined(Q_MOC_RUN) 231 232 #endif // STEPCORE_GSLSOLVER_H 233 234