"""
Loading a CDB input deck
========================

Show the preferred CDB-reader workflow: load a MAPDL CDB deck with
:mod:`mapdl_archive`, hand the parsed grid to
:meth:`femorph_solver.Model.from_grid`, stamp a material, and assemble
the global stiffness / mass matrices.

The example uses the 15-sector rotor deck that ships with
:mod:`mapdl_archive`, so it runs without any user-provided files.
"""

from __future__ import annotations

import mapdl_archive
import numpy as np

import femorph_solver
from femorph_solver import ELEMENTS

# %%
# Parse the CDB
# -------------
archive = mapdl_archive.Archive(mapdl_archive.examples.sector_archive_file)
print(f"parsed grid: {archive.grid}")
print(f"element types present: {sorted(set(archive.etype))}")

# The shipped fixture has 101 HEX8 cells plus 4 WEDGE6 tip cells.
# femorph-solver's HEX8 kernel is hex-only, so we drop the wedges
# (``VTK_HEXAHEDRON`` is cell type 12).
hex_idx = np.where(archive.grid.celltypes == 12)[0]
grid = archive.grid.extract_cells(hex_idx).cast_to_unstructured_grid()
print(f"hex-only sub-grid: {grid.n_cells} cells, {grid.n_points} nodes")

# %%
# Wrap the grid as a femorph-solver ``Model``
# --------------------------------------------
m = femorph_solver.Model.from_grid(grid)

# %%
# Apply material properties
# -------------------------
mat_ids = np.unique(np.asarray(grid.cell_data["ansys_material_type"]))
for mat_id in mat_ids:
    m.assign(
        ELEMENTS.HEX8,
        material={"EX": 2.1e11, "PRXY": 0.30, "DENS": 7850.0},
        et_id=185,
        mat_id=int(mat_id),
    )

# %%
# Assemble K and M
# ----------------
K = m.stiffness_matrix()
M = m.mass_matrix()
print(f"K: {K.shape}, nnz = {K.nnz:,}")
print(f"M: {M.shape}, nnz = {M.nnz:,}")

# %%
# That's the full pre-processing loop
# -----------------------------------
# From here, any of the analyses under :doc:`/gallery/analyses/index`
# can take over — ``m.solve_modal(n_modes=10)``, ``m.solve_static()``,
# ``m.solve_transient(...)``, or the free-standing ``solve_*`` functions
# if you need finer backend control.
