Skip to main content

omnibias.fields.torch.ops.tensor

0.2.0rc1Release candidatePython >=3.10Apache-2.0

Structured scalar, vector, and tensor fields with derivative caches, calculus operators, and coordinate conventions.

import omnibias.fields.torch.ops.tensor
Module contract & mathematical conventions

Divergence of a second-order tensor field (torch).

For solid mechanics / elasticity and the conservative form of momentum balance: given a stress tensor \sigma_{ij}, the row-wise divergence

(\nabla\cdot\sigma)_i = \partial_j \sigma_{ij}

is the body-force-balancing vector. This is the flat (Cartesian) divergence; the covariant version with Christoffel corrections lives in omnibias-geometry.

Shared formulas do not imply universal floating-point identity. Verify dtype, shape, derivative-order support, and the stated numerical assumptions for the path you use.

FUNCTION

tensor_cofactor​

omnibias.fields.torch.ops.tensor_cofactorSource ↗
tensor_cofactor(a: Tensor) -> Tensor

Cofactor matrix \operatorname{cof}A = (\det A)\,A^{-\top}, shape (..., d, d).

Satisfies A @ cof(A)^T = det(A) I (the adjugate/Cramer identity); used for Nanson's formula and the derivative of the Jacobian dJ/dF = cof(F).

Parameters

NameType & defaultContract
apositional-or-keywordTensorRequiredSee the operation contract and implementation below.
ReturnsTensor
Read the implementation
def tensor_cofactor(a: Tensor) -> Tensor:
    r"""Cofactor matrix :math:`\operatorname{cof}A = (\det A)\,A^{-\top}`, shape ``(..., d, d)``.

    Satisfies ``A @ cof(A)^T = det(A) I`` (the adjugate/Cramer identity); used
    for Nanson's formula and the derivative of the Jacobian ``dJ/dF = cof(F)``.
    """
    _require_square(a, "tensor_cofactor")
    det = torch.linalg.det(a)
    inv_t = torch.linalg.inv(a).transpose(-1, -2)
    return det[..., None, None] * inv_t
Other public import paths
  • omnibias.fields.torch.ops.tensor_cofactor
  • omnibias.fields.torch.ops.tensor.tensor_cofactor
FUNCTION

tensor_determinant​

omnibias.fields.torch.ops.tensor_determinantSource ↗
tensor_determinant(a: Tensor) -> Tensor

Determinant of the trailing block \det A, shape (...,).

Parameters

NameType & defaultContract
apositional-or-keywordTensorRequiredSee the operation contract and implementation below.
ReturnsTensor
Read the implementation
def tensor_determinant(a: Tensor) -> Tensor:
    r"""Determinant of the trailing block :math:`\det A`, shape ``(...,)``."""
    _require_square(a, "tensor_determinant")
    return torch.linalg.det(a)
Other public import paths
  • omnibias.fields.torch.ops.tensor_determinant
  • omnibias.fields.torch.ops.tensor.tensor_determinant
FUNCTION

tensor_divergence​

omnibias.fields.torch.ops.tensor_divergenceSource ↗
tensor_divergence(state: FieldState, sigma_names: Sequence[Sequence[str]]) -> Tensor

Row-wise divergence (\nabla\cdot\sigma)_i = \partial_j \sigma_{ij}.

Parameters

state Field state carrying the stress components. sigma_names A (d, d) nested sequence of component names laying out \sigma_{ij} (row i is the output index; column j is the spatial derivative axis). d must equal the number of spatial axes.

Returns

Tensor The divergence vector of shape (B, d).

Parameters

NameType & defaultContract
statepositional-or-keywordFieldStateRequiredField state carrying the stress components.
sigma_namespositional-or-keywordSequence[Sequence[str]]RequiredA (d, d) nested sequence of component names laying out \sigma_{ij} (row i is the output index; column j is the spatial derivative axis). d must equal the number of spatial axes.
ReturnsTensor
Explicit validation & failure cases
  • When len(rows) != d, raises ValueError(f'tensor_divergence expects a {d}x{d} layout (d = number of spatial axes {spatial!r}); got {len(rows)} rows').
  • When len(row) != d, raises ValueError(f'row {i} of sigma_names must have {d} entries, got {len(row)}').

