Wolfram ResearchPRODUCTSPURCHASEFOR USERSCOMPANYOUR SITES
THIS IS DOCUMENTATION FOR AN OBSOLETE PRODUCT.
SEE THE DOCUMENTATION CENTER FOR THE LATEST INFORMATION.

Documentation  / Mathematica  / Built-in Functions  / Numerical Computation  / Equation Solving  / NDSolve Advanced Documentation  /

Overview

Introduction

The Mathematica function NDSolve is a general numerical differential equation solver. It can handle a wide range of ordinary differential equations (ODEs) as well as some partial differential equations (PDEs). In a system of ordinary differential equations there can be any number of unknown functions , but all of these functions must depend on a single "independent variable" t, which is the same for each function. Partial differential equations involve two or more independent variables. NDSolve can also solve some differential-algebraic equations (DAEs) which are typically a mix of differential and algebraic equations.

Finding numerical solutions to ordinary differential equations.

NDSolve represents solutions for the functions xi as InterpolatingFunction objects. TheInterpolatingFunction objects provide approximations to the xi over the range of values tmin to tmax for the independent variable t. In general, NDSolve finds solutions iteratively. It starts at a particular value of t, then takes a sequence of steps, trying eventually to cover the whole range tmin to tmax. In order to get started, NDSolve has to be given appropriate initial or boundary conditions for the xi and their derivatives. These conditions specify values for ], and perhaps derivatives ], at particular points t. When there is only one t at which conditions are given, the equations and initial conditions are collectively referred to as an initial value problem. A boundary value occurs when there are multiple points t. NDSolve can solve nearly all initial value problems that can symbolically be put in normal form (i.e. are solvable for the highest derivative order), but only linear boundary value problems.

This finds a solution for x with t in the range 0 to 2, using an initial condition for x at t⩵1.

When you use NDSolve, the initial or boundary conditions you give must be sufficient to determine the solutions for the xi completely. When you use to find symbolic solutions to differential equations, you may specify fewer conditions. The reason is that DSolve automatically inserts arbitrary symbolic constants C[i] to represent degrees of freedom associated with initial conditions that you have not specified explicitly. Since NDSolve must give a numerical solution, it cannot represent these kinds of additional degrees of freedom. As a result, you must explicitly give all the initial or boundary conditions that are needed to determine the solution. In a typical case, if you have differential equations with up to n"th" derivatives, then you need to either give initial conditions for up to (n-1)"th" derivatives, or give boundary conditions at n points.

This solves an initial value problem for a second order equation, which requires two conditions, and are given at t ⩵ 0.

This plots the solution obtained.

Here is a simple boundary value problem.

You can use NDSolve to solve systems of coupled differential equations as long as each variable has the appropriate number of conditions.

This finds a numerical solution to a pair of coupled equations.

Here is a plot of both solutions.

You can give initial conditions as equations of any kind. If these equations have multiple solutions, NDSolve will generate multiple solutions.

The initial conditions in this case lead to multiple solutions.

NDSolve::mxst: "Maximum number of \!\(10000\) steps reached at the point \!\(x\) == \!\(1.1160976563722613`*^-8\)."

NDSolve was not able to find the solution for y'[x] ⩵ - Sqrt[y[x]^3], y[0] ⩵ -2 because of problems with the branch cut in the square root function.

This shows the real part of the solutions which NDSolve was able to find. (The upper two solutions are strictly real.)

NDSolve can solve mixed system of differential and algebraic equations, referred to as differential-algebraic equations (DAEs). In fact, the example above is an example of a sort of DAE, where the equations are not expressed explicitly in terms of the derivatives. Typically, however, in DAEs, you are not able to solve for the derivatives at all and the problem must be solved using a different method entirely..

Here is a simple DAE.

NDSolve::ndsz: "At \!\(t\) == \!\(1.6656481721762024`\), step size is effectively zero; singularity or stiff system suspected."

