/*========================================================================= Program: Visualization Toolkit Module: vtkRungeKutta45.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkRungeKutta45 * @brief Integrate an initial value problem using 5th * order Runge-Kutta method with adaptive stepsize control. * * * This is a concrete sub-class of vtkInitialValueProblemSolver. * It uses a 5th order Runge-Kutta method with stepsize control to obtain * the values of a set of functions at the next time step. The stepsize * is adjusted by calculating an estimated error using an embedded 4th * order Runge-Kutta formula: * Press, W. H. et al., 1992, Numerical Recipes in Fortran, Second * Edition, Cambridge University Press * Cash, J.R. and Karp, A.H. 1990, ACM Transactions on Mathematical * Software, vol 16, pp 201-222 * * @sa * vtkInitialValueProblemSolver vtkRungeKutta4 vtkRungeKutta2 vtkFunctionSet */ #ifndef vtkRungeKutta45_h #define vtkRungeKutta45_h #include "vtkCommonMathModule.h" // For export macro #include "vtkInitialValueProblemSolver.h" class VTKCOMMONMATH_EXPORT vtkRungeKutta45 : public vtkInitialValueProblemSolver { public: vtkTypeMacro(vtkRungeKutta45, vtkInitialValueProblemSolver); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Construct a vtkRungeKutta45 with no initial FunctionSet. */ static vtkRungeKutta45* New(); using Superclass::ComputeNextStep; //@{ /** * Given initial values, xprev , initial time, t and a requested time * interval, delT calculate values of x at t+delTActual (xnext). * Possibly delTActual != delT. This may occur * because this solver supports adaptive stepsize control. It tries * to change to stepsize such that * the (estimated) error of the integration is less than maxError. * The solver will not set the stepsize smaller than minStep or * larger than maxStep (note that maxStep and minStep should both * be positive, whereas delT can be negative). * Also note that delT is an in/out argument. vtkRungeKutta45 * will modify delT to reflect the best (estimated) size for the next * integration step. * An estimated value for the error is returned (by reference) in error. * This is the norm of the error vector if there are more than * one function to be integrated. * This method returns an error code representing the nature of * the failure: * OutOfDomain = 1, * NotInitialized = 2, * UnexpectedValue = 3 */ int ComputeNextStep(double* xprev, double* xnext, double t, double& delT, double maxError, double& error, void* userData) override { double minStep = delT; double maxStep = delT; double delTActual; return this->ComputeNextStep( xprev, nullptr, xnext, t, delT, delTActual, minStep, maxStep, maxError, error, userData); } int ComputeNextStep(double* xprev, double* dxprev, double* xnext, double t, double& delT, double maxError, double& error, void* userData) override { double minStep = delT; double maxStep = delT; double delTActual; return this->ComputeNextStep( xprev, dxprev, xnext, t, delT, delTActual, minStep, maxStep, maxError, error, userData); } int ComputeNextStep(double* xprev, double* xnext, double t, double& delT, double& delTActual, double minStep, double maxStep, double maxError, double& error, void* userData) override { return this->ComputeNextStep( xprev, nullptr, xnext, t, delT, delTActual, minStep, maxStep, maxError, error, userData); } int ComputeNextStep(double* xprev, double* dxprev, double* xnext, double t, double& delT, double& delTActual, double minStep, double maxStep, double maxError, double& error, void* userData) override; //@} protected: vtkRungeKutta45(); ~vtkRungeKutta45() override; void Initialize() override; // Cash-Karp parameters static double A[5]; static double B[5][5]; static double C[6]; static double DC[6]; double* NextDerivs[6]; int ComputeAStep(double* xprev, double* dxprev, double* xnext, double t, double& delT, double& delTActual, double& error, void* userData); private: vtkRungeKutta45(const vtkRungeKutta45&) = delete; void operator=(const vtkRungeKutta45&) = delete; }; #endif