Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for v0.0.98 #230

Merged
merged 41 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d6fb9cd
member section use enforced
bjhowie Sep 14, 2024
3708c03
report + material updates
bjhowie Sep 14, 2024
566546c
Update member.rst
bjhowie Sep 24, 2024
59ce1f2
Merge branch 'main' into section-material-improvements
bjhowie Sep 24, 2024
ed74561
Fix TC test + remove 3.10 style type hints
bjhowie Sep 24, 2024
a6dc255
v0.0.97 is no longer "in progress"
Nov 9, 2024
96bc75e
Merge pull request #223 from JWock82/release
JWock82 Nov 12, 2024
d1c03e7
Merge branch 'main' into section-material-improvements
JWock82 Nov 12, 2024
e49bff2
Merge pull request #218 from bjhowie/section-material-improvements
JWock82 Nov 12, 2024
eefd8e3
Added code coverage
Nov 12, 2024
98a0002
Cleaning the working tree
Nov 12, 2024
6d9721d
Merge branch 'main' of https://github.com/JWock82/PyNite
Nov 12, 2024
811ef8e
Removed unused file
Nov 12, 2024
1e06b2c
Placed coverage in build-and-test.yml
Nov 12, 2024
f197a8c
Install coverage in CI env
Nov 12, 2024
019f8fa
Fixed typo
Nov 12, 2024
d0c2b29
Stopped exit(0) from executing in GitHub Actions
Nov 12, 2024
fcfa126
Adjusted badges
Nov 12, 2024
f496bbc
Corrected .coverage filepath
Nov 12, 2024
2af47bd
Added codecove token
Nov 12, 2024
19d4f7e
Adjusted badge link
Nov 12, 2024
e984ca6
Archived old MITC4 element
Nov 12, 2024
3bc1c65
Added unit tests for `Visualization.py`
Nov 13, 2024
f5f4907
Updated `requirements.txt` to match v0.0.97
Nov 13, 2024
668e692
Deprecated old code that is no longer maintained
Nov 13, 2024
ac14167
Improved unit tests
Nov 13, 2024
a6a113c
Removed old unused code
Nov 13, 2024
e2c0240
Removed obsolete import
Nov 13, 2024
62b9511
Improvements to unit tests
Nov 13, 2024
8f1571c
Update GitHub Action to run in a headless env
Nov 13, 2024
b801077
Added plate rendering to test
Nov 14, 2024
6d4f9f0
Fix for rendering test
Nov 14, 2024
75754e1
Allow for multiple screenshots w/o shutting down the plotter
Nov 16, 2024
7d0b802
Updated method keyword args
Nov 21, 2024
e29261c
Improved spring rendering in `pyvista`
Nov 22, 2024
4917ec0
Removed argument from `plot_spring`
Nov 23, 2024
c375d28
Fix method keyword args
guyi2000 Dec 6, 2024
4ee8659
Fix render code in examples
guyi2000 Dec 6, 2024
a35b591
Fix FEModel3D and Renderer attr in Examples
guyi2000 Dec 6, 2024
9a3d905
Update for v0.0.98
Dec 6, 2024
cbced09
Merge pull request #229 from guyi2000/examples-fix
JWock82 Dec 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .coverage
Binary file not shown.
23 changes: 20 additions & 3 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ on:

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand All @@ -20,22 +19,40 @@ jobs:

steps:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
python -m pip install scipy
python -m pip install vtk
python -m pip install coverage
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

- name: Test with unittest
run: |
python -m unittest Testing
xvfb-run -a coverage run --source=PyNite -m unittest discover

- name: Convert coverage to XML
run: |
coverage xml -o .coverage.xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
with:
file: .coverage.xml
flags: unittests
name: codecov-coverage
token: ${{ secrets.CODECOV_TOKEN }}

File renamed without changes.
6 changes: 4 additions & 2 deletions Examples/Beam on Elastic Foundation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@
G = 11200 # ksi
boef.add_material('Steel', E, G, 0.3, 490/1000/12**3)

# Define section properties (W8x35)
# Define section properties (W8x35) and add a section to the model
A = 10.3 # in^2
Iz = 127 # in^4 (strong axis)
Iy = 42.6 # in^4 (weak axis)
J = 0.769 # in^4

boef.add_section('W8x35', A, Iy, Iz, J)

# Define the member
boef.add_member('M1', 'N1', 'N' + str(num_nodes), 'Steel', Iy, Iz, J, A)
boef.add_member('M1', 'N1', 'N' + str(num_nodes), 'Steel', 'W8x35')

