{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import pyvista\npyvista.OFF_SCREEN = True\npyvista.set_jupyter_backend('static')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Loading a CDB input deck\n\nShow the preferred CDB-reader workflow: load a MAPDL CDB deck with\n:mod:`mapdl_archive`, hand the parsed grid to\n:meth:`femorph_solver.Model.from_grid`, stamp a material, and assemble\nthe global stiffness / mass matrices.\n\nThe example uses the 15-sector rotor deck that ships with\n:mod:`mapdl_archive`, so it runs without any user-provided files.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from __future__ import annotations\n\nimport mapdl_archive\nimport numpy as np\n\nimport femorph_solver\nfrom femorph_solver import ELEMENTS"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Parse the CDB\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "archive = mapdl_archive.Archive(mapdl_archive.examples.sector_archive_file)\nprint(f\"parsed grid: {archive.grid}\")\nprint(f\"element types present: {sorted(set(archive.etype))}\")\n\n# The shipped fixture has 101 HEX8 cells plus 4 WEDGE6 tip cells.\n# femorph-solver's HEX8 kernel is hex-only, so we drop the wedges\n# (``VTK_HEXAHEDRON`` is cell type 12).\nhex_idx = np.where(archive.grid.celltypes == 12)[0]\ngrid = archive.grid.extract_cells(hex_idx).cast_to_unstructured_grid()\nprint(f\"hex-only sub-grid: {grid.n_cells} cells, {grid.n_points} nodes\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Wrap the grid as a femorph-solver ``Model``\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "m = femorph_solver.Model.from_grid(grid)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Apply material properties\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mat_ids = np.unique(np.asarray(grid.cell_data[\"ansys_material_type\"]))\nfor mat_id in mat_ids:\n    m.assign(\n        ELEMENTS.HEX8,\n        material={\"EX\": 2.1e11, \"PRXY\": 0.30, \"DENS\": 7850.0},\n        et_id=185,\n        mat_id=int(mat_id),\n    )"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Assemble K and M\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "K = m.stiffness_matrix()\nM = m.mass_matrix()\nprint(f\"K: {K.shape}, nnz = {K.nnz:,}\")\nprint(f\"M: {M.shape}, nnz = {M.nnz:,}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## That's the full pre-processing loop\nFrom here, any of the analyses under :doc:`/gallery/analyses/index`\ncan take over \u2014 ``m.solve_modal(n_modes=10)``, ``m.solve_static()``,\n``m.solve_transient(...)``, or the free-standing ``solve_*`` functions\nif you need finer backend control.\n\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.12.3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}