"""Bounded transforms for physical model outputs."""

from __future__ import annotations

import torch
from torch import Tensor


def transform_mortar_outputs(raw: Tensor) -> Tensor:
    """Return mortar compression, tension, flexure, modulus, porosity and creep."""

    compressive = 2.0 + 298.0 * torch.sigmoid(raw[..., 0:1])
    tensile = 0.5 + 29.5 * torch.sigmoid(raw[..., 1:2])
    flexural = 1.0 + 59.0 * torch.sigmoid(raw[..., 2:3])
    elastic = 10.0 + 50.0 * torch.sigmoid(raw[..., 3:4])
    porosity = 0.005 + 0.295 * torch.sigmoid(raw[..., 4:5])
    creep = 0.5 + 3.0 * torch.sigmoid(raw[..., 5:6])
    return torch.cat(
        [compressive, tensile, flexural, elastic, porosity, creep], dim=-1
    )


def transform_itz_outputs(raw: Tensor) -> Tensor:
    """Return ITZ thickness, porosity and elastic modulus."""

    thickness = 5.0 + 65.0 * torch.sigmoid(raw[..., 0:1])
    porosity = 0.05 + 0.65 * torch.sigmoid(raw[..., 1:2])
    elastic = 2.0 + 38.0 * torch.sigmoid(raw[..., 2:3])
    return torch.cat([thickness, porosity, elastic], dim=-1)


def transform_paste_outputs(raw: Tensor) -> Tensor:
    """Return paste tension, modulus, fracture energy and porosity."""

    tensile = 0.5 + 29.5 * torch.sigmoid(raw[..., 0:1])
    elastic = 5.0 + 55.0 * torch.sigmoid(raw[..., 1:2])
    fracture_energy = 1.0 + 199.0 * torch.sigmoid(raw[..., 2:3])
    porosity = 0.02 + 0.58 * torch.sigmoid(raw[..., 3:4])
    return torch.cat([tensile, elastic, fracture_energy, porosity], dim=-1)


def transform_concrete_outputs(raw: Tensor) -> Tensor:
    """Return concrete compressive, tensile and flexural strengths."""

    compressive = 350.0 * torch.sigmoid(raw[..., 0:1])
    tensile = 0.5 + 29.5 * torch.sigmoid(raw[..., 1:2])
    flexural = 1.0 + 49.0 * torch.sigmoid(raw[..., 2:3])
    return torch.cat([compressive, tensile, flexural], dim=-1)
