«  linear_multistep_method   ::   Contents

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 [Ket10] .

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

  • 2N methods pairs

  • 2R methods and embedded pairs

  • 3R methods and embedded pairs

Examples:

>>> from nodepy import lsrk, ivp
>>> myrk = lsrk.load_low_storage('DDAS47')
>>> 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 = lsrk.load_low_storage('RK58[3R]C').__num__()
>>> rk58.name
'RK5(4)8[3R+]C'
>>> rk58.order()
5
>>> problem = ivp.load_ivp('vdp')
>>> t,u = rk58(problem)
>>> u[-1]
array([-1.40278844,  1.23080499])
>>> import nodepy
>>> rk2S = lsrk.load_LSRK("{}/method_coefficients/58-2S_acc.txt".format(nodepy.__path__[0]),has_emb=True)
>>> rk2S.order()
5
>>> rk2S.embedded_method.order()
4
>>> rk3S = lsrk.load_LSRK(nodepy.__path__[0]+'/method_coefficients/58-3Sstar_acc.txt',lstype='3S*')
>>> rk3S.principal_error_norm() 
0.00035742076...
class nodepy.low_storage_rk.TwoNRungeKuttaMethod(coef_a, coef_b, name='2N Runge-Kutta Method', description='', shortname='LSRK2N', order=None)[source]

Class for 2N low-storage Runge-Kutta methods.

These were developed by Williamson, and Carpenter & Kennedy.

References:

Examples:

>>> from nodepy import lsrk
>>> erk = lsrk.load_low_storage("RK45[2N]")
>>> print(erk)
RK45[2N]
2N Method of Carpenter \& Kennedy (1994)
 0     |
 0.150 | 0.150
 0.370 |-0.009  0.379
 0.622 | 0.401 -0.602  0.823
 0.958 |-0.190  0.814 -0.365  0.699
_______|___________________________________
       | 0.006  0.345  0.029  0.468  0.153

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

The coefficients should be specified as follows:

  • The low-storage coefficients are \(coef_a\) and \(coef_b\).

  • The Butcher and Shu-Osher coefficients are computed from the low-storage coefficients.

nodepy.low_storage_rk.twoR2butcher(a, b, regs)[source]
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.TwoRRungeKuttaPair(a, b, bhat=None, regs=2, name='2R Runge-Kutta Method', description='', shortname='LSRK2R', order=(None, 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 [Ket10].

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 [Ket10] .

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_low_storage(which='All')[source]

Loads low-storage methods from the literature.

«  linear_multistep_method   ::   Contents