34 lines
1.0 KiB
Python
34 lines
1.0 KiB
Python
import numpy as np
|
|
from scipy.sparse.linalg import spsolve
|
|
|
|
from femsurrogate.fea.assembly import (
|
|
assemble_global_stiffness,
|
|
assemble_load_vector,
|
|
constrained_dofs,
|
|
node_ids,
|
|
)
|
|
from femsurrogate.fea.model import BeamModel, Displacement
|
|
|
|
|
|
def solve_linear_static(model: BeamModel) -> dict[int, Displacement]:
|
|
stiffness = assemble_global_stiffness(model)
|
|
loads = assemble_load_vector(model)
|
|
fixed = np.array(constrained_dofs(model), dtype=int)
|
|
all_dofs = np.arange(loads.size)
|
|
free = np.setdiff1d(all_dofs, fixed, assume_unique=True)
|
|
|
|
displacements = np.zeros_like(loads)
|
|
displacements[free] = spsolve(stiffness[free][:, free], loads[free])
|
|
|
|
result: dict[int, Displacement] = {}
|
|
for position, node_id in enumerate(node_ids(model)):
|
|
base = position * 3
|
|
result[node_id] = Displacement(
|
|
node_id=node_id,
|
|
ux=float(displacements[base]),
|
|
uy=float(displacements[base + 1]),
|
|
rz=float(displacements[base + 2]),
|
|
)
|
|
|
|
return result
|