|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: differential equations, initial value problems
|
|
Packit |
67cb25 |
single: initial value problems, differential equations
|
|
Packit |
67cb25 |
single: ordinary differential equations, initial value problem
|
|
Packit |
67cb25 |
single: ODEs, initial value problems
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
*******************************
|
|
Packit |
67cb25 |
Ordinary Differential Equations
|
|
Packit |
67cb25 |
*******************************
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This chapter describes functions for solving ordinary differential
|
|
Packit |
67cb25 |
equation (ODE) initial value problems. The library provides a variety
|
|
Packit |
67cb25 |
of low-level methods, such as Runge-Kutta and Bulirsch-Stoer routines,
|
|
Packit |
67cb25 |
and higher-level components for adaptive step-size control. The
|
|
Packit |
67cb25 |
components can be combined by the user to achieve the desired
|
|
Packit |
67cb25 |
solution, with full access to any intermediate steps. A driver object
|
|
Packit |
67cb25 |
can be used as a high level wrapper for easy use of low level
|
|
Packit |
67cb25 |
functions.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
These functions are declared in the header file :file:`gsl_odeiv2.h`.
|
|
Packit |
67cb25 |
This is a new interface in version 1.15 and uses the prefix
|
|
Packit |
67cb25 |
:code:`gsl_odeiv2` for all functions. It is recommended over the
|
|
Packit |
67cb25 |
previous :code:`gsl_odeiv` implementation defined in :file:`gsl_odeiv.h`
|
|
Packit |
67cb25 |
The old interface has been retained under the original name for
|
|
Packit |
67cb25 |
backwards compatibility.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Defining the ODE System
|
|
Packit |
67cb25 |
=======================
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The routines solve the general :math:`n`-dimensional first-order system,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: not texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: {dy_i(t) \over dt} = f_i (t, y_1(t), \dots y_n(t))
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
dy_i(t)/dt = f_i(t, y_1(t), ..., y_n(t))
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for :math:`i = 1, \dots, n`. The stepping functions rely on the vector
|
|
Packit |
67cb25 |
of derivatives :math:`f_i` and the Jacobian matrix,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: not texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: J_{ij} = \partial f_i(t, y(t)) / \partial y_j
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
J_{ij} = df_i(t,y(t)) / dy_j
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
A system of equations is defined using the :type:`gsl_odeiv2_system`
|
|
Packit |
67cb25 |
datatype.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. type:: gsl_odeiv2_system
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This data type defines a general ODE system with arbitrary parameters.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
:code:`int (* function) (double t, const double y[], double dydt[], void * params)`
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function should store the vector elements
|
|
Packit |
67cb25 |
:math:`f_i(t,y,params)` in the array :data:`dydt`,
|
|
Packit |
67cb25 |
for arguments (:data:`t`, :data:`y`) and parameters :data:`params`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The function should return :macro:`GSL_SUCCESS` if the calculation was
|
|
Packit |
67cb25 |
completed successfully. Any other return value indicates an error. A
|
|
Packit |
67cb25 |
special return value :macro:`GSL_EBADFUNC` causes :code:`gsl_odeiv2`
|
|
Packit |
67cb25 |
routines to immediately stop and return. If :code:`function`
|
|
Packit |
67cb25 |
is modified (for example contents of :data:`params`), the user must call an
|
|
Packit |
67cb25 |
appropriate reset function (:func:`gsl_odeiv2_driver_reset`,
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_evolve_reset` or :func:`gsl_odeiv2_step_reset`)
|
|
Packit |
67cb25 |
before continuing. Use return values
|
|
Packit |
67cb25 |
distinct from standard GSL error codes to distinguish your function as
|
|
Packit |
67cb25 |
the source of the error.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Jacobian matrix, ODEs
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
:code:`int (* jacobian) (double t, const double y[], double * dfdy, double dfdt[], void * params)`
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function should store the vector of derivative elements
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: not texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: \partial f_i(t,y,params) / \partial t
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
df_i(t,y,params)/dt
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
in the array :data:`dfdt` and the Jacobian matrix :math:`J_{ij}`
|
|
Packit |
67cb25 |
in the array :data:`dfdy`, regarded as a row-ordered
|
|
Packit |
67cb25 |
matrix :code:`J(i,j) = dfdy[i * dimension + j]` where :code:`dimension`
|
|
Packit |
67cb25 |
is the dimension of the system.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Not all of the stepper algorithms of :code:`gsl_odeiv2` make use of the
|
|
Packit |
67cb25 |
Jacobian matrix, so it may not be necessary to provide this function
|
|
Packit |
67cb25 |
(the :code:`jacobian` element of the struct can be replaced by a null
|
|
Packit |
67cb25 |
pointer for those algorithms).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The function should return :macro:`GSL_SUCCESS` if the calculation was
|
|
Packit |
67cb25 |
completed successfully. Any other return value indicates an error. A
|
|
Packit |
67cb25 |
special return value :macro:`GSL_EBADFUNC` causes :code:`gsl_odeiv2`
|
|
Packit |
67cb25 |
routines to immediately stop and return. If :code:`jacobian`
|
|
Packit |
67cb25 |
is modified (for example contents of :data:`params`), the user must call an
|
|
Packit |
67cb25 |
appropriate reset function (:func:`gsl_odeiv2_driver_reset`,
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_evolve_reset` or :func:`gsl_odeiv2_step_reset`)
|
|
Packit |
67cb25 |
before continuing. Use return values
|
|
Packit |
67cb25 |
distinct from standard GSL error codes to distinguish your function as
|
|
Packit |
67cb25 |
the source of the error.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
:code:`size_t dimension`
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This is the dimension of the system of equations.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
:code:`void * params`
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This is a pointer to the arbitrary parameters of the system.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Stepping Functions
|
|
Packit |
67cb25 |
==================
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The lowest level components are the *stepping functions* which
|
|
Packit |
67cb25 |
advance a solution from time :math:`t` to :math:`t+h` for a fixed
|
|
Packit |
67cb25 |
step-size :math:`h` and estimate the resulting local error.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. type:: gsl_odeiv2_step
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This contains internal parameters for a stepping function.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_odeiv2_step * gsl_odeiv2_step_alloc (const gsl_odeiv2_step_type * T, size_t dim)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function returns a pointer to a newly allocated instance of a
|
|
Packit |
67cb25 |
stepping function of type :data:`T` for a system of :data:`dim`
|
|
Packit |
67cb25 |
dimensions. Please note that if you use a stepper method that
|
|
Packit |
67cb25 |
requires access to a driver object, it is advisable to use a driver
|
|
Packit |
67cb25 |
allocation method, which automatically allocates a stepper, too.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_step_reset (gsl_odeiv2_step * s)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function resets the stepping function :data:`s`. It should be used
|
|
Packit |
67cb25 |
whenever the next use of :data:`s` will not be a continuation of a
|
|
Packit |
67cb25 |
previous step.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: void gsl_odeiv2_step_free (gsl_odeiv2_step * s)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function frees all the memory associated with the stepping function
|
|
Packit |
67cb25 |
:data:`s`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: const char * gsl_odeiv2_step_name (const gsl_odeiv2_step * s)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function returns a pointer to the name of the stepping function.
|
|
Packit |
67cb25 |
For example::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
printf ("step method is '%s'\n", gsl_odeiv2_step_name (s));
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
would print something like :code:`step method is 'rkf45'`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: unsigned int gsl_odeiv2_step_order (const gsl_odeiv2_step * s)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function returns the order of the stepping function on the previous
|
|
Packit |
67cb25 |
step. The order can vary if the stepping function itself is adaptive.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_step_set_driver (gsl_odeiv2_step * s, const gsl_odeiv2_driver * d)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function sets a pointer of the driver object :data:`d` for stepper
|
|
Packit |
67cb25 |
:data:`s`, to allow the stepper to access control (and evolve) object
|
|
Packit |
67cb25 |
through the driver object. This is a requirement for some steppers, to
|
|
Packit |
67cb25 |
get the desired error level for internal iteration of
|
|
Packit |
67cb25 |
stepper. Allocation of a driver object calls this function
|
|
Packit |
67cb25 |
automatically.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_step_apply (gsl_odeiv2_step * s, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv2_system * sys)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function applies the stepping function :data:`s` to the system of
|
|
Packit |
67cb25 |
equations defined by :data:`sys`, using the step-size :data:`h` to advance
|
|
Packit |
67cb25 |
the system from time :data:`t` and state :data:`y` to time :data:`t` + :data:`h`.
|
|
Packit |
67cb25 |
The new state of the system is stored in :data:`y` on output, with an
|
|
Packit |
67cb25 |
estimate of the absolute error in each component stored in :data:`yerr`.
|
|
Packit |
67cb25 |
If the argument :data:`dydt_in` is not null it should point an array
|
|
Packit |
67cb25 |
containing the derivatives for the system at time :data:`t` on input. This
|
|
Packit |
67cb25 |
is optional as the derivatives will be computed internally if they are
|
|
Packit |
67cb25 |
not provided, but allows the reuse of existing derivative information.
|
|
Packit |
67cb25 |
On output the new derivatives of the system at time :data:`t` + :data:`h` will
|
|
Packit |
67cb25 |
be stored in :data:`dydt_out` if it is not null.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The stepping function returns :macro:`GSL_FAILURE` if it is unable to
|
|
Packit |
67cb25 |
compute the requested step. Also, if the user-supplied functions
|
|
Packit |
67cb25 |
defined in the system :data:`sys` return a status other than
|
|
Packit |
67cb25 |
:macro:`GSL_SUCCESS` the step will be aborted. In that case, the
|
|
Packit |
67cb25 |
elements of :data:`y` will be restored to their pre-step values and the
|
|
Packit |
67cb25 |
error code from the user-supplied function will be returned. Failure
|
|
Packit |
67cb25 |
may be due to a singularity in the system or too large step-size
|
|
Packit |
67cb25 |
:data:`h`. In that case the step should be attempted again with a
|
|
Packit |
67cb25 |
smaller step-size, e.g. :data:`h` / 2.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If the driver object is not appropriately set via
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_step_set_driver` for those steppers that need it, the
|
|
Packit |
67cb25 |
stepping function returns :macro:`GSL_EFAULT`. If the user-supplied
|
|
Packit |
67cb25 |
functions defined in the system :data:`sys` returns :macro:`GSL_EBADFUNC`,
|
|
Packit |
67cb25 |
the function returns immediately with the same return code. In this
|
|
Packit |
67cb25 |
case the user must call :func:`gsl_odeiv2_step_reset` before calling
|
|
Packit |
67cb25 |
this function again.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The following algorithms are available,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. type:: gsl_odeiv2_step_type
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: RK2, Runge-Kutta method
|
|
Packit |
67cb25 |
single: Runge-Kutta methods, ordinary differential equations
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_rk2
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Explicit embedded Runge-Kutta (2, 3) method.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: RK4, Runge-Kutta method
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_rk4
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Explicit 4th order (classical) Runge-Kutta. Error estimation is
|
|
Packit |
67cb25 |
carried out by the step doubling method. For more efficient estimate
|
|
Packit |
67cb25 |
of the error, use the embedded methods described below.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Fehlberg method, differential equations
|
|
Packit |
67cb25 |
single: RKF45, Runge-Kutta-Fehlberg method
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_rkf45
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Explicit embedded Runge-Kutta-Fehlberg (4, 5) method. This method is
|
|
Packit |
67cb25 |
a good general-purpose integrator.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Runge-Kutta Cash-Karp method
|
|
Packit |
67cb25 |
single: Cash-Karp, Runge-Kutta method
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_rkck
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Explicit embedded Runge-Kutta Cash-Karp (4, 5) method.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Runge-Kutta Prince-Dormand method
|
|
Packit |
67cb25 |
single: Prince-Dormand, Runge-Kutta method
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_rk8pd
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Explicit embedded Runge-Kutta Prince-Dormand (8, 9) method.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index:: Implicit Euler method
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_rk1imp
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Implicit Gaussian first order Runge-Kutta. Also known as implicit
|
|
Packit |
67cb25 |
Euler or backward Euler method. Error estimation is carried out by the
|
|
Packit |
67cb25 |
step doubling method. This algorithm requires the Jacobian and
|
|
Packit |
67cb25 |
access to the driver object via :func:`gsl_odeiv2_step_set_driver`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index:: Implicit Runge-Kutta method
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_rk2imp
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Implicit Gaussian second order Runge-Kutta. Also known as implicit
|
|
Packit |
67cb25 |
mid-point rule. Error estimation is carried out by the step doubling
|
|
Packit |
67cb25 |
method. This stepper requires the Jacobian and access to the driver
|
|
Packit |
67cb25 |
object via :func:`gsl_odeiv2_step_set_driver`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_rk4imp
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Implicit Gaussian 4th order Runge-Kutta. Error estimation is carried
|
|
Packit |
67cb25 |
out by the step doubling method. This algorithm requires the Jacobian
|
|
Packit |
67cb25 |
and access to the driver object via :func:`gsl_odeiv2_step_set_driver`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Bulirsch-Stoer method
|
|
Packit |
67cb25 |
single: Bader and Deuflhard, Bulirsch-Stoer method.
|
|
Packit |
67cb25 |
single: Deuflhard and Bader, Bulirsch-Stoer method.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_bsimp
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Implicit Bulirsch-Stoer method of Bader and Deuflhard. The method is
|
|
Packit |
67cb25 |
generally suitable for stiff problems. This stepper requires the
|
|
Packit |
67cb25 |
Jacobian.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Adams method
|
|
Packit |
67cb25 |
single: multistep methods, ODEs
|
|
Packit |
67cb25 |
single: predictor-corrector method, ODEs
|
|
Packit |
67cb25 |
single: Nordsieck form
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_msadams
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
A variable-coefficient linear multistep Adams method in Nordsieck
|
|
Packit |
67cb25 |
form. This stepper uses explicit Adams-Bashforth (predictor) and
|
|
Packit |
67cb25 |
implicit Adams-Moulton (corrector) methods in :math:`P(EC)^m`
|
|
Packit |
67cb25 |
functional iteration mode. Method order varies dynamically between 1
|
|
Packit |
67cb25 |
and 12. This stepper requires the access to the driver object via
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_step_set_driver`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index:: BDF method
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. var:: gsl_odeiv2_step_msbdf
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
A variable-coefficient linear multistep backward differentiation
|
|
Packit |
67cb25 |
formula (BDF) method in Nordsieck form. This stepper uses the explicit
|
|
Packit |
67cb25 |
BDF formula as predictor and implicit BDF formula as corrector. A
|
|
Packit |
67cb25 |
modified Newton iteration method is used to solve the system of
|
|
Packit |
67cb25 |
non-linear equations. Method order varies dynamically between 1 and
|
|
Packit |
67cb25 |
5. The method is generally suitable for stiff problems. This stepper
|
|
Packit |
67cb25 |
requires the Jacobian and the access to the driver object via
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_step_set_driver`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Adaptive step-size control, differential equations
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Adaptive Step-size Control
|
|
Packit |
67cb25 |
==========================
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The control function examines the proposed change to the solution
|
|
Packit |
67cb25 |
produced by a stepping function and attempts to determine the optimal
|
|
Packit |
67cb25 |
step-size for a user-specified level of error.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. type:: gsl_odeiv2_control
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This is a workspace for controlling step size.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. type:: gsl_odeiv2_control_type
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This specifies the control type.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_odeiv2_control * gsl_odeiv2_control_standard_new (double eps_abs, double eps_rel, double a_y, double a_dydt)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The standard control object is a four parameter heuristic based on
|
|
Packit |
67cb25 |
absolute and relative errors :data:`eps_abs` and :data:`eps_rel`, and
|
|
Packit |
67cb25 |
scaling factors :data:`a_y` and :data:`a_dydt` for the system state
|
|
Packit |
67cb25 |
:math:`y(t)` and derivatives :math:`y'(t)` respectively.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The step-size adjustment procedure for this method begins by computing
|
|
Packit |
67cb25 |
the desired error level :math:`D_i` for each component,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: not texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: D_i = \epsilon_{abs} + \epsilon_{rel} * (a_{y} |y_i| + a_{dydt} h |y\prime_i|)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
D_i = eps_abs + eps_rel * (a_y |y_i| + a_dydt h |y\prime_i|)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
and comparing it with the observed error :math:`E_i = |yerr_i|`. If the
|
|
Packit |
67cb25 |
observed error :data:`E` exceeds the desired error level :data:`D` by more
|
|
Packit |
67cb25 |
than 10% for any component then the method reduces the step-size by an
|
|
Packit |
67cb25 |
appropriate factor,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: h_{new} = h_{old} * S * (E/D)^{-1/q}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
where :math:`q` is the consistency order of the method (e.g. :math:`q=4` for
|
|
Packit |
67cb25 |
4(5) embedded RK), and :math:`S` is a safety factor of 0.9. The ratio
|
|
Packit |
67cb25 |
:math:`E/D` is taken to be the maximum of the ratios
|
|
Packit |
67cb25 |
:math:`E_i/D_i`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If the observed error :math:`E` is less than 50% of the desired error
|
|
Packit |
67cb25 |
level :data:`D` for the maximum ratio :math:`E_i/D_i` then the algorithm
|
|
Packit |
67cb25 |
takes the opportunity to increase the step-size to bring the error in
|
|
Packit |
67cb25 |
line with the desired level,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: h_{new} = h_{old} * S * (E/D)^{-1/(q+1)}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This encompasses all the standard error scaling methods. To avoid
|
|
Packit |
67cb25 |
uncontrolled changes in the stepsize, the overall scaling factor is
|
|
Packit |
67cb25 |
limited to the range :math:`1/5` to 5.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_odeiv2_control * gsl_odeiv2_control_y_new (double eps_abs, double eps_rel)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function creates a new control object which will keep the local
|
|
Packit |
67cb25 |
error on each step within an absolute error of :data:`eps_abs` and
|
|
Packit |
67cb25 |
relative error of :data:`eps_rel` with respect to the solution :math:`y_i(t)`.
|
|
Packit |
67cb25 |
This is equivalent to the standard control object with :data:`a_y` = 1 and
|
|
Packit |
67cb25 |
:data:`a_dydt` = 0.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_odeiv2_control * gsl_odeiv2_control_yp_new (double eps_abs, double eps_rel)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function creates a new control object which will keep the local
|
|
Packit |
67cb25 |
error on each step within an absolute error of :data:`eps_abs` and
|
|
Packit |
67cb25 |
relative error of :data:`eps_rel` with respect to the derivatives of the
|
|
Packit |
67cb25 |
solution :math:`y'_i(t)`. This is equivalent to the standard control
|
|
Packit |
67cb25 |
object with :data:`a_y` = 0 and :data:`a_dydt` = 1.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_odeiv2_control * gsl_odeiv2_control_scaled_new (double eps_abs, double eps_rel, double a_y, double a_dydt, const double scale_abs[], size_t dim)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function creates a new control object which uses the same algorithm
|
|
Packit |
67cb25 |
as :func:`gsl_odeiv2_control_standard_new` but with an absolute error
|
|
Packit |
67cb25 |
which is scaled for each component by the array :data:`scale_abs`.
|
|
Packit |
67cb25 |
The formula for :math:`D_i` for this control object is,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: not texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: D_i = \epsilon_{abs} s_i + \epsilon_{rel} * (a_{y} |y_i| + a_{dydt} h |y\prime_i|)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
D_i = eps_abs * s_i + eps_rel * (a_y |y_i| + a_dydt h |y\prime_i|)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
where :math:`s_i` is the :math:`i`-th component of the array :data:`scale_abs`.
|
|
Packit |
67cb25 |
The same error control heuristic is used by the Matlab ODE suite.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_odeiv2_control * gsl_odeiv2_control_alloc (const gsl_odeiv2_control_type * T)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function returns a pointer to a newly allocated instance of a
|
|
Packit |
67cb25 |
control function of type :data:`T`. This function is only needed for
|
|
Packit |
67cb25 |
defining new types of control functions. For most purposes the standard
|
|
Packit |
67cb25 |
control functions described above should be sufficient.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_control_init (gsl_odeiv2_control * c, double eps_abs, double eps_rel, double a_y, double a_dydt)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function initializes the control function :data:`c` with the
|
|
Packit |
67cb25 |
parameters :data:`eps_abs` (absolute error), :data:`eps_rel` (relative
|
|
Packit |
67cb25 |
error), :data:`a_y` (scaling factor for y) and :data:`a_dydt` (scaling
|
|
Packit |
67cb25 |
factor for derivatives).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: void gsl_odeiv2_control_free (gsl_odeiv2_control * c)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function frees all the memory associated with the control function
|
|
Packit |
67cb25 |
:data:`c`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_control_hadjust (gsl_odeiv2_control * c, gsl_odeiv2_step * s, const double y[], const double yerr[], const double dydt[], double * h)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function adjusts the step-size :data:`h` using the control function
|
|
Packit |
67cb25 |
:data:`c`, and the current values of :data:`y`, :data:`yerr` and :data:`dydt`.
|
|
Packit |
67cb25 |
The stepping function :data:`step` is also needed to determine the order
|
|
Packit |
67cb25 |
of the method. If the error in the y-values :data:`yerr` is found to be
|
|
Packit |
67cb25 |
too large then the step-size :data:`h` is reduced and the function returns
|
|
Packit |
67cb25 |
:macro:`GSL_ODEIV_HADJ_DEC`. If the error is sufficiently small then
|
|
Packit |
67cb25 |
:data:`h` may be increased and :macro:`GSL_ODEIV_HADJ_INC` is returned. The
|
|
Packit |
67cb25 |
function returns :macro:`GSL_ODEIV_HADJ_NIL` if the step-size is
|
|
Packit |
67cb25 |
unchanged. The goal of the function is to estimate the largest
|
|
Packit |
67cb25 |
step-size which satisfies the user-specified accuracy requirements for
|
|
Packit |
67cb25 |
the current point.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: const char * gsl_odeiv2_control_name (const gsl_odeiv2_control * c)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function returns a pointer to the name of the control function.
|
|
Packit |
67cb25 |
For example::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
printf ("control method is '%s'\n", gsl_odeiv2_control_name (c));
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
would print something like :code:`control method is 'standard'`
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_control_errlevel (gsl_odeiv2_control * c, const double y, const double dydt, const double h, const size_t ind, double * errlev)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function calculates the desired error level of the :data:`ind`-th component
|
|
Packit |
67cb25 |
to :data:`errlev`. It requires the value (:data:`y`) and value of the derivative
|
|
Packit |
67cb25 |
(:data:`dydt`) of the component, and the current step size :data:`h`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_control_set_driver (gsl_odeiv2_control * c, const gsl_odeiv2_driver * d)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function sets a pointer of the driver object :data:`d` for control
|
|
Packit |
67cb25 |
object :data:`c`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Evolution
|
|
Packit |
67cb25 |
=========
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The evolution function combines the results of a stepping function and
|
|
Packit |
67cb25 |
control function to reliably advance the solution forward one step
|
|
Packit |
67cb25 |
using an acceptable step-size.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. type:: gsl_odeiv2_evolve
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This workspace contains parameters for controlling the evolution function
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_odeiv2_evolve * gsl_odeiv2_evolve_alloc (size_t dim)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function returns a pointer to a newly allocated instance of an
|
|
Packit |
67cb25 |
evolution function for a system of :data:`dim` dimensions.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_evolve_apply (gsl_odeiv2_evolve * e, gsl_odeiv2_control * con, gsl_odeiv2_step * step, const gsl_odeiv2_system * sys, double * t, double t1, double * h, double y[])
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function advances the system (:data:`e`, :data:`sys`) from time
|
|
Packit |
67cb25 |
:data:`t` and position :data:`y` using the stepping function :data:`step`.
|
|
Packit |
67cb25 |
The new time and position are stored in :data:`t` and :data:`y` on output.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The initial step-size is taken as :data:`h`. The control function
|
|
Packit |
67cb25 |
:data:`con` is applied to check whether the local error estimated by the
|
|
Packit |
67cb25 |
stepping function :data:`step` using step-size :data:`h` exceeds the
|
|
Packit |
67cb25 |
required error tolerance. If the error is too high, the step is
|
|
Packit |
67cb25 |
retried by calling :data:`step` with a decreased step-size. This process
|
|
Packit |
67cb25 |
is continued until an acceptable step-size is found. An estimate of
|
|
Packit |
67cb25 |
the local error for the step can be obtained from the components of
|
|
Packit |
67cb25 |
the array :code:`e->yerr[]`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If the user-supplied functions defined in the system :data:`sys` returns
|
|
Packit |
67cb25 |
:macro:`GSL_EBADFUNC`, the function returns immediately with the same
|
|
Packit |
67cb25 |
return code. In this case the user must call
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_step_reset` and
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_evolve_reset` before calling this function again.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Otherwise, if the user-supplied functions defined in the system
|
|
Packit |
67cb25 |
:data:`sys` or the stepping function :data:`step` return a status other
|
|
Packit |
67cb25 |
than :macro:`GSL_SUCCESS`, the step is retried with a decreased
|
|
Packit |
67cb25 |
step-size. If the step-size decreases below machine precision, a
|
|
Packit |
67cb25 |
status of :macro:`GSL_FAILURE` is returned if the user functions
|
|
Packit |
67cb25 |
returned :macro:`GSL_SUCCESS`. Otherwise the value returned by user
|
|
Packit |
67cb25 |
function is returned. If no acceptable step can be made, :data:`t` and
|
|
Packit |
67cb25 |
:data:`y` will be restored to their pre-step values and :data:`h` contains
|
|
Packit |
67cb25 |
the final attempted step-size.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If the step is successful the function returns a suggested step-size
|
|
Packit |
67cb25 |
for the next step in :data:`h`. The maximum time :data:`t1` is guaranteed
|
|
Packit |
67cb25 |
not to be exceeded by the time-step. On the final time-step the value
|
|
Packit |
67cb25 |
of :data:`t` will be set to :data:`t1` exactly.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_evolve_apply_fixed_step (gsl_odeiv2_evolve * e, gsl_odeiv2_control * con, gsl_odeiv2_step * step, const gsl_odeiv2_system * sys, double * t, const double h, double y[])
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function advances the ODE-system (:data:`e`, :data:`sys`, :data:`con`)
|
|
Packit |
67cb25 |
from time :data:`t` and position :data:`y` using the stepping function
|
|
Packit |
67cb25 |
:data:`step` by a specified step size :data:`h`. If the local error
|
|
Packit |
67cb25 |
estimated by the stepping function exceeds the desired error level,
|
|
Packit |
67cb25 |
the step is not taken and the function returns
|
|
Packit |
67cb25 |
:macro:`GSL_FAILURE`. Otherwise the value returned by user function is
|
|
Packit |
67cb25 |
returned.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_evolve_reset (gsl_odeiv2_evolve * e)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function resets the evolution function :data:`e`. It should be used
|
|
Packit |
67cb25 |
whenever the next use of :data:`e` will not be a continuation of a
|
|
Packit |
67cb25 |
previous step.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: void gsl_odeiv2_evolve_free (gsl_odeiv2_evolve * e)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function frees all the memory associated with the evolution function
|
|
Packit |
67cb25 |
:data:`e`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_evolve_set_driver (gsl_odeiv2_evolve * e, const gsl_odeiv2_driver * d)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function sets a pointer of the driver object :data:`d` for evolve
|
|
Packit |
67cb25 |
object :data:`e`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: discontinuities, in ODE systems
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If a system has discontinuous changes in the derivatives at known
|
|
Packit |
67cb25 |
points, it is advisable to evolve the system between each discontinuity
|
|
Packit |
67cb25 |
in sequence. For example, if a step-change in an external driving
|
|
Packit |
67cb25 |
force occurs at times :math:`t_a, t_b` and :math:`t_c` then evolution
|
|
Packit |
67cb25 |
should be carried out over the ranges :math:`(t_0,t_a)`,
|
|
Packit |
67cb25 |
:math:`(t_a,t_b)`, :math:`(t_b,t_c)`, and :math:`(t_c,t_1)` separately
|
|
Packit |
67cb25 |
and not directly over the range :math:`(t_0,t_1)`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Driver
|
|
Packit |
67cb25 |
======
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The driver object is a high level wrapper that combines the evolution,
|
|
Packit |
67cb25 |
control and stepper objects for easy use.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_odeiv2_driver * gsl_odeiv2_driver_alloc_y_new (const gsl_odeiv2_system * sys, const gsl_odeiv2_step_type * T, const double hstart, const double epsabs, const double epsrel)
|
|
Packit |
67cb25 |
gsl_odeiv2_driver * gsl_odeiv2_driver_alloc_yp_new (const gsl_odeiv2_system * sys, const gsl_odeiv2_step_type * T, const double hstart, const double epsabs, const double epsrel)
|
|
Packit |
67cb25 |
gsl_odeiv2_driver * gsl_odeiv2_driver_alloc_standard_new (const gsl_odeiv2_system * sys, const gsl_odeiv2_step_type * T, const double hstart, const double epsabs, const double epsrel, const double a_y, const double a_dydt)
|
|
Packit |
67cb25 |
gsl_odeiv2_driver * gsl_odeiv2_driver_alloc_scaled_new (const gsl_odeiv2_system * sys, const gsl_odeiv2_step_type * T, const double hstart, const double epsabs, const double epsrel, const double a_y, const double a_dydt, const double scale_abs[])
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
These functions return a pointer to a newly allocated instance of a
|
|
Packit |
67cb25 |
driver object. The functions automatically allocate and initialise the
|
|
Packit |
67cb25 |
evolve, control and stepper objects for ODE system :data:`sys` using
|
|
Packit |
67cb25 |
stepper type :data:`T`. The initial step size is given in
|
|
Packit |
67cb25 |
:data:`hstart`. The rest of the arguments follow the syntax and
|
|
Packit |
67cb25 |
semantics of the control functions with same name
|
|
Packit |
67cb25 |
(:code:`gsl_odeiv2_control_*_new`).
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_driver_set_hmin (gsl_odeiv2_driver * d, const double hmin)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The function sets a minimum for allowed step size :data:`hmin` for
|
|
Packit |
67cb25 |
driver :data:`d`. Default value is 0.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_driver_set_hmax (gsl_odeiv2_driver * d, const double hmax)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The function sets a maximum for allowed step size :data:`hmax` for
|
|
Packit |
67cb25 |
driver :data:`d`. Default value is :macro:`GSL_DBL_MAX`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_driver_set_nmax (gsl_odeiv2_driver * d, const unsigned long int nmax)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The function sets a maximum for allowed number of steps :data:`nmax` for
|
|
Packit |
67cb25 |
driver :data:`d`. Default value of 0 sets no limit for steps.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_driver_apply (gsl_odeiv2_driver * d, double * t, const double t1, double y[])
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function evolves the driver system :data:`d` from :data:`t` to
|
|
Packit |
67cb25 |
:data:`t1`. Initially vector :data:`y` should contain the values of
|
|
Packit |
67cb25 |
dependent variables at point :data:`t`. If the function is unable to
|
|
Packit |
67cb25 |
complete the calculation, an error code from
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_evolve_apply` is returned, and :data:`t` and :data:`y`
|
|
Packit |
67cb25 |
contain the values from last successful step.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
If maximum number of steps is reached, a value of :macro:`GSL_EMAXITER`
|
|
Packit |
67cb25 |
is returned. If the step size drops below minimum value, the function
|
|
Packit |
67cb25 |
returns with :macro:`GSL_ENOPROG`. If the user-supplied functions
|
|
Packit |
67cb25 |
defined in the system :data:`sys` returns :macro:`GSL_EBADFUNC`, the
|
|
Packit |
67cb25 |
function returns immediately with the same return code. In this case
|
|
Packit |
67cb25 |
the user must call :func:`gsl_odeiv2_driver_reset` before calling this
|
|
Packit |
67cb25 |
function again.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_driver_apply_fixed_step (gsl_odeiv2_driver * d, double * t, const double h, const unsigned long int n, double y[])
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function evolves the driver system :data:`d` from :data:`t` with
|
|
Packit |
67cb25 |
:data:`n` steps of size :data:`h`. If the function is unable to complete
|
|
Packit |
67cb25 |
the calculation, an error code from
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_evolve_apply_fixed_step` is returned, and :data:`t` and
|
|
Packit |
67cb25 |
:data:`y` contain the values from last successful step.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_driver_reset (gsl_odeiv2_driver * d)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function resets the evolution and stepper objects.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_driver_reset_hstart (gsl_odeiv2_driver * d, const double hstart)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The routine resets the evolution and stepper objects and sets new
|
|
Packit |
67cb25 |
initial step size to :data:`hstart`. This function can be used e.g. to
|
|
Packit |
67cb25 |
change the direction of integration.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_odeiv2_driver_free (gsl_odeiv2_driver * d)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function frees the driver object, and the related evolution,
|
|
Packit |
67cb25 |
stepper and control objects.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Examples
|
|
Packit |
67cb25 |
========
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Van der Pol oscillator, example
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The following program solves the second-order nonlinear Van der Pol
|
|
Packit |
67cb25 |
oscillator equation,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: u''(t) + \mu u'(t) (u(t)^2 - 1) + u(t) = 0
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This can be converted into a first order system suitable for use with
|
|
Packit |
67cb25 |
the routines described in this chapter by introducing a separate
|
|
Packit |
67cb25 |
variable for the velocity, :math:`v = u'(t)`,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: not texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
u' &= v \\
|
|
Packit |
67cb25 |
v' &= -u + \mu v (1-u^2)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
u' = v
|
|
Packit |
67cb25 |
v' = -u + \mu v (1-u^2)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The program begins by defining functions for these derivatives and
|
|
Packit |
67cb25 |
their Jacobian. The main function uses driver level functions to solve
|
|
Packit |
67cb25 |
the problem. The program evolves the solution from :math:`(u, v) = (1, 0)`
|
|
Packit |
67cb25 |
at :math:`t = 0` to :math:`t = 100`. The step-size :math:`h` is
|
|
Packit |
67cb25 |
automatically adjusted by the controller to maintain an absolute
|
|
Packit |
67cb25 |
accuracy of :math:`10^{-6}`
|
|
Packit |
67cb25 |
in the function values :math:`(u, v)`.
|
|
Packit |
67cb25 |
The loop in the example prints the solution at the points
|
|
Packit |
67cb25 |
:math:`t_i = 1, 2, \dots, 100`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. include:: examples/ode-initval.c
|
|
Packit |
67cb25 |
:code:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The user can work with the lower level functions directly, as in
|
|
Packit |
67cb25 |
the following example. In this case an intermediate result is printed
|
|
Packit |
67cb25 |
after each successful step instead of equidistant time points.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. include:: examples/ode-initval-low-level.c
|
|
Packit |
67cb25 |
:code:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
For functions with multiple parameters, the appropriate information
|
|
Packit |
67cb25 |
can be passed in through the :data:`params` argument in
|
|
Packit |
67cb25 |
:type:`gsl_odeiv2_system` definition (:data:`mu` in this example) by using
|
|
Packit |
67cb25 |
a pointer to a struct.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. figure:: /images/ode-vdp.png
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Numerical solution of the Van der Pol oscillator equation
|
|
Packit |
67cb25 |
using Prince-Dormand 8th order Runge-Kutta.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
It is also possible to work with a non-adaptive integrator, using only
|
|
Packit |
67cb25 |
the stepping function itself,
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_driver_apply_fixed_step` or
|
|
Packit |
67cb25 |
:func:`gsl_odeiv2_evolve_apply_fixed_step`. The following program uses
|
|
Packit |
67cb25 |
the driver level function, with fourth-order
|
|
Packit |
67cb25 |
Runge-Kutta stepping function with a fixed stepsize of
|
|
Packit |
67cb25 |
0.001.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. include:: examples/odefixed.c
|
|
Packit |
67cb25 |
:code:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
References and Further Reading
|
|
Packit |
67cb25 |
==============================
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* Ascher, U.M., Petzold, L.R., *Computer Methods for Ordinary
|
|
Packit |
67cb25 |
Differential and Differential-Algebraic Equations*, SIAM,
|
|
Packit |
67cb25 |
Philadelphia, 1998.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* Hairer, E., Norsett, S. P., Wanner, G., *Solving Ordinary Differential
|
|
Packit |
67cb25 |
Equations I: Nonstiff Problems*, Springer, Berlin, 1993.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* Hairer, E., Wanner, G., *Solving Ordinary Differential
|
|
Packit |
67cb25 |
Equations II: Stiff and Differential-Algebraic Problems*,
|
|
Packit |
67cb25 |
Springer, Berlin, 1996.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Many of the basic Runge-Kutta formulas can be found in the Handbook of
|
|
Packit |
67cb25 |
Mathematical Functions,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* Abramowitz & Stegun (eds.), *Handbook of Mathematical Functions*,
|
|
Packit |
67cb25 |
Section 25.5.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The implicit Bulirsch-Stoer algorithm :code:`bsimp` is described in the
|
|
Packit |
67cb25 |
following paper,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* G. Bader and P. Deuflhard, "A Semi-Implicit Mid-Point Rule for Stiff
|
|
Packit |
67cb25 |
Systems of Ordinary Differential Equations.", Numer.: Math.: 41, 373--398,
|
|
Packit |
67cb25 |
1983.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The Adams and BDF multistep methods :code:`msadams` and :code:`msbdf`
|
|
Packit |
67cb25 |
are based on the following articles,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* G. D. Byrne and A. C. Hindmarsh, "A Polyalgorithm for the
|
|
Packit |
67cb25 |
Numerical Solution of Ordinary Differential Equations.",
|
|
Packit |
67cb25 |
ACM Trans. Math. Software, 1, 71--96, 1975.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* P. N. Brown, G. D. Byrne and A. C. Hindmarsh, "VODE: A
|
|
Packit |
67cb25 |
Variable-coefficient ODE Solver.", SIAM J. Sci. Stat. Comput. 10,
|
|
Packit |
67cb25 |
1038--1051, 1989.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* A. C. Hindmarsh, P. N. Brown, K. E. Grant, S. L. Lee, R. Serban,
|
|
Packit |
67cb25 |
D. E. Shumaker and C. S. Woodward, "SUNDIALS: Suite of
|
|
Packit |
67cb25 |
Nonlinear and Differential/Algebraic Equation Solvers.", ACM
|
|
Packit |
67cb25 |
Trans. Math. Software 31, 363--396, 2005.
|