# Introduction¶

This page gives a brief overview of some of the features of EinsteinPy. For more complete hands-on tutorials, please refer to the Jupyter notebooks in Examples.

`metric`

Module¶

EinsteinPy provides a way to define the background geometry for relativistic dynamics. This geometry has a central operating quantity known as the Metric tensor, that encapsulates all the geometrical and topological information about the 4D spacetime.

EinsteinPy provides a

`BaseMetric`

class, that has various utility functions and a proper template, that can be used to define custom Metric classes. All predefined classes in`metric`

derive from this class.The central quantities required to simulate the trajectory of a particle in a gravitational field are the metric derivatives, that can be succinctly written using Christoffel Symbols. EinsteinPy provides an easy-to-use interface to calculate these symbols for the predefined metrics. To perform calculations for general metrics, see the

`symbolic`

module.`BaseMetric`

also provides support for`f_vec`

and`perturbation`

, where`f_vec`

corresponds to the RHS of the geodesic equation and`perturbation`

is a linear Kerr-Schild Perturbation that can be defined on the underlying metric. Note that EinsteinPy does not perform physical checks on`perturbation`

currently. Users should exercise caution while using it.

`geodesic`

Module¶

EinsteinPy provides an intuitive interface for calculating timelike and nulllike geodesics for vacuum solutions. Below, we calculate the orbit of a precessing particle in Schwarzschild spacetime.

First, we import all the relevant modules and classes and define the initial conditions for our test particle, such as its initial 3-position in spherical coordinates and corresponding 3-momentum (or 3-velocity, given that we are working in geometric units with \(M = 1\)).

import numpy as np from einsteinpy.geodesic import Timelike from einsteinpy.plotting.geodesic import StaticGeodesicPlotter position = [40., np.pi / 2, 0.] momentum = [0., 0., 3.83405] a = 0. # Spin = 0 for a Schwarzschild black hole steps = 5500 # Number of steps to be taken by the solver delta = 1 # Step size

After defining our initial conditions, we can use `Timelike`

to create a Geodesic object, that automatically calculates the trajectory.

geod = Timelike( metric="Schwarzschild", metric_params=(a,), position=position, momentum=momentum, steps=steps, delta=delta, suppress_warnings=True, return_cartesian=True ) print(geod)Geodesic Object:( Type : (Time-like), Metric : (Schwarzschild), Metric Parameters : ((0.0,)), Initial 4-Position : ([ 0. 40. 1.57079633 0. ]), Initial 4-Momentum : ([-0.97914661 0. 0. 3.83405 ]), Trajectory = ( (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, ... 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499]), array([[ 1.03068069e+00, 3.99997742e+01, 9.58510673e-02, ..., -3.87363444e-04, 5.62571365e-19, 3.83405000e+00], [ 2.06136190e+00, 3.99987445e+01, 1.91699898e-01, ..., -9.48048366e-04, 1.12515772e-18, 3.83404999e+00], ..., [ 5.71172446e+02, 1.55983863e+01, 1.49940531e+01, ..., 1.65861080e-01, 3.12992232e-15, 3.83405010e+00], [ 5.72250940e+02, 1.55832138e+01, 1.52252617e+01, ..., 1.64780132e-01, 3.13183198e-15, 3.83404993e+00]])) ), Output Position Coordinate System = (Cartesian) ))

We can also obtain a static plot of the geodesic using `StaticGeodesicPlotter`

.

# Use InteractiveGeodesicPlotter() to get interactive plots sgpl = StaticGeodesicPlotter() sgpl.plot2D(geod) sgpl.show()

`coordinates`

Module¶

EinsteinPy currently supports 3 coordinate systems, namely, Cartesian, Spherical and Boyer-Lindquist. The `coordinates`

module provides a way to convert between these coordinate systems. Below, we show how to convert 4-positions and velocities (defined alongside positions) between Cartesian and Boyer-Lindquist coordinates.

