# 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 with the (non `AbstractConnectionManifold`

) `AbstractManifold`

, i.e. 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.AbstractConnectionManifold`

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

Equip an `AbstractManifold`

explicitly with an `AbstractAffineConnection`

`G`

.

`AbstractConnectionManifold`

is defined by values of `christoffel_symbols_second`

, which is used for a default implementation of `exp`

, `log`

and `vector_transport_to`

. Closed-form formulae for particular connection manifolds may be explicitly implemented when available.

An overview of basic properties of affine connection manifolds can be found in ^{[Pennec2020]}.

`Manifolds.ConnectionManifold`

โ Type`ConnectionManifold(M, C)`

Decorate the `AbstractManifold`

`M`

with `AbstractAffineConnection`

`C`

.

`Manifolds.LeviCivitaConnection`

โ Type`LeviCivitaConnection`

The Levi-Civita connection of a Riemannian manifold.

## Functions

`Base.exp`

โ Method`exp(M::AbstractConnectionManifold, p, X)`

Compute the exponential map on the `AbstractConnectionManifold`

`M`

equipped with corresponding affine connection.

If `M`

is a `MetricManifold`

with a metric that was declared the default metric using `is_default_metric`

, 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_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.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.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`

`Manifolds.solve_exp_ode`

โ Method```
solve_exp_ode(
M::AbstractConnectionManifold,
p,
X,
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`

## 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`

.

- Pennec2020
X. Pennec and M. Lorenzi, โ5 - Beyond Riemannian geometry: The affine connection setting for transformation groups,โ in Riemannian Geometric Statistics in Medical Image Analysis, X. Pennec, S. Sommer, and T. Fletcher, Eds. Academic Press, 2020, pp. 169โ229. doi: 10.1016/B978-0-12-814725-2.00012-1.