Skip to content

Commit f4a6321

Browse files
committed
Finished physical members
1 parent f0c365a commit f4a6321

File tree

3 files changed

+17
-66
lines changed

3 files changed

+17
-66
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ An easy to use elastic 3D structural engineering finite element analysis library
1818
* Member point loads, linearly varying distributed loads, and nodal loads are supported.
1919
* Classify loads by load case and create load combinations from load cases.
2020
* Produces shear, moment, and deflection results and diagrams for each member.
21+
* Automatic handling of internal nodes on frame members (physical members).
2122
* Tension-only and compression-only elements.
2223
* Spring elements: two-way, tension-only, and compression-only.
2324
* Spring supports: two-way and one-way.
@@ -33,11 +34,11 @@ As I've gotten into the structural engineering profession, I've found there's a
3334

3435
1. Accuracy: There are no guarantees PyNite is error free, but accuracy and correctness are a priority. When bugs or errors are identified, top priority will be given to eliminate them. PyNite's code is frequently reviewed, and its output is tested against a suite of textbook problems with known solutions using continuous integration (CI) anytime a change to the code base is made. If you do happen to find an error, please report it as an issue.
3536

36-
2. Simplicity: There are other finite element alternatives out there with many more capabilities, but they are often lacking in documentation, written in outdated languages, or require extensive knowledge of finite element theory and/or element formulations to use. PyNite is not intended to be the most technically advanced solver out there. Rather, the goal is to provide a robust yet simple general purpose package.
37+
2. Simplicity: There are other finite element alternatives out there with many more capabilities, but they are often lacking in documentation, written in difficult languages, or require extensive knowledge of finite element theory and/or element formulations to use. PyNite is not intended to be the most technically advanced solver out there. Rather, the goal is to provide a robust yet simple general purpose package.
3738

38-
4. Improvement: I plan to continue supporting PyNite for many years to come. There are a lot of pieces I'd like to add to PyNite going forward. There's a lot of potential to create extensions as well to solve all kinds of engineering problems. There are more problems to solve than I have time for, so some priorities will have to be made. The plan is to keep PyNite mainstream, adding core functionality first. Occasionally however I may just add what interests me at the time.
39+
4. Improvement: I plan to continue supporting PyNite for many years to come. There are a lot of pieces I'd like to add to PyNite going forward. There's a lot of potential to create extensions as well to solve all kinds of engineering problems. There are more problems to solve than I have time for, so some priorities will have to be made. The plan is to keep PyNite mainstream, adding core functionality first.
3940

40-
5. Collaboration: The intent is to keep PyNite free and open source. This will encourage future development and contributions. Keeping it open source will allow anyone to inspect and improve the code it runs on. If you see an area you think you can help PyNite improve in you are encouraged to contribute. I'd like to get PyNite doing a lot more. Don't be offended if I'm a little slow to accept your contributions. FEA is a very technical subject and accuracy is extremely important to me. Sometimes I'm a little slow understanding both FEA and Python and it takes some time for me to comprehend what's being proposed. I also have a young family to take care of that takes first priority.
41+
5. Collaboration: The intent is to keep PyNite free and open source. This will encourage future development and contributions. Keeping it open source will allow anyone to inspect and improve the code it runs on. If you see an area you can help PyNite improve in you are encouraged to contribute.
4142

4243
# Support
4344
Whether you just need help getting started with PyNite, or are looking to build something more complex, there are a few resources available:
@@ -64,7 +65,7 @@ PyNite depends on the following packages:
6465
# What's New?
6566

6667
v0.0.67
67-
* Added physical members. Members now automatically detect internal nodes.
68+
* Added physical members. Members now automatically detect internal nodes and subdivide themselves and their loads.
6869
* Refactoring: deprecated old method names for member results. You may now have some errors show up if you still try to get member results using the old method names.
6970
* Bug fix for P-Delta analysis. Global displacements were correct, but member internal forces were neglecting the geometric stiffness matrix. The impact of this bug was minimal, since the strain induced by correct global displacements was still being considered prior to this update. You should see a slight change to member P-Delta results.
7071
* Code simplification for P-Delta analysis.

Testing/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# Use warnings flag to suppress the PendingDeprecationWarning
1212
# from numpy.matrix
1313
# unittest.main(warnings='ignore')
14-
test_suite = unittest.TestLoader().discover("Testing", pattern='test_AISC*.py')
14+
test_suite = unittest.TestLoader().discover("Testing", pattern='test_*.py')
1515

1616
# `TextTestRunner` does not exit the module. CI will get confused unless we save the result
1717
# and send the proper exit code.

Testing/test_AISC_PDelta_benchmarks.py

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
class Test_AISC_Benchmark(unittest.TestCase):
1515
"""
16-
AISC's benchmark problems used to determine if a second order analysis
17-
procedure is rigorous enough.
16+
AISC's benchmark problems used to determine if a second order analysis procedure is rigorous
17+
enough.
1818
"""
1919

