Influence lines are constructed for a plane truss.
This example is adapted from a CE221 project .
Two analysis procedures are performed:# !pip install -U opensees veux xara
import xara import numpy as np import veux
def create_model(): model = xara.Model('basic', ndm=2, ndf=2) # ------------------------------ # Geometry parameters # ------------------------------ span = 12.0 # Total length in meters num_elem = 11 # Number of elements num_node = 7 # Number of node node_x_diff= span/(num_node-1) # ------------------------------ # Material properties # ------------------------------ # Material & section for W14x38 E = 210e9 # Pa # Young's modulus in Pascals (steel) A1 = 0.00723 # Cross-sectional area in m² Fy = 340e6 model.uniaxialMaterial("Steel02", 1, Fy, E, 0.02) # Material & section for HSS10x10x½ A2 = 0.00645 # Cross-sectional area in m² model.uniaxialMaterial("Steel02", 2, Fy, E, 0.02) # ------------------------------ # Define nodes # ------------------------------ for i in range(1, num_node+1): if i <= 4: model.node(i ,((i-1)*node_x_diff*2,0)) elif i>4: model.node(i ,(4*(i-5)+node_x_diff,node_x_diff)) # ------------------------------ # Define boundary conditions # ------------------------------ model.fix(1, (1, 1)) # Pin at node 1 model.fix(4, (0, 1)) # Roller at node 4 # ------------------------------ # Define beam and truss elements # ------------------------------ for i in range(1,num_elem+1): if i <=3: # Beam: W14x38 between nodes 1 and 2 model.element("truss", i, (i, i+1), A1, 1) elif i <=5: # Beam: HSS10x10x½ between node 5 and 6 model.element("truss", i, (i+1, i+2), A2, 2) elif i <=8: # Beam: HSS10x10x½ between node 1 and 5 model.element("truss", i, (i-5, i-1), A2, 2) elif i <=11: # Beam: HSS10x10x½ between node 2 and 5 model.element("truss", i, (i-4, i-7), A2, 2) return model model = create_model() veux.render(model)
def create_load(model, load, loc): "Add loading to a the model" model.timeSeries('Linear', 1) model.pattern('Plain', 1, 1) for node in range(1, 4+1): if model.nodeCoord(node)[0] > loc: break right_node = node left_node = node-1 L = 4 a = loc - model.nodeCoord(left_node)[0] model.load(left_node, (0, (4-a)/4*load), pattern=1) model.load(right_node, (0, a/4*load), pattern=1) return model
def analyze(model, steps=1): # ------------------------------ # Define analysis # ------------------------------ model.constraints('Plain') model.system('BandGeneral') model.test('NormUnbalance', 1.0e-7, 10) model.algorithm('Newton') model.integrator('LoadControl', 1/steps) model.analysis('Static') # ------------------------------ # Perform analysis # ------------------------------ u, p = [], [] for i in range(steps): model.analyze(1) p.append(model.getTime()) u.append(model.nodeDisp(6, 2)) return u, p
forces = {i: {"x": [], "force": []} for i in create_model().getEleTags()}
for x in np.linspace(0, 12, 10): model = create_model() create_load(model, 1.0, x) analyze(model) for elem in model.getEleTags(): forces[elem]["x"].append(x) forces[elem]["force"].append(model.eleResponse(elem, "basicForce"))
import matplotlib.pyplot as plt plt.style.use("veux-web") fig, ax = plt.subplots(figsize=(10, 6)) for elem in range(1, 12): ax.plot(forces[elem]["x"], forces[elem]["force"], label=f"Member {elem}") ax.set_xlabel("Location (m)") ax.set_ylabel("Axial Response (N/N)") fig.legend()
plt.plot(*analyze(create_load(create_model(), 10e6, 6.0), 40));