These are explicit source guards. Backend operations may also raise for invalid shapes, dtypes, or unsupported devices.

Executed regression · tensor divergence cross backend

Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.

def test_tensor_divergence_cross_backend(make_torch_field, make_jax_field, grid_nodes):  # type: ignore[no-untyped-def]
    ts = make_torch_field()(torch.as_tensor(grid_nodes, dtype=torch.float64))
    js = make_jax_field()(jnp.asarray(grid_nodes, dtype=jnp.float64))
    layout = (("u", "v"), ("v", "u"))
    t = _np(ts.ops.tensor_divergence(ts, layout))
    j = _np(js.ops.tensor_divergence(js, layout))
    assert np.allclose(t, j, rtol=1e-12, atol=1e-12)
python -m pytest "packages/omnibias-fields/tests/test_integration_norms.py::test_tensor_divergence_cross_backend" -q
Read the implementation
def tensor_divergence(
    state: FieldState,
    sigma_names: Sequence[Sequence[str]],
) -> Tensor:
    r"""Row-wise divergence :math:`(\nabla\cdot\sigma)_i = \partial_j \sigma_{ij}`.

    Parameters
    ----------
    state
        Field state carrying the stress components.
    sigma_names
        A ``(d, d)`` nested sequence of component names laying out
        :math:`\sigma_{ij}` (row ``i`` is the output index; column ``j`` is the
        spatial derivative axis). ``d`` must equal the number of spatial axes.

    Returns
    -------
    Tensor
        The divergence vector of shape ``(B, d)``.
    """
    spatial = state.coordinate_spec.spatial_axes
    d = len(spatial)
    rows = list(sigma_names)
    if len(rows) != d:
        raise ValueError(
            f"tensor_divergence expects a {d}x{d} layout (d = number of spatial "
            f"axes {spatial!r}); got {len(rows)} rows"
        )
    cols: list[Tensor] = []
    for i, row in enumerate(rows):
        row = list(row)
        if len(row) != d:
            raise ValueError(
                f"row {i} of sigma_names must have {d} entries, got {len(row)}"
            )
        acc: Tensor | None = None
        for j in range(d):
            term = derivative(state, row[j], axis=spatial[j], order=1)
            acc = term if acc is None else acc + term
        assert acc is not None
        cols.append(acc)
    return torch.stack(cols, dim=-1)
Other public import paths
  • omnibias.fields.torch.ops.tensor_divergence
  • omnibias.fields.torch.ops.tensor.tensor_divergence
FUNCTION

tensor_double_dot​

omnibias.fields.torch.ops.tensor_double_dotSource ↗
tensor_double_dot(a: Tensor, b: Tensor) -> Tensor

Frobenius double contraction A:B = \sum_{ij} A_{ij} B_{ij}.

Operates on the trailing two axes of two equally-shaped tensor batches (e.g. stress : strain_rate for viscous dissipation). Returns shape (B,).

Parameters

NameType & defaultContract
apositional-or-keywordTensorRequiredSee the operation contract and implementation below.
bpositional-or-keywordTensorRequiredSee the operation contract and implementation below.
ReturnsTensor
Explicit validation & failure cases
  • When a.shape != b.shape, raises ValueError(f'tensor_double_dot requires equal shapes; got {tuple(a.shape)} and {tuple(b.shape)}').
  • When a.ndim < 2, raises ValueError('tensor_double_dot requires at least 2 trailing axes').

These are explicit source guards. Backend operations may also raise for invalid shapes, dtypes, or unsupported devices.

Executed regression · tensor double dot value and dissipation sign

Recorded coverage confirms this test executed the API body. This example belongs to the pinned upstream test suite. It may use fixtures and imports from its full file. Run it from that checkout with its test dependencies installed.

def test_tensor_double_dot_value_and_dissipation_sign():
    nodes = _nodes(3)
    st = _state("torch", "3d", nodes)
    S = st.ops.strain_rate(st, ("u", "v", "w"))
    dd = _np(st.ops.tensor_double_dot(S, S))
    assert np.allclose(dd, (_np(S) ** 2).sum(axis=(-2, -1)), rtol=1e-12, atol=1e-12)
    assert np.all(dd >= 0.0)  # S:S is a sum of squares
python -m pytest "packages/omnibias-fields/tests/test_vector_calculus.py::test_tensor_double_dot_value_and_dissipation_sign" -q
Read the implementation
def tensor_double_dot(a: Tensor, b: Tensor) -> Tensor:
    r"""Frobenius double contraction :math:`A:B = \sum_{ij} A_{ij} B_{ij}`.

    Operates on the trailing two axes of two equally-shaped tensor batches
    (e.g. ``stress : strain_rate`` for viscous dissipation). Returns shape ``(B,)``.
    """
    if a.shape != b.shape:
        raise ValueError(
            f"tensor_double_dot requires equal shapes; got {tuple(a.shape)} "
            f"and {tuple(b.shape)}"
        )
    if a.ndim < 2:
        raise ValueError("tensor_double_dot requires at least 2 trailing axes")
    return (a * b).sum(dim=(-2, -1))
Other public import paths
  • omnibias.fields.torch.ops.tensor_double_dot
  • omnibias.fields.torch.ops.tensor.tensor_double_dot
FUNCTION

tensor_inverse​

omnibias.fields.torch.ops.tensor_inverseSource ↗
tensor_inverse(a: Tensor) -> Tensor

Inverse of the trailing block A^{-1}, shape (..., d, d).

Parameters

NameType & defaultContract
apositional-or-keywordTensorRequiredSee the operation contract and implementation below.
ReturnsTensor
Read the implementation
def tensor_inverse(a: Tensor) -> Tensor:
    r"""Inverse of the trailing block :math:`A^{-1}`, shape ``(..., d, d)``."""
    _require_square(a, "tensor_inverse")
    return torch.linalg.inv(a)
Other public import paths
  • omnibias.fields.torch.ops.tensor_inverse
  • omnibias.fields.torch.ops.tensor.tensor_inverse
FUNCTION

tensor_matmul​

omnibias.fields.torch.ops.tensor_matmulSource ↗
tensor_matmul(a: Tensor, b: Tensor) -> Tensor

Batched matrix product (AB)_{ik} = A_{ij} B_{jk}, shape (..., d, d).

Parameters

NameType & defaultContract
apositional-or-keywordTensorRequiredSee the operation contract and implementation below.
bpositional-or-keywordTensorRequiredSee the operation contract and implementation below.
ReturnsTensor
Read the implementation
def tensor_matmul(a: Tensor, b: Tensor) -> Tensor:
    r"""Batched matrix product :math:`(AB)_{ik} = A_{ij} B_{jk}`, shape ``(..., d, d)``."""
    return torch.matmul(a, b)
Other public import paths
  • omnibias.fields.torch.ops.tensor_matmul
  • omnibias.fields.torch.ops.tensor.tensor_matmul
FUNCTION

tensor_trace​

omnibias.fields.torch.ops.tensor_traceSource ↗
tensor_trace(a: Tensor) -> Tensor

Trace of the trailing block \operatorname{tr}A = A_{ii}, shape (...,).

Parameters

NameType & defaultContract
apositional-or-keywordTensorRequiredSee the operation contract and implementation below.
ReturnsTensor
Read the implementation
def tensor_trace(a: Tensor) -> Tensor:
    r"""Trace of the trailing block :math:`\operatorname{tr}A = A_{ii}`, shape ``(...,)``."""
    _require_square(a, "tensor_trace")
    return torch.diagonal(a, dim1=-2, dim2=-1).sum(dim=-1)
Other public import paths
  • omnibias.fields.torch.ops.tensor_trace
  • omnibias.fields.torch.ops.tensor.tensor_trace
FUNCTION

tensor_transpose​

omnibias.fields.torch.ops.tensor_transposeSource ↗
tensor_transpose(a: Tensor) -> Tensor

Transpose the trailing two axes: A^\top, shape (..., d, d).

Parameters

NameType & defaultContract
apositional-or-keywordTensorRequiredSee the operation contract and implementation below.
ReturnsTensor
Read the implementation
def tensor_transpose(a: Tensor) -> Tensor:
    r"""Transpose the trailing two axes: :math:`A^\top`, shape ``(..., d, d)``."""
    _require_square(a, "tensor_transpose")
    return a.transpose(-1, -2)
Other public import paths
  • omnibias.fields.torch.ops.tensor_transpose
  • omnibias.fields.torch.ops.tensor.tensor_transpose