MATHEMATICA 教程

# NDSolve 方法的插件框架

## 引言

NDSolve 所设置的控制机制使用户能够自定义数值积分算法并将其作为规范用于 NDSolve 的选项 Method.

NDSolve 以面向对象的方式对它的数值算法以及所需信息进行访问. 在数值积分的每一步，NDSolve 以一种能够根据需要保存私有数据的形式将方法保存起来.

NDSolve 不直接对与算法相关的数据进行访问，因此用户可以以任何方便或高效使用的形式保留所需的信息. 可能保存在私有数据中的算法和信息只能通过该算法对象的方法函数才能访问.The key interaction between a method algorithm object and NDSolve is through a function.

 obj["Step"[inputs]] attempt to take a single time step using the numerical algorithm

Required function used by NDSolve.

The following is a list of important properties of the method and its function that should be defined.

 obj["StepInputs"] the list of input arguments that the step function should be given obj["StepOutput"] the list of outputs that the step function will return obj["StepMode"] set to the step mode obj["DifferenceOrder"] set to the current asymptotic difference order of the algorithm

Properties that should be defined for using a method algorithm object obj in NDSolve.

The table below gives specifications that can be used for step inputs and/or outputs.

 short name full name component "F" "Function" the function given the right-hand side of the ODE system or the residual for a DAE system "T" "Time" current time "H" "TimeStep" time step "X" "DependentVariables" current values of dependent variables other than discrete "XI" "DependentVariablesIncrement" such that gives the values of the dependent variables after the step; if is given as \$Failed, then the step is rejected and will be recomputed (the time step returned should be smaller) "XP" "TemporalDerivatives" the time derivatives of the dependent variables "D" "DiscreteVariables" the discrete variables that take on a continuous range of values "ID" "IndexedDiscreteVariables" the discrete variables that take on a finite set of values "P" "Parameters" the parameters other than ones for which sensitivity is being computed "SP" "SensitivityParameters" the parameters for which sensitivity is being computed "SD" "SolutionData" the solution data list "Obj" "MethodObject" a new setting for obj that will be used for the next step "State" "StateData" the object

Step input and output specifications.

The solution data is the list of values with components relating to different variable types. The solution data in the active direction can be obtained from an object state using . Many of the specifications listed above correspond directly to solution data components.

For input, the specification for the function should be given with the arguments it will be given. These arguments should be solution data components. All can be used to indicate that all arguments used by NDSolve should be expected.

For output, if the method only returns some of the values in some cases (e.g. the method object does not change every step) then you can use Null for any output except the increment to indicate that it should not be used.

## 经典 Runge-Kutta

This specifies for NDSolve the inputs and outputs for the step function. The template is used to make this work for all instances of CRK4 method objects.
This is an equivalent specification using the full names.

 Out[8]=

 Out[9]=

 Out[11]=

 InitializeMethod[Algorithm Identifier,stepmode,state,Algorithm Options] NDSolve 在首次使用一种用于特定积分的算法时，进行初始化所计算的表达式，根据方法是否在一个步进控制程序或另一种方法框架内被调用，stepmode 是 Automatic 或 ；state 是由 NDSolve 所用的 对象， 是一个包含特别指定使用某种特定算法的任何选项的列表，例如 Method->{Algorithm Identifier, opts} 中的 {opts} Algorithm Identifier/:InitializeMethod[Algorithm Identifier,stepmode_,rhs_NumericalFunction,state_NDSolveState,{opts___?OptionQ}]:=initialization 使得规则与算法相联系的初始化定义，initialization 应该返回一个 形式的算法对象

NDSolve 中初始化算法.

## Crank-Nicolson

This is an example of how to set up an implicit method. To solve the system of ODEs , the scheme for a time step of size is , where and . In general, for nonlinear , the equations need to be solved with Newton iteration.

Instead of using a true Newton iteration where the Jacobian is updated at each step, the Jacobian will be computed once and its LU decomposition will be used repeatedly to solve the linear equations. As long as time steps are not too large, this will generally converge as well as the full Newton method and each iteration beyond the first is substantially cheaper.

To avoid possible problems with the Newton iteration not converging, the method will be set up to take method options that control the maximum number of iterations and the convergence tolerance.

Define options and method initialization for the Crank-Nicolson method.
Define the step function.
This specifies for NDSolve the inputs, outputs, difference order, and step mode for the Crank-Nicolson method.
Here is how the method can be called with option settings.
 Out[21]=

For a linear problem, the solution is given by the first iteration. However, for a nonlinear problem, convergence may take longer.

This fails because the nonlinear problem cannot be expected to converge in 1 iteration with such large time steps.
 Out[22]=
With more iterations the solution is successful.
 Out[23]=

Since the Crank-Nicolson method is usually considered regarding solving PDEs, here is an example of the method solving the wave equation. Since this is a linear equation, convergence occurs in 1 iteration so the method is quite fast.

This uses the Crank-Nicolson method to solve the wave equation with periodic boundary conditions.
 Out[24]=
A density plot of the solution.
 Out[25]=

## Invoking Another Method

One of the strengths of the NDSolve framework comes from the capability to nest methods in various ways.

 NDSolve`InitializeSubmethod[caller,submspec,stepmode,sd,f,state] initializes the submethod specified by Method->submspec in the initialization of the method caller; stepmode, sd, f, and state are as in InitializeMethod NDSolve`InvokeMethod[submobj,f,h,sd,state] invoke the submethod with method object submobj with function f, time step h, solution data sd, and object state, returning a list where hnew is the new time step, sdnew is the solution data at the step end with unchanged components set to Null, and submobjnew is the new submethod object

Using submethods.

InitializeSubmethod effectively calls after separating out the method name from any suboptions that are given. If successful, it returns the method object that you can later use in InvokeMethod.

InvokeMethod effectively constructs a function for the submethod. Since the arguments for the function are specified by the specification for the submethod, the function f given to InvokeMethod should have all the arguments used by NDSolve and can be specified in the caller specification by "Function"[All]. Note that for built-in methods, there may not be an explicit function and InvokeMethod handles these using efficient internal code. The result returned by InvokeMethod is always constructed from the submethod's actual output to match a of .

Here is an example that simply calls a submethod to provide simple monitoring of the steps and difference order.

Define the method options and the initialization for the method.
The step function for the method simply invokes the submethod and applies the monitor function to the result and the difference order.
Set the inputs and outputs.
Derive all other properties from the submethod.
Use the method.
 Out[7]=

For a more complicated integration the method can be used with Reap to collect data.

Collect the logarithm of the step size and difference order as a function of time for integrating the Van der Pol oscillator and plot the solution.
 Out[9]=
Show the logarithm of the step size and the difference order for steps near the sudden change.
 Out[10]=

NDSolve 框架而言，写一个自动控制步进的算法并非更难，但误差估计和确定适当步长的要求通常使得这一任务的难度无论从数学角度还是从编程角度来说大为增加. 下面的例子是对 Shampine 和 Watts 的 Fortran DEABM 代码的局部改编，以放入 NDSolve 框架. 根据 [SG75] 中所介绍的判据，该算法适应性地选择步长和阶数.

 Out[41]=

 Out[42]=

 Out[45]=

 Out[46]=

## 教程专集教程专集

New to Mathematica? Find your learning path »
Have a question? Ask support »