Differential Equations
Mathwrist C++ API Series
Abstract
This document details the C++ programming interface to solve differential equations in Mathwrist’s Numerical Programming Library (NPL). We target on the initial value problems of ordinary differential equations (ODE) and initial/boundary value problems of linear parabolic partial differential equations (PDE). Please refer to our differential equation white paper for technical overview.
1 Ordinary Differential Equation
1.1 General ODE Interface
The common interface class ODE of -dimensional ODE system
(1) |
is defined in header file “ode.h”. Users need supply a derived class under the ODE interface and implement the following pure virtual functions. This interface doesn’t assume linearity on an actual ODE problem. Users can choose an explicit method to solve this general form of problems.
1.1.1 Dimension Size
Description:
It returns the dimension size of the ODE system, which is the number of unknown variables to be solved simultaneously.
1.1.2 Start Time and End Time
Description:
It returns the ODE system start time and end time respectively.
1.1.3 Compute
Description:
It computes the derivative as of time , given the values of . Both parameters _y and _fty are pointers to -element buffer that are managed by NPL ODE solvers. Pointer _y stores the values of . On return, parameter _fty holds the values of .
1.2 Linear ODE Interface
A system of ODE is linear if it has the form , where is a matrix that doesn’t depend on . is the external source function. A homogeneous ODE system has .
Linear ODEs can be solved using implicit methods in NPL for better numerical stability. Essentially, we solve a linear system (2) at each time step, see our differential equation white paper for details. In order to use implicit methods, users need supply a concrete class derived from the ODE_Linear interface class and implement its pure virtual functions. Class “ODE_Linear” is also defined in header file “ode.h”.
(2) |
1.2.1 Homogeneity
Description:
Return true if the ODE is homogeneous, .
1.2.2 Compact Size of
Description:
very often is a sparse matrix. Users may choose a compact storage to represent and specify the total number of elements of in their compact form. NPL solvers then use this information to allocate enough memory to store . If is constant, a derived class may return the size of to be 0 and cache the constant matrix internally.
1.2.3 Compute and
Description:
This function evaluates and as of time and stores the result to provided buffer pointers _A and _s.
Parameters _A points to a memory buffer managed by NPL solvers. _A is allocated to store the number of elements specified by size_A() function. When size_A() returns 0, pointer _A will be a null pointer. In which case, NPL assumes is handled internally in a derived class.
When the ODE is homogeneous, parameter _s is passed as a null pointer and can be ignored. Otherwise, it points to a memory buffer managed by NPL solvers. It should store -element of source function values on return.
1.2.4 Compute
Description:
This function asks the concrete linear ODE class to compute with given , and . Parameters _A and _s are same as that of the update(t, _A, _s) function. Parameter _y points to a buffer that stores -element of values. Parameter _yp is pointer to -element buffer that stores the result on return.
1.2.5 Solve Linear System (2)
Description:
This function requires a concrete linear ODE derived class to solve linear system (2) using its compact storage that is passed from parameter _A. Parameter t is the time variable value. Parameter h is ODE solver’s time marching step length. Parameter _y holds the -element right hand side vector on call. It should store the solution vector on return.
1.3 IDeC Solver
Mathwrist NPL uses an Iterative Deferred Correction (IDeC) framework to solve all ODE problems. ODE_IDeC solver class is defined in header file “ode_idec.h”.
1.3.1 Method of Choice
Description
This ODE_IDeC::Method enumeration list is a member of class ODE_IDeC It gives users different combination choices of base methods and IDeC methods. A base method starts the process with an first-order or second order approximation of . IDeC methods then raise the accuracy order at each error correction iteration.
Enumeration | Base Method | IDeC | ODE Class |
---|---|---|---|
O1_CLASSIC_EXPLICIT | explicit Euler | classic | General |
O2_CLASSIC_EXPLICIT | Adams-Bashforth 3-step explicit | classic | General |
O1_SPECTRAL_EXPLICIT | explicit Euler | spectral | General |
O2_SPECTRAL_EXPLICIT | Adams-Bashforth 3-step explicit | spectral | General |
O1_CLASSIC_IMPLICIT | implicit Euler | classic | Linear |
O1_SPECTRAL_IMPLICIT | implicit Euler | spectral | Linear |
1.3.2 Constructor
Description:
Construct an IDeC solver object given a method of choice, degree of interpolation/approximation polynomial and number of error correction iterations.
Parameter m is one of the ODE_IDeC::Method enumeration item. It specifies what base method and IDeC method are used.
Parameter p specifies the degree of interpolation polynomial used in class IDeC method or the degree of Chebyshev approximation polynomial in spectral IDeC. REQUIRED: in classic IDeC and in spectral IDeC.
Parameter q specifies the number of error correction iterations. implies no error correction is applied, in which case the approximation result from the base method is immediately returned. REQUIRED: .
1.3.3 Solver Operator
Description:
Solve an ODE problem by iterative deferred correction method.
Parameter o is an object of concrete ODE problems supplied by the user. It is derived from the ODE base class for problems to be solved with explicit methods, or derived from ODE_Linear class if implicit methods are desired.
Parameter N is the suggested number of time discretization steps. For problems to be solved with explicit methods, time marching step size needs be fine enough to retain numerical stability.
Parameter y0 is a -elment buffer managed by the caller to provide initial values of .
Parameter yT is a -element buffer managed by the caller. It stores the numerical solution on return.
2 Parabolic Partial Differential Equation
2.1 Parabolic PDE Interface
We consider 1-d linear parabolic PDE initial and boundary value problems in the following form,
(3) | |||
(4) | |||
(5) | |||
(6) |
, where the boundary conditions (6) are expressed as the general Robin boundary conditions. The exact behavior of linear parabolic PDEs are abstracted to a set of interfaces defined in class PDEParabolic1D in “pde_parabolic.h” header file.
Multiple problems that are governed by the same PDE (3) but subject to different initial value (4) and boundary conditions (6) or different source function in (3) can be solved simultaneously.
2.1.1 Boundary Conditions
Description:
The nested class PDEParabolic1D::BoundaryCondition represents boundary conditions in the general Robin boundary condition form. For Dirichlet boundary conditions, , . For Neumann boundary conditions, and .
Users need implement the eval() pure virtual function in a derived class. Parameter t is the time variable. Parameter x is the boundary state value either or . Parameter ip is the index ID of the -th problem when multiple problems are solved together.
2.1.2 Initial Values
Description:
The nested struct PDEParabolic1D::InitialValueFunct is designed to serve as both the initial value function in (4) and the update function to support events and resets. We will describe handling events and resets in a separate section.
Users need implement the eval() pure virtual function in a derived class, where
-
•
Parameter x is a -element buffer of discretized spatial states that are ordered from lower boundary to high boundary .
-
•
Parameter t is the current time . If is greater than the PDE start time , parameter v_x holds the PDE solution computed by a solver up to this current time. If the actual problem requires to be updated at events or resets, v_x should be updated on the return of this function call. The updated then serves as the new initial values for on-going process.
-
•
Parameter event_id indicates if the current time is on one of the events specified by the user. If so, in a user supplied event time array event_time. Otherwise, event_id is passed as a negative value.
-
•
Parameter v_x is a matrix in-out parameter, where is the number of problems to be solved simultaneously subject to the same PDE, is the number of spatial discretization states. On call, it holds the PDE solution computed by a solver up to time . On return, it receives updated initial values.
2.1.3 Source Function
Description:
The nested struct PDEParabolic1D::SourceFunct represents the external source function in (3). Users need implement the add() pure virtual function in a derived class with the following parameters.
-
•
Parameter x is a pointer to the -element buffer of discretized spatial state variable .
-
•
Parameter n specifies the number of spatial states.
-
•
Parameter t is the current time to evaluate source function .
-
•
Parameter ip indicates the source function is to be evaluated for the -th problem when multiple problems governed by the same PDE are solved together.
-
•
Parameter c is a scalar quantity to be multiplied to .
-
•
Parameter r is a pointer to a -element vector where the source function vector are scaled by and then added to , NOT assigned. In other words, vector on function return.
2.1.4 Specification
Description:
The nested struct PDEParabolic::Specification groups a list of control setting to specify how the PDE should be solved.
Data member event_t holds important event time points that we want a PDE solver to make a step at .
Data member n_problems is the number of problems to be solved together. These problems all follow the same PDE and differ from each other on initial values, boundary conditions and source functions.
Data member t_smooth_initial_values is a time , , where and are the PDE start and end time respectively. If such a time is provided, we will solve the problem in two stages. In an initial smoothing stage , a 4-th order accurate finite difference method is used to smooth out initial values from to . A PDE solver then takes as the initial value for the subsequent stage .
Boolean data member reset_initial_value_at_events is true if we want the solver to reset initial values at those event times. At an event time , the initial value function supplied by a user is called by the PDE solver. Inside the initial value function, users may update the solution , which becomes the new initial value to continue the process.
Boolean data member reset_initial_value_at_steps is true if we want the solver to reset initial values at each discretization time step, which effectively treats each step as a new initial value problem. At each time discretization step , user supplied initial value function is called to update .
Boolean data member stop_at_last_event instructs a PDE solver to stop at the last event time. Otherwise the solver will run all the way to PDE end time .
2.1.5 Observation
Description:
The nested struct PDEParabolic1D::Observation is a helper struct for users and NPL internally to mark observation points on PDE mesh grids, i.e. used in model calibration. Data members t and x are the observation time value and state variable value . Data member range_v allows users to specify the observed value range.
2.1.6 Control Function
Description:
The nest struct PDEParabolic1D::Control is an interface for advanced use of PDE solvers. Function could be based on a mathematical model with model parameter . Given some observation data , we could calibrate model parameter by formulating an optimal control problem, for example,
2.1.7 Domain Query
Description:
The rectangular domain of function can be queried by the following PDEParabolic1D class member functions:
-
1.
Returns the lower state boundary .
-
2.
Returns the upper state boundary .
-
3.
Returns the PDE start time .
-
4.
Returns the PDE end time .
2.1.8 Coefficient Function
Description:
Users need derive from PDEParabolic1D interface class and implement this coefficient() pure virtual member function to evaluate coefficient functions , and that appears in (3).
Parameter t is the value of time variable . Parameter x is a pointer to -element buffer of discretized states. Parameter n_x specifies the number of states in the discretization buffer x.
Parameter _ftx, _gtx and _htx each is a pointer to -element buffer to store , and on function return.
For efficiency, an concrete derived class doesn’t have to fill the content of _ftx, _gtx and _htx by zero if the corresponding differential term doesn’t exist in (3). Instead, it could leave the content not touched.
2.2 Crank-Nicolson Method
Solver class PDEParabolic_CN implements Crank-Nicolson finite difference method in “pde_parabolio_cn.h” header file.
2.2.1 Constructor
Description:
Create a solver object with given discretization settings. Parameter pde is an object of user derived PDE class under PDEParabolic1D base class. Parameter dx suggests the spatial discretization step size. Parameter dt suggests the time dimension discretization step size.
2.2.2 Query Functions
Description:
-
1.
Set the implicitness parameter in the general different equation form that is documented in Mathwrist’s white paper. Crank-Nicolson method should set . or 1 is effectively a fully explicit or a fully implicit method respectively.
-
2.
Return the implicitness parameter used by the solver.
-
3.
Return an object reference to the PDE problem to be solved.
-
4.
Return a buffer of discretized spatial states that is used by the solver.
-
5.
Return the time step size.
2.2.3 Solver Operator
Description:
Solve number of initial value problems simultaneously using Crank Nicolson method.
Parameter f_t is the initial value funtion. It also serves as the callback function to update at events or resets.
Parameter bc_lo and bc_hi specify the lower and upper boundary conditions respectively.
Parameter s_tx is a pointer to the external source function. Pass nullptr if the PDE is homogeneous.
Parameter spec is a problem specification.
Parameter V a matrix to hold the numerical solutions, where is the number of problems in specification and is the number of discretized states.
2.3 Spectral Collocation Method
Solver class PDEParabolic_SC implements spectral collocation method in header file “pde_parabolio_spectral.h”.
2.3.1 Constructor
Description:
Parameter pde is an object of user derived PDE class under PDEParabolic1D base class. Parameter n is the degree of Chebyshev approximation polynomial. Parameter q is the number of error correction iterations used in implicit IDeC, REQUIRED: . Parameter dt suggests the time dimension step size used in implicit IDeC.
2.3.2 Query Functions
Description:
-
1.
Return an object reference to the PDE problem to be solved.
-
2.
Return the collocation points in physical states. The number of collocation points is equal to the degree of Chebyshev approximation polynomial + 1.
-
3.
Return the time step size.
-
4.
Return the number of error correction iterations.
2.3.3 Solver Operator
Description:
Solve number of initial value problems simultaneously using spectral collocation method.
Parameter f_t is the initial value funtion. It also serves as the callback function to update at events or resets.
Parameter bc_lo and bc_hi specify the lower and upper boundary conditions respectively.
Parameter s_tx is a pointer to the external source function. Pass nullptr if the PDE is homogeneous.
Parameter spec is a problem specification.
Parameter C is a coefficient matrix on return of the function. It holds Chebyshev expansion coefficients to approximate the solutions, where is the number of problems in specification and is the degree of Chebyshev approximation polynomial. The numerical solution of each problem can be recovered by creating a ChebyshevCurve object with a row of coefficients of C.
2.4 Method of Lines
Solver class PDEParabolic_MoL implements method of lines (finite difference) in header file “pde_parabolio_mol.h”.
2.4.1 Finite Difference Accuracy Order
Description:
Enumeration item PDEParabolic_MoL::O2 and PDEParabolic_MoL::O4 instruct a solver to approximate the partial derivative operator by a 2nd or 4th order accurate finite difference scheme respectively.
2.4.2 Constructor
Description:
Parameter pde is an object of user derived PDE class under PDEParabolic1D base class. Parameter o is the order of finite difference scheme to be used. Parameter q is the number of error correction iterations used in implicit IDeC, REQUIRED: . Parameter dx suggests the finite difference discretization step size in states. Parameter dt suggests the time dimension step size used in implicit IDeC.
2.4.3 Query Functions
Description:
-
1.
Return an object reference to the PDE problem to be solved.
-
2.
Return the order of finite difference scheme.
-
3.
Return a buffer of discretized spatial states that is used by the solver.
-
4.
Return the time step size.
-
5.
Return the number of error correction iterations.
2.4.4 Solver Operator
Description:
Solve number of initial value problems simultaneously using method of lines.
Parameter f_t is the initial value funtion. It also serves as the callback function to update at events or resets.
Parameter bc_lo and bc_hi specify the lower and upper boundary conditions respectively.
Parameter s_tx is a pointer to the external source function. Pass nullptr if the PDE is homogeneous.
Parameter spec is a problem specification.
Parameter V a matrix to hold the numerical solutions, where is the number of problems in specification and is the number of discretized states.