示例#1
0
    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
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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
        )
示例#5
0
    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
        )
示例#6
0
    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)
示例#7
0
    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)
示例#8
0
    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()
示例#9
0
    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)]()
示例#10
0
    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
示例#11
0
    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)