# In the next few lines no load case or load combination is being specified. When this is the case,
# PyNite internally creates a default load case ('Case 1') and a default load combination
Expand Down
27 changes: 15 additions & 12 deletions Examples/Braced Frame - Spring Supported.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
braced_frame.add_node('N3', 15*12, 12*12, 0)
braced_frame.add_node('N4', 15*12, 0*12, 0)

# Define column properties (use W10x33 from the AISC Manual):
# Define column properties (use W10x33 from the AISC Manual) and add section to the model:
Iy = 36.6 # in^4
Iz = 171 # in^4
J = 0.58 # in^4
A = 9.71 # in^2
braced_frame.add_section('W10x33', A, Iy, Iz, J)

# Define a material
E = 29000 # Young's modulus (ksi)
Expand All @@ -27,29 +28,31 @@
braced_frame.add_material('Steel', E, G, nu, rho)

# Define the columns
braced_frame.add_member('Col1', 'N1', 'N2', 'Steel', Iy, Iz, J, A)
braced_frame.add_member('Col2', 'N4', 'N3', 'Steel', Iy, Iz, J, A)
braced_frame.add_member('Col1', 'N1', 'N2', 'Steel', 'W10x33')
braced_frame.add_member('Col2', 'N4', 'N3', 'Steel', 'W10x33')

# Define beam properties (Use W8x24)
# Define beam properties (Use W8x24) and add section to the model
Iy = 18.3 # in^4
Iz = 82.7 # in^4
J = 0.346 # in^4
A = 7.08 # in^2
braced_frame.add_section('W8x24', A, Iy, Iz, J)

# Define the beams
braced_frame.add_member('Beam', 'N2', 'N3', 'Steel', Iy, Iz, J, A)
braced_frame.add_member('Beam', 'N2', 'N3', 'Steel', 'W8x24')
braced_frame.def_releases('Beam', Ryi=True, Rzi=True, Ryj=True, Rzj=True)

# Define the brace properties
# We'll use a section with L/r <= 300 which is a common rule of thumb for
# tension members. We'll use L4x4x1/4.
# tension members. We'll use L4x4x1/4.
Iy = 3 # in^4
Iz = 3 # in^4
J = 0.0438 # in^4
A = 1.94 # in^2
braced_frame.add_section('L4x4x1/4', A, Iy, Iz, J)

# Define a brace (tension and compression - both ways)
braced_frame.add_member('Brace1', 'N1', 'N3', 'Steel', Iy, Iz, J, A)
braced_frame.add_member('Brace1', 'N1', 'N3', 'Steel', 'L4x4x1/4')

