Note
Go to the end to download the full example code.
Building a model with MAPDL-style verbs#
When you don’t have a CDB and don’t want to build a pyvista mesh
from scratch, the femorph_solver.Model exposes a set of verbs
that mirror MAPDL’s /PREP7 commands one-to-one: n for nodes,
e for elements, et / mp / r for the type / material /
real tables. Here we build a 4-element cantilever beam out of
SOLID185 hexes entirely with the verb API — no pyvista, no CDB.
from __future__ import annotations
import numpy as np
import pyvista as pv
import femorph_solver
Start from an empty Model#
m = femorph_solver.Model()
m.et(1, "SOLID185")
m.mp("EX", 1, 2.1e11)
m.mp("PRXY", 1, 0.30)
m.mp("DENS", 1, 7850.0)
m.type(1)
m.mat(1)
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:24: 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(1, "SOLID185")
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:25: 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", 1, 2.1e11)
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:26: 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", 1, 0.30)
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:27: 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", 1, 7850.0)
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:28: DeprecationWarning: Model.type(...) is a MAPDL-dialect shortcut and has moved off the Model public surface. Use `APDL(model).type(et_id)` for line-by-line APDL deck porting, or the native `Model.from_grid(pv_grid)` for new code.
m.type(1)
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:29: DeprecationWarning: Model.mat(...) is a MAPDL-dialect shortcut and has moved off the Model public surface. Use `APDL(model).mat(mat_id)` for line-by-line APDL deck porting, or the native `Model.assign("HEX8", material, mat_id=...)` for new code.
m.mat(1)
Add nodes with n()#
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:41: DeprecationWarning: Model.n(...) is a MAPDL-dialect shortcut and has moved off the Model public surface. Use `APDL(model).n(num, x, y, z)` for line-by-line APDL deck porting, or the native `Model.from_grid(pv_grid)` for new code.
m.n(nn, i * LX / NX, j * LY, k * LZ)
Add elements with e()#
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:49: DeprecationWarning: Model.e(...) is a MAPDL-dialect shortcut and has moved off the Model public surface. Use `APDL(model).e(*node_nums)` for line-by-line APDL deck porting, or the native `Model.from_grid(pv_grid)` for new code.
m.e(
model: 20 nodes, 4 elements
Apply BCs and solve#
for j in range(2):
for k in range(2):
m.d(node_id[(0, j, k)], "ALL")
for j in range(2):
for k in range(2):
m.f(node_id[(NX, j, k)], "FZ", -250.0)
res = m.solve()
dof_map = m.dof_map()
tip_nodes = [node_id[(NX, j, k)] for j in range(2) for k in range(2)]
tip_uz = np.array(
[
res.displacement[int(np.where((dof_map[:, 0] == nn) & (dof_map[:, 1] == 2))[0][0])]
for nn in tip_nodes
]
)
print(f"tip UZ (mean over 4 corner nodes): {tip_uz.mean():.4e} m")
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:67: DeprecationWarning: Model.d(...) is a MAPDL-dialect shortcut and has moved off the Model public surface. Use `APDL(model).d(node, label, value)` for line-by-line APDL deck porting, or the native `Model.fix(nodes=..., where=..., dof=...)` for new code.
m.d(node_id[(0, j, k)], "ALL")
/home/runner/_work/solver/solver/examples/pre-processing/example_build_mesh.py:71: DeprecationWarning: Model.f(...) is a MAPDL-dialect shortcut and has moved off the Model public surface. Use `APDL(model).f(node, label, value)` for line-by-line APDL deck porting, or the native `Model.apply_force(node, fx=..., fy=..., fz=...)` for new code.
m.f(node_id[(NX, j, k)], "FZ", -250.0)
tip UZ (mean over 4 corner nodes): -1.4761e-06 m
Render#
grid = femorph_solver.io.static_result_to_grid(m, res)
plotter = pv.Plotter(off_screen=True)
plotter.add_mesh(grid, style="wireframe", color="gray", opacity=0.35, label="undeformed")
plotter.add_mesh(
grid.warp_by_vector("displacement", factor=500.0),
scalars="displacement_magnitude",
show_edges=True,
cmap="viridis",
scalar_bar_args={"title": "|u| [m]"},
label="deformed (×500)",
)
plotter.add_legend()
plotter.add_axes()
plotter.show()

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