Skip to content

Commit a1aafa1

Browse files
committed
cmp
1 parent 3ce2fe4 commit a1aafa1

File tree

7 files changed

+640
-22
lines changed

7 files changed

+640
-22
lines changed

assets/img/examples/e0020.png

-112 KB
Loading

content/en/examples/Example3/index.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ is created using steel and concrete fibers.
6969

7070
### Materials
7171

72-
7372
![](img/RCsection0.svg)
7473

7574
{{< tabs tabTotal="2" >}}

content/en/examples/FrameBuckling/index.md

Lines changed: 285 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
---
2-
title: "Linearized Buckling"
3-
tags: ["Python", "Tcl", "Frame"]
2+
#title: "Linearized Buckling"
3+
title: "Column Buckling"
4+
meta:
5+
title: "A nonlinear buckling simulation of a column with varied boundary conditions and finite element formulations"
6+
tags: ["Frame"]
47
#render: ./model.glb
5-
description: Corotational frame elements are used to approximate Euler's buckling load.
8+
description: >-
9+
This example performs a nonlinear buckling analysis of a column under axial load,
10+
using various element formulations and end conditions.
611
downloads:
712
Python: ["buckling.py"]
813
Tcl: ["buckling.tcl"]
14+
weight: 20
915
---
1016

1117

1218
## Problem
1319

14-
Corotational frame elements are used to approximate Euler's buckling load which is given by:
20+
This example analyzes a column subject to axial loading until buckling occurs.
21+
Different element types, shear deformation settings, and boundary conditions are compared
22+
by computing the critical load and comparing it to the theoretical Euler load which is given by:
1523

1624
\[
1725
P_{\mathrm{euler}} = \frac{\pi^2 EI}{L^2}
@@ -57,3 +65,276 @@ $$
5765
$$
5866
\tan \lambda_{\text {cr }}=\chi \lambda_{\text {cr }}=\frac{\lambda_{\text {cr }}}{1+\lambda_{\text {cr }} 2 \varphi / 12}
5967
$$
68+
69+
## Implementation
70+
71+
72+
## Model
73+
74+
We begin by importing the required modules and defining some material and section properties.
75+
76+
{{< tabs tabTotal="2" >}}
77+
{{% tab name="Python" %}}
78+
```python
79+
import opensees.openseespy as ops
80+
import numpy as np
81+
from math import pi
82+
83+
FACTORS = {
84+
"pin-pin": 1,
85+
"fix-roll": 1,
86+
"fix-fix": 0.5,
87+
"fix-pin": 0.7,
88+
"fix-free": 2,
89+
"pin-roll": 2,
90+
}
91+
```
92+
{{% /tab %}}
93+
{{< /tabs >}}
94+
95+
We define a function `create_column` that constructs the finite element model of the column
96+
based on options like element type, shear deformation flag, and spatial dimension:
97+
98+
{{< tabs tabTotal="2" >}}
99+
{{% tab name="Python" %}}
100+
```python
101+
def create_column(boundary="pin-pin", elem_data=None, ndm=2):
102+
if elem_data is None:
103+
elem_data = {}
104+
105+
elem_type = elem_data.get("type", "forceBeamColumnCBDI")
106+
geom_type = elem_data.get("transform", "Corotational")
107+
use_shear = elem_data.get("shear", False)
108+
kinematics = elem_data.get("order", 0)
109+
110+
E = 29000.0
111+
G = 11200.0
112+
A = 112.0
113+
I = 110.0
114+
Ay = 3/6*A
115+
Az = 3/6*A
116+
L = 60.0
117+
ne = 10
118+
nIP = 5
119+
120+
model = ops.Model(ndm=ndm)
121+
122+
for i in range(1, ne+2):
123+
y = (i-1)/float(ne)*L
124+
location = (0.0, y, 0.0) if ndm == 3 else (0.0, y)
125+
model.node(i, location)
126+
model.mass(i, *[1.0]*model.getNDF())
127+
128+
fix_node(model, 1, boundary.split("-")[0])
129+
fix_node(model, ne+1, boundary.split("-")[1])
130+
```
131+
{{% /tab %}}
132+
{{< /tabs >}}
133+
134+
The section is defined as an `ElasticFrame` and assigned to each element in the column:
135+
136+
{{< tabs tabTotal="2" >}}
137+
{{% tab name="Python" %}}
138+
```python
139+
sec_tag = 1
140+
properties = [E, A, I]
141+
if ndm == 3:
142+
properties += [2*I, "-J", 100*I, "-G", G]
143+
if use_shear:
144+
properties += ["-Ay", Ay, "-G", G]
145+
if ndm == 3:
146+
properties += ["-Az", Az]
147+
model.section("ElasticFrame", sec_tag, *properties)
148+
149+
geo_tag = 1
150+
vector = (0, 0, 1) if ndm == 3 else ()
151+
model.geomTransf(geom_type, geo_tag, *vector)
152+
153+
for i in range(1, ne+1):
154+
model.element(elem_type, i, (i, i+1),
155+
section=sec_tag,
156+
transform=geo_tag,
157+
order=kinematics,
158+
shear=int(use_shear))
159+
```
160+
{{% /tab %}}
161+
{{< /tabs >}}
162+
163+
The axial load is applied at the top node, using the Euler buckling expression as a reference:
164+
165+
{{< tabs tabTotal="2" >}}
166+
{{% tab name="Python" %}}
167+
```python
168+
if use_shear:
169+
phi = 12*E*I/(Ay*G*L**2)
170+
lam = buckle_factor(boundary, phi)
171+
kL = L/lam
172+
euler_load = E*I/kL**2 / (1 + lam**2*phi/12)
173+
else:
174+
kL = L / buckle_factor(boundary)
175+
euler_load = E*I/kL**2
176+
177+
model.pattern("Plain", 1, "Linear")
178+
load = (0.0, -euler_load, 0.0) if ndm == 2 else (0.0, -euler_load, 0.0, 0, 0, 0)
179+
model.load(ne+1, *load, pattern=1)
180+
181+
return model, euler_load
182+
```
183+
{{% /tab %}}
184+
{{< /tabs >}}
185+
186+
## Buckling Analysis
187+
188+
A nonlinear static analysis is performed to determine the limit load. The first
189+
eigenvalue of the tangent stiffness matrix is tracked and interpolated to find the
190+
load factor at which it reaches zero.
191+
192+
{{< tabs tabTotal="2" >}}
193+
{{% tab name="Python" %}}
194+
```python
195+
def buckling_analysis(model, peak_load):
196+
load_step = 0.01
197+
PeakLoadRatio = 1.5
198+
199+
model.system('UmfPack')
200+
model.test("EnergyIncr", 1e-8, 20, 9)
201+
model.algorithm("Newton")
202+
model.integrator("LoadControl", load_step)
203+
model.analysis("Static")
204+
205+
lam_0 = model.getTime()
206+
eig_0 = model.eigen("-fullGenLapack", 1)[0]
207+
208+
limit_load = None
209+
for i in range(1, int(PeakLoadRatio/load_step)+1):
210+
if model.analyze(1) != 0:
211+
break
212+
lam = model.getTime()
213+
eig = model.eigen("-fullGenLapack", 1)[0]
214+
if eig <= 0.0:
215+
lam_i = lam_0 + (lam - lam_0)*eig_0/(eig_0-eig)
216+
limit_load = lam_i * peak_load
217+
break
218+
lam_0 = lam
219+
eig_0 = eig
220+
221+
return limit_load
222+
```
223+
{{% /tab %}}
224+
{{< /tabs >}}
225+
226+
## Results
227+
228+
The following script compares element formulations and boundary conditions in 3D with and without shear deformation:
229+
230+
{{< tabs tabTotal="2" >}}
231+
{{% tab name="Python" %}}
232+
```python
233+
if __name__ == "__main__":
234+
for ndm in (3,):
235+
for shear in (False, True):
236+
for elem in ("PrismFrame", "ForceFrame", "ExactFrame"):
237+
print(f"\n{elem:10} Shear Order Theory Computed Error")
238+
for boundary in FACTORS:
239+
orders = (0,)
240+
for order in orders:
241+
if not shear and "Exact" in elem:
242+
continue
243+
elem_data = {
244+
"type": elem,
245+
"shear": shear,
246+
"order": order,
247+
"transform": "Corotational"
248+
}
249+
model, euler_load = create_column(boundary, elem_data, ndm=ndm)
250+
limit_load = buckling_analysis(model, euler_load)
251+
model.wipe()
252+
del model
253+
print(f" {boundary:10} {shear:8} {order:8} ", end="")
254+
if limit_load is None:
255+
print("No singularity found.")
256+
else:
257+
err = 100*(limit_load/euler_load - 1)
258+
print(f"{euler_load:10.2f} {limit_load:10.2f} {err:10.3f} %")
259+
```
260+
{{% /tab %}}
261+
{{< /tabs >}}
262+
263+
264+
### Euler
265+
266+
| Boundary | Critical Load |
267+
|-------------|---------------|
268+
| pin-pin | 8745.57 |
269+
| fix-roll | 8745.57 |
270+
| fix-fix | 34982.26 |
271+
| fix-pin | 17891.23 |
272+
| fix-free | 2186.39 |
273+
| pin-roll | 2186.39 |
274+
275+
PrismFrame
276+
277+
| Boundary | Computed | Error |
278+
|-------------|---------------|-----------|
279+
| pin-pin | 8841.80 | 1.100 % |
280+
| fix-roll | 8841.80 | 1.100 % |
281+
| fix-fix | 36559.09 | 4.507 % |
282+
| fix-pin | 18296.87 | 2.267 % |
283+
| fix-free | 2192.37 | 0.273 % |
284+
| pin-roll | 2192.37 | 0.273 % |
285+
286+
ForceFrame
287+
288+
| Boundary | Computed | Error |
289+
|-------------|------------|----------|
290+
| pin-pin | 8841.80 | 1.100 % |
291+
| fix-roll | 8841.80 | 1.100 % |
292+
| fix-fix | 36559.09 | 4.507 % |
293+
| fix-pin | 18296.87 | 2.267 % |
294+
| fix-free | 2192.37 | 0.273 % |
295+
| pin-roll | 2192.37 | 0.273 % |
296+
297+
### Shear
298+
299+
PrismFrame
300+
301+
| Boundary | Computed | Error |
302+
|-----------|------------|-----------|
303+
| pin-pin | 8718.89 | 1.085 % |
304+
| fix-roll | 8718.88 | 1.085 % |
305+
| fix-fix | 34545.22 | 4.259 % |
306+
| fix-pin | 17727.65 | 2.192 % |
307+
| fix-free | 2184.73 | 0.272 % |
308+
| pin-roll | 2184.73 | 0.273 % |
309+
310+
ForceFrame
311+
312+
| Boundary | Computed | Error |
313+
|-----------|------------|-----------|
314+
| pin-pin | 8718.89 | 1.085 % |
315+
| fix-roll | 8718.88 | 1.085 % |
316+
| fix-fix | 34545.22 | 4.259 % |
317+
| fix-pin | 17727.65 | 2.192 % |
318+
| fix-free | 2184.73 | 0.272 % |
319+
| pin-roll | 2184.73 | 0.273 % |
320+
321+
ExactFrame
322+
323+
| Boundary | Computed | Error |
324+
|-----------|------------|-----------|
325+
| pin-pin | 8792.02 | 1.933 % |
326+
| fix-roll | 8792.01 | 1.933 % |
327+
| fix-fix | 35773.31 | 7.965 % |
328+
| fix-pin | 18068.91 | 4.159 % |
329+
| fix-free | 2189.24 | 0.480 % |
330+
| pin-roll | 2189.25 | 0.480 % |
331+
332+
333+
| Boundary | Critical Load |
334+
|-----------|------------|
335+
| pin-pin | 8625.30
336+
| fix-roll | 8625.30
337+
| fix-fix | 33134.20
338+
| fix-pin | 17347.40
339+
| fix-free | 2178.80
340+
| pin-roll | 2178.80

0 commit comments

Comments
 (0)