text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkInitialValueProblemSolver.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   vtkInitialValueProblemSolver
   * @brief   Integrate a set of ordinary
   * differential equations (initial value problem) in time.
   *
   *
   * Given a vtkFunctionSet which returns dF_i(x_j, t)/dt given x_j and
   * t, vtkInitialValueProblemSolver computes the value of F_i at t+deltat.
   *
   * @warning
   * vtkInitialValueProblemSolver and it's subclasses are not thread-safe.
   * You should create a new integrator for each thread.
   *
   * @sa
   * vtkRungeKutta2 vtkRungeKutta4
   */
  
  #ifndef vtkInitialValueProblemSolver_h
  #define vtkInitialValueProblemSolver_h
  
  #include "vtkCommonMathModule.h" // For export macro
  #include "vtkObject.h"
  
  class vtkFunctionSet;
  
  class VTKCOMMONMATH_EXPORT vtkInitialValueProblemSolver : public vtkObject
  {
  public:
    vtkTypeMacro(vtkInitialValueProblemSolver, vtkObject);
    void PrintSelf(ostream& os, vtkIndent indent) override;
  
    //@{
    /**
     * Given initial values, xprev , initial time, t and a requested time
     * interval, delT calculate values of x at t+delTActual (xnext).
     * For certain concrete sub-classes delTActual != delT. This occurs
     * when the solver supports adaptive stepsize control. If this
     * is the case, the solver 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.
     * Also note that delT is an in/out argument. Adaptive solvers
     * 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.
     * Note that only some concrete sub-classes support this. Otherwise,
     * the error is set to 0.
     * This method returns an error code representing the nature of
     * the failure:
     * OutOfDomain = 1,
     * NotInitialized = 2,
     * UnexpectedValue = 3
     */
    virtual int ComputeNextStep(
      double* xprev, double* xnext, double t, double& delT, double maxError, double& error)
    {
      return this->ComputeNextStep(xprev, xnext, t, delT, maxError, error, nullptr);
    }
  
    virtual int ComputeNextStep(double* xprev, double* xnext, double t, double& delT, double maxError,
      double& error, void* userData)
    {
      double minStep = delT;
      double maxStep = delT;
      double delTActual;
      return this->ComputeNextStep(
        xprev, nullptr, xnext, t, delT, delTActual, minStep, maxStep, maxError, error, userData);
    }
  
    virtual int ComputeNextStep(double* xprev, double* dxprev, double* xnext, double t, double& delT,
      double maxError, double& error)
    {
      return this->ComputeNextStep(xprev, dxprev, xnext, t, delT, maxError, error, nullptr);
    }
  
    virtual int ComputeNextStep(double* xprev, double* dxprev, double* xnext, double t, double& delT,
      double maxError, double& error, void* userData)
    {
      double minStep = delT;
      double maxStep = delT;
      double delTActual;
      return this->ComputeNextStep(
        xprev, dxprev, xnext, t, delT, delTActual, minStep, maxStep, maxError, error, userData);
    }
    virtual int ComputeNextStep(double* xprev, double* xnext, double t, double& delT,
      double& delTActual, double minStep, double maxStep, double maxError, double& error)
    {
      return this->ComputeNextStep(
        xprev, xnext, t, delT, delTActual, minStep, maxStep, maxError, error, nullptr);
    }
  
    virtual int ComputeNextStep(double* xprev, double* xnext, double t, double& delT,
      double& delTActual, double minStep, double maxStep, double maxError, double& error,
      void* userData)
    {
      return this->ComputeNextStep(
        xprev, nullptr, xnext, t, delT, delTActual, minStep, maxStep, maxError, error, userData);
    }
  
    virtual int ComputeNextStep(double* xprev, double* dxprev, double* xnext, double t, double& delT,
      double& delTActual, double minStep, double maxStep, double maxError, double& error)
    {
      return this->ComputeNextStep(
        xprev, dxprev, xnext, t, delT, delTActual, minStep, maxStep, maxError, error, nullptr);
    }
  
    virtual int ComputeNextStep(double* vtkNotUsed(xprev), double* vtkNotUsed(dxprev),
      double* vtkNotUsed(xnext), double vtkNotUsed(t), double& vtkNotUsed(delT),
      double& vtkNotUsed(delTActual), double vtkNotUsed(minStep), double vtkNotUsed(maxStep),
      double vtkNotUsed(maxError), double& vtkNotUsed(error), void* vtkNotUsed(userData))
    {
      return 0;
    }
    //@}
  
    //@{
    /**
     * Set / get the dataset used for the implicit function evaluation.
     */
    virtual void SetFunctionSet(vtkFunctionSet* functionset);
    vtkGetObjectMacro(FunctionSet, vtkFunctionSet);
    //@}
  
    /**
     * Returns 1 if the solver uses adaptive stepsize control,
     * 0 otherwise
     */
    virtual vtkTypeBool IsAdaptive() { return this->Adaptive; }
  
    enum ErrorCodes
    {
      OUT_OF_DOMAIN = 1,
      NOT_INITIALIZED = 2,
      UNEXPECTED_VALUE = 3
    };
  
  protected:
    vtkInitialValueProblemSolver();
    ~vtkInitialValueProblemSolver() override;
  
    virtual void Initialize();
  
    vtkFunctionSet* FunctionSet;
  
    double* Vals;
    double* Derivs;
    int Initialized;
    vtkTypeBool Adaptive;
  
  private:
    vtkInitialValueProblemSolver(const vtkInitialValueProblemSolver&) = delete;
    void operator=(const vtkInitialValueProblemSolver&) = delete;
  };
  
  #endif
  