"""TorsoCAE journal: sound transmission between two rooms through an aluminium panel (SEA)."""

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

ROOM = (2.0, 1.5, 1.2)            # each room's depth (x), width (y), height (z), m
THICKNESS = 0.006                 # panel, m; its faces are the rooms' shared wall
YOUNG, POISSON, DENSITY = 70.0e9, 0.33, 2700.0
PANEL_LOSS = 0.01
AIR_DENSITY, SOUND_SPEED = 1.21, 343.0
ROOM_LOSS = 0.01
SOURCE_POWER = 0.01               # W per band into the source room
LIMITING_ANGLE_DEG = 78.0
BANDS = ("third_octave", 100.0, 10000.0)


def run_case() -> dict:
    session = TorsoCAESession()
    depth, width, height = ROOM
    session.csg_make_shape("box", {"dx": depth, "dy": width, "dz": height, "cx": -depth, "cy": 0, "cz": 0},
                           name="Source room", body_id="body_0")
    session.csg_make_shape("box", {"dx": THICKNESS, "dy": width, "dz": height, "cx": 0, "cy": 0, "cz": 0},
                           name="Panel", body_id="body_1")
    session.csg_make_shape("box", {"dx": depth, "dy": width, "dz": height, "cx": THICKNESS, "cy": 0, "cz": 0},
                           name="Receiving room", body_id="body_2")
    for index, body in enumerate(("body_0", "body_1", "body_2")):
        session.select_body(body)
        session.mesh(mesh_id=f"mesh_{index}", algo_id="structured_hex", size_factor=1, size_min=0, size_max=0.3,
                     order=1, dim=3)
    session.set_physics("structural", submodel="statistical_energy_analysis", backend="torso")
    session.set_mesh_physics("mesh_0", "sea_acoustic_cavity")
    session.set_mesh_physics("mesh_1", "sea_plate")
    session.set_mesh_physics("mesh_2", "sea_acoustic_cavity")
    session.solid("body_1").material(E=YOUNG, nu=POISSON, rho=DENSITY, damping_loss_factor=PANEL_LOSS,
                                     physics="sea_plate")
    for body in ("body_0", "body_2"):
        session.solid(body).material(rho=AIR_DENSITY, sound_speed=SOUND_SPEED, damping_loss_factor=ROOM_LOSS,
                                     physics="sea_acoustic_cavity")
    session.auto_tie()
    session.surface(1, scope_id="body_0").bc("sea_input_power", values=[SOURCE_POWER])
    kind, start, stop = BANDS
    session.set_model_options(sea_band_type=kind, frequency_start_hz=start, frequency_stop_hz=stop,
                              nonresonant_limiting_angle_deg=LIMITING_ANGLE_DEG)
    return session.compute()


if __name__ == "__main__":
    print(run_case()["npz_path"])
