Implementing a new metric

Gradus.jl is able to integrate any 3+1 dimensional metric. A new metric may be defined by implementing one of the abstract types with a concrete type, and defining a number of methods. Depending on what you want to be able to do with a metric, different functions need to be implemented.

Gradus also provides a few derivative abstract types to implement to ensure the most efficient code is executed for a given metric (see Metric parameter types below).

Example: Schwarzschild

As a minimal example, here is how the Schwarzschild metric may be implemented. First, we must define what the metric parameters for this metric are. These are effectively constants of the spacetime, representing physical quantities that appear in the metric expression. For the Schwarzschild metric, this is only the black hole mass $M$, but e.g. the Kerr metric also has the black hole spin $a$.

We can choose the integration strategy by sub-typing an abstract type representing different classes of spacetimes. For the Schwarzschild metric, we will use the static, axis-symmetric class, with the automatic differentiation (AD) backend. With AD, we only need to specify the non-zero components of the metric as Julia functions, and the rest is done for us.

For ease, we choose the Eddington-Finkelstein coordinates of the Schwarzschild solution, which may be written

\[\text{d}s^2 = - \left( 1 - \frac{2 M}{r} \right) \text{d}t^2 + \left( 1 - \frac{2 M}{r} \right)^{-1} \text{d}r^2 + r^2 \text{d}\theta^2 + r^2 \sin^2(\theta) \text{d}\phi^2.\]

Here is a possible implementation for Gradus.jl:

using Gradus

@with_kw struct EddingtonFinkelsteinAD{T} <: AbstractStaticAxisSymmetric{T}
    M = 1.0
end

function Gradus.metric_components(m::EddingtonFinkelsteinAD{T}, rθ) where {T}
    (r, θ) = rθ
    M = m.M

    tt = -(1 - (2M / r))
    rr = -inv(tt)
    θθ = r^2
    ϕϕ = r^2 * sin(θ)^2

    (tt, rr, θθ, ϕϕ, T(0.0))
end

Gradus.inner_radius(m::EddingtonFinkelsteinAD) = 2 * m.M

A few notes:

  • We use @with_kw from Parameters.jl to define various utility constructors for us.
  • metric_components must return five elements for AbstractStaticAxisSymmetric, where the last element is the off-axis $g_{t \phi}$ matrix element, which in this case is always 0.
  • The inner_radius function defines the inner-radius of integration chart. This defines where the integration should terminate to avoid running indefinitely, and is, in this case, set to the event-horizon of our metric.

That's all we need! This metric is now ready to be traced in the usual way.

Note

For more examples of how to implement different metrics, click on the "source" button of a metric in Implemented Metrics. Alternatively, view the source code directly here.

Metric parameter types

The following types may be implemented to add new metrics. Each type has different requirements for its interface.

First-Order

Gradus.four_velocityFunction
four_velocity(x, m::AbstractFirstOrderMetric, p)

Calculate the four-velocity at a point u, given a set of metric parameters and the constants of motion in p.

source
Gradus.calc_lqFunction
calc_lq(m::AbstractFirstOrderMetric, pos, param))

Calculate constants of motion $L$ and $Q$, given a set of metric parameters, the geodesic position, and the param vector.

source
Gradus.VrFunction
Vr(m::AbstractFirstOrderMetric, u, p)

Effective potential in the radial direction. Used only to track sign changes.

source
Gradus.VθFunction
Vθ(m::AbstractFirstOrderMetric, u, p)

Effective potential in the angular direction. Used only to track sign changes.

source

Second-Order

Gradus.metric_componentsFunction
metric_components(m::AbstractMetric{T}, x)

Return a tuple with each non-zero metric component for the metric described by m at position x. Note that the position need not be a four-vector, and for specific implementations may only be a subset of the total manifold coordinates. See specific implementations for subtypes of AbstractMetric for details.

source
metric_components(m::AbstractStaticAxisSymmetric, rθ

Interface for AbstractStaticAxisSymmetric. Should return a vector or tuple with the elements

\[\left( g_{tt}, g_{rr}, g_{\theta \theta}, g_{\phi \phi}, g_{t\phi} \right).\]

source
Gradus.AbstractStaticAxisSymmetricType
AbstractStaticAxisSymmetric{T}

Specialisation for static, axis-symmetric metrics. Here, the metric is of the form

\[ g_{\mu\nu} = \left( \begin{matrix} g_{tt} & 0 & 0 & g_{t\phi} \\ 0 & g_{rr} & 0 & 0 \\ 0 & 0 & g_{\theta\theta} & 0 \\ g_{t\phi} & 0 & 0 & g_{\phi\phi} \end{matrix} \right),\]

where the only non-zero off axis elements are $g_{t\phi}$.

Required implementations:

source