import numpy as np from astropy import units as u from einsteinpy.coordinates import BoyerLindquistDifferential, CartesianDifferential, Cartesian, BoyerLindquist M = 1e20 * u.kg a = 0.5 * u.one # 4-Position t = 1. * u.s x = 0.2 * u.km y = 0.15 * u.km z = 0. * u.km _4pos_cart = Cartesian(t, x, y, z) # The keyword arguments, M & a are required for conversion to & from Boyer-Lindquist coordinates _4pos_bl = _4pos_cart.to_bl(M=M, a=a) print(_4pos_bl) cartsn_pos = _4pos_bl.to_cartesian(M=M, a=a) print(cartsn_pos) # With position & velocity v_x = 150 * u.km / u.s v_y = 250 * u.km / u.s v_z = 0. * u.km / u.s pos_vel_cart = CartesianDifferential(t, x, y, z, v_x, v_y, v_z) # Converting to Boyer-Lindquist coordinates pos_vel_bl = pos_vel_cart.bl_differential(M=M, a=a) print(pos_vel_bl) # Converting back to Cartesian coordinates pos_vel_cart = pos_vel_bl.cartesian_differential(M=M, a=a) print(pos_vel_cart)Boyer-Lindquist Coordinates: t = (1.0 s), r = (250.0 m), theta = (1.5707963267948966 rad), phi = (0.6435011087932844 rad) Cartesian Coordinates: t = (1.0 s), x = (200.0 m), y = (150.0 m), z = (1.5308084989341916e-14 m) Boyer-Lindquist Coordinates: t = (1.0 s), r = (250.0 m), theta = (1.5707963267948966 rad), phi = (0.6435011087932844 rad) v_t: None, v_r: 270000.0 m / s, v_th: -0.0 rad / s, v_p: 440.0 rad / s Cartesian Coordinates: t = (1.0 s), x = (200.0 m), y = (150.0 m), z = (1.5308084989341916e-14 m) v_t: None, v_x: 150000.0 m / s, v_y: 250000.0 m / s, v_z: 1.6532731788489268e-11 m / s

You can also pass a `einsteinpy.metric.*`

object to the differential object to set `v_t`

. For usage without units, see the functions in `einsteinpy.coordinates.util`

.

`symbolic`

Module¶

EinsteinPy also supports a robust symbolic module that allows users to access several predefined metrics, or to define custom metrics and perform symbolic calculations. A short example with a predefined metric is shown below.

from sympy import simplify from einsteinpy.symbolic import Schwarzschild, ChristoffelSymbols, EinsteinTensor m = Schwarzschild() ch = ChristoffelSymbols.from_metric(m) G1 = EinsteinTensor.from_metric(m) print(f"ch(1, 2, k) = {simplify(ch[1, 2, :])}") # k is an index in [0, 1, 2, 3] print(G1.arr)ch(1, 2, k) = [0, 0, -r + r_s, 0] [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

## Utility functions¶

EinsteinPy provides a great set of utility functions in many of the modules which are frequently used in general and numerical relativity.

- Utils in
`coordinates`

, that allow: - Unitless conversion between coordinate systems for both position & velocity in the following systems:
Cartesian

Spherical

Boyer-Lindquist

Calculation of Lorentz factor

Calculation of timelike component of 4-velocity in any pseudo-Riemannian metric

- Utils in
- Utils in
`geodesic`

that can be used to calculate quantities related to the vacuum solutions, such as: \(\rho^2 = r^2 + a^2\cos^2(\theta)\) or \(\Delta = r^2 - r_s r + a^2 + r_Q^2\)

Calculation of particle 4-momentum

- Utils in

## Future Plans¶

- Support for null-geodesics in different geometries
Partial support is available for vacuum solutions since version 0.4.0.

Ultimate goal is to provide numerical solutions for Einstein’s equations for arbitrarily complex matter distributions.

Relativistic hydrodynamics