PyCBA 0.4.1__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyCBA-0.4.1/src/PyCBA.egg-info → PyCBA-0.5.1}/PKG-INFO +1 -1
- {PyCBA-0.4.1 → PyCBA-0.5.1/src/PyCBA.egg-info}/PKG-INFO +1 -1
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/__init__.py +1 -1
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/analysis.py +1 -1
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/beam.py +19 -6
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/inf_lines.py +62 -11
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/load.py +21 -28
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/results.py +20 -4
- PyCBA-0.5.1/tests/test_basic.py +554 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/tests/test_inf_lines.py +1 -1
- PyCBA-0.4.1/tests/test_basic.py +0 -267
- {PyCBA-0.4.1 → PyCBA-0.5.1}/LICENSE +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/README.md +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/pyproject.toml +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/setup.cfg +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/setup.py +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/PyCBA.egg-info/SOURCES.txt +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/PyCBA.egg-info/dependency_links.txt +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/PyCBA.egg-info/requires.txt +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/PyCBA.egg-info/top_level.txt +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/bridge.py +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/pattern.py +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/utils.py +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/src/pycba/vehicle.py +0 -0
- {PyCBA-0.4.1 → PyCBA-0.5.1}/tests/test_bridge.py +0 -0
|
@@ -220,6 +220,18 @@ class Beam:
|
|
|
220
220
|
"""
|
|
221
221
|
return len(self._restraints)
|
|
222
222
|
|
|
223
|
+
@property
|
|
224
|
+
def no_fixed_restraints(self):
|
|
225
|
+
"""
|
|
226
|
+
Returns the number of fixed restraints of the beam (fully-supported DOFs)
|
|
227
|
+
|
|
228
|
+
Returns
|
|
229
|
+
-------
|
|
230
|
+
no_fixed_restraints : int
|
|
231
|
+
The number of fixed restraints in the beam
|
|
232
|
+
"""
|
|
233
|
+
return len(np.where(np.array(self._restraints) == -1)[0])
|
|
234
|
+
|
|
223
235
|
@property
|
|
224
236
|
def length(self):
|
|
225
237
|
"""
|
|
@@ -268,9 +280,10 @@ class Beam:
|
|
|
268
280
|
|
|
269
281
|
return ispan, pos_in_span
|
|
270
282
|
|
|
271
|
-
def
|
|
283
|
+
def get_ref(self, i_span: int) -> LoadCNL:
|
|
272
284
|
"""
|
|
273
|
-
Returns
|
|
285
|
+
Returns Released End Forces for the member; that is, the Consistent Nodal Loads
|
|
286
|
+
modified for the element type (i.e. releases)
|
|
274
287
|
|
|
275
288
|
Parameters
|
|
276
289
|
----------
|
|
@@ -279,18 +292,18 @@ class Beam:
|
|
|
279
292
|
|
|
280
293
|
Returns
|
|
281
294
|
-------
|
|
282
|
-
|
|
295
|
+
ref : LoadCNL
|
|
283
296
|
The totalled CNL object for the member, considering all loads.
|
|
284
297
|
|
|
285
298
|
"""
|
|
286
|
-
|
|
299
|
+
ref = np.zeros(4)
|
|
287
300
|
L = self.mbr_lengths[i_span]
|
|
288
301
|
eType = self.mbr_eletype[i_span]
|
|
289
302
|
|
|
290
303
|
for load in self._loads:
|
|
291
304
|
if load.i_span == i_span:
|
|
292
|
-
|
|
293
|
-
return
|
|
305
|
+
ref += load.get_ref(L, eType)
|
|
306
|
+
return ref
|
|
294
307
|
|
|
295
308
|
def get_span_k(self, i_span: int) -> np.ndarray:
|
|
296
309
|
"""
|
|
@@ -119,21 +119,72 @@ class InfluenceLines:
|
|
|
119
119
|
self.create_ils()
|
|
120
120
|
|
|
121
121
|
x = self.vResults[0].results.x
|
|
122
|
-
dx = x[2] - x[1]
|
|
123
|
-
idx = np.where(np.abs(x - poi) <= dx * 1e-6)[0][0]
|
|
124
|
-
# find the nearest support to the poi
|
|
125
|
-
idxr = (
|
|
126
|
-
np.abs(np.cumsum(np.insert(self.ba.beam.mbr_lengths, 0, 0)) - poi)
|
|
127
|
-
).argmin()
|
|
128
122
|
npts = len(self.vResults)
|
|
129
123
|
eta = np.zeros(npts)
|
|
130
124
|
|
|
131
|
-
|
|
132
|
-
|
|
125
|
+
# Preparations for reaction ILs
|
|
126
|
+
#
|
|
127
|
+
# Get vector of the node locations
|
|
128
|
+
node_locations = np.cumsum(np.insert(self.ba.beam.mbr_lengths, 0, 0))
|
|
129
|
+
# Link the supported DOF to the index in the BeamAnalysis reactions vector
|
|
130
|
+
idx_mask = np.zeros_like(self.ba._beam.restraints)
|
|
131
|
+
idx_mask[np.where(np.array(self.ba._beam.restraints) == -1)] = np.arange(
|
|
132
|
+
self.ba.beam.no_fixed_restraints
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# idx = np.abs(x - poi).argmin()
|
|
136
|
+
|
|
137
|
+
if load_effect.upper() == "V":
|
|
138
|
+
dx = x[2] - x[1]
|
|
139
|
+
idx = np.where(np.abs(x - poi) <= dx * 1e-6)[0][0]
|
|
140
|
+
for i, res in enumerate(self.vResults):
|
|
133
141
|
eta[i] = res.results.V[idx]
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
142
|
+
|
|
143
|
+
elif load_effect.upper() == "R":
|
|
144
|
+
#
|
|
145
|
+
# Getting the correct reaction is tricky
|
|
146
|
+
#
|
|
147
|
+
# The indices of the supported DOFs wrt the node locations vector
|
|
148
|
+
vert_sups_dof_idx = np.where(np.array(self.ba._beam.restraints)[::2] == -1)[
|
|
149
|
+
0
|
|
150
|
+
]
|
|
151
|
+
# The locations then of these supports
|
|
152
|
+
vert_sups_locs = node_locations[vert_sups_dof_idx]
|
|
153
|
+
# The index of the closest support
|
|
154
|
+
closest_vert_sup_idx = np.abs(vert_sups_locs - poi).argmin()
|
|
155
|
+
# And its value
|
|
156
|
+
closest_vert_sup = vert_sups_locs[closest_vert_sup_idx]
|
|
157
|
+
# And now the index of this support in the node locations vector
|
|
158
|
+
vert_sup_node_idx = np.where(node_locations == closest_vert_sup)[0][0]
|
|
159
|
+
# And hence its index in the overall DOFs vector
|
|
160
|
+
vert_sup_dof_idx = 2 * vert_sup_node_idx
|
|
161
|
+
# And finally the index of the support nearest the POI in the reactions vector
|
|
162
|
+
vert_sup_idx = idx_mask[vert_sup_dof_idx]
|
|
163
|
+
|
|
164
|
+
for i, res in enumerate(self.vResults):
|
|
165
|
+
eta[i] = res.R[vert_sup_idx]
|
|
166
|
+
|
|
167
|
+
elif load_effect.upper() == "MR":
|
|
168
|
+
#
|
|
169
|
+
# Follows the same logic for the vertical reaction
|
|
170
|
+
#
|
|
171
|
+
mt_sups_dof_idx = np.where(np.array(self.ba._beam.restraints)[1::2] == -1)[
|
|
172
|
+
0
|
|
173
|
+
]
|
|
174
|
+
mt_sups_locs = node_locations[mt_sups_dof_idx]
|
|
175
|
+
closest_mt_sup_idx = np.abs(mt_sups_locs - poi).argmin()
|
|
176
|
+
closest_mt_sup = mt_sups_locs[closest_mt_sup_idx]
|
|
177
|
+
mt_sup_node_idx = np.where(node_locations == closest_mt_sup)[0][0]
|
|
178
|
+
mt_sup_dof_idx = 2 * mt_sup_node_idx + 1
|
|
179
|
+
mt_sup_idx = idx_mask[mt_sup_dof_idx]
|
|
180
|
+
|
|
181
|
+
for i, res in enumerate(self.vResults):
|
|
182
|
+
eta[i] = res.R[mt_sup_idx]
|
|
183
|
+
|
|
184
|
+
else:
|
|
185
|
+
dx = x[2] - x[1]
|
|
186
|
+
idx = np.where(np.abs(x - poi) <= dx * 1e-6)[0][0]
|
|
187
|
+
for i, res in enumerate(self.vResults):
|
|
137
188
|
eta[i] = res.results.M[idx]
|
|
138
189
|
|
|
139
190
|
return (np.array(self.pos), eta)
|
|
@@ -182,7 +182,7 @@ class Load:
|
|
|
182
182
|
"""
|
|
183
183
|
self.i_span = i_span
|
|
184
184
|
|
|
185
|
-
def get_cnl(self, L
|
|
185
|
+
def get_cnl(self, L):
|
|
186
186
|
# Enforce virtual base class
|
|
187
187
|
raise NotImplementedError
|
|
188
188
|
|
|
@@ -215,29 +215,26 @@ class Load:
|
|
|
215
215
|
"""
|
|
216
216
|
return np.heaviside(v, value)
|
|
217
217
|
|
|
218
|
-
def
|
|
218
|
+
def get_ref(self, L: float, eType: int) -> LoadCNL:
|
|
219
219
|
"""
|
|
220
|
-
|
|
221
|
-
Loads of the applied loading to the correct nodal
|
|
222
|
-
element type.
|
|
220
|
+
Returns the Released End Forces for a span of length L of element eType:
|
|
221
|
+
converts the Consistent Nodal Loads of the applied loading to the correct nodal
|
|
222
|
+
loading depending on the element type.
|
|
223
223
|
|
|
224
224
|
Parameters
|
|
225
225
|
----------
|
|
226
|
-
cnl : LoadCNL
|
|
227
|
-
The nodal loading statically consistent with the externally applied loads.
|
|
228
226
|
L : float
|
|
229
|
-
The length of the member
|
|
227
|
+
The length of the member
|
|
230
228
|
eType : int
|
|
231
|
-
The element type
|
|
229
|
+
The member element type
|
|
232
230
|
|
|
233
231
|
Returns
|
|
234
232
|
-------
|
|
235
233
|
LoadCNL
|
|
236
|
-
|
|
237
|
-
type.
|
|
238
|
-
|
|
234
|
+
Released End Forces for this load type: the nodal loads to be applied in
|
|
235
|
+
the analysis, consistent with the element type.
|
|
239
236
|
"""
|
|
240
|
-
|
|
237
|
+
cnl = self.get_cnl(L, eType)
|
|
241
238
|
ref = np.zeros(4)
|
|
242
239
|
fm = 6 / (4 * L) # flexibility coeff for moment
|
|
243
240
|
|
|
@@ -248,14 +245,14 @@ class Load:
|
|
|
248
245
|
ref[3] = 1.0 * cnl.Mb
|
|
249
246
|
elif eType == 3: # DOF = moment at i node
|
|
250
247
|
ref[0] = fm * cnl.Ma
|
|
251
|
-
ref[1] = 0
|
|
248
|
+
ref[1] = 1.0 * cnl.Ma
|
|
252
249
|
ref[2] = -fm * cnl.Ma
|
|
253
|
-
ref[3] =
|
|
250
|
+
ref[3] = 0.5 * cnl.Ma
|
|
254
251
|
elif eType == 4: # keep only vertical, remove moments
|
|
255
|
-
ref[0] =
|
|
256
|
-
ref[1] = 1.0 * cnl.
|
|
257
|
-
ref[2] =
|
|
258
|
-
ref[3] = 1.0 * cnl.
|
|
252
|
+
ref[0] = -(cnl.Ma + cnl.Mb) / L
|
|
253
|
+
ref[1] = 1.0 * cnl.Ma
|
|
254
|
+
ref[2] = (cnl.Ma + cnl.Mb) / L
|
|
255
|
+
ref[3] = 1.0 * cnl.Mb
|
|
259
256
|
else:
|
|
260
257
|
# no nothing if it is FF
|
|
261
258
|
pass
|
|
@@ -319,8 +316,7 @@ class LoadUDL(Load):
|
|
|
319
316
|
Ma=w * L**2 / 12.0,
|
|
320
317
|
Mb=-w * L**2 / 12.0,
|
|
321
318
|
)
|
|
322
|
-
|
|
323
|
-
return self.released_end_forces(cnl, L, eType)
|
|
319
|
+
return cnl
|
|
324
320
|
|
|
325
321
|
def get_mbr_results(self, x: np.ndarray, L: float) -> MemberResults:
|
|
326
322
|
"""
|
|
@@ -416,8 +412,7 @@ class LoadPL(Load):
|
|
|
416
412
|
Ma=P * a * b**2 / L**2,
|
|
417
413
|
Mb=-P * a**2 * b / L**2,
|
|
418
414
|
)
|
|
419
|
-
|
|
420
|
-
return self.released_end_forces(cnl, L, eType)
|
|
415
|
+
return cnl
|
|
421
416
|
|
|
422
417
|
def get_mbr_results(self, x: np.ndarray, L: float) -> MemberResults:
|
|
423
418
|
"""
|
|
@@ -512,7 +507,7 @@ class LoadPUDL(Load):
|
|
|
512
507
|
Mb=-(w * c / L**2) * (t * s**2 + (t - 2 * s) * c**2 / 12),
|
|
513
508
|
)
|
|
514
509
|
# implicit conversion to tuple in correct order
|
|
515
|
-
return
|
|
510
|
+
return cnl
|
|
516
511
|
|
|
517
512
|
def get_mbr_results(self, x: np.ndarray, L: float) -> MemberResults:
|
|
518
513
|
"""
|
|
@@ -608,8 +603,7 @@ class LoadMaMb(Load):
|
|
|
608
603
|
Ma=Ma,
|
|
609
604
|
Mb=Mb,
|
|
610
605
|
)
|
|
611
|
-
|
|
612
|
-
return self.released_end_forces(cnl, L, eType)
|
|
606
|
+
return cnl
|
|
613
607
|
|
|
614
608
|
def get_mbr_results(self, x: np.ndarray, L: float) -> MemberResults:
|
|
615
609
|
"""
|
|
@@ -690,8 +684,7 @@ class LoadML(Load):
|
|
|
690
684
|
Ma=(m * b / L**2) * (2 * a - b),
|
|
691
685
|
Mb=(m * a / L**2) * (2 * b - a),
|
|
692
686
|
)
|
|
693
|
-
|
|
694
|
-
return self.released_end_forces(cnl, L, eType)
|
|
687
|
+
return cnl
|
|
695
688
|
|
|
696
689
|
def get_mbr_results(self, x: np.ndarray, L: float) -> MemberResults:
|
|
697
690
|
"""
|
|
@@ -8,7 +8,7 @@ import numpy as np
|
|
|
8
8
|
import matplotlib.pyplot as plt
|
|
9
9
|
from scipy import integrate
|
|
10
10
|
from .beam import Beam
|
|
11
|
-
from .load import MemberResults, LoadMaMb
|
|
11
|
+
from .load import MemberResults, LoadMaMb, LoadCNL
|
|
12
12
|
from copy import deepcopy
|
|
13
13
|
|
|
14
14
|
|
|
@@ -105,7 +105,7 @@ class BeamResults:
|
|
|
105
105
|
fmbr = np.zeros(4)
|
|
106
106
|
for j in range(4):
|
|
107
107
|
fmbr[j] = np.sum(kb[j][:] * dmbr[:])
|
|
108
|
-
fmbr += beam.
|
|
108
|
+
fmbr += beam.get_ref(i)
|
|
109
109
|
res = self._member_values(beam, i, fmbr, dmbr)
|
|
110
110
|
# Shift x vals by location of mbr starting point
|
|
111
111
|
res.x += sumL
|
|
@@ -138,6 +138,9 @@ class BeamResults:
|
|
|
138
138
|
"""
|
|
139
139
|
|
|
140
140
|
L = beam.mbr_lengths[i_span]
|
|
141
|
+
EI = beam.mbr_EIs[i_span]
|
|
142
|
+
etype = beam.mbr_eletype[i_span]
|
|
143
|
+
|
|
141
144
|
dx = L / self.npts
|
|
142
145
|
x = np.zeros(self.npts + 3)
|
|
143
146
|
x[1 : self.npts + 2] = dx * np.arange(0, self.npts + 1)
|
|
@@ -148,16 +151,29 @@ class BeamResults:
|
|
|
148
151
|
res = MaMb.get_mbr_results(x, L)
|
|
149
152
|
|
|
150
153
|
# Now get the results for all the applied loads on a simple span
|
|
154
|
+
Ma = 0
|
|
155
|
+
Mb = 0
|
|
151
156
|
for load in beam._loads:
|
|
152
157
|
if load.i_span != i_span:
|
|
153
158
|
continue
|
|
154
159
|
res += load.get_mbr_results(x, L)
|
|
160
|
+
cnl = load.get_cnl(L, etype)
|
|
161
|
+
Ma += cnl.Ma
|
|
162
|
+
Mb += cnl.Mb
|
|
163
|
+
|
|
164
|
+
# If no releases, the rotation at i is easy
|
|
165
|
+
R0 = d[1]
|
|
166
|
+
|
|
167
|
+
# Otherwise, check account for releases
|
|
168
|
+
if etype > 1:
|
|
169
|
+
theta = (d[2] - d[0]) / L
|
|
170
|
+
phi = (L / (3 * EI)) * (-(f[1] - 0.5 * f[3]) + (Ma - 0.5 * Mb))
|
|
171
|
+
R0 = theta - phi
|
|
155
172
|
|
|
156
173
|
# And superimpose end displacements using Moment-Area
|
|
157
174
|
h = L / self.npts
|
|
158
|
-
EI = beam.mbr_EIs[i_span]
|
|
159
175
|
|
|
160
|
-
R = integrate.cumtrapz(res.M[1:-1], dx=h, initial=0) / EI +
|
|
176
|
+
R = integrate.cumtrapz(res.M[1:-1], dx=h, initial=0) / EI + R0
|
|
161
177
|
D = integrate.cumtrapz(R, dx=h, initial=0) + d[0]
|
|
162
178
|
|
|
163
179
|
res.R[1:-1] = R
|
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Basic tests for PyCBA operation
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
import numpy as np
|
|
7
|
+
import pycba as cba
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_1span_ee():
|
|
11
|
+
"""
|
|
12
|
+
Test fixed-fixed beam with point load in the middle
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
P = 10 # kN
|
|
16
|
+
L = 10 # m
|
|
17
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
18
|
+
R = [-1, -1, -1, -1]
|
|
19
|
+
LM = [[1, 2, P, 0.5 * L, 0]]
|
|
20
|
+
|
|
21
|
+
beam_analysis = cba.BeamAnalysis([L], EI, R, LM)
|
|
22
|
+
out = beam_analysis.analyze()
|
|
23
|
+
assert out == 0
|
|
24
|
+
|
|
25
|
+
Ma = beam_analysis.beam_results.results.M[1]
|
|
26
|
+
Mb = beam_analysis.beam_results.results.M[-2]
|
|
27
|
+
Mc = beam_analysis.beam_results.results.M[51]
|
|
28
|
+
|
|
29
|
+
assert Ma == pytest.approx(-P * L / 8)
|
|
30
|
+
assert Mb == pytest.approx(-P * L / 8)
|
|
31
|
+
assert Mc == pytest.approx(P * L / 8)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_1span_ep():
|
|
35
|
+
"""
|
|
36
|
+
Test fixed-pinned beam with point load in the middle
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
P = 10 # kN
|
|
40
|
+
L = 10 # m
|
|
41
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
42
|
+
R = [-1, -1, -1, 0]
|
|
43
|
+
LM = [[1, 2, P, 0.5 * L, 0]]
|
|
44
|
+
|
|
45
|
+
beam_analysis = cba.BeamAnalysis([L], EI, R, LM)
|
|
46
|
+
out = beam_analysis.analyze()
|
|
47
|
+
assert out == 0
|
|
48
|
+
|
|
49
|
+
Ma = beam_analysis.beam_results.results.M[1]
|
|
50
|
+
Mb = beam_analysis.beam_results.results.M[-2]
|
|
51
|
+
Mc = beam_analysis.beam_results.results.M[51]
|
|
52
|
+
|
|
53
|
+
assert Ma == pytest.approx(-3 * P * L / 16)
|
|
54
|
+
assert Mb == pytest.approx(0)
|
|
55
|
+
assert Mc == pytest.approx(5 * P * L / 32)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_1span_ep_eletype2():
|
|
59
|
+
"""
|
|
60
|
+
Test fixed-pinned beam with point load in the middle, using eleType 2
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
P = 10 # kN
|
|
64
|
+
L = 10 # m
|
|
65
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
66
|
+
R = [-1, -1, -1, -1] # Notice, fixed-fixed supports
|
|
67
|
+
LM = [[1, 2, P, 0.5 * L, 0]]
|
|
68
|
+
|
|
69
|
+
beam_analysis = cba.BeamAnalysis([L], EI, R, LM, eletype=[2])
|
|
70
|
+
out = beam_analysis.analyze()
|
|
71
|
+
assert out == 0
|
|
72
|
+
|
|
73
|
+
Ma = beam_analysis.beam_results.results.M[1]
|
|
74
|
+
Mb = beam_analysis.beam_results.results.M[-2]
|
|
75
|
+
Mc = beam_analysis.beam_results.results.M[51]
|
|
76
|
+
|
|
77
|
+
assert Ma == pytest.approx(-3 * P * L / 16)
|
|
78
|
+
assert Mb == pytest.approx(0)
|
|
79
|
+
assert Mc == pytest.approx(5 * P * L / 32)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_1span_pe():
|
|
83
|
+
"""
|
|
84
|
+
Test pinned-fixed beam with point load in the middle
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
P = 10 # kN
|
|
88
|
+
L = 10 # m
|
|
89
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
90
|
+
R = [-1, 0, -1, -1]
|
|
91
|
+
LM = [[1, 2, P, 0.5 * L, 0]]
|
|
92
|
+
|
|
93
|
+
beam_analysis = cba.BeamAnalysis([L], EI, R, LM)
|
|
94
|
+
out = beam_analysis.analyze()
|
|
95
|
+
assert out == 0
|
|
96
|
+
|
|
97
|
+
Ma = beam_analysis.beam_results.results.M[1]
|
|
98
|
+
Mb = beam_analysis.beam_results.results.M[-2]
|
|
99
|
+
Mc = beam_analysis.beam_results.results.M[51]
|
|
100
|
+
|
|
101
|
+
assert Ma == pytest.approx(0)
|
|
102
|
+
assert Mb == pytest.approx(-3 * P * L / 16)
|
|
103
|
+
assert Mc == pytest.approx(5 * P * L / 32)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_1span_pe_eletype3():
|
|
107
|
+
"""
|
|
108
|
+
Test pinned-fixed beam with point load in the middle, using eleType 3
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
P = 10 # kN
|
|
112
|
+
L = 10 # m
|
|
113
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
114
|
+
R = [-1, -1, -1, -1] # Notice, fixed-fixed supports
|
|
115
|
+
LM = [[1, 2, P, 0.5 * L, 0]]
|
|
116
|
+
|
|
117
|
+
beam_analysis = cba.BeamAnalysis([L], EI, R, LM, eletype=[3])
|
|
118
|
+
out = beam_analysis.analyze()
|
|
119
|
+
assert out == 0
|
|
120
|
+
|
|
121
|
+
Ma = beam_analysis.beam_results.results.M[1]
|
|
122
|
+
Mb = beam_analysis.beam_results.results.M[-2]
|
|
123
|
+
Mc = beam_analysis.beam_results.results.M[51]
|
|
124
|
+
|
|
125
|
+
assert Ma == pytest.approx(0)
|
|
126
|
+
assert Mb == pytest.approx(-3 * P * L / 16)
|
|
127
|
+
assert Mc == pytest.approx(5 * P * L / 32)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_1span_pp():
|
|
131
|
+
"""
|
|
132
|
+
Test pinned-pinned beam with point load in the middle
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
P = 10 # kN
|
|
136
|
+
L = 10 # m
|
|
137
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
138
|
+
R = [-1, 0, -1, 0]
|
|
139
|
+
LM = [[1, 2, P, 0.5 * L, 0]]
|
|
140
|
+
|
|
141
|
+
beam_analysis = cba.BeamAnalysis([L], EI, R, LM)
|
|
142
|
+
out = beam_analysis.analyze()
|
|
143
|
+
assert out == 0
|
|
144
|
+
|
|
145
|
+
Ma = beam_analysis.beam_results.results.M[1]
|
|
146
|
+
Mb = beam_analysis.beam_results.results.M[-2]
|
|
147
|
+
Mc = beam_analysis.beam_results.results.M[51]
|
|
148
|
+
|
|
149
|
+
assert Ma == pytest.approx(0)
|
|
150
|
+
assert Mb == pytest.approx(0)
|
|
151
|
+
assert Mc == pytest.approx(P * L / 4)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def test_1span_pp_eletype4():
|
|
155
|
+
"""
|
|
156
|
+
Test pinned-pinned beam with point load in the middle, using eleType 4
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
P = 10 # kN
|
|
160
|
+
L = 10 # m
|
|
161
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
162
|
+
R = [-1, -1, -1, -1] # Notice, fixed-fixed supports
|
|
163
|
+
LM = [[1, 2, P, 0.5 * L, 0]]
|
|
164
|
+
|
|
165
|
+
beam_analysis = cba.BeamAnalysis([L], EI, R, LM, eletype=[4])
|
|
166
|
+
out = beam_analysis.analyze()
|
|
167
|
+
assert out == 0
|
|
168
|
+
|
|
169
|
+
Ma = beam_analysis.beam_results.results.M[1]
|
|
170
|
+
Mb = beam_analysis.beam_results.results.M[-2]
|
|
171
|
+
Mc = beam_analysis.beam_results.results.M[51]
|
|
172
|
+
|
|
173
|
+
assert Ma == pytest.approx(0)
|
|
174
|
+
assert Mb == pytest.approx(0)
|
|
175
|
+
assert Mc == pytest.approx(P * L / 4)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def get_1span_beam_def(etype):
|
|
179
|
+
P = 10 # kN
|
|
180
|
+
L = 10 # m
|
|
181
|
+
a = 0.25 * L
|
|
182
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
183
|
+
R = [-1, -1, -1, -1] # Notice, fixed-fixed supports
|
|
184
|
+
LM = [[1, 2, P, a, 0]]
|
|
185
|
+
|
|
186
|
+
beam_analysis = cba.BeamAnalysis([L], EI, R, LM, eletype=[etype])
|
|
187
|
+
beam_analysis.analyze()
|
|
188
|
+
|
|
189
|
+
d = beam_analysis.beam_results.results.D
|
|
190
|
+
dmax = min(d)
|
|
191
|
+
|
|
192
|
+
return P, L, EI, a, dmax
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def test_1span_def_ff():
|
|
196
|
+
"""
|
|
197
|
+
Test fixed-fixed beam deflection for off-centre point load
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
P, L, EI, aa, dmax = get_1span_beam_def(etype=1)
|
|
201
|
+
|
|
202
|
+
# a>b
|
|
203
|
+
b = aa
|
|
204
|
+
a = L - b
|
|
205
|
+
ymax = -(2 * P * a**3 * b**2) / (3 * (3 * a + b) ** 2 * EI)
|
|
206
|
+
|
|
207
|
+
assert dmax == pytest.approx(ymax, abs=1e-6)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def test_1span_def_fp():
|
|
211
|
+
"""
|
|
212
|
+
Test fixed-pinned beam deflection for off-centre point load
|
|
213
|
+
"""
|
|
214
|
+
P, L, EI, aa, dmax = get_1span_beam_def(etype=2)
|
|
215
|
+
|
|
216
|
+
a = aa
|
|
217
|
+
b = L - a
|
|
218
|
+
ymax = -(P * a**2 * b) / (6 * EI) * (b / (3 * L - a)) ** 0.5
|
|
219
|
+
|
|
220
|
+
assert dmax == pytest.approx(ymax, abs=1e-6)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def test_1span_def_pf():
|
|
224
|
+
"""
|
|
225
|
+
Test pinned-fixed beam deflection for off-centre point load
|
|
226
|
+
"""
|
|
227
|
+
P, L, EI, aa, dmax = get_1span_beam_def(etype=3)
|
|
228
|
+
|
|
229
|
+
b = aa
|
|
230
|
+
ymax = -(P * b) / (3 * EI) * (L**2 - b**2) ** 3 / (3 * L**2 - b**2) ** 2
|
|
231
|
+
|
|
232
|
+
assert dmax == pytest.approx(ymax, abs=1e-6)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def test_1span_def_pp():
|
|
236
|
+
"""
|
|
237
|
+
Test pinned-pinned beam deflection for off-centre point load
|
|
238
|
+
"""
|
|
239
|
+
P, L, EI, aa, dmax = get_1span_beam_def(etype=4)
|
|
240
|
+
|
|
241
|
+
a = aa
|
|
242
|
+
ymax = -(3**0.5) * P * a * (L**2 - a**2) ** 1.5 / (27 * EI * L)
|
|
243
|
+
|
|
244
|
+
assert dmax == pytest.approx(ymax, abs=1e-6)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def test_2span_udl():
|
|
248
|
+
"""
|
|
249
|
+
Execute a two-span beam analysis and check the reaction results.
|
|
250
|
+
Uses a direct definition of the LM
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
L = [7.5, 7.0]
|
|
254
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
255
|
+
R = [-1, 0, -1, 0, -1, 0]
|
|
256
|
+
LM = [[1, 1, 20, 0, 0], [2, 1, 20, 0, 0]]
|
|
257
|
+
|
|
258
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
259
|
+
out = beam_analysis.analyze()
|
|
260
|
+
assert out == 0
|
|
261
|
+
|
|
262
|
+
r = beam_analysis.beam_results.R
|
|
263
|
+
assert r == pytest.approx([57.41666667, 181.42261905, 51.16071429])
|
|
264
|
+
|
|
265
|
+
dmax = max(beam_analysis.beam_results.results.D)
|
|
266
|
+
dmin = min(beam_analysis.beam_results.results.D)
|
|
267
|
+
assert [dmax, dmin] == pytest.approx(
|
|
268
|
+
[1.0118938958333364e-05, -0.0020629648925781247], abs=1e-6
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def test_2span_load_wrappers():
|
|
273
|
+
"""
|
|
274
|
+
Execute a two-span beam analysis and check the reaction results.
|
|
275
|
+
Uses the wrappers for defining loads.
|
|
276
|
+
"""
|
|
277
|
+
|
|
278
|
+
L = [7.5, 7.0]
|
|
279
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
280
|
+
R = [-1, 0, -1, 0, -1, 0]
|
|
281
|
+
|
|
282
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R)
|
|
283
|
+
beam_analysis.add_pl(1, 40, 3.5)
|
|
284
|
+
beam_analysis.add_udl(1, 10)
|
|
285
|
+
beam_analysis.add_pudl(2, 20, 2.0, 3.0)
|
|
286
|
+
beam_analysis.add_ml(2, 50, 3)
|
|
287
|
+
|
|
288
|
+
out = beam_analysis.analyze()
|
|
289
|
+
assert out == 0
|
|
290
|
+
|
|
291
|
+
r = beam_analysis.beam_results.R
|
|
292
|
+
assert r == pytest.approx([45.41648878, 121.10155896, 8.48195226])
|
|
293
|
+
|
|
294
|
+
dmax = max(beam_analysis.beam_results.results.D)
|
|
295
|
+
dmin = min(beam_analysis.beam_results.results.D)
|
|
296
|
+
assert [dmax, dmin] == pytest.approx(
|
|
297
|
+
[0.00011753212898873195, -0.0023044064201367506]
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def test_2span_pl_ml_fixed():
|
|
302
|
+
"""
|
|
303
|
+
Execute a two-span beam analysis and check the reaction results
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
L = [5.0, 5.0]
|
|
307
|
+
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
308
|
+
R = [-1, 0, -1, 0, -1, -1]
|
|
309
|
+
LM = [[1, 2, 50, 3, 0], [2, 4, 50, 2, 0]]
|
|
310
|
+
|
|
311
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
312
|
+
out = beam_analysis.analyze()
|
|
313
|
+
assert out == 0
|
|
314
|
+
|
|
315
|
+
r = beam_analysis.beam_results.R
|
|
316
|
+
assert r == pytest.approx([14.0, 57.6, -21.6, 28.0])
|
|
317
|
+
|
|
318
|
+
dmax = max(beam_analysis.beam_results.results.D)
|
|
319
|
+
dmin = min(beam_analysis.beam_results.results.D)
|
|
320
|
+
assert [dmax, dmin] == pytest.approx(
|
|
321
|
+
[0.00017414416666666662, -0.00042251493055555565], abs=1e-6
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def test_3span_diff_settlement():
|
|
326
|
+
L = [15, 15, 15]
|
|
327
|
+
EI = 30 * np.array([500e8, 500e8, 500e8]) * 1e-6 # kNm2
|
|
328
|
+
R = [-1, 0, 1e8, 0, 1e8, 0, -1, 0]
|
|
329
|
+
LM = [[1, 1, 20, 0, 0], [2, 1, 20, 0, 0], [3, 1, 20, 0, 0]]
|
|
330
|
+
|
|
331
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
332
|
+
out = beam_analysis.analyze()
|
|
333
|
+
assert out == 0
|
|
334
|
+
|
|
335
|
+
r = beam_analysis.beam_results.R
|
|
336
|
+
assert r == pytest.approx([120.00175999, 120.00175999])
|
|
337
|
+
|
|
338
|
+
dmax = max(beam_analysis.beam_results.results.D)
|
|
339
|
+
dmin = min(beam_analysis.beam_results.results.D)
|
|
340
|
+
assert [dmax, dmin] == pytest.approx(
|
|
341
|
+
[0.0002778734578837245, -0.004648274177216889], abs=1e-5
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def test_3span_subframe():
|
|
346
|
+
L = [6, 8, 6]
|
|
347
|
+
EI = 30 * np.array([50e8, 50e8, 50e8]) * 1e-6
|
|
348
|
+
R = [-1, 486e9, -1, 486e9, -1, 486e9, -1, 486e9]
|
|
349
|
+
LM = [[1, 1, 10, 0, 0], [2, 1, 20, 0, 0], [3, 1, 10, 0, 0]]
|
|
350
|
+
|
|
351
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
352
|
+
out = beam_analysis.analyze()
|
|
353
|
+
assert out == 0
|
|
354
|
+
|
|
355
|
+
r = beam_analysis.beam_results.R
|
|
356
|
+
assert r == pytest.approx([29.99999451, 110.00000549, 110.00000549, 29.99999451])
|
|
357
|
+
|
|
358
|
+
dmax = max(beam_analysis.beam_results.results.D)
|
|
359
|
+
dmin = min(beam_analysis.beam_results.results.D)
|
|
360
|
+
assert [dmax, dmin] == pytest.approx([0.0, -0.0014222225377228067], abs=1e-6)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def test_4span_posttensioned():
|
|
364
|
+
L = [6, 8, 6, 8]
|
|
365
|
+
EI = 30 * np.array([100e8, 100e8, 100e8, 100e8]) * 1e-6 # kNm2
|
|
366
|
+
R = [-1, 0, -1, 0, -1, 0, -1, 0, -1, 0]
|
|
367
|
+
LM = [
|
|
368
|
+
[1, 3, 20, 0, 1],
|
|
369
|
+
[1, 3, -10, 1, 4],
|
|
370
|
+
[1, 3, 20, 5, 1],
|
|
371
|
+
[1, 4, 50, 0, 0],
|
|
372
|
+
[2, 3, 20, 0, 1.5],
|
|
373
|
+
[2, 3, -10, 1.5, 5],
|
|
374
|
+
[2, 3, 20, 6.5, 1.5],
|
|
375
|
+
[3, 3, 20, 0, 1],
|
|
376
|
+
[3, 3, -10, 1, 4],
|
|
377
|
+
[3, 3, 20, 5, 1],
|
|
378
|
+
[4, 3, 20, 0, 1.5],
|
|
379
|
+
[4, 3, -10, 1.5, 5],
|
|
380
|
+
[4, 3, 20, 6.5, 1.5],
|
|
381
|
+
[4, 4, -75, 8, 0],
|
|
382
|
+
]
|
|
383
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
384
|
+
out = beam_analysis.analyze()
|
|
385
|
+
assert out == 0
|
|
386
|
+
|
|
387
|
+
r = beam_analysis.beam_results.R
|
|
388
|
+
assert r == pytest.approx(
|
|
389
|
+
[14.87359893, -13.64621406, 15.69634808, -17.62411672, 20.70038377]
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
dmax = max(beam_analysis.beam_results.results.D)
|
|
393
|
+
dmin = min(beam_analysis.beam_results.results.D)
|
|
394
|
+
assert [dmax, dmin] == pytest.approx(
|
|
395
|
+
[0.0012715273282923978, -0.00013897273612280755], abs=1e-6
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
def test_2span_pinned():
|
|
400
|
+
w = 20
|
|
401
|
+
L = [10, 10]
|
|
402
|
+
EI = 30 * np.array([600e7, 600e7]) * 1e-6
|
|
403
|
+
eType = [2, 1]
|
|
404
|
+
R = [-1, 0, -1, 0, -1, 0]
|
|
405
|
+
LM = [[1, 1, w, 0, 0], [2, 1, w, 0, 0]]
|
|
406
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM, eType)
|
|
407
|
+
out = beam_analysis.analyze()
|
|
408
|
+
assert out == 0
|
|
409
|
+
|
|
410
|
+
r = beam_analysis.beam_results.R
|
|
411
|
+
assert r == pytest.approx([w * 5, w * 10, w * 5])
|
|
412
|
+
|
|
413
|
+
dmax = max(beam_analysis.beam_results.results.D)
|
|
414
|
+
dmin = min(beam_analysis.beam_results.results.D)
|
|
415
|
+
assert [dmax, dmin] == pytest.approx([0, -5 * w * L[0] ** 4 / (384 * EI[0])])
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def test_3span_hinge():
|
|
419
|
+
L = [5, 5, 10]
|
|
420
|
+
EI = 30 * 600e7 * np.ones(len(L)) * 1e-6
|
|
421
|
+
eType = [2, 1, 1]
|
|
422
|
+
R = [-1, -1, 0, 0, -1, 0, -1, 0]
|
|
423
|
+
LM = [[3, 2, 20, 5, 0]]
|
|
424
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM, eType)
|
|
425
|
+
out = beam_analysis.analyze()
|
|
426
|
+
assert out == 0
|
|
427
|
+
|
|
428
|
+
r = beam_analysis.beam_results.R
|
|
429
|
+
assert r == pytest.approx([-3.75, -18.75, 15.625, 8.125])
|
|
430
|
+
|
|
431
|
+
dmax = max(beam_analysis.beam_results.results.D)
|
|
432
|
+
dmin = min(beam_analysis.beam_results.results.D)
|
|
433
|
+
assert [dmax, dmin] == pytest.approx(
|
|
434
|
+
[0.0008680555555555557, -0.0016677326388888887], abs=1e-6
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def test_flipped_hinge():
|
|
439
|
+
# 3-span with etype 2
|
|
440
|
+
L = [5, 5, 10]
|
|
441
|
+
EI = 30 * 600e7 * np.ones(len(L)) * 1e-6
|
|
442
|
+
eType = [2, 1, 1]
|
|
443
|
+
R = [-1, -1, 0, 0, -1, 0, -1, -1]
|
|
444
|
+
LM = [[3, 2, 20, 5, 0]]
|
|
445
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM, eType)
|
|
446
|
+
out = beam_analysis.analyze()
|
|
447
|
+
d1 = beam_analysis.beam_results.results.D
|
|
448
|
+
|
|
449
|
+
# Same beam flipped, etype 3
|
|
450
|
+
L = [10, 5, 5]
|
|
451
|
+
EI = 30 * 600e7 * np.ones(len(L)) * 1e-6
|
|
452
|
+
eType = [1, 1, 3]
|
|
453
|
+
R = [-1, -1, -1, 0, 0, 0, -1, -1]
|
|
454
|
+
LM = [[1, 2, 20, 5, 0]]
|
|
455
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM, eType)
|
|
456
|
+
beam_analysis.analyze()
|
|
457
|
+
d2 = beam_analysis.beam_results.results.D
|
|
458
|
+
|
|
459
|
+
# Confirm flipped deflected shapes are close
|
|
460
|
+
assert d1 == pytest.approx(d2[::-1], abs=1e-7)
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def test_hinges():
|
|
464
|
+
# Based on example in Logan's First Course in FE, Ex. 4.10
|
|
465
|
+
a = 4
|
|
466
|
+
b = 2
|
|
467
|
+
P = 20
|
|
468
|
+
L = [a, b]
|
|
469
|
+
EI = 30 * 600e7 * 1e-6
|
|
470
|
+
EIvec = EI * np.ones(len(L))
|
|
471
|
+
eType = [1, 3]
|
|
472
|
+
R = [-1, -1, 0, 0, -1, -1]
|
|
473
|
+
LM = [[1, 2, P, a, 0]]
|
|
474
|
+
beam_analysis = cba.BeamAnalysis(L, EIvec, R, LM, eType)
|
|
475
|
+
beam_analysis.analyze()
|
|
476
|
+
|
|
477
|
+
phi2_1 = beam_analysis.beam_results.vRes[0].R[-2]
|
|
478
|
+
phi2_1_theory = -(a**2 * b**3 * P) / (2 * (b**3 + a**3) * EI)
|
|
479
|
+
|
|
480
|
+
assert phi2_1_theory == pytest.approx(phi2_1)
|
|
481
|
+
|
|
482
|
+
phi2_2 = beam_analysis.beam_results.vRes[1].R[1]
|
|
483
|
+
phi2_2_theory = (a**3 * b**2 * P) / (2 * (b**3 + a**3) * EI)
|
|
484
|
+
|
|
485
|
+
assert phi2_2_theory == pytest.approx(phi2_2)
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
def test_3span_hinge_il():
|
|
489
|
+
L = [5, 5, 10]
|
|
490
|
+
EI = 30 * 600e7 * np.ones(len(L)) * 1e-6
|
|
491
|
+
eType = [2, 1, 1]
|
|
492
|
+
R = [-1, -1, 0, 0, -1, 0, -1, 0]
|
|
493
|
+
|
|
494
|
+
ils = cba.InfluenceLines(L, EI, R, eType)
|
|
495
|
+
ils.create_ils(step=0.05)
|
|
496
|
+
(x, y) = ils.get_il(15.0, "V")
|
|
497
|
+
|
|
498
|
+
assert [min(y), max(y)] == pytest.approx([-0.4009469062500001, 0.59375], abs=1e-6)
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
def test_moment_load():
|
|
502
|
+
L = [10.0]
|
|
503
|
+
EI = 30 * 600e7 * np.ones(len(L)) * 1e-6
|
|
504
|
+
eType = [1]
|
|
505
|
+
R = [-1, 0, -1, 0]
|
|
506
|
+
|
|
507
|
+
for a in [0, 5, 10]:
|
|
508
|
+
LM = [[1, 4, 10, a, 0]]
|
|
509
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R, LM, eType)
|
|
510
|
+
out = beam_analysis.analyze()
|
|
511
|
+
assert out == 0
|
|
512
|
+
|
|
513
|
+
# Check deflection closes
|
|
514
|
+
d = beam_analysis.beam_results.D[[0, 2]]
|
|
515
|
+
assert d == pytest.approx([0.0, 0.0])
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
def test_envelopes():
|
|
519
|
+
L = [6, 4, 6]
|
|
520
|
+
EI = 30 * 10e9 * 1e-6
|
|
521
|
+
R = [-1, 0, -1, 0, -1, 0, -1, 0]
|
|
522
|
+
beam_analysis = cba.BeamAnalysis(L, EI, R)
|
|
523
|
+
|
|
524
|
+
LMg = [[1, 1, 25, 0, 0], [2, 1, 25, 0, 0], [3, 1, 25, 0, 0]]
|
|
525
|
+
γg_max = 1.4
|
|
526
|
+
γg_min = 1.0
|
|
527
|
+
LMq = [[1, 1, 10, 0, 0], [2, 1, 10, 0, 0], [3, 1, 10, 0, 0]]
|
|
528
|
+
γq_max = 1.6
|
|
529
|
+
γq_min = 0
|
|
530
|
+
|
|
531
|
+
lp = cba.LoadPattern(beam_analysis)
|
|
532
|
+
lp.set_dead_loads(LMg, γg_max, γg_min)
|
|
533
|
+
lp.set_live_loads(LMq, γq_max, γq_min)
|
|
534
|
+
env = lp.analyze()
|
|
535
|
+
|
|
536
|
+
m_locs = np.array([3, 6, 8, 10, 13])
|
|
537
|
+
idx = [(np.abs(env.x - x)).argmin() for x in m_locs]
|
|
538
|
+
assert np.allclose(
|
|
539
|
+
env.Mmax[idx], np.array([163.79, 0, 11.75, 0, 163.79]), atol=1e-2
|
|
540
|
+
)
|
|
541
|
+
assert np.allclose(
|
|
542
|
+
env.Mmin[idx], np.array([0, -163.38, -81.42, -163.38, 0]), atol=1e-2
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
n = beam_analysis.beam_results.npts
|
|
546
|
+
nspans = beam_analysis.beam.no_spans
|
|
547
|
+
Vmax = np.array(
|
|
548
|
+
[np.max(env.Vmax[i * (n + 3) : (i + 1) * (n + 3)]) for i in range(nspans)]
|
|
549
|
+
)
|
|
550
|
+
assert np.allclose(Vmax, np.array([131.1, 123.94, 180.23]), atol=1e-2)
|
|
551
|
+
Vmin = np.array(
|
|
552
|
+
[np.min(env.Vmin[i * (n + 3) : (i + 1) * (n + 3)]) for i in range(nspans)]
|
|
553
|
+
)
|
|
554
|
+
assert np.allclose(Vmin, np.array([-180.23, -123.94, -131.10]), atol=1e-2)
|
PyCBA-0.4.1/tests/test_basic.py
DELETED
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Basic tests for PyCBA operation
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import pytest
|
|
6
|
-
import numpy as np
|
|
7
|
-
import pycba as cba
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def test_2span_udl():
|
|
11
|
-
"""
|
|
12
|
-
Execute a two-span beam analysis and check the reaction results.
|
|
13
|
-
Uses a direct definition of the LM
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
L = [7.5, 7.0]
|
|
17
|
-
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
18
|
-
R = [-1, 0, -1, 0, -1, 0]
|
|
19
|
-
LM = [[1, 1, 20, 0, 0], [2, 1, 20, 0, 0]]
|
|
20
|
-
|
|
21
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
22
|
-
out = beam_analysis.analyze()
|
|
23
|
-
assert out == 0
|
|
24
|
-
|
|
25
|
-
r = beam_analysis.beam_results.R
|
|
26
|
-
assert r == pytest.approx([57.41666667, 181.42261905, 51.16071429])
|
|
27
|
-
|
|
28
|
-
dmax = max(beam_analysis.beam_results.results.D)
|
|
29
|
-
dmin = min(beam_analysis.beam_results.results.D)
|
|
30
|
-
assert [dmax, dmin] == pytest.approx(
|
|
31
|
-
[1.0118938958333364e-05, -0.0020629648925781247], abs=1e-6
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def test_2span_load_wrappers():
|
|
36
|
-
"""
|
|
37
|
-
Execute a two-span beam analysis and check the reaction results.
|
|
38
|
-
Uses the wrappers for defining loads.
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
L = [7.5, 7.0]
|
|
42
|
-
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
43
|
-
R = [-1, 0, -1, 0, -1, 0]
|
|
44
|
-
|
|
45
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R)
|
|
46
|
-
beam_analysis.add_pl(1, 40, 3.5)
|
|
47
|
-
beam_analysis.add_udl(1, 10)
|
|
48
|
-
beam_analysis.add_pudl(2, 20, 2.0, 3.0)
|
|
49
|
-
beam_analysis.add_ml(2, 50, 3)
|
|
50
|
-
|
|
51
|
-
out = beam_analysis.analyze()
|
|
52
|
-
assert out == 0
|
|
53
|
-
|
|
54
|
-
r = beam_analysis.beam_results.R
|
|
55
|
-
assert r == pytest.approx([45.41648878, 121.10155896, 8.48195226])
|
|
56
|
-
|
|
57
|
-
dmax = max(beam_analysis.beam_results.results.D)
|
|
58
|
-
dmin = min(beam_analysis.beam_results.results.D)
|
|
59
|
-
assert [dmax, dmin] == pytest.approx(
|
|
60
|
-
[0.00011753212898873195, -0.0023044064201367506]
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def test_2span_pl_ml_fixed():
|
|
65
|
-
"""
|
|
66
|
-
Execute a two-span beam analysis and check the reaction results
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
L = [5.0, 5.0]
|
|
70
|
-
EI = 30 * 600e7 * 1e-6 # kNm2
|
|
71
|
-
R = [-1, 0, -1, 0, -1, -1]
|
|
72
|
-
LM = [[1, 2, 50, 3, 0], [2, 4, 50, 2, 0]]
|
|
73
|
-
|
|
74
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
75
|
-
out = beam_analysis.analyze()
|
|
76
|
-
assert out == 0
|
|
77
|
-
|
|
78
|
-
r = beam_analysis.beam_results.R
|
|
79
|
-
assert r == pytest.approx([14.0, 57.6, -21.6, 28.0])
|
|
80
|
-
|
|
81
|
-
dmax = max(beam_analysis.beam_results.results.D)
|
|
82
|
-
dmin = min(beam_analysis.beam_results.results.D)
|
|
83
|
-
assert [dmax, dmin] == pytest.approx(
|
|
84
|
-
[0.00017414416666666662, -0.00042251493055555565], abs=1e-6
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def test_3span_diff_settlement():
|
|
89
|
-
L = [15, 15, 15]
|
|
90
|
-
EI = 30 * np.array([500e8, 500e8, 500e8]) * 1e-6 # kNm2
|
|
91
|
-
R = [-1, 0, 1e8, 0, 1e8, 0, -1, 0]
|
|
92
|
-
LM = [[1, 1, 20, 0, 0], [2, 1, 20, 0, 0], [3, 1, 20, 0, 0]]
|
|
93
|
-
|
|
94
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
95
|
-
out = beam_analysis.analyze()
|
|
96
|
-
assert out == 0
|
|
97
|
-
|
|
98
|
-
r = beam_analysis.beam_results.R
|
|
99
|
-
assert r == pytest.approx([120.00175999, 120.00175999])
|
|
100
|
-
|
|
101
|
-
dmax = max(beam_analysis.beam_results.results.D)
|
|
102
|
-
dmin = min(beam_analysis.beam_results.results.D)
|
|
103
|
-
assert [dmax, dmin] == pytest.approx(
|
|
104
|
-
[0.0002778734578837245, -0.004648274177216889], abs=1e-6
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def test_3span_subframe():
|
|
109
|
-
L = [6, 8, 6]
|
|
110
|
-
EI = 30 * np.array([50e8, 50e8, 50e8]) * 1e-6
|
|
111
|
-
R = [-1, 486e9, -1, 486e9, -1, 486e9, -1, 486e9]
|
|
112
|
-
LM = [[1, 1, 10, 0, 0], [2, 1, 20, 0, 0], [3, 1, 10, 0, 0]]
|
|
113
|
-
|
|
114
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
115
|
-
out = beam_analysis.analyze()
|
|
116
|
-
assert out == 0
|
|
117
|
-
|
|
118
|
-
r = beam_analysis.beam_results.R
|
|
119
|
-
assert r == pytest.approx([29.99999451, 110.00000549, 110.00000549, 29.99999451])
|
|
120
|
-
|
|
121
|
-
dmax = max(beam_analysis.beam_results.results.D)
|
|
122
|
-
dmin = min(beam_analysis.beam_results.results.D)
|
|
123
|
-
assert [dmax, dmin] == pytest.approx([0.0, -0.0014222225377228067], abs=1e-6)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def test_4span_posttensioned():
|
|
127
|
-
L = [6, 8, 6, 8]
|
|
128
|
-
EI = 30 * np.array([100e8, 100e8, 100e8, 100e8]) * 1e-6 # kNm2
|
|
129
|
-
R = [-1, 0, -1, 0, -1, 0, -1, 0, -1, 0]
|
|
130
|
-
LM = [
|
|
131
|
-
[1, 3, 20, 0, 1],
|
|
132
|
-
[1, 3, -10, 1, 4],
|
|
133
|
-
[1, 3, 20, 5, 1],
|
|
134
|
-
[1, 4, 50, 0, 0],
|
|
135
|
-
[2, 3, 20, 0, 1.5],
|
|
136
|
-
[2, 3, -10, 1.5, 5],
|
|
137
|
-
[2, 3, 20, 6.5, 1.5],
|
|
138
|
-
[3, 3, 20, 0, 1],
|
|
139
|
-
[3, 3, -10, 1, 4],
|
|
140
|
-
[3, 3, 20, 5, 1],
|
|
141
|
-
[4, 3, 20, 0, 1.5],
|
|
142
|
-
[4, 3, -10, 1.5, 5],
|
|
143
|
-
[4, 3, 20, 6.5, 1.5],
|
|
144
|
-
[4, 4, -75, 8, 0],
|
|
145
|
-
]
|
|
146
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R, LM)
|
|
147
|
-
out = beam_analysis.analyze()
|
|
148
|
-
assert out == 0
|
|
149
|
-
|
|
150
|
-
r = beam_analysis.beam_results.R
|
|
151
|
-
assert r == pytest.approx(
|
|
152
|
-
[14.87359893, -13.64621406, 15.69634808, -17.62411672, 20.70038377]
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
dmax = max(beam_analysis.beam_results.results.D)
|
|
156
|
-
dmin = min(beam_analysis.beam_results.results.D)
|
|
157
|
-
assert [dmax, dmin] == pytest.approx(
|
|
158
|
-
[0.0012715273282923978, -0.00013897273612280755], abs=1e-6
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def test_2span_pinned():
|
|
163
|
-
w = 20
|
|
164
|
-
L = [10, 10]
|
|
165
|
-
EI = 30 * np.array([600e7, 600e7]) * 1e-6
|
|
166
|
-
eType = [2, 1]
|
|
167
|
-
R = [-1, 0, -1, 0, -1, 0]
|
|
168
|
-
LM = [[1, 1, w, 0, 0], [2, 1, w, 0, 0]]
|
|
169
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R, LM, eType)
|
|
170
|
-
out = beam_analysis.analyze()
|
|
171
|
-
assert out == 0
|
|
172
|
-
|
|
173
|
-
r = beam_analysis.beam_results.R
|
|
174
|
-
assert r == pytest.approx([w * 5, w * 10, w * 5])
|
|
175
|
-
|
|
176
|
-
dmax = max(beam_analysis.beam_results.results.D)
|
|
177
|
-
dmin = min(beam_analysis.beam_results.results.D)
|
|
178
|
-
assert [dmax, dmin] == pytest.approx([0, -5 * w * L[0] ** 4 / (384 * EI[0])])
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
def test_3span_hinge():
|
|
182
|
-
L = [5, 5, 10]
|
|
183
|
-
EI = 30 * 600e7 * np.ones(len(L)) * 1e-6
|
|
184
|
-
eType = [2, 1, 1]
|
|
185
|
-
R = [-1, -1, 0, 0, -1, 0, -1, 0]
|
|
186
|
-
LM = [[3, 2, 20, 5, 0]]
|
|
187
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R, LM, eType)
|
|
188
|
-
out = beam_analysis.analyze()
|
|
189
|
-
assert out == 0
|
|
190
|
-
|
|
191
|
-
r = beam_analysis.beam_results.R
|
|
192
|
-
assert r == pytest.approx([-3.75, -18.75, 15.625, 8.125])
|
|
193
|
-
|
|
194
|
-
dmax = max(beam_analysis.beam_results.results.D)
|
|
195
|
-
dmin = min(beam_analysis.beam_results.results.D)
|
|
196
|
-
assert [dmax, dmin] == pytest.approx(
|
|
197
|
-
[0.0008680555555555557, -0.0016677326388888887], abs=1e-6
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def test_3span_hinge_il():
|
|
202
|
-
L = [5, 5, 10]
|
|
203
|
-
EI = 30 * 600e7 * np.ones(len(L)) * 1e-6
|
|
204
|
-
eType = [2, 1, 1]
|
|
205
|
-
R = [-1, -1, 0, 0, -1, 0, -1, 0]
|
|
206
|
-
|
|
207
|
-
ils = cba.InfluenceLines(L, EI, R, eType)
|
|
208
|
-
ils.create_ils(step=0.05)
|
|
209
|
-
(x, y) = ils.get_il(15.0, "V")
|
|
210
|
-
|
|
211
|
-
assert [min(y), max(y)] == pytest.approx([-0.4009469062500001, 0.59375], abs=1e-6)
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
def test_moment_load():
|
|
215
|
-
L = [10.0]
|
|
216
|
-
EI = 30 * 600e7 * np.ones(len(L)) * 1e-6
|
|
217
|
-
eType = [1]
|
|
218
|
-
R = [-1, 0, -1, 0]
|
|
219
|
-
|
|
220
|
-
for a in [0, 5, 10]:
|
|
221
|
-
LM = [[1, 4, 10, a, 0]]
|
|
222
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R, LM, eType)
|
|
223
|
-
out = beam_analysis.analyze()
|
|
224
|
-
assert out == 0
|
|
225
|
-
|
|
226
|
-
# Check deflection closes
|
|
227
|
-
d = beam_analysis.beam_results.D[[0, 2]]
|
|
228
|
-
assert d == pytest.approx([0.0, 0.0])
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
def test_envelopes():
|
|
232
|
-
L = [6, 4, 6]
|
|
233
|
-
EI = 30 * 10e9 * 1e-6
|
|
234
|
-
R = [-1, 0, -1, 0, -1, 0, -1, 0]
|
|
235
|
-
beam_analysis = cba.BeamAnalysis(L, EI, R)
|
|
236
|
-
|
|
237
|
-
LMg = [[1, 1, 25, 0, 0], [2, 1, 25, 0, 0], [3, 1, 25, 0, 0]]
|
|
238
|
-
γg_max = 1.4
|
|
239
|
-
γg_min = 1.0
|
|
240
|
-
LMq = [[1, 1, 10, 0, 0], [2, 1, 10, 0, 0], [3, 1, 10, 0, 0]]
|
|
241
|
-
γq_max = 1.6
|
|
242
|
-
γq_min = 0
|
|
243
|
-
|
|
244
|
-
lp = cba.LoadPattern(beam_analysis)
|
|
245
|
-
lp.set_dead_loads(LMg, γg_max, γg_min)
|
|
246
|
-
lp.set_live_loads(LMq, γq_max, γq_min)
|
|
247
|
-
env = lp.analyze()
|
|
248
|
-
|
|
249
|
-
m_locs = np.array([3, 6, 8, 10, 13])
|
|
250
|
-
idx = [(np.abs(env.x - x)).argmin() for x in m_locs]
|
|
251
|
-
assert np.allclose(
|
|
252
|
-
env.Mmax[idx], np.array([163.79, 0, 11.75, 0, 163.79]), atol=1e-2
|
|
253
|
-
)
|
|
254
|
-
assert np.allclose(
|
|
255
|
-
env.Mmin[idx], np.array([0, -163.38, -81.42, -163.38, 0]), atol=1e-2
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
n = beam_analysis.beam_results.npts
|
|
259
|
-
nspans = beam_analysis.beam.no_spans
|
|
260
|
-
Vmax = np.array(
|
|
261
|
-
[np.max(env.Vmax[i * (n + 3) : (i + 1) * (n + 3)]) for i in range(nspans)]
|
|
262
|
-
)
|
|
263
|
-
assert np.allclose(Vmax, np.array([131.1, 123.94, 180.23]), atol=1e-2)
|
|
264
|
-
Vmin = np.array(
|
|
265
|
-
[np.min(env.Vmin[i * (n + 3) : (i + 1) * (n + 3)]) for i in range(nspans)]
|
|
266
|
-
)
|
|
267
|
-
assert np.allclose(Vmin, np.array([-180.23, -123.94, -131.10]), atol=1e-2)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|