# Element stiffness matrix in local coordinates
k_local = (E*A/L) * np.array([
[1, -1],
[-1, 1]
])
# Transformation matrix
T = np.array([
[c, s, 0, 0],
[0, 0, c, s]
])
# Element stiffness matrix in global coordinates
k_global = T.T @ k_local @ T
# Get global DOF indices
dof_indices = [
2*(node1-1), 2*(node1-1)+1,
2*(node2-1), 2*(node2-1)+1
]
# Add to global stiffness matrix
for i in range(4):
for j in range(4):
K_global[dof_indices[i], dof_indices[j]] += k_global[i,
j]
# Apply boundary conditions
fixed_dofs = []
for node_id, support in self.supports.items():
if support == 'fixed':
fixed_dofs.extend([2*(node_id-1), 2*(node_id-1)+1])
elif support == 'pinned' or support == 'roller':
fixed_dofs.append(2*(node_id-1)+1) # Fixed in y-direction
# Remove fixed DOFs from the system
free_dofs = [i for i in range(2*num_nodes) if i not in fixed_dofs]
K_reduced = K_global[np.ix_(free_dofs, free_dofs)]
# Create force vector
F = np.zeros(2*num_nodes)
for node_id, force in self.forces.items():
F[2*(node_id-1)] = force['fx']
F[2*(node_id-1)+1] = force['fy']
F_reduced = F[free_dofs]
# Solve for displacements
try:
displacements = np.linalg.solve(K_reduced, F_reduced)
except np.linalg.LinAlgError:
print("Error: Structure is unstable or matrix is singular")
return
# Create full displacement vector
U = np.zeros(2*num_nodes)
U[free_dofs] = displacements
P a g e 4 | 62