Note that while both of the equations have derivative terms, the variable y appears without any derivatives, so NDSolve issues a warning message. When the usual substitution to convert to first order equations is made, one of the equations does indeed become effectively algebraic.

Also, since y only appears algebraically, it is not necessary to give an initial condition to determine its values. Finding initial conditions which are consistent with DAEs can, in fact be quite difficult. The advanced documentation notebook specifically on has more information.

This shows a plot of the solutions.

From the plot, you can see that the derivative of y is tending to vary arbitrarily fast. Even though it does not explicitly appear in the equations, this condition means that the solver cannot continue further.

Unknown functions in differential equations do not necessarily have to be represented by single symbols. If you have a large number of unknown functions, for example, you will often find it more convenient to give the functions names like x[i] or .

This constructs a set of twenty-five coupled differential equations and initial conditions and solves them.

This actually computes an approximate solution of the heat equation for a rod with constant temperatures at either end of the rod. (For more accurate solutions, you can increase n.)

The result is an approximate solution to the heat equation for a 1-dimensional rod of length 1 with constant temperature maintained at either end. This shows the solutions considered as spatial values as a function of time.

An unknown function can also be specified to have a vector (or matrix) value. The dimensionality of an unknown function is taken from its initial condition. You can mix scalar and vector unknown functions as long as the equations have consistent dimensionality according to the rules of Mathematica arithmetic. The InterpolatingFunction result will give values with the same dimensionality as the unknown function. Using non-scalar variables is very convenient when a system of differential equations is governed by a process that may be difficult or inefficient to express symbolically.

This uses a vector valued unknown function to solve the same system as above.

NDSolve is able to solve some partial differential equations directly when you specify more independent variables.

Finding numerical solutions to partial differential equations.

Here is a solution of the heat equation found directly by NDSolve.

Here is a plot of the solution.

NDSolve currently uses the numerical method of lines to compute solutions to partial differential equations. The method is restricted to problems which can be posed with an initial condition in at least one independent variable. For example, the method cannot solve elliptic PDEs such as Laplace's equation because these require boundary values. For the problems it does solve, the method of lines is quite general, handling systems of PDEs or nonlinearity well, and often quite fast. Details of the method are given in the advanced documentation on .

This finds a numerical solution to a generalization of the nonlinear sine-Gordon equation to two spatial dimensions with periodic boundary conditions.

Here is a plot of the result at t⩵3.

As mentioned above, NDSolve works by taking a sequence of steps in the independent variable t. NDSolve uses an adaptive procedure to determine the size of these steps. In general, if the solution appears to be varying rapidly in a particular region, then NDSolve will reduce the step size so as to be able to better track the solution.

NDSolve allows you to specify the precision or accuracy of result you want. In general, NDSolve makes the steps it takes smaller and smaller until the solution reached satisfies either the AccuracyGoal or the PrecisionGoal you give. The setting for AccuracyGoal effectively determines the absolute error to allow in the solution, while the setting for PrecisionGoal determines the relative error. If you need to track a solution whose value comes close to zero, then you will typically need to increase the setting for AccuracyGoal. By setting AccuracyGoal -> Infinity, you tell NDSolve to use PrecisionGoal only. Generally, AccuracyGoal and PrecisionGoal are used to control the error local to a particular time step. For some differential equations, this error can accumulate, so it is possible that the precision or accuracy of the result at the end of the time interval may be much less than what you might expect from the settings of AccuracyGoal and PrecisionGoal. NDSolve uses the setting you give for WorkingPrecision to determine the precision to use in its internal computations. If you specify large values for AccuracyGoal or PrecisionGoal, then you typically need to give a somewhat larger value for WorkingPrecision. With the default setting of Automatic, AccuracyGoal and PrecisionGoal are both equal to the half of setting for WorkingPrecision.

NDSolve uses error estimates for determining whether it is meeting the specified tolerances. When working with systems of equations, it uses the setting of the option NormFunction->f to combine errors in different components. The norm is scaled in terms of the tolerances, given sol that NDSolve tries to take steps such that where is the component of the error and is the component of the current solution.

