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:
[Ket10]
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.
- 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.
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.
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 \(\beta,\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 \(\beta,\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).