# Let's add spring supports to the base of the structure. We'll add a couple of
# extra nodes at the base of the structure that will receive the springs. The
Expand Down Expand Up @@ -97,18 +100,18 @@
# to the full member length. Note also that the direction uses lowercase
# notations to indicate member local coordinate systems. Brace loads have been
# neglected.
braced_frame.add_member_dist_load('Beam', Direction='Fy', w1=-0.024/12,
braced_frame.add_member_dist_load('Beam', direction='Fy', w1=-0.024/12,
w2=-0.024/12, x1=0, x2=15*12, case='D')
braced_frame.add_member_dist_load('Col1', Direction='Fx', w1=-0.033/12,
braced_frame.add_member_dist_load('Col1', direction='Fx', w1=-0.033/12,
w2=-0.033/12, x1=0, x2=12*12, case='D')
braced_frame.add_member_dist_load('Col2', Direction='Fx', w1=-0.033/12,
braced_frame.add_member_dist_load('Col2', direction='Fx', w1=-0.033/12,
w2=-0.033/12, x1=0, x2=12*12, case='D')

# Add nodal wind loads of 25 kips to each side of the frame. Note that the
# direction uses uppercase notation to indicate model global coordinate
# system.
braced_frame.add_node_load('N2', Direction='FX', P=25, case='W')
braced_frame.add_node_load('N3', Direction='FX', P=25, case='W')
braced_frame.add_node_load('N2', direction='FX', P=25, case='W')
braced_frame.add_node_load('N3', direction='FX', P=25, case='W')

# Create load combinations
# Note that the load combination '1.4D' has no lateral load, but does have
Expand Down
25 changes: 13 additions & 12 deletions Examples/Braced Frame - Tension Only.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Iz = 171 # in^4
J = 0.58 # in^4
A = 9.71 # in^2
braced_frame.add_section('W10x33', A, Iy, Iz, J)

# Define a material
E = 29000 # ksi
Expand All @@ -27,17 +28,18 @@
braced_frame.add_material('Steel', E, G, nu, rho)

# Define the columns
braced_frame.add_member('Col1', 'N1', 'N2', 'Steel', Iy, Iz, J, A)
braced_frame.add_member('Col2', 'N4', 'N3', 'Steel', Iy, Iz, J, A)
braced_frame.add_member('Col1', 'N1', 'N2', 'Steel', 'W10x33')
braced_frame.add_member('Col2', 'N4', 'N3', 'Steel', 'W10x33')

# Define beam properties (Use W8x24)
Iy = 18.3 # in^4
Iz = 82.7 # in^4
J = 0.346 # in^4
A = 7.08 # in^2
braced_frame.add_section('W8x24', A, Iy, Iz, J)

# Define the beams
braced_frame.add_member('Beam', 'N2', 'N3', 'Steel', Iy, Iz, J, A)
braced_frame.add_member('Beam', 'N2', 'N3', 'Steel', 'W8x24')
braced_frame.def_releases('Beam', Ryi=True, Rzi=True, Ryj=True, Rzj=True)

# Define the brace properties
Expand All @@ -47,12 +49,11 @@
Iz = 3 # in^4
J = 0.0438 # in^4
A = 1.94 # in^2
braced_frame.add_section('L4x4x1/4', A, Iy, Iz, J)

# Define the braces
braced_frame.add_member('Brace1', 'N1', 'N3', 'Steel', Iy, Iz, J, A,
tension_only=True)
braced_frame.add_member('Brace2', 'N4', 'N2', 'Steel', Iy, Iz, J, A,
tension_only=True)
braced_frame.add_member('Brace1', 'N1', 'N3', 'Steel', 'L4x4x1/4', tension_only=True)
braced_frame.add_member('Brace2', 'N4', 'N2', 'Steel', 'L4x4x1/4', tension_only=True)

# Release the brace ends to form an axial member
braced_frame.def_releases('Brace1', Ryi=True, Rzi=True, Ryj=True, Rzj=True)
Expand All @@ -75,18 +76,18 @@
# to the full member length. Note also that the direction uses lowercase
# notations to indicate member local coordinate systems. Brace loads have been
# neglected.
braced_frame.add_member_dist_load('Beam', Direction='Fy', w1=-0.024/12,
braced_frame.add_member_dist_load('Beam', direction='Fy', w1=-0.024/12,
w2=-0.024/12, x1=0, x2=15*12, case='D')
braced_frame.add_member_dist_load('Col1', Direction='Fx', w1=-0.033/12,
braced_frame.add_member_dist_load('Col1', direction='Fx', w1=-0.033/12,
w2=-0.033/12, x1=0, x2=12*12, case='D')
braced_frame.add_member_dist_load('Col2', Direction='Fx', w1=-0.033/12,
braced_frame.add_member_dist_load('Col2', direction='Fx', w1=-0.033/12,
w2=-0.033/12, x1=0, x2=12*12, case='D')

# Add nodal wind loads of 25 kips to each side of the frame. Note that the
# direction uses uppercase notation to indicate model global coordinate
# system.
braced_frame.add_node_load('N2', Direction='FX', P=25, case='W')
braced_frame.add_node_load('N3', Direction='FX', P=25, case='W')
braced_frame.add_node_load('N2', direction='FX', P=25, case='W')
braced_frame.add_node_load('N3', direction='FX', P=25, case='W')

# Create load combinations
# Note that the load combination '1.4D' has no lateral load, but does have
Expand Down
10 changes: 8 additions & 2 deletions Examples/Circular Bin with Conical Hopper.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,11 @@
model.analyze()

# Render the model. Labels and loads will be turned off to speed up interaction.
from PyNite.Visualization import Renderer, render_model
render_model(model, 0.1, render_loads=True, color_map='dz', combo_name='1.4F', labels=False)
from PyNite.Visualization import Renderer
rndr = Renderer(model)
rndr.annotation_size = 0.1
rndr.render_loads = False
rndr.color_map = 'dz'
rndr.combo_name = '1.4F'
rndr.labels = False
rndr.render_model()
25 changes: 16 additions & 9 deletions Examples/Moment Frame - Lateral Load.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Iz = 171 # in^4
J = 0.58 # in^4
A = 9.71 # in^2
MomentFrame.add_section('W10x33', A, Iy, Iz, J)

# Define a material
E = 29000 # ksi
Expand All @@ -27,17 +28,18 @@
MomentFrame.add_material('Steel', E, G, nu, rho)

# Define the columns
MomentFrame.add_member('Col1', 'N1', 'N2', 'Steel', Iy, Iz, J, A)
MomentFrame.add_member('Col2', 'N4', 'N3', 'Steel', Iy, Iz, J, A)
MomentFrame.add_member('Col1', 'N1', 'N2', 'Steel', 'W10x33')
MomentFrame.add_member('Col2', 'N4', 'N3', 'Steel', 'W10x33')

# Define beam properties (Use W8x24)
Iy = 18.3 # in^4
Iz = 82.7 # in^4
J = 0.346 # in^4
A = 7.08 # in^2
MomentFrame.add_section('W8x24', A, Iy, Iz, J)

# Define the beams
MomentFrame.add_member('Beam', 'N2', 'N3', 'Steel', Iy, Iz, J, A)
MomentFrame.add_member('Beam', 'N2', 'N3', 'Steel', 'W8x24')

# Provide fixed supports at the bases of the columns
MomentFrame.def_support('N1', support_DX=True, support_DY=True, support_DZ=True, support_RX=True, support_RY=True, support_RZ=True)
Expand All @@ -46,13 +48,13 @@
# Add self weight dead loads to the frame
# Note that we could leave 'x1' and 'x2' undefined below and it would default to the full member length
# Note also that the direction uses lowercase notations to indicate member local coordinate systems
MomentFrame.add_member_dist_load('Beam', Direction='Fy', w1=-0.024/12, w2=-0.024/12, x1=0, x2=15*12, case='D')
MomentFrame.add_member_dist_load('Col1', Direction='Fx', w1=-0.033/12, w2=-0.033/12, x1=0, x2=12*12, case='D')
MomentFrame.add_member_dist_load('Col2', Direction='Fx', w1=-0.033/12, w2=-0.033/12, x1=0, x2=12*12, case='D')
MomentFrame.add_member_dist_load('Beam', direction='Fy', w1=-0.024/12, w2=-0.024/12, x1=0, x2=15*12, case='D')
MomentFrame.add_member_dist_load('Col1', direction='Fx', w1=-0.033/12, w2=-0.033/12, x1=0, x2=12*12, case='D')
MomentFrame.add_member_dist_load('Col2', direction='Fx', w1=-0.033/12, w2=-0.033/12, x1=0, x2=12*12, case='D')

# Add a nodal wind load of 10 kips at the left side of the frame
# Note that the direction uses uppercase notation to indicate model global coordinate system
MomentFrame.add_node_load('N2', Direction='FX', P=10, case='W')
MomentFrame.add_node_load('N2', direction='FX', P=10, case='W')

# Create two load combinations
MomentFrame.add_load_combo('1.2D+1.0W', factors={'D':1.2, 'W':1.0})
Expand All @@ -69,8 +71,13 @@
# MomentFrame.analyze_linear(log=True)

# Display the deformed shape of the structure magnified 50 times with the text height 5 model units (inches) high
from PyNite import Visualization
Visualization.render_model(MomentFrame, annotation_size=5, deformed_shape=True, deformed_scale=50, combo_name='1.2D+1.0W')
from PyNite.Visualization import Renderer
rndr = Renderer(MomentFrame)
rndr.annotation_size = 5
rndr.deformed_shape = True
rndr.deformed_scale = 50
rndr.combo_name = '1.2D+1.0W'
rndr.render_model(MomentFrame)

# Plot the moment diagram for the beam
MomentFrame.members['Beam'].plot_moment('Mz', combo_name='1.2D+1.0W')
Expand Down
5 changes: 3 additions & 2 deletions Examples/P-Delta Analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
# Add nodes
cantilever.add_node('N' + str(i+1), 0, i*L/(num_nodes - 1), 0)

# Add the member
cantilever.add_member('M1', 'N1', 'N6', 'Steel', I, I, 200/12**4, 10/12**2)
# Add the section and member
cantilever.add_section('MySection', 10/12**2, I, I, 200/12**4)
cantilever.add_member('M1', 'N1', 'N6', 'Steel', 'MySection')

# Add a fixed support at the base of the column
cantilever.def_support('N1', True, True, True, True, True, True)
Expand Down
10 changes: 5 additions & 5 deletions Examples/Rectangular Tank Wall - Hydrostatic Loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
renderer.deformed_scale = 1000
renderer.color_map = 'Qy'
renderer.combo_name = '1.4F'
renderer.labels = True
renderer.show_labels = True
renderer.scalar_bar = True
renderer.scalar_bar_text_size = 12
renderer.render_model()
Expand All @@ -89,10 +89,10 @@
My = -0.0242*qo*a**2

# Pynite solution
Qx_pn = model.Quads['Q176'].shear(-1, 0, True, '1.4F')[0, 0]
Qy_pn = model.Meshes['MSH1'].max_shear('Qy', '1.4F')
Mx_pn = model.Quads['Q176'].moment(-1, 0, True, '1.4F')[0, 0]
My_pn = model.Meshes['MSH1'].min_moment('My', '1.4F')
Qx_pn = model.quads['Q176'].shear(-1, 0, True, '1.4F')[0, 0]
Qy_pn = model.meshes['MSH1'].max_shear('Qy', '1.4F')
Mx_pn = model.quads['Q176'].moment(-1, 0, True, '1.4F')[0, 0]
My_pn = model.meshes['MSH1'].min_moment('My', '1.4F')

# Comparison of solutions
print('Max Moment at Side Mid-Height of Wall, Mx | Pynite: ', Mx_pn, '| Timoshenko: ', Mx)
Expand Down
7 changes: 5 additions & 2 deletions Examples/Simple Beam - Factored Envelope.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
rho = 2.836e-4 # Density (kci)
simple_beam.add_material('Steel', E, G, nu, rho)

# Add a beam with the following properties:
# Add a section with the following properties:
# Iy = 100 in^4, Iz = 150 in^4, J = 250 in^4, A = 20 in^2
simple_beam.add_member('M1', 'N1', 'N2', 'Steel', 100, 150, 250, 20)
simple_beam.add_section('MySection', 20, 100, 150, 250)

#Add member
simple_beam.add_member('M1', 'N1', 'N2', 'Steel', 'MySection')

# Provide simple supports
simple_beam.def_support('N1', True, True, True, True, False, False) # Constrained for torsion at 'N1'
Expand Down
7 changes: 5 additions & 2 deletions Examples/Simple Beam - Point Load.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@
rho = 2.836e-4 # Density (kci)
simple_beam.add_material('Steel', E, G, nu, rho)

# Add a beam with the following properties:
# Add a section with the following properties:
# Iy = 100 in^4, Iz = 150 in^4, J = 250 in^4, A = 20 in^2
simple_beam.add_member('M1', 'N1', 'N2', 'Steel', 100, 150, 250, 20)
simple_beam.add_section('MySection', 20, 100, 150, 250)

#Add member
simple_beam.add_member('M1', 'N1', 'N2', 'Steel', 'MySection')

# Provide simple supports
simple_beam.def_support('N1', True, True, True, True, False, False) # Constrained for torsion at 'N1'
Expand Down
7 changes: 5 additions & 2 deletions Examples/Simple Beam - Uniform Load.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
rho = 2.836e-4 # Density (kci)
simple_beam.add_material('Steel', E, G, nu, rho)

# Add a beam with the following properties:
# Add a section with the following properties:
# Iy = 100 in^4, Iz = 150 in^4, J = 250 in^4, A = 20 in^2
simple_beam.add_member('M1', 'N1', 'N2', 'Steel', 100, 150, 250, 20)
simple_beam.add_section('MySection', 20, 100, 150, 250)

#Add member
simple_beam.add_member('M1', 'N1', 'N2', 'Steel', 'MySection')

# Provide simple supports
simple_beam.def_support('N1', True, True, True, False, False, False)
Expand Down
7 changes: 4 additions & 3 deletions Examples/Space Frame - Nodal Loads 1.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
Iy = 100
Iz = 100
A = 10
frame.add_section('MySection', A, Iy, Iz, J)

# Define a material
E = 30000
Expand All @@ -34,9 +35,9 @@
rho = 2.836e-4
frame.add_material('Steel', E, G, nu, rho)

frame.add_member('M1', 'N2', 'N1', 'Steel', Iy, Iz, J, A)
frame.add_member('M2', 'N3', 'N1', 'Steel', Iy, Iz, J, A)
frame.add_member('M3', 'N4', 'N1', 'Steel', Iy, Iz, J, A)
frame.add_member('M1', 'N2', 'N1', 'Steel', 'MySection')
frame.add_member('M2', 'N3', 'N1', 'Steel', 'MySection')
frame.add_member('M3', 'N4', 'N1', 'Steel', 'MySection')

# Add nodal loads
frame.add_node_load('N1', 'FY', -50)
Expand Down
Loading
Loading