This generates a high-precision solution to a differential equation.

Here is the value of the solution at the endpoint.

Through its adaptive procedure, NDSolve is able to solve "stiff" differential equations in which there are several components varying with t at extremely different rates.

NDSolve follows the general procedure of reducing step size until it tracks solutions accurately. There is a problem, however, when the true solution has a singularity. In this case, NDSolve might go on reducing the step size forever, and never terminate. To avoid this problem, the option MaxSteps specifies the maximum number of steps that NDSolve will ever take in attempting to find a solution. For ordinary differential equations, the default setting is MaxSteps -> 10000.

NDSolve stops after taking 10,000 steps.

NDSolve::mxst: "Maximum number of \!\(10000\) steps reached at the point \!\(x\) == \!\(-1.8024722723866666`*^-212\)."

There is in fact a singularity in the solution at x=0.

The default setting MaxSteps -> 10000 should be sufficient for most equations with smooth solutions. When solutions have a complicated structure, however, you may sometimes have to choose larger settings for MaxSteps. With the setting MaxSteps -> Infinity there is no upper limit on the number of steps used.

NDSolve has several different methods built in for computing solutions as well as a mechanism for adding additional methods. With the default setting Method->Automatic, NDSolve will choose a method which should be appropriate for the differential equations. For example, if the equations have stiffness, implicit methods will be used as needed, or if the equations make a DAE, a special DAE method will be used. In general, it is not possible to determine the nature of solutions to differential equations without actually solving them: thus, the default Automatic methods are good for solving as wide variety of problems, but the one chosen may not be the best on available for your particular problem. Also, you may want to choose methods, such as symplectic integrators, which preserve certain properties of the solution.

Choosing an appropriate method for a particular system can be quite difficult. To complicate it further, many methods have their own settings which can greatly affect solution efficiency and accuracy. Much of this documentation consists of descriptions of methods to give you an idea of when they should be used and how to adjust them to solve particular problems. Furthermore, NDSolve has a mechanism that allows you to define your own methods and still have the equations and results processed by NDSolve just as for the built-in methods.

