Skip to main content

omnibias.fields.torch.ops.norms

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.norms
Module contract & mathematical conventions

Inner products and L2 / Sobolev norms as standalone ops (torch).

All quantities are quadrature integrals over the box domain implied by the rule; state must be evaluated at the rule's nodes (see omnibias.fields.torch.ops.integral.integrate).

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

inner_product​

omnibias.fields.torch.ops.inner_productSource ↗
inner_product(state: FieldState, name_a: str, name_b: str, *, rule: QuadratureSpec, weight: str | None=None) -> Tensor

Weighted real inner product \langle a, b\rangle_w = \int_\Omega w\,a\,b\,dx.

Parameters

state Field state evaluated at the quadrature nodes. name_a, name_b Component names of the two factors. rule Quadrature rule. weight Optional component name of a positive weight field w (default None means w = 1).

Parameters

NameType & defaultContract
statepositional-or-keywordFieldStateRequiredField state evaluated at the quadrature nodes.
name_apositional-or-keywordstrRequiredComponent names of the two factors.
name_bpositional-or-keywordstrRequiredSee the operation contract and implementation below.
rulekeyword-onlyQuadratureSpecRequiredQuadrature rule.
weightkeyword-onlystr | NoneDefault: NoneOptional component name of a positive weight field w (default None means w = 1).
ReturnsTensor
Executed regression · inner product 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_inner_product_cross_backend(make_torch_field, make_jax_field):  # type: ignore[no-untyped-def]
    rule = gauss_legendre(BOUNDS, (8, 8))
    ts = make_torch_field()(torch.as_tensor(rule.nodes, dtype=torch.float64))
    js = make_jax_field()(jnp.asarray(rule.nodes, dtype=jnp.float64))
    t = _np(ts.ops.inner_product(ts, "u", "v", rule=rule))
    j = _np(js.ops.inner_product(js, "u", "v", rule=rule))
    assert np.allclose(t, j, rtol=1e-12, atol=1e-12)
python -m pytest "packages/omnibias-fields/tests/test_integration_norms.py::test_inner_product_cross_backend" -q
Read the implementation
def inner_product(
    state: FieldState,
    name_a: str,
    name_b: str,
    *,
    rule: QuadratureSpec,
    weight: str | None = None,
) -> Tensor:
    r"""Weighted real inner product :math:`\langle a, b\rangle_w
    = \int_\Omega w\,a\,b\,dx`.

    Parameters
    ----------
    state
        Field state evaluated at the quadrature nodes.
    name_a, name_b
        Component names of the two factors.
    rule
        Quadrature rule.
    weight
        Optional component name of a positive weight field ``w`` (default
        ``None`` means ``w = 1``).
    """
    a = value(state, name_a)
    b = value(state, name_b)
    integrand = a * b
    if weight is not None:
        integrand = integrand * value(state, weight)
    return _integrate_values(integrand, rule)
Other public import paths
  • omnibias.fields.torch.ops.inner_product
  • omnibias.fields.torch.ops.norms.inner_product
FUNCTION

l2_norm​

omnibias.fields.torch.ops.l2_normSource ↗
l2_norm(state: FieldState, name: str, *, rule: QuadratureSpec) -> Tensor

\lVert u\rVert_{L^2} = \sqrt{\int_\Omega u^2\,dx}.

Parameters

NameType & defaultContract
statepositional-or-keywordFieldStateRequiredSee the operation contract and implementation below.
namepositional-or-keywordstrRequiredSee the operation contract and implementation below.
rulekeyword-onlyQuadratureSpecRequiredSee the operation contract and implementation below.
ReturnsTensor
Executed regression · l2 norm matches analytic

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_l2_norm_matches_analytic(make_torch_field):  # type: ignore[no-untyped-def]
    rule = gauss_legendre(BOUNDS, (8, 8))  # u^2 is degree 4 -> need >=3 nodes
    field = make_torch_field()
    state = field(torch.as_tensor(rule.nodes, dtype=torch.float64))
    got = float(_np(state.u.l2_norm(rule=rule)))
    # ||u||^2 = (int_0^1 (1+2x+x^2)^2 dx)(int_-1^1 (1-y)^2 dy).
    # (1+2x+x^2)^2 = (x+1)^4 -> int_0^1 = (2^5-1)/5 = 31/5.
    # (1-y)^2 -> int_-1^1 = 8/3.
    exp = np.sqrt((31.0 / 5.0) * (8.0 / 3.0))
    assert np.isclose(got, exp, rtol=1e-12, atol=1e-12)
python -m pytest "packages/omnibias-fields/tests/test_integration_norms.py::test_l2_norm_matches_analytic" -q
Read the implementation
def l2_norm(state: FieldState, name: str, *, rule: QuadratureSpec) -> Tensor:
    r""":math:`\lVert u\rVert_{L^2} = \sqrt{\int_\Omega u^2\,dx}`."""
    sq = _integrate_values(value(state, name) ** 2, rule)
    return torch.sqrt(sq)
