Skip to content

Commit 5b49a63

Browse files
committed
cmp - update cyclic example
1 parent eab1e19 commit 5b49a63

File tree

5 files changed

+137
-25
lines changed

5 files changed

+137
-25
lines changed

content/en/examples/FrameCycling/column_cycles.py

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# Written: Vesna Terzic (vesna@berkeley.edu)
66
# Created: 12/2011
77
#
8+
import os
89
from math import sqrt, pi
910
import opensees.openseespy as ops
1011
import matplotlib.pyplot as plt
@@ -170,19 +171,9 @@ def lehman_section(model, D, clearCover):
170171
# Aggregate shear to the RC section
171172
secTag = secnTag + 1
172173
model.section("Aggregator", secTag, steelTag + 6, "Vy", "-section", secnTag)
173-
return secTag
174+
return secTag
174175

175-
if __name__ == "__main__":
176-
# Set element type (force-based = 1, displacement-based = 2)
177-
eleType = 1
178-
179-
# Number of finite elements and integration points per element
180-
if eleType == 1:
181-
ne = 1
182-
nIP = 5
183-
elif eleType == 2:
184-
ne = 4
185-
nIP = 3
176+
def create_column(ne, nIP, element):
186177

187178
# Create a 2D model with 3 DOFs per node
188179
model = ops.Model(ndm=2, ndf=3)
@@ -211,12 +202,15 @@ def lehman_section(model, D, clearCover):
211202
model.geomTransf("Corotational", transfTag)
212203

213204
for i in range(ne):
214-
if eleType == 1:
215-
model.element("forceBeamColumn", i + 1, (i + 1, i + 2), nIP, secTag, transfTag)
216-
elif eleType == 2:
217-
model.element("dispBeamColumn", i + 1, (i + 1, i + 2), nIP, secTag, transfTag)
205+
model.element(element, i + 1, (i + 1, i + 2), nIP, secTag, transfTag)
206+
207+
return model
218208

219209

210+
def analyze_column(ne, nIP, eleType):
211+
212+
model = create_column(ne, nIP, eleType)
213+
220214
# Define Gravity Load
221215
IDctrlNode = ne + 1
222216

@@ -268,8 +262,8 @@ def lehman_section(model, D, clearCover):
268262
model.sp(IDctrlNode, IDctrlDOF, 1.0, pattern=2)
269263

270264
# Define recorders for displacement and force
271-
model.recorder("Node", "disp", "-file", "out/Disp.out", "-time", "-node", ne + 1, dof=1)
272-
model.recorder("Node", "reaction", "-file", "out/Force.out", "-time", "-node", 1, dof=1)
265+
model.recorder("Node", "disp", "-time", file="out/_disp.out", node=ne+1, dof=1)
266+
model.recorder("Node", "reaction", "-time", file="out/_force.out", node=1, dof=1)
273267

274268
# Cyclic analysis
275269
model.constraints("Penalty", 1.0e14, 1.0e14)
@@ -281,5 +275,52 @@ def lehman_section(model, D, clearCover):
281275
model.analysis("Static")
282276

283277
ok = model.analyze(anpts)
278+
if ok != 0:
279+
raise Exception("Analysis failed")
280+
281+
model.wipe()
284282

283+
with open("out/_disp.out", "r") as f:
284+
lines = f.readlines()
285+
disp = [float(line.split()[1]) for line in lines]
286+
time = [float(line.split()[0]) for line in lines]
287+
with open("out/_force.out", "r") as f:
288+
lines = f.readlines()
289+
force = [float(line.split()[1]) for line in lines]
285290

291+
os.remove("out/_disp.out")
292+
os.remove("out/_force.out")
293+
294+
295+
return time, disp, force
296+
297+
if __name__ == "__main__":
298+
299+
fig, ax = plt.subplots()
300+
301+
# Set element type (force-based = 1, displacement-based = 2)
302+
for element in "dispBeamColumn", "forceBeamColumn":
303+
# Number of finite elements and integration points per element
304+
if "force" in element:
305+
ne = 1
306+
nIP = 5
307+
else:
308+
# Displacement formulation
309+
ne = 4
310+
nIP = 3
311+
312+
time, disp, force = analyze_column(ne, nIP, element)
313+
314+
ax.plot(disp, force, label=element)
315+
316+
ax.set_xlabel("Displacement [in]")
317+
ax.set_ylabel("Force [kips]")
318+
fig.legend()
319+
plt.show()
320+
321+
322+
fig, ax = plt.subplots()
323+
ax.plot(time, disp)
324+
ax.set_xlabel("Time [s]")
325+
ax.set_ylabel("Displacement [in]")
326+
plt.show()

content/en/examples/FrameCycling/index.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,15 @@ The intent of this example is to show how to properly model inelastic beam-colum
3737
## Model Generation
3838

3939
- The column is modeled using either force-based or displacement-based elements.
40-
- The column height <code>H</code> is 96 inches, and the diameter <code>D</code> is 24 inches.
41-
- The clear cover of concrete <code>clearCover</code> is 0.75 inches.
40+
- The column height <code>H</code> is 96 inches
4241

4342
```python
4443
import xara
44+
4545
# Create a 2D model with 3 DOFs per node
4646
model = xara.Model(ndm=2, ndf=3)
4747

48-
# Input parameters
4948
H = 96.0 * inch # Column height
50-
D = 24.0 * inch # Column diameter
51-
clearCover = 0.75 * inch # Clear cover of concrete
5249

5350
# Define nodes
5451
model.node(1, (0.0, 0.0))
@@ -108,7 +105,13 @@ $$
108105

109106
### Section
110107

108+
- The diameter <code>D</code> is 24 inches.
109+
- The clear cover of concrete <code>clearCover</code> is 0.75 inches.
110+
111111
```python
112+
D = 24.0 * inch # Column diameter
113+
clearCover = 0.75 * inch # Clear cover of concrete
114+
112115
theta = 360.0 / numBars
113116
model.section("fiberSec", secnTag, GJ=1e8)
114117
# Core patch
@@ -141,6 +144,12 @@ for i in range(ne):
141144

142145
### Cycling
143146

147+
```python
148+
# Define recorders for displacement and force
149+
model.recorder("Node", "disp", "-time", file="out/Disp.out", node=ne+1, dof=1)
150+
model.recorder("Node", "reaction", "-time", file="out/Force.out", node=1, dof=1)
151+
```
152+
144153
## Resources
145154

146155
The slides from the original presentation can be downloaded <a href="https://opensees.berkeley.edu/wiki/images/c/c5/FFvsDF.pdf">here</a>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import matplotlib.pyplot as plt
2+
plt.style.use("veux-web")
3+
import numpy as np
4+
5+
def main(argv):
6+
x = None
7+
y_files = []
8+
argi = iter(argv)
9+
for arg in argi:
10+
if arg == "--x":
11+
x = next(argi)
12+
else:
13+
if x is None:
14+
x = np.loadtxt(arg)
15+
else:
16+
y_files.append(arg)
17+
18+
print(y_files)
19+
ys = [
20+
np.loadtxt(f)[:,-1]
21+
for f in y_files
22+
]
23+
if len(ys) > 0:
24+
for y in ys:
25+
plt.plot(x, y)
26+
else:
27+
plt.plot(x)
28+
29+
plt.show()
30+
31+
if __name__ == "__main__":
32+
import sys
33+
main(sys.argv[1:])

content/en/examples/FrameOffsets/diamond.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def diamond_solution(EI, EA, L, off=0):
1414
[0, 0, 1],
1515
[0, 0, off/np.sqrt(2)]])
1616

17-
A = Ag@Ao #Ag[:,:3]@Ao[:3,:]
17+
A = Ag@Ao
1818
Ke = np.array([[EA/Le, 0, 0],
1919
[ 0, 4*EI/Le, 2*EI/Le],
2020
[ 0, 2*EI/Le, 4*EI/Le]])
Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
11
---
22
title: Rigid Offsets
3-
draft: true
3+
draft: false
44
---
55

6+
In this example we investigate the `offset` argument for frame geometric transformations.
7+
8+
$$
9+
\boldsymbol{A}_v = \begin{bmatrix}
10+
-dX/L_e & dY/L_e & 0 & dX/L_e \\
11+
-dY/L_e^2 & -dX/L_e^2 & 0 & dY/L_e^2 \\
12+
-dY/L_e^2 & -dX/L_e^2 & 1 & dY/L_e^2 \\
13+
\end{bmatrix}
14+
$$
15+
16+
$$
17+
\boldsymbol{A}_o =
18+
\begin{bmatrix}
19+
0 & 1 & 0 \\
20+
1 & 0 & -L_o/\sqrt{2} \\
21+
0 & 0 & 1 \\
22+
0 & 0 & L_o/\sqrt{2} \\
23+
\end{bmatrix}
24+
$$
25+
26+
$$
27+
\boldsymbol{K}_e = \begin{bmatrix}
28+
EA/L_e & 0 & 0 \\
29+
0 & 4 EI/L_e & 2 EI/L_e \\
30+
0 & 2 EI/L_e & 4 EI/L_e \\
31+
\end{bmatrix}
32+
$$
33+
34+
{{< fold diamond.py >}}
635

0 commit comments

Comments
 (0)