When NDSolve computes a solution, there are typically three phases. First, the equations are processed, usually into a function which represents the right hand side of the equations in normal form. Next, the function is used to iterate the solution from the initial conditions. Finally, data saved during the iteration procedure is processed into one or more InterpolatingFunctions. Using functions in the NDSolve` context, you can run these steps separately and, more importantly, have more control over the iteration process. The steps are tied by an object which keeps all of the data necessary for solving the differential equations.

Design

Features

Supporting a large number of numerical integration methods for differential equations is a lot of work.

In order to cut down on maintenance and duplication of code common components are shared between methods.

This approach also allows code optimization to be carried out in just a few central routines.

The principal features of the NDSolve framework are:

Uniform design and interface.

Code reuse (common code base).

Objection orientation (method property specification and communication).

Data hiding.

Separation of method initialization phase and run-time computation.

Numerical methods are hierarchical and reentrant.

Uniform treatment of rounding errors (see [HLW02], [SS02] and the references therein).

Vectorized framework based on a generalization of the BLAS model [LAPACK99] using optimized in-place arithmetic.

Many schemes such as ExplicitRungeKutta and ImplicitRungeKutta use a tensor framework that allows families of methods to share one implementation.

All methods are type and precision dynamic.

Plug-in capabilities allow user extensibility and prototyping.

Specialized data structures.

Common time stepping

A common time stepping mechanism is used for all one step methods. The routine handles a number of different criteria including:

step sizes in a numerical integration do not become too small in value - which may happen in solving stiff systems

step sizes do not change sign unexpectedly - which may be a consequence of user programming error

step sizes are not increased after a step rejection

step sizes are not decreased drastically towards the end of an integration

specified (or detected) singularities are handled by restarting the integration

divergence of iterations in implicit methods (e.g. using fixed large step sizes)

unrecoverable integration errors (e.g. numerical exceptions)

rounding error feedback (compensated summation) is particularly advantageous for high order methods or methods that conserve specific quantities during the numerical integration.

Data encapsulation

Each method has its own data object which contains information that is needed for the invocation of the method. This includes, but is not limited to, coefficients, workspaces, step size control parameters, step size acceptance/rejection information, Jacobian matrices. This is a generalization of the ideas used in codes like LSODA ([H83], [P83]).

Method hierarchy

Methods are reentrant and hierarchical, meaning that one method can call another. This is a generalization of the ideas used in the Generic ODE Solving System, Godess (see [O95], [O98] and the references therein) which is implemented in C++.

Initial design

The original method framework design allowed a number of methods to be invoked in the solver.

First revision

This was later extended to allow one method to call another in a sequential fashion, with an arbitrary number of levels of nesting.

The construction of compound integration methods is particularly useful in geometric numerical integration.

Second revision

A more general tree invocation process was required to implement composition methods:

This is an example of a method composed with its adjoint.

Current state

The tree invocation process was extended to allow for a subfield to be solved by each method, instead of the entire vector field.

This example turns up in the ABC flow (see ).

User extensibility

Built-in methods can be used as building blocks for the efficient construction of special purpose (compound) integrators. User defined methods can also be added.

Method classes

Methods such as ExplicitRungeKutta include a number of schemes of different orders. Moreover, alternative coefficient choices can be specified by the user. This is a generalization of the ideas found in RKSUITE [BGS93].

Automatic selection and user controllability

The framework provides automatic step size selection and method order selection. Methods are user configurable via method options.

For example a user can select the class of ExplicitRungeKutta methods and the code will automatically attempt to ascertain the `optimal' order according to problem, the relative and absolute local error tolerances and the initial step size estimate.

Here is a list of options appropriate for ExplicitRungeKutta.

Shared features

These features are not necessarily restricted to NDSolve since they can also be used for other types of numerical methods.

Function evaluation is performed using a NumericalFunction which dynamically changes type as needed, such as when IEEE floating point overflow or underflow occurs. It also calls Mathematica's compiler Compile for efficiency when appropriate.

Jacobian evaluation uses symbolic differentiation or finite difference approximations, including automatic or user specifiable sparsity detection.

Dense linear algebra is based on LAPACK and sparse linear algebra uses special purpose packages such as UMFPACK.

Common subexpressions in the numerical evaluation of the function representing a differential system are detected and collected to avoid repeated work.

Other supporting functionality that has been implemented is described in .

Some basic methods

The following table gives some of the one step methods that have been implemented:

where , I denotes the identity matrix and J denotes the Jacobian matrix

Although the implicit midpoint method has not been implemented as a separate method, it is available through the one stage Guass scheme of the ImplicitRungeKutta method.

Acknowledgements

A number of people have helped in shaping the design and implementation of the methods and framework in NDSolve. We would like to thank them for sharing their experience and their enthusiasm for the project.

Thanks to Giulia Spaletta who collaborated in the development of a number of methods.

Thanks to Alan Hindmarsh for allowing us to use the codes LSODA, CVODE and IDA.

Thanks also to the following people for fruitful discussions: John Butcher, Jeff Cash, Ernst Hairer, Robert McLachlan, Per Christian Moan, Reinout Quispel.

Aspects of the new framework have been presented at various symposia and workshops over the years. We would particularly like to thank the groups at Bergen and Trondheim, Norway and Bari, Italy.

Thanks also to Andrew Hunt of Wolfram Research for a number of stylistic improvements to the documentation.

Robert Knapp and Mark Sofroniou.



Any questions about topics on this page? Click here to get an individual response.Buy NowMore Information


 © 2009 Wolfram Research, Inc.  Terms of Use  Privacy Policy |
Sign up for our newsletter: