# low_storage_rk¶

Typically, implementation of a Runge-Kutta method requires $$s \times N$$ memory locations, where $$s$$ is the number of stages of the method and $$N$$ is the number of unknowns. Certain classes of Runge-Kutta methods can be implemented using substantially less memory, by taking advantage of special relations among the coefficients. Three main classes have been developed in the literature:

• 2N (Williamson) methods
• 2R (van der Houwen/Wray) methods
• 2S methods

Each of these classes requires only $$2\times N$$ memory locations. Additional methods have been developed that use more than two memory locations per unknown but still provide a substantial savings over traditional methods. These are referred to as, e.g., 3S, 3R, 4R, and so forth. For a review of low-storage methods, see [ketcheson2010] .

In NodePy, low-storage methods are a subclass of explicit Runge-Kutta methods (and/or explicit Runge-Kutta pairs). In addition to the usual properties, they possess arrays of low-storage coefficients. They override the generic RK implementation of time-stepping and use special memory-efficient implementations instead. It should be noted that, although these low-storage algorithms are implemented, due to Python language restrictions an extra intermediate copy of the solution array will be created. Thus the implementation in NodePy is not really minimum-storage.

At the moment, the following classes are implemented:

• 2S : Methods using two registers (under Ketcheson’s assumption)

• 2S* : Methods using two registers, one of which retains the previous

step solution

• 3S* : Methods using three registers, one of which retains the previous

step solution

• 2S embedded pairs

• 3S* embedded pairs

• 2R embedded pairs

• 3R embedded pairs

Examples:

>>> from nodepy import lsrk, ivp
>>> print(myrk)
DDAS4()7[2R]
2R Method of Tselios \& Simos (2007)
0.000 |
0.336 | 0.336
0.286 | 0.094  0.192
0.745 | 0.094  0.150  0.501
0.639 | 0.094  0.150  0.285  0.110
0.724 | 0.094  0.150  0.285 -0.122  0.317
0.911 | 0.094  0.150  0.285 -0.122  0.061  0.444
_______|_________________________________________________
| 0.094  0.150  0.285 -0.122  0.061  0.346  0.187

>>> rk58.name
'RK5(4)8[3R+]C'
>>> rk58.order()
5
>>> t,u = rk58(problem)
>>> u[-1]
array([-1.40278844,  1.23080499])
>>> import nodepy
>>> rk2S.order()
5
>>> rk2S.embedded_method.order()
4
>>> rk3S.principal_error_norm()
0.00035742076...

class nodepy.low_storage_rk.TwoRRungeKuttaMethod(a, b, bhat=None, regs=2, name='2R Runge-Kutta Method', description='', shortname='LSRK2R', order=None)[source]

Class for 2R/3R/4R low-storage Runge-Kutta pairs.

These were developed by van der Houwen, Wray, and Kennedy et. al. Only 2R and 3R methods have been implemented so far.

References:

Initializes the 2R method by storing the low-storage coefficients and computing the Butcher array.

The coefficients should be specified as follows:

• For all methods, the weights $$b$$ are used to fill in the appropriate entries in $$A$$.
• For 2R methods, a is a vector of length $$s-1$$ containing the first subdiagonal of $$A$$
• For 3R methods, a is a $$2\times s-1$$ array whose first row contains the first subdiagonal of $$A$$ and whose second row contains the second subdiagonal of $$A$$.
class nodepy.low_storage_rk.TwoSRungeKuttaMethod(betavec, gamma, delta, lstype, name='Low-storage Runge-Kutta Method', description='', shortname='LSRK2S', order=None)[source]

Class for low-storage Runge-Kutta methods that use Ketcheson’s assumption (2S, 2S*, and 3S* methods).

This class cannot be used for embedded pairs. Use the class TwoSRungeKuttaPair instead.

The low-storage coefficient arrays $$eta,\gamma,\delta$$ follow the notation of [ketcheson2010] .

The argument lstype must be one of the following values:

• 2S
• 2S*
• 3S*

Initializes the low-storage method by storing the low-storage coefficients and computing the Butcher coefficients.

class nodepy.low_storage_rk.TwoSRungeKuttaPair(betavec, gamma, delta, lstype, bhat=None, name='Low-storage Runge-Kutta Pair', description='', shortname='LSRK2S', order=None)[source]

Class for low-storage embedded Runge-Kutta pairs that use Ketcheson’s assumption (2S, 2S*, and 3S* methods).

This class is only for embedded pairs. Use the class TwoSRungeKuttaMethod for single 2S/3S methods.

The low-storage coefficient arrays $$eta,\gamma,\delta$$ follow the notation of [ketcheson2010] .

The argument lstype must be one of the following values:

• 2S
• 2S*
• 2S_pair
• 3S*
• 3S*_pair

The 2S/2S*/3S* classes do not need an extra register for the error estimate, while the 2S_pair/3S_pair methods do.

Initializes the low-storage pair by storing the low-storage coefficients and computing the Butcher coefficients.

nodepy.low_storage_rk.load_LSRK(file, lstype='2S', has_emb=False)[source]

Load low storage methods of the types 2S/2S*/3S*/2S_pair/3S_pair from a file containing the low-storage coefficient arrays. If has_emb=True, the method has an embedded method that requires an extra register.

The use of both _pair and has_emb seems redundant; this should be corrected in the future.

nodepy.low_storage_rk.load_LSRK_RKOPT(file, lstype='2S', has_emb=False)[source]

Load low storage methods of the types 2S/2S*/3S*/2S_pair/3S_pair from a file containing the low-storage coefficient arrays. Such a file is usually written by RK-opt (see https://github.com/ketch/RK-opt).

nodepy.low_storage_rk.load_2R(name)[source]

Loads 2R low-storage methods from the literature.