"""TorsoCAE journal: L, T and X joints of identical steel plates (SEA line junctions)."""

from __future__ import annotations

import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[4]
SERVER_DIR = ROOT / "server"
if str(SERVER_DIR) not in sys.path:
    sys.path.insert(0, str(SERVER_DIR))

from pytorsocae import TorsoCAESession

THICKNESS = 0.004
WIDTH = 0.8                      # along the junction line, m
BASE_LENGTH, WEB_HEIGHT = 1.0, 0.6
YOUNG, POISSON, DENSITY = 210.0e9, 0.3, 7850.0
LOSS = 0.01
BAND_HZ = 20.0                   # one-third-octave band, well below the in-plane wave regime
JOINTS = ("L", "T", "X")


def run_case(joint: str) -> dict:
    """The base plate along x, a web standing on it (and for X a second one hanging below)."""
    if joint not in JOINTS:
        raise ValueError(f"joint must be one of {JOINTS}")
    line_x = BASE_LENGTH - THICKNESS if joint == "L" else 0.5 * (BASE_LENGTH - THICKNESS)
    session = TorsoCAESession()
    session.csg_make_shape("box", {"dx": BASE_LENGTH, "dy": WIDTH, "dz": THICKNESS, "cx": 0, "cy": 0, "cz": 0},
                           name="Base", body_id="body_0")
    session.csg_make_shape("box", {"dx": THICKNESS, "dy": WIDTH, "dz": WEB_HEIGHT, "cx": line_x, "cy": 0,
                                   "cz": THICKNESS}, name="Upper web", body_id="body_1")
    bodies = ["body_0", "body_1"]
    if joint == "X":
        session.csg_make_shape("box", {"dx": THICKNESS, "dy": WIDTH, "dz": WEB_HEIGHT, "cx": line_x, "cy": 0,
                                       "cz": -WEB_HEIGHT}, name="Lower web", body_id="body_2")
        bodies.append("body_2")
    session.set_physics("structural", submodel="statistical_energy_analysis", backend="torso")
    for index, body in enumerate(bodies):
        session.select_body(body)
        session.mesh(mesh_id=f"mesh_{index}", algo_id="structured_hex", size_factor=1, size_min=0, size_max=0.1,
                     order=1, dim=3)
        session.set_mesh_physics(f"mesh_{index}", "sea_plate")
        session.solid(body).material(E=YOUNG, nu=POISSON, rho=DENSITY, damping_loss_factor=LOSS, physics="sea_plate")
    session.auto_tie()
    session.surface(5, scope_id="body_0").bc("sea_point_force", values=[1.0])
    session.set_model_options(sea_band_type="third_octave", frequency_start_hz=BAND_HZ, frequency_stop_hz=BAND_HZ)
    return session.compute()


if __name__ == "__main__":
    for joint in JOINTS:
        print(joint, run_case(joint)["npz_path"])
