# Connection manifold

A connection manifold always consists of a topological manifold together with a connection $\Gamma$.

However, often there is an implicitly assumed (default) connection, like the `LeviCivitaConnection`

connection on a Riemannian manifold. It is not necessary to use this decorator if you implement just one (or the first) connection. If you later introduce a second, the old (first) connection can be used without an explicitly stated connection.

This manifold decorator serves two purposes:

- to implement different connections (e.g. in closed form) for one
`AbstractManifold`

- to provide a way to compute geodesics on manifolds, where this
`AbstractAffineConnection`

does not yield a closed formula.

An example of usage can be found in Cartan-Schouten connections, see `AbstractCartanSchoutenConnection`

.

## Types

`Manifolds.AbstractAffineConnection`

โ Type`AbstractAffineConnection`

Abstract type for affine connections on a manifold.

`Manifolds.ConnectionManifold`

โ Type`ConnectionManifold{๐ฝ,,M<:AbstractManifold{๐ฝ},G<:AbstractAffineConnection} <: AbstractDecoratorManifold{๐ฝ}`

**Constructor**

`ConnectionManifold(M, C)`

Decorate the `AbstractManifold`

`M`

with `AbstractAffineConnection`

`C`

.

`Manifolds.IsConnectionManifold`

โ Type`IsConnectionManifold <: AbstractTrait`

Specify that a certain decorated Manifold is a connection manifold in the sence that it provides explicit connection properties, extending/changing the default connection properties of a manifold.

`Manifolds.IsDefaultConnection`

โ Type`IsDefaultConnection{G<:AbstractAffineConnection}`

Specify that a certain `AbstractAffineConnection`

is the default connection for a manifold. This way the corresponding `ConnectionManifold`

falls back to the default methods of the manifold it decorates.

`Manifolds.LeviCivitaConnection`

โ Type`LeviCivitaConnection`

The Levi-Civita connection of a Riemannian manifold.

## Functions

`Base.exp`

โ Method`exp(::TraitList{IsConnectionManifold}, M::AbstractDecoratorManifold, p, X)`

Compute the exponential map on a manifold that `IsConnectionManifold`

`M`

equipped with corresponding affine connection.

If `M`

is a `MetricManifold`

with a `IsDefaultMetric`

trait, this method falls back to `exp(M, p, X)`

.

Otherwise it numerically integrates the underlying ODE, see `solve_exp_ode`

. Currently, the numerical integration is only accurate when using a single coordinate chart that covers the entire manifold. This excludes coordinates in an embedded space.

`Manifolds.christoffel_symbols_first`

โ Method```
christoffel_symbols_first(
M::AbstractManifold,
p,
B::AbstractBasis;
backend::AbstractDiffBackend = default_differential_backend(),
)
```

Compute the Christoffel symbols of the first kind in local coordinates of basis `B`

. The Christoffel symbols are (in Einstein summation convention)

\[ฮ_{ijk} = \frac{1}{2} \Bigl[g_{kj,i} + g_{ik,j} - g_{ij,k}\Bigr],\]

where $g_{ij,k}=\frac{โ}{โ p^k} g_{ij}$ is the coordinate derivative of the local representation of the metric tensor. The dimensions of the resulting multi-dimensional array are ordered $(i,j,k)$.

`Manifolds.christoffel_symbols_second`

โ Method```
christoffel_symbols_second(
M::AbstractManifold,
p,
B::AbstractBasis;
backend::AbstractDiffBackend = default_differential_backend(),
)
```

Compute the Christoffel symbols of the second kind in local coordinates of basis `B`

. For affine connection manifold the Christoffel symbols need to be explicitly implemented while, for a `MetricManifold`

they are computed as (in Einstein summation convention)

\[ฮ^{l}_{ij} = g^{kl} ฮ_{ijk},\]

where $ฮ_{ijk}$ are the Christoffel symbols of the first kind (see `christoffel_symbols_first`

), and $g^{kl}$ is the inverse of the local representation of the metric tensor. The dimensions of the resulting multi-dimensional array are ordered $(l,i,j)$.

`Manifolds.christoffel_symbols_second_jacobian`

