Warning, file /education/step/stepcore/solver.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 /** \file solver.h 0008 * \brief Solver interface 0009 */ 0010 0011 #ifndef STEPCORE_SOLVER_H 0012 #define STEPCORE_SOLVER_H 0013 0014 #include "object.h" 0015 #include "vector.h" 0016 0017 namespace StepCore 0018 { 0019 0020 /** \ingroup solvers 0021 * \brief Generic Solver interface 0022 * 0023 * Provides generic interface suitable for large variety of ordinary 0024 * differential equations integration algorithms. 0025 * 0026 * It solves system of the first order differential equations: 0027 * \f{eqnarray*} 0028 * \frac{dy_i(t)}{dt} &=& f(y_i(t), t) \\ 0029 * y_i(t_0) &=& y^0_i 0030 * \f} 0031 * 0032 * Dimension of system is provided via setDimension(), 0033 * function \f$f\f$ is provided via setFunction(). 0034 * 0035 * It also provides interface for setting allowed local tolerance. 0036 * It can be defined using two properties: toleranceAbs and toleranceRel. 0037 * 0038 * On each step solver calculates local error estimation (which depends on 0039 * used integration method) and local error ratio for each variable 0040 * using the following formula: 0041 * \f[ 0042 * \mbox{localErrorRatio}_i = \frac{|\mbox{localError}_i|} 0043 * {\mbox{toleranceAbs} + \mbox{toleranceRel} \cdot | y_i |} 0044 * \f] 0045 * 0046 * Non-adaptive solvers cancel current step if maximal local error ratio is 0047 * bigger than 1.1 (exact value depends on solver) and doEvolve() function 0048 * returns false. 0049 * 0050 * Adaptive solvers use maximal local error ratio to change time step until 0051 * the ratio becomes almost equal 1. If it can't be made smaller than 1.1 0052 * (exact value depends on solver), solvers cancel current step and doEvolve() 0053 * function returns false. 0054 * 0055 * Maximal (over all variables) error estimation and error ratio from last 0056 * time step can be obtained using localError() and localErrorRatio() methods. 0057 */ 0058 class Solver: public Object 0059 { 0060 //Q_OBJECT 0061 STEPCORE_OBJECT(Solver) 0062 0063 public: 0064 /** Callback function type */ 0065 typedef int (*Function)(double t, const double* y, const double* yvar, 0066 double* f, double* fvar, void* params); 0067 0068 /** Constructs a solver */ 0069 explicit Solver(int dimension = 0, Function function = nullptr, 0070 void* params = nullptr, double stepSize = 0.001); 0071 /** Constructs a solver */ 0072 explicit Solver(double stepSize); 0073 0074 virtual ~Solver() {} 0075 0076 /** Get solver type */ 0077 QString solverType() const { return metaObject()->className(); } 0078 0079 /** Get ODE dimension */ 0080 int dimension() const { return _dimension; } 0081 /** Set ODE dimension */ 0082 virtual void setDimension(int dimension) { _dimension = dimension; } 0083 0084 /** Get callback function */ 0085 Function function() const { return _function; } 0086 /** Set callback function */ 0087 virtual void setFunction(Function function) { _function = function; } 0088 0089 /** Get callback function params */ 0090 void* params() const { return _params; } 0091 /** Set callback function params */ 0092 virtual void setParams(void* params) { _params = params; } 0093 0094 /** Get step size */ 0095 double stepSize() const { return _stepSize; } 0096 /** Set step size (solver can adjust it later) */ 0097 virtual void setStepSize(double stepSize) { _stepSize = stepSize; } 0098 0099 /** Get absolute allowed local tolerance */ 0100 double toleranceAbs() const { return _toleranceAbs; } 0101 /** Set absolute allowed local tolerance */ 0102 virtual void setToleranceAbs(double toleranceAbs) { _toleranceAbs = toleranceAbs; } 0103 0104 /** Get relative allowed local tolerance */ 0105 double toleranceRel() const { return _toleranceRel; } 0106 /** Set relative allowed local tolerance */ 0107 virtual void setToleranceRel(double toleranceRel) { _toleranceRel = toleranceRel; } 0108 0109 /** Get error estimation from last step */ 0110 double localError() const { return _localError; } 0111 /** Get local tolerance calculated at last step */ 0112 double localErrorRatio() const { return _localErrorRatio; } 0113 0114 /** Calculate function value */ 0115 virtual int doCalcFn(double* t, const VectorXd* y, const VectorXd* yvar = nullptr, 0116 VectorXd* f = nullptr, VectorXd* fvar = nullptr) = 0; 0117 0118 /** Integrate. 0119 * \param t Current time (will be updated by the new value) 0120 * \param t1 Target time 0121 * \param y Function value 0122 * \param yvar Function variance 0123 * \return Solver::OK on success, error status on failure 0124 * \todo Provide error message 0125 */ 0126 virtual int doEvolve(double* t, double t1, VectorXd* y, VectorXd* yvar) = 0; 0127 0128 public: 0129 /** Status codes for doCalcFn and doEvolve */ 0130 enum { OK = 0, 0131 ToleranceError = 2048, 0132 InternalError = 2049, 0133 CollisionDetected = 4096, 0134 IntersectionDetected = 4097, 0135 Aborted = 8192, 0136 CollisionError = 16384, 0137 ConstraintError = 32768 0138 }; 0139 0140 protected: 0141 int _dimension; 0142 Function _function; 0143 void* _params; 0144 0145 double _stepSize; 0146 double _toleranceAbs; 0147 double _toleranceRel; 0148 double _localError; 0149 double _localErrorRatio; 0150 }; 0151 0152 inline Solver::Solver(int dimension, Function function, void* params, double stepSize) 0153 : _dimension(dimension), _function(function), _params(params), _stepSize(stepSize), 0154 _toleranceAbs(0.001), _toleranceRel(0.001), _localError(0), _localErrorRatio(0) 0155 { 0156 } 0157 0158 inline Solver::Solver(double stepSize) 0159 : _dimension(0), _function(nullptr), _params(nullptr), _stepSize(stepSize), 0160 _toleranceAbs(0.001), _toleranceRel(0.001), _localError(0), _localErrorRatio(0) 0161 { 0162 } 0163 0164 } // namespace StepCore 0165 0166 #endif 0167