Other public import paths
  • omnibias.fields.torch.ops.l2_norm
  • omnibias.fields.torch.ops.norms.l2_norm
FUNCTION

sobolev_norm​

omnibias.fields.torch.ops.sobolev_normSource ↗
sobolev_norm(state: FieldState, name: str, *, rule: QuadratureSpec, k: int=1, weights: tuple[float, ...] | None=None) -> Tensor

Sobolev norm \lVert u\rVert_{H^k}.

\lVert u\rVert_{H^k}^2 = \sum_{m=0}^{k} c_m \sum_{|\alpha|=m} \int_\Omega (\partial^\alpha u)^2\,dx,

where order m=0 is \int u^2, m=1 is the squared spatial gradient, and m=2 is the squared spatial Hessian (Frobenius). Every order is taken over the *spatial* axes only (the time axis, if any, is excluded), so on a spacetime field this is a consistent spatial Sobolev seminorm sum rather than a mixed space-time norm. k must be in {0, 1, 2} (higher orders raise NotImplementedError). weights supplies the per-order coefficients c_m (default all ones).

Parameters

NameType & defaultContract
statepositional-or-keywordFieldStateRequiredSee the operation contract and implementation below.
namepositional-or-keywordstrRequiredSee the operation contract and implementation below.
rulekeyword-onlyQuadratureSpecRequiredSee the operation contract and implementation below.
kkeyword-onlyintDefault: 1See the operation contract and implementation below.
weightskeyword-onlytuple[float, ...] | NoneDefault: NoneSee the operation contract and implementation below.
ReturnsTensor
Explicit validation & failure cases
  • When k < 0, raises ValueError(f'k must be >= 0, got {k}').
  • When k > 2, raises NotImplementedError(f'sobolev_norm currently supports k in {{0, 1, 2}}; got k={k}. Higher orders need the full multi-index expansion.').
  • When len(coeffs) != k + 1, raises ValueError(f'weights must have length k+1 = {k + 1}, got {len(coeffs)}').

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

Executed regression · sobolev norm 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_sobolev_norm_cross_backend(make_torch_field, make_jax_field):  # type: ignore[no-untyped-def]
    rule = gauss_legendre(BOUNDS, (8, 8))
    ts = make_torch_field()(torch.as_tensor(rule.nodes, dtype=torch.float64))
    js = make_jax_field()(jnp.asarray(rule.nodes, dtype=jnp.float64))
    for k in (0, 1, 2):
        t = _np(ts.u.sobolev_norm(rule=rule, k=k))
        j = _np(js.u.sobolev_norm(rule=rule, k=k))
        assert np.allclose(t, j, rtol=1e-12, atol=1e-12), k
python -m pytest "packages/omnibias-fields/tests/test_integration_norms.py::test_sobolev_norm_cross_backend" -q
Read the implementation
def sobolev_norm(
    state: FieldState,
    name: str,
    *,
    rule: QuadratureSpec,
    k: int = 1,
    weights: tuple[float, ...] | None = None,
) -> Tensor:
    r"""Sobolev norm :math:`\lVert u\rVert_{H^k}`.

    .. math::

        \lVert u\rVert_{H^k}^2 = \sum_{m=0}^{k} c_m
            \sum_{|\alpha|=m} \int_\Omega (\partial^\alpha u)^2\,dx,

    where order ``m=0`` is :math:`\int u^2`, ``m=1`` is the squared spatial
    gradient, and ``m=2`` is the squared spatial Hessian (Frobenius). Every
    order is taken over the *spatial* axes only (the time axis, if any, is
    excluded), so on a spacetime field this is a consistent spatial Sobolev
    seminorm sum rather than a mixed space-time norm. ``k`` must be in
    ``{0, 1, 2}`` (higher orders raise :class:`NotImplementedError`). ``weights``
    supplies the per-order coefficients :math:`c_m` (default all ones).
    """
    if k < 0:
        raise ValueError(f"k must be >= 0, got {k}")
    if k > 2:
        raise NotImplementedError(
            "sobolev_norm currently supports k in {0, 1, 2}; "
            f"got k={k}. Higher orders need the full multi-index expansion."
        )
    coeffs = (1.0,) * (k + 1) if weights is None else weights
    if len(coeffs) != k + 1:
        raise ValueError(f"weights must have length k+1 = {k + 1}, got {len(coeffs)}")

    total = coeffs[0] * _integrate_values(value(state, name) ** 2, rule)
    if k >= 1:
        g = gradient(state, name)                       # (B, n_spatial)
        total = total + coeffs[1] * _integrate_values((g ** 2).sum(dim=-1), rule)
    if k >= 2:
        h = spatial_hessian(state, name)                 # (B, n_spatial, n_spatial)
        total = total + coeffs[2] * _integrate_values((h ** 2).sum(dim=(-2, -1)), rule)
    return torch.sqrt(total)
Other public import paths
  • omnibias.fields.torch.ops.sobolev_norm
  • omnibias.fields.torch.ops.norms.sobolev_norm