โ Method```
christoffel_symbols_second_jacobian(
M::AbstractManifold,
p,
B::AbstractBasis;
backend::AbstractDiffBackend = default_differential_backend(),
)
```

Get partial derivatives of the Christoffel symbols of the second kind for manifold `M`

at `p`

with respect to the coordinates of `B`

, i.e.

\[\frac{โ}{โ p^l} ฮ^{k}_{ij} = ฮ^{k}_{ij,l}.\]

The dimensions of the resulting multi-dimensional array are ordered $(i,j,k,l)$.

`Manifolds.connection`

โ Method`connection(M::AbstractManifold)`

Get the connection (an object of a subtype of `AbstractAffineConnection`

) of `AbstractManifold`

`M`

.

`Manifolds.connection`

โ Method`connection(M::ConnectionManifold)`

Return the connection associated with `ConnectionManifold`

`M`

.

`Manifolds.gaussian_curvature`

โ Method`gaussian_curvature(M::AbstractManifold, p, B::AbstractBasis; backend::AbstractDiffBackend = default_differential_backend())`

Compute the Gaussian curvature of the manifold `M`

at the point `p`

using basis `B`

. This is equal to half of the scalar Ricci curvature, see `ricci_curvature`

.

`Manifolds.is_default_connection`

โ Method`is_default_connection(M::AbstractManifold, G::AbstractAffineConnection)`

returns whether an `AbstractAffineConnection`

is the default metric on the manifold `M`

or not. This can be set by defining this function, or setting the `IsDefaultConnection`

trait for an `AbstractDecoratorManifold`

.

`Manifolds.ricci_tensor`

โ Method`ricci_tensor(M::AbstractManifold, p, B::AbstractBasis; backend::AbstractDiffBackend = default_differential_backend())`

Compute the Ricci tensor, also known as the Ricci curvature tensor, of the manifold `M`

at the point `p`

using basis `B`

, see `https://en.wikipedia.org/wiki/Ricci_curvature#Introduction_and_local_definition`

.

`Manifolds.solve_exp_ode`

โ Method```
solve_exp_ode(
M::AbstractConnectionManifold,
p,
X,
t::Number,
B::AbstractBasis;
backend::AbstractDiffBackend = default_differential_backend(),
solver = AutoVern9(Rodas5()),
kwargs...,
)
```

Approximate the exponential map on the manifold by evaluating the ODE descripting the geodesic at 1, assuming the default connection of the given manifold by solving the ordinary differential equation

\[\frac{d^2}{dt^2} p^k + ฮ^k_{ij} \frac{d}{dt} p_i \frac{d}{dt} p_j = 0,\]

where $ฮ^k_{ij}$ are the Christoffel symbols of the second kind, and the Einstein summation convention is assumed. The argument `solver`

follows the `OrdinaryDiffEq`

conventions. `kwargs...`

specify keyword arguments that will be passed to `OrdinaryDiffEq.solve`

.

Currently, the numerical integration is only accurate when using a single coordinate chart that covers the entire manifold. This excludes coordinates in an embedded space.

This function only works when OrdinaryDiffEq.jl is loaded with

`using OrdinaryDiffEq`

`ManifoldsBase.riemann_tensor`

โ Method`riemann_tensor(M::AbstractManifold, p, B::AbstractBasis; backend::AbstractDiffBackend=default_differential_backend())`

Compute the Riemann tensor $R^l_{ijk}$, also known as the Riemann curvature tensor, at the point `p`

in local coordinates defined by `B`

. The dimensions of the resulting multi-dimensional array are ordered $(l,i,j,k)$.

The function uses the coordinate expression involving the second Christoffel symbol, see `https://en.wikipedia.org/wiki/Riemann_curvature_tensor#Coordinate_expression`

for details.

**See also**

`christoffel_symbols_second`

, `christoffel_symbols_second_jacobian`

## Charts and bases of vector spaces

All connection-related functions take a basis of a vector space as one of the arguments. This is needed because generally there is no way to define these functions without referencing a basis. In some cases there is no need to be explicit about this basis, and then for example a `DefaultOrthonormalBasis`

object can be used. In cases where being explicit about these bases is needed, for example when using multiple charts, a basis can be specified, for example using `induced_basis`

.