def test_event_horizon_for_nonrotating_case(): M = 5e27 a = 0.0 _scr = schwarzschild_radius_dimensionless(M) a1 = kerr_utils.event_horizon(M, a, np.pi / 4) a2 = kerr_utils.event_horizon(M, a, np.pi / 4, "Spherical") assert_allclose(a1, a2, rtol=1e-4, atol=0.0) assert_allclose(a1[0], _scr, rtol=1e-4, atol=0.0)
def test_event_horizon_for_nonrotating_case(): M = 5e27 a = 0.0 _scr = utils.schwarzschild_radius(M * u.kg).value a1 = kerr_utils.event_horizon(_scr, a, np.pi / 4) a2 = kerr_utils.event_horizon(_scr, a, np.pi / 4, "Spherical") assert_allclose(a1, a2, rtol=0.0, atol=1e-5) assert_allclose(a1[0], _scr, rtol=0.0, atol=1e-5)
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 = kerr_utils.event_horizon(self.M.value, self.a.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( 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)
M = 4e30 scr = schwarzschild_radius(M * u.kg).value # for nearly maximally rotating black hole a1 = 0.499999 * scr # for ordinary black hole a2 = 0.3 * scr # In[ ]: ergo1, ergo2, hori1, hori2 = list(), list(), list(), list() thetas = np.linspace(0, np.pi, 720) for t in thetas: ergo1.append(kerr_utils.radius_ergosphere(M, a1, t, "Spherical")) ergo2.append(kerr_utils.radius_ergosphere(M, a2, t, "Spherical")) hori1.append(kerr_utils.event_horizon(M, a1, t, "Spherical")) hori2.append(kerr_utils.event_horizon(M, a2, t, "Spherical")) ergo1, ergo2, hori1, hori2 = np.array(ergo1), np.array(ergo2), np.array( hori1), np.array(hori2) # In[ ]: Xe1, Ye1 = ergo1[:, 0] * np.sin(ergo1[:, 1]), ergo1[:, 0] * np.cos(ergo1[:, 1]) Xh1, Yh1 = hori1[:, 0] * np.sin(hori1[:, 1]), hori1[:, 0] * np.cos(hori1[:, 1]) Xe2, Ye2 = ergo2[:, 0] * np.sin(ergo2[:, 1]), ergo2[:, 0] * np.cos(ergo2[:, 1]) Xh2, Yh2 = hori2[:, 0] * np.sin(hori2[:, 1]), hori2[:, 0] * np.cos(hori2[:, 1]) # In[ ]: Xe1
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 _event_hor = kerr_utils.event_horizon(self.M.value, self.a)[0] * 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] <= _event_hor): warnings.warn( "r component of position vector reached event horizon. ", 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 _event_hor = kerr_utils.event_horizon(self.M.value, self.a)[0] * 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] <= _event_hor): warnings.warn( "r component of position vector reached event horizon. ", 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)]()
""" 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 ) <<<<<<< HEAD _scr = self.schwarzschild_r.value * 1.001 _event_hor = ( kerr_utils.event_horizon(self.schwarzschild_r.value, self.a)[0] * 1.001 ) ======= _event_hor = kerr_utils.event_horizon(self.M.value, self.a.value)[0] * 1.001 >>>>>>> 0e311bec1be2508a28ebd8a3f8b7b944db997269 while ODE.t < end_lambda: vecs.append(ODE.y) lambdas.append(ODE.t) ODE.step() <<<<<<< HEAD if (not singularity_reached) and (ODE.y[1] <= _event_hor): warnings.warn( "r component of position vector reached event horizon. ", RuntimeWarning,