Source code for einsteinpy.integrators.runge_kutta

import warnings

import numpy as np
from scipy import integrate


[docs] class RK4naive: """ Class for Defining Runge-Kutta 4th Order ODE solving method """ def __init__(self, fun, t0, y0, t_bound, stepsize): """ Initialization Parameters ---------- fun : function Should accept t, y as parameters, and return same type as y t0 : float Initial t y0 : ~numpy.array or float Initial y t_bound : float Boundary time - the integration won't continue beyond it. It also determines the direction of the integration. stepsize : float Size of each increment in t """ self.t = t0 self.y = y0 self.t_bound = t_bound self.step_size = stepsize self._fun = fun self.direction = 1 * (self.t_bound >= t0) - 1 * (not self.t_bound < t0)
[docs] def step(self): """ Updates the value of self.t and self.y """ if (self.t >= self.t_bound and self.direction == 1) or ( self.t <= self.t_bound and self.direction == -1 ): warnings.warn("Out of bounds set by t_bound. ", RuntimeWarning) return k0 = self._fun(self.t, self.y) k1 = self._fun( self.t + (self.step_size / 2.0), self.y + (self.step_size / 2.0) * k0 ) k2 = self._fun( self.t + (self.step_size / 2.0), self.y + (self.step_size / 2.0) * k1 ) k3 = self._fun(self.t + self.step_size, self.y + (self.step_size) * k2) self.y = self.y + ((self.step_size / 6.0) * (k0 + 2 * k1 + 2 * k2 + k3)) self.t = self.t + self.step_size
[docs] class RK45(integrate.RK45): """ This Class inherits ~scipy.integrate.RK45 Class """ def __init__(self, fun, t0, y0, t_bound, stepsize, rtol=None, atol=None): """ Initialization Parameters ---------- fun : function Should accept t, y as parameters, and return same type as y t0 : float Initial t y0 : ~numpy.array or float Initial y t_bound : float Boundary time - the integration won't continue beyond it. It also determines the direction of the integration. stepsize : float Size of each increment in t rtol : float Relative tolerance, defaults to 0.2*stepsize atol : float Absolute tolerance, defaults to rtol/0.8e3 """ vectorized = not isinstance(y0, float) self._t_bound = t_bound if rtol is None: rtol = 0.2 * stepsize if atol is None: atol = rtol / 0.8e3 super(RK45, self).__init__( fun=fun, t0=t0, y0=y0, t_bound=self._t_bound, first_step=0.8 * stepsize, max_step=8.0 * stepsize, rtol=rtol, atol=atol, vectorized=vectorized, )
[docs] def step(self): """ Updates the value of self.t and self.y """ try: super(RK45, self).step() except RuntimeError: warnings.warn( "Attempt to step on a failed or finished solver. (Invalid Value or out of bounds of t_bound)", RuntimeWarning, )