Note
Go to the end to download the full example code.
Building a model from a pyvista grid#
When you don’t have a CDB on disk, the easiest way to build a
femorph_solver.Model from scratch is to author a
pyvista.UnstructuredGrid directly and hand it to
femorph_solver.Model.from_grid(). Here we build a 4-element
HEX8 cantilever beam this way — no foreign deck required.
from __future__ import annotations
import numpy as np
import pyvista as pv
from vtkmodules.util.vtkConstants import VTK_HEXAHEDRON
import femorph_solver
from femorph_solver import ELEMENTS
Wrap as a Model and stamp material#
m = femorph_solver.Model.from_grid(grid)
m.assign(ELEMENTS.HEX8, material={"EX": 2.1e11, "PRXY": 0.30, "DENS": 7850.0})
print(f"model: {m.n_nodes} nodes, {m.n_elements} elements")
model: 20 nodes, 4 elements
Apply BCs and solve#
node_nums = np.asarray(grid.point_data["ansys_node_num"])
pts = np.asarray(grid.points)
fixed = node_nums[pts[:, 0] < 1e-9]
m.fix(nodes=fixed.tolist(), dof="ALL")
tip_mask = pts[:, 0] > LX - 1e-9
tip_nodes = node_nums[tip_mask]
for tip_nn in tip_nodes:
m.apply_force(int(tip_nn), fz=-250.0)
res = m.solve()
dof_map = m.dof_map()
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")
tip UZ (mean over 4 corner nodes): -1.4761e-06 m
Render#
deformed = femorph_solver.io.static_result_to_grid(m, res)
plotter = pv.Plotter(off_screen=True)
plotter.add_mesh(deformed, style="wireframe", color="gray", opacity=0.35, label="undeformed")
plotter.add_mesh(
deformed.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 1.112 seconds)