def calculate_trajectory_iterator( self, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=True, ): """ Calculate trajectory in manifold according to geodesic equation Yields an iterator Parameters ---------- OdeMethodKwargs : dict, optional Kwargs to be supplied to the ODESolver Dictionary with key 'stepsize' along with a float value is expected Defaults to ``{'stepsize': 1e-3}`` return_cartesian : bool, optional Whether to return calculated values in Cartesian Coordinates Defaults to ``True`` Yields ------ float Affine Parameter, Lambda, where the geodesic equations were evaluated ~numpy.ndarray Numpy array containing [x0, x1, x2, x3, v0, v1, v2, v3] for each Lambda """ ODE = RK45( fun=self.metric.f_vec, t0=0.0, y0=self.state, t_bound=1e300, **OdeMethodKwargs, ) g = self.metric _scr = g.sch_rad * 1.001 while True: if return_cartesian: # Getting the corresponding Conversion superclass # of the differential object conv = type(self.coords).__bases__[0] v = ODE.y vals = conv(v[0], v[1], v[2], v[3], v[5], v[6], v[7]).convert_cartesian(M=g.M, a=g.a) yield ODE.t, np.hstack((vals[:4], v[4], vals[4:])) else: yield ODE.t, ODE.y ODE.step() if ODE.y[1] <= _scr: warnings.warn( "Test particle has reached Schwarzchild Radius. ", RuntimeWarning) break
def calculate_trajectory_iterator( self, start_lambda=0.0, stop_on_singularity=True, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=False, ): """ Calculate trajectory in manifold according to geodesic equation. Yields an iterator. Parameters ---------- start_lambda : float Starting lambda, defaults to 0.0, (lambda ~= t) stop_on_singularity : bool Whether to stop further computation on reaching singularity, defaults to True OdeMethodKwargs : dict Kwargs to be supplied to the ODESolver, defaults to {'stepsize': 1e-3} Dictionary with key 'stepsize' along with an float value is expected. return_cartesian : bool True if coordinates and velocities are required in cartesian coordinates(SI units), defaults to Falsed Yields ------ float proper time ~numpy.ndarray array of [t, x1, x2, x3, velocity_of_time, v1, v2, v3] for each proper time(lambda). """ ODE = RK45( fun=self.f_vec, t0=start_lambda, y0=self.initial_vec, t_bound=1e300, **OdeMethodKwargs ) crossed_event_horizon = False _event_hor = ( kerrnewman_utils.event_horizon(self.M.value, self.a.value, self.Q.value)[0] * 1.001 ) while True: if not return_cartesian: yield ODE.t, ODE.y else: v = ODE.y si_vals = BoyerLindquistConversion( v[1], v[2], v[3], v[5], v[6], v[7], self.a.value ).convert_cartesian() yield ODE.t, np.hstack((v[0], si_vals[:3], v[4], si_vals[3:])) ODE.step() if (not crossed_event_horizon) and (ODE.y[1] <= _event_hor): warnings.warn("particle reached event horizon. ", RuntimeWarning) if stop_on_singularity: break else: crossed_event_horizon = True
def calculate_trajectory_iterator( self, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=True, ): """ Calculate trajectory in manifold according to geodesic equation Yields an iterator Parameters ---------- OdeMethodKwargs : dict, optional Kwargs to be supplied to the ODESolver Dictionary with key 'stepsize' along with a float value is expected Defaults to ``{'stepsize': 1e-3}`` return_cartesian : bool, optional Whether to return calculated values in Cartesian Coordinates Defaults to ``True`` Yields ------ float Affine Parameter, Lambda, where the geodesic equations were evaluated ~numpy.ndarray Numpy array containing [x0, x1, x2, x3, v0, v1, v2, v3] for each Lambda """ ODE = RK45( fun=self.metric.f_vec, t0=0.0, y0=self.init_vec, t_bound=1e300, **OdeMethodKwargs, ) _scr = self.metric.sch_rad * 1.001 while True: if not return_cartesian: yield ODE.t, ODE.y else: conv_coords = { "S": SphericalConversion, "BL": BoyerLindquistConversion, } v = ODE.y si_vals = conv_coords[self.metric.coords]( v[1], v[2], v[3], v[5], v[6], v[7]).convert_cartesian() yield ODE.t, np.hstack((v[0], si_vals[:3], v[4], si_vals[3:])) ODE.step() if ODE.y[1] <= _scr: warnings.warn( "Test particle has reached Schwarzchild Radius. ", RuntimeWarning) break
def calculate_trajectory( self, start_lambda=0.0, end_lambda=10.0, stop_on_singularity=True, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=False, ): """ Calculate trajectory in manifold according to geodesic equation Parameters ---------- start_lambda : float Starting lambda(proper time), defaults to 0.0, (lambda ~= t) end_lamdba : float Lambda(proper time) where iteartions will stop, defaults to 100000 stop_on_singularity : bool Whether to stop further computation on reaching singularity, defaults to True OdeMethodKwargs : dict Kwargs to be supplied to the ODESolver, defaults to {'stepsize': 1e-3} Dictionary with key 'stepsize' along with an float value is expected. return_cartesian : bool True if coordinates and velocities are required in cartesian coordinates(SI units), defaults to False Returns ------- ~numpy.ndarray N-element array containing proper time. ~numpy.ndarray (n,8) shape array of [t, x1, x2, x3, velocity_of_time, v1, v2, v3] for each proper time(lambda). """ vecs = list() lambdas = list() crossed_event_horizon = False ODE = RK45( fun=self.f_vec, t0=start_lambda, y0=self.initial_vec, t_bound=end_lambda, **OdeMethodKwargs )
def calculate_trajectory_iterator( self, start_lambda=0.0, stop_on_singularity=True, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=False, ): """ Calculate trajectory in manifold according to geodesic equation. Yields an iterator. Parameters ---------- start_lambda : float Starting lambda, defaults to 0.0, (lambda ~= t) stop_on_singularity : bool Whether to stop further computation on reaching singularity, defaults to True OdeMethodKwargs : dict Kwargs to be supplied to the ODESolver, defaults to {'stepsize': 1e-3} Dictionary with key 'stepsize' along with an float value is expected. return_cartesian : bool True if coordinates and velocities are required in cartesian coordinates(SI units), defaults to Falsed Yields ------ float proper time ~numpy.ndarray array of [t, x1, x2, x3, velocity_of_time, v1, v2, v3] for each proper time(lambda). """ ODE = RK45( fun=self.f_vec, t0=start_lambda, y0=self.initial_vec, t_bound=1e300, **OdeMethodKwargs )
def calculate_trajectory( self, start_lambda=0.0, end_lambda=10.0, stop_on_singularity=True, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=False, ): """ Calculate trajectory in manifold according to geodesic equation Parameters ---------- start_lambda : float Starting lambda(proper time), defaults to 0, (lambda ~= t) end_lamdba : float Lambda(proper time) where iteartions will stop, defaults to 100000 stop_on_singularity : bool Whether to stop further computation on reaching singularity, defaults to True OdeMethodKwargs : dict Kwargs to be supplied to the ODESolver, defaults to {'stepsize': 1e-3} Dictionary with key 'stepsize' along with an float value is expected. return_cartesian : bool True if coordinates and velocities are required in cartesian coordinates(SI units), defaults to False Returns ------- ~numpy.ndarray N-element array containing proper time. ~numpy.ndarray (n,8) shape array of [t, x1, x2, x3, velocity_of_time, v1, v2, v3] for each proper time(lambda). """ vecs = list() lambdas = list() crossed_event_horizon = False ODE = RK45(fun=self.f_vec, t0=start_lambda, y0=self.initial_vec, t_bound=end_lambda, **OdeMethodKwargs) _event_hor = kerr_utils.event_horizon(self.M.value, self.a.value)[0] * 1.001 while ODE.t < end_lambda: vecs.append(ODE.y) lambdas.append(ODE.t) ODE.step() if (not crossed_event_horizon) and (ODE.y[1] <= _event_hor): warnings.warn("particle reached event horizon. ", RuntimeWarning) if stop_on_singularity: break else: crossed_event_horizon = True vecs, lambdas = np.array(vecs), np.array(lambdas) if not return_cartesian: return lambdas, vecs else: cart_vecs = list() for v in vecs: si_vals = BoyerLindquistConversion( v[1], v[2], v[3], v[5], v[6], v[7], self.a.value).convert_cartesian() cart_vecs.append( np.hstack((v[0], si_vals[:3], v[4], si_vals[3:]))) return lambdas, np.array(cart_vecs)
def calculate_trajectory( self, end_lambda=10.0, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=True, ): """ Calculate trajectory in spacetime, according to Geodesic Equations Parameters ---------- end_lambda : float, optional Affine Parameter, Lambda, where iterations will stop Equivalent to Proper Time for Timelike Geodesics Defaults to ``10`` OdeMethodKwargs : dict, optional Kwargs to be supplied to the ODESolver Dictionary with key 'stepsize' along with a float value is expected Defaults to ``{'stepsize': 1e-3}`` return_cartesian : bool, optional Whether to return calculated values in Cartesian Coordinates Defaults to ``True`` Returns ------- ~numpy.ndarray N-element numpy array containing Lambda, where the geodesic equations were evaluated ~numpy.ndarray (n,8) shape numpy array containing [x0, x1, x2, x3, v0, v1, v2, v3] for each Lambda """ ODE = RK45( fun=self.metric.f_vec, t0=0.0, y0=self.init_vec, t_bound=end_lambda, **OdeMethodKwargs, ) vecs = list() lambdas = list() _scr = self.metric.sch_rad * 1.001 while ODE.t < end_lambda: vecs.append(ODE.y) lambdas.append(ODE.t) ODE.step() if ODE.y[1] <= _scr: warnings.warn( "Test particle has reached Schwarzchild Radius. ", RuntimeWarning) break vecs, lambdas = np.array(vecs), np.array(lambdas) if not return_cartesian: return lambdas, vecs conv_coords = { "S": SphericalConversion, "BL": BoyerLindquistConversion, } cart_vecs = list() for v in vecs: si_vals = conv_coords[self.metric.coords]( v[1], v[2], v[3], v[5], v[6], v[7]).convert_cartesian() cart_vecs.append(np.hstack((v[0], si_vals[:3], v[4], si_vals[3:]))) return lambdas, np.array(cart_vecs)
def calculate_trajectory_iterator( self, start_lambda=0.0, stop_on_singularity=True, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=False, ): """ Calculate trajectory in manifold according to geodesic equation Yields an iterator Parameters ---------- start_lambda : float Starting lambda, defaults to 0.0, (lambda ~= t) stop_on_singularity : bool Whether to stop further computation on reaching singularity, defaults to True OdeMethodKwargs : dict Kwargs to be supplied to the ODESolver, defaults to {'stepsize': 1e-3} Dictionary with key 'stepsize' along with an float value is expected. return_cartesian : bool True if coordinates and velocities are required in cartesian coordinates(SI units), defaults to Falsed Yields ------ tuple (lambda, (8,) shape ~numpy.array of [t, pos1, pos2, pos3, velocity_of_time, vel1, vel2, vel3]) """ singularity_reached = False ODE = RK45(fun=self.f_vec, t0=start_lambda, y0=self.initial_vec, t_bound=1e300, **OdeMethodKwargs) _scr = self.schwarzschild_r.value * 1.001 def yielder_func(): nonlocal singularity_reached while True: if not return_cartesian: yield (ODE.t, ODE.y) else: temp = np.copy(ODE.y) temp[1:4] = BLToCartesian_pos(ODE.y[1:4], self.a) temp[5:8] = BLToCartesian_vel(ODE.y[1:4], ODE.y[5:8], self.a) yield (ODE.t, temp) ODE.step() if (not singularity_reached) and (ODE.y[1] <= _scr): warnings.warn( "r component of position vector reached Schwarzchild Radius. ", RuntimeWarning, ) if stop_on_singularity: break else: singularity_reached = True if return_cartesian: self.units_list = [ u.s, u.m, u.m, u.m, u.one, u.m / u.s, u.m / u.s, u.m / u.s, ] return yielder_func()
def calculate_trajectory( self, start_lambda=0.0, end_lambda=10.0, stop_on_singularity=True, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=False, ): """ Calculate trajectory in manifold according to geodesic equation Parameters ---------- start_lambda : float Starting lambda, defaults to 0.0, (lambda ~= t) end_lamdba : float Lambda where iteartions will stop, defaults to 100000 stop_on_singularity : bool Whether to stop further computation on reaching singularity, defaults to True OdeMethodKwargs : dict Kwargs to be supplied to the ODESolver, defaults to {'stepsize': 1e-3} Dictionary with key 'stepsize' along with an float value is expected. return_cartesian : bool True if coordinates and velocities are required in cartesian coordinates(SI units), defaults to False Returns ------- tuple (~numpy.array of lambda, (n,8) shape ~numpy.array of [t, pos1, pos2, pos3, velocity_of_time, vel1, vel2, vel3]) """ vec_list = list() lambda_list = list() singularity_reached = False ODE = RK45(fun=self.f_vec, t0=start_lambda, y0=self.initial_vec, t_bound=end_lambda, **OdeMethodKwargs) _scr = self.schwarzschild_r.value * 1.001 while ODE.t < end_lambda: vec_list.append(ODE.y) lambda_list.append(ODE.t) ODE.step() if (not singularity_reached) and (ODE.y[1] <= _scr): warnings.warn( "r component of position vector reached Schwarzchild Radius. ", RuntimeWarning, ) if stop_on_singularity: break else: singularity_reached = True def _not_cartesian(): return (np.array(lambda_list), np.array(vec_list)) def _cartesian(): self.units_list = [ u.s, u.m, u.m, u.m, u.one, u.m / u.s, u.m / u.s, u.m / u.s, ] return (np.array(lambda_list), BL2C_8dim(np.array(vec_list), self.a)) choice_dict = {0: _not_cartesian, 1: _cartesian} return choice_dict[int(return_cartesian)]()
def calculate_trajectory_iterator( self, start_lambda=0.0, stop_on_singularity=True, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=False, ): """ Calculate trajectory in manifold according to geodesic equation. Yields an iterator. Parameters ---------- start_lambda : float Starting lambda, defaults to 0.0, (lambda ~= t) stop_on_singularity : bool Whether to stop further computation on reaching singularity, defaults to True OdeMethodKwargs : dict Kwargs to be supplied to the ODESolver, defaults to {'stepsize': 1e-3} Dictionary with key 'stepsize' along with an float value is expected. return_cartesian : bool True if coordinates and velocities are required in cartesian coordinates(SI units), defaults to Falsed Yields ------ float proper time ~numpy.ndarray array of [t, x1, x2, x3, velocity_of_time, v1, v2, v3] for each proper time(lambda). """ ODE = RK45(fun=self.f_vec, t0=start_lambda, y0=self.initial_vec, t_bound=1e300, **OdeMethodKwargs) singularity_reached = False _scr = self.scr.value * 1.001 while True: if not return_cartesian: yield ODE.t, ODE.y else: v = ODE.y si_vals = (BoyerLindquistDifferential( v[1] * u.m, v[2] * u.rad, v[3] * u.rad, v[5] * u.m / u.s, v[6] * u.rad / u.s, v[7] * u.rad / u.s, self.a, ).cartesian_differential().si_values()) yield ODE.t, np.hstack((v[0], si_vals[:3], v[4], si_vals[3:])) ODE.step() if (not singularity_reached) and (ODE.y[1] <= _scr): warnings.warn("particle reached Schwarzschild Radius. ", RuntimeWarning) if stop_on_singularity: break else: singularity_reached = True
def calculate_trajectory( self, start_lambda=0.0, end_lambda=10.0, stop_on_singularity=True, OdeMethodKwargs={"stepsize": 1e-3}, return_cartesian=False, ): """ Calculate trajectory in manifold according to geodesic equation Parameters ---------- start_lambda : float Starting lambda(proper time), defaults to 0, (lambda ~= t) end_lamdba : float Lambda(proper time) where iteartions will stop, defaults to 100000 stop_on_singularity : bool Whether to stop further computation on reaching singularity, defaults to True OdeMethodKwargs : dict Kwargs to be supplied to the ODESolver, defaults to {'stepsize': 1e-3} Dictionary with key 'stepsize' along with an float value is expected. return_cartesian : bool True if coordinates and velocities are required in cartesian coordinates(SI units), defaults to False Returns ------- ~numpy.ndarray N-element array containing proper time. ~numpy.ndarray (n,8) shape array of [t, x1, x2, x3, velocity_of_time, v1, v2, v3] for each proper time(lambda). """ ODE = RK45(fun=self.f_vec, t0=start_lambda, y0=self.initial_vec, t_bound=end_lambda, **OdeMethodKwargs) vecs = list() lambdas = list() singularity_reached = False _scr = self.scr.value * 1.001 while ODE.t < end_lambda: vecs.append(ODE.y) lambdas.append(ODE.t) ODE.step() if (not singularity_reached) and (ODE.y[1] <= _scr): warnings.warn("particle reached Schwarzchild Radius. ", RuntimeWarning) if stop_on_singularity: break else: singularity_reached = True vecs, lambdas = np.array(vecs), np.array(lambdas) if not return_cartesian: return lambdas, vecs else: cart_vecs = list() for v in vecs: si_vals = (SphericalDifferential( v[1] * u.m, v[2] * u.rad, v[3] * u.rad, v[5] * u.m / u.s, v[6] * u.rad / u.s, v[7] * u.rad / u.s, ).cartesian_differential().si_values()) cart_vecs.append( np.hstack((v[0], si_vals[:3], v[4], si_vals[3:]))) return lambdas, np.array(cart_vecs)