Loading a CDB input deck#

Show the preferred CDB-reader workflow: load an MAPDL CDB with mapdl_archive, hand the parsed grid to 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 mapdl_archive, so it runs without any user-provided files.

from __future__ import annotations

import mapdl_archive
import numpy as np

import femorph_solver

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 SOLID185 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")
parsed grid: UnstructuredGrid (0x78fb962236a0)
  N Cells:    105
  N Points:   655
  X Bounds:   -1.216e+00, 5.571e-02
  Y Bounds:   -1.663e+00, -4.353e-01
  Z Bounds:   -7.875e-01, -2.610e-02
  N Arrays:   12
element types present: [np.int32(185)]
hex-only sub-grid: 101 cells, 230 nodes

Wrap the grid as a femorph-solver Model#

m = femorph_solver.Model.from_grid(grid)
m.et(185, "SOLID185")
/home/runner/_work/solver/solver/examples/pre-processing/example_cdb_load.py:39: DeprecationWarning: Model.et(...) is a MAPDL-dialect shortcut and has moved off the Model public surface.  Use `APDL(model).et(et_id, name)` for line-by-line APDL deck porting, or the native `Model.assign("HEX8", material)` for new code.
  m.et(185, "SOLID185")

Apply material properties#

for mat_id in np.unique(np.asarray(grid.cell_data["ansys_material_type"])):
    m.mp("EX", int(mat_id), 2.1e11)
    m.mp("PRXY", int(mat_id), 0.30)
    m.mp("DENS", int(mat_id), 7850.0)
/home/runner/_work/solver/solver/examples/pre-processing/example_cdb_load.py:45: DeprecationWarning: Model.mp(...) is a MAPDL-dialect shortcut and has moved off the Model public surface.  Use `APDL(model).mp(prop, mat_id, value)` for line-by-line APDL deck porting, or the native `Model.assign(element, {prop: value, ...})` for new code.
  m.mp("EX", int(mat_id), 2.1e11)
/home/runner/_work/solver/solver/examples/pre-processing/example_cdb_load.py:46: DeprecationWarning: Model.mp(...) is a MAPDL-dialect shortcut and has moved off the Model public surface.  Use `APDL(model).mp(prop, mat_id, value)` for line-by-line APDL deck porting, or the native `Model.assign(element, {prop: value, ...})` for new code.
  m.mp("PRXY", int(mat_id), 0.30)
/home/runner/_work/solver/solver/examples/pre-processing/example_cdb_load.py:47: DeprecationWarning: Model.mp(...) is a MAPDL-dialect shortcut and has moved off the Model public surface.  Use `APDL(model).mp(prop, mat_id, value)` for line-by-line APDL deck porting, or the native `Model.assign(element, {prop: value, ...})` for new code.
  m.mp("DENS", int(mat_id), 7850.0)

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:,}")
K: (690, 690), nnz = 33,750
M: (690, 690), nnz = 33,750

That’s the full pre-processing loop#

From here, any of the analyses under Analyses can take over — m.modal_solve(n_modes=10), m.solve(), m.transient_solve(...), or the free-standing solve_* functions if you need finer backend control.

Total running time of the script: (0 minutes 0.024 seconds)

Gallery generated by Sphinx-Gallery