femethods 0.1.7a2__py3-none-any.whl → 0.1.8__py3-none-any.whl
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.
- femethods/__init__.py +8 -5
- femethods/core/__init__.py +4 -0
- femethods/mesh.py +245 -101
- femethods/validation.py +104 -0
- {femethods-0.1.7a2.dist-info → femethods-0.1.8.dist-info}/METADATA +281 -262
- femethods-0.1.8.dist-info/RECORD +9 -0
- {femethods-0.1.7a2.dist-info → femethods-0.1.8.dist-info}/WHEEL +1 -1
- femethods-0.1.8.dist-info/licenses/License.txt +7 -0
- {femethods-0.1.7a2.dist-info → femethods-0.1.8.dist-info}/top_level.txt +0 -1
- femethods/core/_base_elements.py +0 -422
- femethods/core/_common.py +0 -117
- femethods/elements.py +0 -389
- femethods/loads.py +0 -38
- femethods/reactions.py +0 -176
- femethods-0.1.7a2.dist-info/RECORD +0 -18
- tests/__init__.py +0 -1
- tests/functional tests/__init__.py +0 -0
- tests/functional tests/settings.py +0 -11
- tests/functional tests/test_fixed_support_beams.py +0 -38
- tests/functional tests/test_simply_supported_beam.py +0 -136
- tests/functional tests/validate.py +0 -44
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Functional tests for simply supported beams (beams with two pinned reactions)
|
|
3
|
-
|
|
4
|
-
https://www.awc.org/pdf/codes-standards/publications/design-aids/AWC-DA6-BeamFormulas-0710.pdf
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from settings import E, EI, Ixx, L, P
|
|
8
|
-
from validate import validate
|
|
9
|
-
|
|
10
|
-
from femethods.elements import Beam
|
|
11
|
-
from femethods.loads import PointLoad
|
|
12
|
-
from femethods.reactions import PinnedReaction
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def test_simply_supported_beam_center_load():
|
|
16
|
-
"""simple beam - concentrated load at center
|
|
17
|
-
Load case 7
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
# Exact setup
|
|
21
|
-
R = -P / 2 # lbs, reactions
|
|
22
|
-
M_max = -P * L / 4 # psi, maximum moment
|
|
23
|
-
d_max = P * L ** 3 / (48 * EI) # max displacement
|
|
24
|
-
|
|
25
|
-
# Numerical setup
|
|
26
|
-
beam = Beam(
|
|
27
|
-
length=L,
|
|
28
|
-
loads=[PointLoad(magnitude=P, location=L / 2)],
|
|
29
|
-
reactions=[PinnedReaction(x) for x in [0, L]],
|
|
30
|
-
E=E,
|
|
31
|
-
Ixx=Ixx,
|
|
32
|
-
)
|
|
33
|
-
beam.solve()
|
|
34
|
-
|
|
35
|
-
validate(beam, loc=L / 2, R=[(R, 0), (R, 0)], M_loc=M_max, d_loc=d_max)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def test_simply_supported_beam_offset_load():
|
|
39
|
-
"""simple beam - concentrated load at arbitrary points
|
|
40
|
-
Load case 8
|
|
41
|
-
"""
|
|
42
|
-
locations = [2, 3, 5, 7, 8]
|
|
43
|
-
for location in locations:
|
|
44
|
-
# Exact setup
|
|
45
|
-
a = location
|
|
46
|
-
b = L - a
|
|
47
|
-
R1 = -P * b / L
|
|
48
|
-
R2 = -P * a / L
|
|
49
|
-
M_loc = -P * a * b / L # moment at load
|
|
50
|
-
d_loc = P * a ** 2 * b ** 2 / (3 * EI * L) # deflection at load
|
|
51
|
-
|
|
52
|
-
# numerical result
|
|
53
|
-
beam = Beam(
|
|
54
|
-
L,
|
|
55
|
-
loads=[PointLoad(P, location)],
|
|
56
|
-
reactions=[PinnedReaction(x) for x in [0, L]],
|
|
57
|
-
E=E,
|
|
58
|
-
Ixx=Ixx,
|
|
59
|
-
)
|
|
60
|
-
beam.solve()
|
|
61
|
-
|
|
62
|
-
# verify reactions
|
|
63
|
-
validate(beam, loc=location, R=[(R1, 0), (R2, 0)], M_loc=M_loc, d_loc=d_loc)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def test_simply_supported_beam_equal_symmetric_loads():
|
|
67
|
-
"""Simple beam: Two equal concentrated loads symmetrically placed
|
|
68
|
-
load case 9
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
R = -P # both reactions are equal
|
|
72
|
-
a = L / 4
|
|
73
|
-
M_loc = -P * a # max moment (at center between loads)
|
|
74
|
-
d_loc = P * a / (24 * EI) * (3 * L ** 2 - 4 * a ** 2) # max deflection (at center)
|
|
75
|
-
|
|
76
|
-
p = [PointLoad(magnitude=P, location=x) for x in [a, L - a]]
|
|
77
|
-
r = [PinnedReaction(x) for x in [0, L]]
|
|
78
|
-
beam = Beam(length=L, loads=p, reactions=r, E=E, Ixx=Ixx)
|
|
79
|
-
beam.solve()
|
|
80
|
-
|
|
81
|
-
# verify reactions
|
|
82
|
-
validate(beam, loc=L / 2, R=[(R, 0), (R, 0)], M_loc=M_loc, d_loc=d_loc)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def test_simply_supported_beam_equal_non_symmetric_loads():
|
|
86
|
-
"""Simple beam: Two equal concentrated loads non-symmetrically placed
|
|
87
|
-
load case 10
|
|
88
|
-
"""
|
|
89
|
-
|
|
90
|
-
a = L / 4 # location of first load from right
|
|
91
|
-
b = L / 5 # location of second load from left
|
|
92
|
-
R1 = -P / L * (L - a + b)
|
|
93
|
-
R2 = -P / L * (L + a - b)
|
|
94
|
-
|
|
95
|
-
M1 = R1 * a # moment at first load
|
|
96
|
-
x = L / 2
|
|
97
|
-
Mx = R1 * x + P * (x - a) # moment at center
|
|
98
|
-
M2 = R2 * b # moment at second load
|
|
99
|
-
|
|
100
|
-
p = [PointLoad(magnitude=P, location=x) for x in [a, L - b]]
|
|
101
|
-
r = [PinnedReaction(x) for x in [0, L]]
|
|
102
|
-
beam = Beam(length=L, loads=p, reactions=r, E=E, Ixx=Ixx)
|
|
103
|
-
beam.solve()
|
|
104
|
-
|
|
105
|
-
# verify reactions
|
|
106
|
-
for m, loc in zip((M1, Mx, M2), (a, L / 2, L - b)):
|
|
107
|
-
validate(beam, loc=loc, R=[(R1, 0), (R2, 0)], M_loc=m, d_loc=None)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def test_simply_supported_beam_unequal_non_symmetric_loads():
|
|
111
|
-
"""Simple beam: Two unequal concentrated loads non-symmetrically placed
|
|
112
|
-
load case 11
|
|
113
|
-
"""
|
|
114
|
-
|
|
115
|
-
P1 = -900
|
|
116
|
-
P2 = -1200
|
|
117
|
-
a = L / 4 # location of first load from right
|
|
118
|
-
b = L / 5 # location of second load from left
|
|
119
|
-
|
|
120
|
-
R1 = -(P1 * (L - a) + P2 * b) / L
|
|
121
|
-
R2 = -(P1 * a + P2 * (L - b)) / L
|
|
122
|
-
|
|
123
|
-
M1 = R1 * a
|
|
124
|
-
x = L / 2
|
|
125
|
-
Mx = R1 * x + P1 * (x - a)
|
|
126
|
-
M2 = R2 * b
|
|
127
|
-
|
|
128
|
-
p = [PointLoad(magnitude=P1, location=a), PointLoad(magnitude=P2, location=L - b)]
|
|
129
|
-
r = [PinnedReaction(x) for x in [0, L]]
|
|
130
|
-
beam = Beam(length=L, loads=p, reactions=r, E=E, Ixx=Ixx)
|
|
131
|
-
beam.solve()
|
|
132
|
-
|
|
133
|
-
# verify reactions
|
|
134
|
-
for m, loc in zip((M1, Mx, M2), (a, L / 2, L - b)):
|
|
135
|
-
# assert approx(beam.reactions[0].value[0], rel=1e-4) == R1*1.25
|
|
136
|
-
validate(beam, loc=loc, R=[(R1, 0), (R2, 0)], M_loc=m, d_loc=None)
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Module to contain common verification code for functional tests
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from pytest import approx
|
|
6
|
-
|
|
7
|
-
from settings import TOL
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def validate(beam, loc, R, M_loc, d_loc):
|
|
11
|
-
"""Verify key values in the beam to exact values
|
|
12
|
-
|
|
13
|
-
Compare the following parameters between the numerical (beam) calculations
|
|
14
|
-
and values from exact, tabulated equations for specific cases.
|
|
15
|
-
* Reactions: given as a tuple of (force, moment)
|
|
16
|
-
* Moment at a specific location (loc)
|
|
17
|
-
* Displacement at a specific location (loc)
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
msgs = []
|
|
21
|
-
exact = []
|
|
22
|
-
for r in R:
|
|
23
|
-
exact.append(r[0])
|
|
24
|
-
exact.append(r[1])
|
|
25
|
-
msgs.append("Reaction force not equal")
|
|
26
|
-
msgs.append("Reaction moment not equal")
|
|
27
|
-
|
|
28
|
-
exact.append(M_loc)
|
|
29
|
-
exact.append(d_loc)
|
|
30
|
-
msgs.append("Moment at location not equal")
|
|
31
|
-
msgs.append("Deflection at location not equal")
|
|
32
|
-
|
|
33
|
-
numerical = []
|
|
34
|
-
for r in beam.reactions:
|
|
35
|
-
numerical.append(r.value[0])
|
|
36
|
-
numerical.append((r.value[1]))
|
|
37
|
-
numerical.append(beam.moment(loc)) # moment at given location
|
|
38
|
-
numerical.append(beam.deflection(loc)) # deflection at given location
|
|
39
|
-
|
|
40
|
-
for e, n, msg in zip(exact, numerical, msgs):
|
|
41
|
-
if e is None:
|
|
42
|
-
# there is not an exact value to compare, skip it
|
|
43
|
-
continue
|
|
44
|
-
assert approx(n, rel=TOL, abs=TOL) == e, msg
|