Follower loading#
Download notebookCantilever beam subjected to follower end load.
import veux
import numpy as np
from veux.motion import Motion
import xara
import matplotlib.pyplot as plt
Modeling#
def create_cantilever(ne, element, transform="Corotational02"):
model = xara.Model(ndm=3, ndf=6)
L = 100
nen = 2
nmn = ne*(nen-1)+1
sec = 1
A = 1.61538e8
I = 3.5e7
model.section("ElasticFrame", sec,
E=1,
G=1,
A=A,
Ay=A,
Az=A,
Iy=I*100,
Iz=I,
J =I
)
model.geomTransf(transform, 1, (0,0,1))
for i,x in enumerate(np.linspace(0, L, nmn)):
model.node(i, (x,0,0))
for i in range(ne):
start = i * (nen - 1)
nodes = list(range(start, start + nen))
model.element(element, i+1, nodes,
section=sec, transform=1, shear=1)
model.fix(0, (1,1,1, 1,1,1))
return model
Loading#
To create the follower load, use "director" for the basis argument in a xara.FrameLoad.
def apply_loading(model):
# Tag of the last-created element
ne = model.getEleTags()[-1]
pattern = xara.StaticPattern([
xara.FrameLoad(model,
shape="Point",
force = [0, 1, 0],
basis = "director",
offset=[1.0,0,0],
elements=[ne]
)
])
# Add the pattern to the model
model.pattern(pattern)
Analysis#
def analyze(model: xara.Model, motion):
speed = 3000 # animation frames
Pmax = 150e3 # N
model.system('Umfpack')
model.integrator("LoadControl", Pmax/1000)
# model.test("NormDispIncr", 1e-10, 500, 1)
model.test("Energy", 1e-18, 10, 0)
# model.test("Residual", 1e-6, 200, 2)
model.algorithm("NewtonLineSearch", 0.8)
model.analysis("Static")
u = []
v = []
w = []
P = []
tip = model.getNodeTags()[-1]
while model.getTime() < Pmax:
if model.analyze(1) != 0:
print(f"Failed at time = {100*model.getTime()/Pmax}% with v = {v[-1]}")
break
motion.advance(time=model.getTime()/speed)
motion.draw_sections(rotation=model.nodeRotation,
position=model.nodeDisp)
u.append(-model.nodeDisp(tip, 1))
v.append( model.nodeDisp(tip, 2))
w.append( model.nodeDisp(tip, 3))
P.append( model.getTime())
return P, u, v, w
ne = 10
model = create_cantilever(ne, element="ForceFrame")
apply_loading(model)
artist = veux.create_artist(model, model_config=dict(extrude_outline="square"))
artist.draw_nodes(size=10)
artist.draw_sections()
motion = Motion(artist)
P, u, v, w = analyze(model, motion)
motion.add_to(artist.canvas)
artist
fig, ax = plt.subplots()
ax.set_xlabel("Load, $P$")
ax.set_ylabel(r"Displacement")
ax.axvline(0, color='black', linestyle='-', linewidth=1)
ax.axhline(0, color='black', linestyle='-', linewidth=1)
ax.plot(P, u, label="$u$")
ax.plot(P, v, label="$v$")
ax.plot(P, w, label="$w$")
ax.set_xlim([0, None])
ax.legend()
plt.show()
References#
C. M. Perez and F. C. Filippou, “On nonlinear geometric transformations of finite elements,” Numerical Meth Engineering, vol. 125, no. 17, Sep. 2024, doi: 10.1002/nme.7506.