2020
def setUp(self):
@@ -27,7 +27,7 @@ def tearDown(self):
2727
# Reset the print function to normal
2828
sys.stdout = sys.__stdout__
2929

30-
def test_AISC_Benchmark_PhysMember(self):
30+
def test_AISC_Benchmark(self):
3131

3232
# Create the cantilever model
3333
cantilever = FEModel3D()
@@ -44,7 +44,7 @@ def test_AISC_Benchmark_PhysMember(self):
4444
num_nodes = 6
4545
for i in range(num_nodes):
4646
# Add nodes
47-
cantilever.add_node('N' + str(i+1), 0, i*L/6, 0)
47+
cantilever.add_node('N' + str(i+1), 0, i*L/(num_nodes - 1), 0)
4848

4949
# Add the member
5050
cantilever.add_member('M1', 'N1', 'N6', E, G, I, I, 200/12**4, 10/12**2)
@@ -61,13 +61,13 @@ def test_AISC_Benchmark_PhysMember(self):
6161
# Perform 2nd order analysis
6262
cantilever.analyze_PDelta()
6363

64-
from PyNite.Visualization import Renderer
65-
renderer = Renderer(cantilever)
66-
renderer.annotation_size = 0.5
67-
renderer.window_width = 750
68-
renderer.window_height = 750
69-
renderer.deformed_shape = True
70-
renderer.render_model()
64+
# from PyNite.Visualization import Renderer
65+
# renderer = Renderer(cantilever)
66+
# renderer.annotation_size = 0.5
67+
# renderer.window_width = 750
68+
# renderer.window_height = 750
69+
# renderer.deformed_shape = True
70+
# renderer.render_model()
7171

7272
# The moment at the base of the column
7373
calculated_moment = cantilever.Nodes['N1'].RxnMZ['Combo 1']
@@ -80,56 +80,6 @@ def test_AISC_Benchmark_PhysMember(self):
8080
Mmax = H*L*(math.tan(alpha)/alpha)
8181
ymax = H*L**3/(3*E*I)*(3*(math.tan(alpha)-alpha)/alpha**3)
8282

83-
# Compare the calculation results
84-
# self.assertAlmostEqual(calculated_moment/Mmax, 1.0, 1)
85-
# self.assertAlmostEqual(calculated_displacement/(ymax*12), 1.0, 1)
86-
87-
def test_AISC_Benckmark_Segments(self):
88-
# Create the cantilever model
89-
cantilever = FEModel3D()
90-
91-
# Define the column and its properties
92-
L = 20 # ft
93-
H = 5 # kips lateral load
94-
P = 100 # kips axial load
95-
G = 11200*12**2 # shear modulus (ksf)
96-
E = 29000*12**2 # modulus of elasticity (ksf)
97-
I = 100/12**4 # moment of inertia (ft^4)
98-
99-
# Break the column into several segments in order to capture P-little-delta effects
100-
num_segs = 5
101-
num_nodes = num_segs + 1
102-
for i in range(num_nodes):
103-
# Add nodes
104-
cantilever.add_node(str(i+1), 0, i*L/(num_segs), 0)
105-
106-
for i in range(num_segs):
107-
# Add members between nodes
108-
cantilever.add_member(str(i+1), str(i+1), str(i+2), E, G, I, I, 200/12**4, 10/12**2)
109-
110-
# Add a fixed support at the base of the column
111-
cantilever.def_support('1', True, True, True, True, True, True)
112-
113-
# Add a -10 kip axial load to the top of the column
114-
cantilever.add_node_load(str(num_nodes), 'FY', -P)
115-
116-
# Add a 5 kip lateral load to the top of the column
117-
cantilever.add_node_load(str(num_nodes), 'FX', H)
118-
119-
# Perform 2nd order analysis
120-
cantilever.analyze_PDelta()
121-
122-
# The moment at the base of the column
123-
calculated_moment = cantilever.Nodes['1'].RxnMZ['Combo 1']
124-
125-
# the deflection at the top of the column
126-
calculated_displacement = cantilever.Nodes[str(num_nodes)].DX['Combo 1']*12
127-
128-
# Calculate the AISC benchmark problem solution:
129-
alpha = (P*L**2/(E*I))**0.5
130-
Mmax = H*L*(math.tan(alpha)/alpha)
131-
ymax = H*L**3/(3*E*I)*(3*(math.tan(alpha)-alpha)/alpha**3)
132-
13383
# Compare the calculation results
13484
self.assertAlmostEqual(calculated_moment/Mmax, 1.0, 1)
13585
self.assertAlmostEqual(calculated_displacement/(ymax*12), 1.0, 1)

0 commit comments

Comments
 (0)