coordinates.mixins.mathops.CoordinateSystemMathMixin.raise_index_dense#
- CoordinateSystemMathMixin.raise_index_dense(tensor_field: ndarray, index: int, rank: int, *coordinates: ndarray, inverse_metric_field: ndarray | None = None, fixed_axes: Dict[str, float] | None = None, out: ndarray | None = None, **kwargs) ndarray [source]#
Raise a single tensor index using \(g^{ab}\).
The routine contracts the supplied inverse metric with
tensor_field
\[T^{\mu}{}_{\dots} = g^{\mu\nu} \, T_{\nu\dots}\]- Parameters:
tensor_field (
numpy.ndarray
) – Tensor field of shape(F₁, ..., F_m, N, ...)
, where the last rank axes are the tensor index dimensions.index – Which tensor slot (
0, ..., rank-1
) to raise.rank (
int
) – Number of trailing axes that represent tensor indices (i.e., tensor rank). The rank determines the number of identified coordinate axes and therefore determines the shape of the returned array.*coordinates – ND coordinate grids in canonical axis order. Only needed when
inverse_metric_field
is None.inverse_metric_field (
numpy.ndarray
) – Inverse metric tensor with shape(F₁, ..., F_n, N, )
or(F₁, ..., F_n, N, N)
, whereN == n
. Must be broadcast-compatible with the field shape of tensor_field.fixed_axes – Constant axis values to use when computing the metric.
out – Optional output buffer.
**kwargs – Forwarded verbatim to
dense_raise_index()
.
- Returns:
Tensor identical to
tensor_field
except the chosen slot is now contravariant.- Return type:
Examples
In spherical coordinates, the vector \(V_\mu = (r^2,r^2,0)\) becomes
\[v^\mu = g^{\mu\mu} V_\mu = (r^2, 1, 0).\]To perform the operation computationally,
>>> from pymetric.coordinates import SphericalCoordinateSystem >>> from pymetric.utilities.logging import pg_log >>> pg_log.level = 50 >>> >>> # Build the coordinate system. >>> u = SphericalCoordinateSystem() >>> >>> # Create the R,THETA grid. >>> r = np.linspace(1e-3,1,10) >>> theta = np.linspace(1e-3,np.pi-1e-3,10) >>> R, THETA = np.meshgrid(r,theta) >>> >>> # Create the vector field. >>> V_co = np.stack([R**2,R**2,np.zeros_like(R)],axis=-1) >>> >>> # Raise the index. >>> V_contra = u.raise_index_dense(V_co,0,1,R, THETA, fixed_axes={'phi':0}) >>> V_contra.shape (10, 10, 3) >>> np.allclose(V_contra[...,0],R**2) True >>> np.allclose(V_contra[...,1],np.ones_like(R)) True
It is also possible to provide the inverse metric immediately to avoid needing to compute it on the fly. This also allows us to get away without the coordinates.
>>> from pymetric.coordinates import SphericalCoordinateSystem >>> >>> # Build the coordinate system. >>> u = SphericalCoordinateSystem() >>> >>> # Create the R,THETA grid. >>> r = np.linspace(1e-3,1,10) >>> theta = np.linspace(1e-3,np.pi-1e-3,10) >>> R, THETA = np.meshgrid(r,theta) >>> >>> # Create the vector field. >>> V_co = np.stack([R**2,R**2,np.zeros_like(R)],axis=-1) >>> >>> # Create the inverse metric tensor >>> imt = np.stack([np.ones_like(R),R**-2,R**-2 * np.sin(THETA)**-1],axis=-1) >>> >>> # Raise the index. >>> V_contra = u.raise_index_dense(V_co,0,1, inverse_metric_field=imt, fixed_axes={'phi':0}) >>> V_contra.shape (10, 10, 3) >>> np.allclose(V_contra[...,0],R**2) True >>> np.allclose(V_contra[...,1],np.ones_like(R)) True