PyCBA 0.4.0__tar.gz → 0.4.2__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.0/src/PyCBA.egg-info → PyCBA-0.4.2}/PKG-INFO +2 -1
- {PyCBA-0.4.0 → PyCBA-0.4.2}/README.md +1 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2/src/PyCBA.egg-info}/PKG-INFO +2 -1
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/__init__.py +1 -1
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/beam.py +12 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/inf_lines.py +28 -5
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/load.py +33 -1
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/results.py +2 -2
- {PyCBA-0.4.0 → PyCBA-0.4.2}/tests/test_basic.py +25 -20
- {PyCBA-0.4.0 → PyCBA-0.4.2}/LICENSE +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/pyproject.toml +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/setup.cfg +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/setup.py +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/PyCBA.egg-info/SOURCES.txt +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/PyCBA.egg-info/dependency_links.txt +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/PyCBA.egg-info/requires.txt +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/PyCBA.egg-info/top_level.txt +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/analysis.py +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/bridge.py +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/pattern.py +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/utils.py +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/src/pycba/vehicle.py +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/tests/test_bridge.py +0 -0
- {PyCBA-0.4.0 → PyCBA-0.4.2}/tests/test_inf_lines.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyCBA
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Python Continuous Beam Analysis
|
|
5
5
|
Author-email: Colin Caprani <colin.caprani@monash.edu>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -49,3 +49,4 @@ One of the main functions of `PyCBA` is that the basic analysis engine forms the
|
|
|
49
49
|
|
|
50
50
|
- Influence line generation
|
|
51
51
|
- Moving load analysis for bridges, targeted at bridge access assessments
|
|
52
|
+
- Load patterning and enveloping
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyCBA
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Python Continuous Beam Analysis
|
|
5
5
|
Author-email: Colin Caprani <colin.caprani@monash.edu>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -49,3 +49,4 @@ One of the main functions of `PyCBA` is that the basic analysis engine forms the
|
|
|
49
49
|
|
|
50
50
|
- Influence line generation
|
|
51
51
|
- Moving load analysis for bridges, targeted at bridge access assessments
|
|
52
|
+
- Load patterning and enveloping
|
|
@@ -219,6 +219,18 @@ class Beam:
|
|
|
219
219
|
The number of restraints in the beam
|
|
220
220
|
"""
|
|
221
221
|
return len(self._restraints)
|
|
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])
|
|
222
234
|
|
|
223
235
|
@property
|
|
224
236
|
def length(self):
|
|
@@ -121,18 +121,41 @@ class InfluenceLines:
|
|
|
121
121
|
x = self.vResults[0].results.x
|
|
122
122
|
dx = x[2] - x[1]
|
|
123
123
|
idx = np.where(np.abs(x - poi) <= dx * 1e-6)[0][0]
|
|
124
|
-
#
|
|
125
|
-
|
|
126
|
-
np.abs(np.cumsum(np.insert(self.ba.beam.mbr_lengths, 0, 0)) - poi)
|
|
127
|
-
).argmin()
|
|
124
|
+
#idx = np.abs(x - poi).argmin()
|
|
125
|
+
|
|
128
126
|
npts = len(self.vResults)
|
|
129
127
|
eta = np.zeros(npts)
|
|
128
|
+
|
|
129
|
+
#
|
|
130
|
+
# Getting the correct vertical reaction is tricky
|
|
131
|
+
# Should be relatively easy to extend to get moment reactions too.
|
|
132
|
+
#
|
|
133
|
+
# Get vector of the node locations
|
|
134
|
+
node_locations = np.cumsum(np.insert(self.ba.beam.mbr_lengths, 0, 0))
|
|
135
|
+
# The indices of the supported vertical DOFs wrt the node locations vector
|
|
136
|
+
vert_sup_dof_idx = np.where(np.array(self.ba._beam.restraints)[::2]==-1)[0]
|
|
137
|
+
# The locations then of these vertical supports
|
|
138
|
+
vert_sup_locs = node_locations[vert_sup_dof_idx]
|
|
139
|
+
# The index of the closest vertical support
|
|
140
|
+
closest_vert_sup_idx = np.abs(vert_sup_locs-poi).argmin()
|
|
141
|
+
# And its value
|
|
142
|
+
closest_vert_sup = vert_sup_locs[closest_vert_sup_idx]
|
|
143
|
+
# And now the indixe of this support in the node locations vector
|
|
144
|
+
node_idx = np.where(node_locations==closest_vert_sup)[0][0]
|
|
145
|
+
# And hence its index in the overall DOFs vector
|
|
146
|
+
dof_idx = 2*node_idx
|
|
147
|
+
|
|
148
|
+
# Now we must link the supported DOF to the index in the BeamAnalysis reactions vector
|
|
149
|
+
idx_mask = np.zeros_like(self.ba._beam.restraints)
|
|
150
|
+
idx_mask[np.where(np.array(self.ba._beam.restraints)==-1)] = np.arange(self.ba.beam.no_fixed_restraints)
|
|
151
|
+
# And finally the index of the vertical support nearest the POI in the reactions vector
|
|
152
|
+
vert_sup_idx = idx_mask[dof_idx]
|
|
130
153
|
|
|
131
154
|
for i, res in enumerate(self.vResults):
|
|
132
155
|
if load_effect == "V":
|
|
133
156
|
eta[i] = res.results.V[idx]
|
|
134
157
|
elif load_effect == "R":
|
|
135
|
-
eta[i] = res.R[
|
|
158
|
+
eta[i] = res.R[vert_sup_idx]
|
|
136
159
|
else:
|
|
137
160
|
eta[i] = res.results.M[idx]
|
|
138
161
|
|
|
@@ -799,7 +799,7 @@ def parse_LM(LM: LoadMatrix) -> List[Load]:
|
|
|
799
799
|
return loads
|
|
800
800
|
|
|
801
801
|
|
|
802
|
-
def add_LM(LM1: LoadMatrix, LM2: LoadMatrix):
|
|
802
|
+
def add_LM(LM1: LoadMatrix, LM2: LoadMatrix) -> LoadMatrix:
|
|
803
803
|
"""
|
|
804
804
|
Adds two load matrices and returns the sum; this enables superposition
|
|
805
805
|
|
|
@@ -824,3 +824,35 @@ def add_LM(LM1: LoadMatrix, LM2: LoadMatrix):
|
|
|
824
824
|
LM.append(load)
|
|
825
825
|
|
|
826
826
|
return LM
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
def factor_LM(LM: LoadMatrix, gamma: float) -> LoadMatrix:
|
|
830
|
+
"""
|
|
831
|
+
Applies a factor to the loads in a `LoadMatrix` object
|
|
832
|
+
|
|
833
|
+
Parameters
|
|
834
|
+
----------
|
|
835
|
+
LM : LoadMatrix
|
|
836
|
+
The `LoadMatrix` object
|
|
837
|
+
|
|
838
|
+
gamma : float
|
|
839
|
+
A factor to apply to the load magnitudes
|
|
840
|
+
|
|
841
|
+
Returns
|
|
842
|
+
-------
|
|
843
|
+
LM : LoadMatrix
|
|
844
|
+
The factored `LoadMatrix` object
|
|
845
|
+
"""
|
|
846
|
+
LMnew = []
|
|
847
|
+
for load in LM:
|
|
848
|
+
i_span = load[0]
|
|
849
|
+
l_type = load[1]
|
|
850
|
+
mag = gamma * load[2]
|
|
851
|
+
if l_type == 1: # UDL
|
|
852
|
+
LMnew.append([i_span, l_type, mag])
|
|
853
|
+
elif l_type == 2 or l_type == 4: # PL or ML
|
|
854
|
+
LMnew.append([i_span, l_type, mag, load[3]])
|
|
855
|
+
else: # PUDL
|
|
856
|
+
LMnew.append([i_span, l_type, mag, load[3], load[4]])
|
|
857
|
+
|
|
858
|
+
return LMnew
|
|
@@ -371,7 +371,7 @@ class Envelopes:
|
|
|
371
371
|
raise ValueError("No results to display")
|
|
372
372
|
|
|
373
373
|
L = self.x[-1]
|
|
374
|
-
|
|
374
|
+
|
|
375
375
|
fig, axs = plt.subplots(2, 1, sharex=True, **kwargs)
|
|
376
376
|
|
|
377
377
|
ax = axs[0]
|
|
@@ -389,7 +389,7 @@ class Envelopes:
|
|
|
389
389
|
ax.grid()
|
|
390
390
|
ax.set_ylabel("Shear Force (kN)")
|
|
391
391
|
ax.set_xlabel("Distance along beam (m)")
|
|
392
|
-
|
|
392
|
+
|
|
393
393
|
if each:
|
|
394
394
|
for res in self.vResults:
|
|
395
395
|
axs[0].plot(self.x, res.results.M, "r", lw=0.5)
|
|
@@ -227,36 +227,41 @@ def test_moment_load():
|
|
|
227
227
|
d = beam_analysis.beam_results.D[[0, 2]]
|
|
228
228
|
assert d == pytest.approx([0.0, 0.0])
|
|
229
229
|
|
|
230
|
+
|
|
230
231
|
def test_envelopes():
|
|
231
|
-
L = [6,4,6]
|
|
232
|
+
L = [6, 4, 6]
|
|
232
233
|
EI = 30 * 10e9 * 1e-6
|
|
233
|
-
R = [-1,0
|
|
234
|
+
R = [-1, 0, -1, 0, -1, 0, -1, 0]
|
|
234
235
|
beam_analysis = cba.BeamAnalysis(L, EI, R)
|
|
235
|
-
|
|
236
|
-
LMg = [[1,1,25,0,0],
|
|
237
|
-
[2,1,25,0,0],
|
|
238
|
-
[3,1,25,0,0]]
|
|
236
|
+
|
|
237
|
+
LMg = [[1, 1, 25, 0, 0], [2, 1, 25, 0, 0], [3, 1, 25, 0, 0]]
|
|
239
238
|
γg_max = 1.4
|
|
240
239
|
γg_min = 1.0
|
|
241
|
-
LMq = [[1,1,10,0,0],
|
|
242
|
-
[2,1,10,0,0],
|
|
243
|
-
[3,1,10,0,0]]
|
|
240
|
+
LMq = [[1, 1, 10, 0, 0], [2, 1, 10, 0, 0], [3, 1, 10, 0, 0]]
|
|
244
241
|
γq_max = 1.6
|
|
245
242
|
γq_min = 0
|
|
246
|
-
|
|
243
|
+
|
|
247
244
|
lp = cba.LoadPattern(beam_analysis)
|
|
248
|
-
lp.set_dead_loads(LMg
|
|
249
|
-
lp.set_live_loads(LMq
|
|
245
|
+
lp.set_dead_loads(LMg, γg_max, γg_min)
|
|
246
|
+
lp.set_live_loads(LMq, γq_max, γq_min)
|
|
250
247
|
env = lp.analyze()
|
|
251
|
-
|
|
248
|
+
|
|
252
249
|
m_locs = np.array([3, 6, 8, 10, 13])
|
|
253
250
|
idx = [(np.abs(env.x - x)).argmin() for x in m_locs]
|
|
254
|
-
assert np.allclose(
|
|
255
|
-
|
|
256
|
-
|
|
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
|
+
|
|
257
258
|
n = beam_analysis.beam_results.npts
|
|
258
259
|
nspans = beam_analysis.beam.no_spans
|
|
259
|
-
Vmax = np.array(
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
assert np.allclose(
|
|
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
|
|
File without changes
|