Skip to content

Commit

Permalink
Merge pull request #152 from JWock82/Material
Browse files Browse the repository at this point in the history
Material
  • Loading branch information
JWock82 authored Mar 16, 2023
2 parents 0ef428e + 0e1b09f commit e69c847
Show file tree
Hide file tree
Showing 38 changed files with 1,150 additions and 574 deletions.
7 changes: 5 additions & 2 deletions Examples/Beam on Elastic Foundation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@
# Spring supports at all other locations
boef.def_support_spring('N' + str(i + 1), 'DY', ks, '-')

# Define member material properties (W8x35)
# Define member material properties
E = 29000 # ksi
G = 11200 # ksi
boef.add_material('Steel', E, G, 0.3, 490/1000/12**3)

# Define section properties (W8x35)
A = 10.3 # in^2
Iz = 127 # in^4 (strong axis)
Iy = 42.6 # in^4 (weak axis)
J = 0.769 # in^4

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

# 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
17 changes: 11 additions & 6 deletions Examples/Braced Frame - Spring Supported.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@
braced_frame.add_node('N4', 15*12, 0*12, 0)

# Define column properties (use W10x33 from the AISC Manual):
E = 29000 # ksi
G = 11400 # ksi
Iy = 36.6 # in^4
Iz = 171 # in^4
J = 0.58 # in^4
A = 9.71 # in^2

# Define a material
E = 29000 # Young's modulus (ksi)
G = 11200 # Shear modulus (ksi)
nu = 0.3 # Poisson's ratio
rho = 0.490/12**2 # Density (kci)
braced_frame.add_material('Steel', E, G, nu, rho)

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

# Define beam properties (Use W8x24)
Iy = 18.3 # in^4
Expand All @@ -32,7 +37,7 @@
A = 7.08 # in^2

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

# Define the brace properties
Expand All @@ -44,7 +49,7 @@
A = 1.94 # in^2

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

# 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
19 changes: 12 additions & 7 deletions Examples/Braced Frame - Tension Only.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@
braced_frame.add_node('N4', 15*12, 0*12, 0)

# Define column properties (use W10x33 from the AISC Manual):
E = 29000 # ksi
G = 11400 # ksi
Iy = 36.6 # in^4
Iz = 171 # in^4
J = 0.58 # in^4
A = 9.71 # in^2

# Define a material
E = 29000 # ksi
G = 11400 # ksi
nu = 0.3 # Poisson's ratio
rho = 0.490/12**2 # Density (kci)
braced_frame.add_material('Steel', E, G, nu, rho)

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

# Define beam properties (Use W8x24)
Iy = 18.3 # in^4
Expand All @@ -32,7 +37,7 @@
A = 7.08 # in^2

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

# Define the brace properties
Expand All @@ -44,9 +49,9 @@
A = 1.94 # in^2

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

# Release the brace ends to form an axial member
Expand Down
50 changes: 27 additions & 23 deletions Examples/Circular Bin with Conical Hopper.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from math import pi
from PyNite.FEModel3D import FEModel3D
from PyNite.Mesh import FrustrumMesh, CylinderMesh
from PyNite.Visualization import render_model

t = 0.25/12
E = 29000*1000*12**2
G = 11200*1000*12**2
nu = 0.3
kx_mod=1
ky_mod=1
Expand All @@ -18,36 +18,38 @@
start_node = 'N1'
start_element = 'Q1'

# Generate the conical hopper mesh
hopper_mesh = FrustrumMesh(mesh_size, r_shell, r_hopper, h_hopper, t, E, nu, kx_mod, ky_mod,
center, axis, start_node, start_element)
# Create a finite element model
model = FEModel3D()

# Determine how many elements make up the circumference at the top of the hopper. This will
# determine the number of elements making up the circumference of the cylindrical shell.
n_hopper = hopper_mesh.num_quads_outer
# Add steel as a material
model.add_material('Steel', E, G, nu, 490)

# Find an unused node and element name to start the cylinder off with
first_node = 'N' + str(len(hopper_mesh.nodes) + 1)
first_element = 'Q' + str(len(hopper_mesh.elements) + 1)
# Add the conical hopper mesh to the model
model.add_frustrum_mesh('MSH1', mesh_size, r_shell, r_hopper, h_hopper, t, 'Steel', kx_mod, ky_mod, center, axis)

# Generate the cylindrical shell
shell_mesh = CylinderMesh(mesh_size, r_shell, h_shell, t, E, nu, kx_mod, ky_mod, center, axis,
first_node, first_element, n_hopper)
# Generate the mesh. The mesh would automatically be generated during analysis, but we want to
# manipulate it now so we'll generate it in advance.
model.Meshes['MSH1'].generate()

# Create a finite element model
model = FEModel3D()
# Determine how many elements make up the circumference at the top of the hopper. This will
# determine the number of elements making up the circumference of the cylindrical shell.
n_hopper = model.Meshes['MSH1'].num_quads_outer

# Add the two meshes to the model
model.add_mesh(hopper_mesh)
# Find an unused node and element name to start the cylinder off with
first_node = 'N' + str(len(model.Nodes.values()) + 1)
first_element = 'Q' + str(len(model.Quads.values()) + 1)

import cProfile
# cProfile.run('model.add_mesh(shell_mesh)', sort='cumtime')
model.add_mesh(shell_mesh)
# Add the cylindrical shell mesh
model.add_cylinder_mesh('MSH2', mesh_size, r_shell, h_shell, t, 'Steel', kx_mod, ky_mod, center,
axis, num_elements=n_hopper, element_type='Quad')

# The two meshes have overlapping duplicate nodes that need to be merged
# cProfile.run('model.merge_duplicate_nodes()', sort='cumtime')
model.merge_duplicate_nodes()

# This next line can be used in place of the prior line to profile the merge code and find
# innefficiencies
# cProfile.run('model.merge_duplicate_nodes()', sort='cumtime')

# Add hydrostatic pressure to each element in the model
for element in model.Quads.values():
Yavg = (element.i_node.Y + element.j_node.Y + element.m_node.Y + element.n_node.Y)/4
Expand All @@ -62,8 +64,10 @@
model.add_load_combo('1.4F', {'Hydrostatic': 1.4})

# Analyze the model
cProfile.run('model.analyze()', sort='cumtime')
# model.analyze()
# import cProfile
# cProfile.run('model.analyze()', sort='cumtime')
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)
15 changes: 10 additions & 5 deletions Examples/Moment Frame - Lateral Load.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@
MomentFrame.add_node('N4', 15*12, 0*12, 0)

# Define column properties (use W10x33 from the AISC Manual):
E = 29000 # ksi
G = 11400 # ksi
Iy = 36.6 # in^4
Iz = 171 # in^4
J = 0.58 # in^4
A = 9.71 # in^2

# Define a material
E = 29000 # ksi
G = 11200 # ksi
nu = 0.3 # Poisson's ratio
rho = 0.490/12**3 # Density (kci)
MomentFrame.add_material('Steel', E, G, nu, rho)

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

# Define beam properties (Use W8x24)
Iy = 18.3 # in^4
Expand All @@ -32,7 +37,7 @@
A = 7.08 # in^2

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

# 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 Down
22 changes: 10 additions & 12 deletions Examples/Rectangular Plate Bending - Qauds.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,28 @@
# problem that element is better suited, as long as the wall does not have significant transverse
# shear deformations, and the elements are not skewed. See the "Rectangular Tank Wall -
# Hydrostatic Loads" example using that element.

E = 57000*(4000)**0.5*12**2 # psf
t = 1 # ft
width = 10 # ft
height = 20 # ft
nu = 0.17
mesh_size = 1 # ft
load = 250 # psf

# Create a new rectangular mesh of quadrilaterals
from PyNite.Mesh import RectangleMesh
mesh = RectangleMesh(mesh_size, width, height, t, E, nu, kx_mod=1, ky_mod=1, origin=[0, 0, 0],
plane='XY', start_node='N1', start_element='Q1', element_type='Quad')

# Generate the mesh. Rectangle meshes won't generate unless you tell them to.
# This allows you to add openings to them before meshing.
mesh.generate()

# Create a finite element model
from PyNite import FEModel3D
model = FEModel3D()

# Define concrete in the model
E = 57000*(4000)**0.5*12**2 # psf
model.add_material('Concrete', E, 0.4*E, 0.17, 150)

# Add the mesh to the model
model.add_mesh(mesh)
model.add_rectangle_mesh('MSH1', mesh_size, width, height, t, 'Concrete', 1, 1, [0, 0, 0], 'XY', element_type='Quad')

# PyNite automatically generates each mesh when it analyzes. Sometimes it's convenient to generate
# the nodes and elements in the mesh in advance so that we can manipulate the mesh prior to
# analysis.
model.Meshes['MSH1'].generate()

# Step through each quadrilateral in the model
for element in model.Quads.values():
Expand Down
25 changes: 12 additions & 13 deletions Examples/Rectangular Tank Wall - Hydrostatic Loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
from PyNite.Mesh import RectangleMesh
from PyNite.Visualization import render_model

# Create a finite element model
model = FEModel3D()

# Set material properties for the wall (4500 psi concrete)
E = 57000*(4500)**0.5*12**2 # psf
G = 0.4*E
nu = 0.17
rho = 150 # pcf
model.add_material('Concrete', E, G, nu, rho)

# Choose a mesh size
mesh_size = 1
Expand All @@ -27,19 +33,12 @@
# deformations), rectangular plate elements will produce better plate corner stress results.
# 2. It'd be nice to have the mesh hit the liquid level, so we'll add a control point at the
# liquid level to the list of control points along the mesh's local y-axis.
mesh = RectangleMesh(mesh_size, width, height, t, E, nu, kx_mod=1, ky_mod=1, origin=[0, 0, 0],
plane='XY', y_control=[HL], start_node='N1', start_element='R1',
element_type='Rect')

# Generate the mesh. Rectangle meshes won't generate unless you tell them to.
# This allows you to add openings to them before meshing.
mesh.generate()

# Create a finite element model
model = FEModel3D()
model.add_rectangle_mesh('MSH1', mesh_size, width, height, t, 'Concrete', kx_mod=1, ky_mod=1,
origin=[0, 0, 0], plane='XY', y_control=[HL], element_type='Rect')

# Add the mesh to the model
model.add_mesh(mesh)
# Generate the mesh prior to analysis. This step is optional, but it allows you to work with it to
# it before analyzing.
model.Meshes['MSH1'].generate()

# Step through each quadrilateral and rectangular plate in the model
for element in list(model.Quads.values()) + list(model.Plates.values()):
Expand All @@ -51,7 +50,7 @@
if Yavg < HL:

# Add hydrostatic loads to the element
if mesh.element_type == 'Rect':
if model.Meshes['MSH1'].element_type == 'Rect':
model.add_plate_surface_pressure(element.name, 62.4*(HL - Yavg), case='F')
else:
model.add_quad_surface_pressure(element.name, 62.4*(HL - Yavg), case='F')
Expand Down
29 changes: 15 additions & 14 deletions Examples/Shear Wall with Openings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@
from PyNite.Mesh import RectangleMesh, RectOpening
from math import isclose

# Create a finite element model
model = FEModel3D()

# Set material properties for the wall (2 ksi masonry)
f_m = 2000 # Masonry compressive strength (psi)
E = 900*f_m/1000 # Masonry modulus of elasticity (ksi)
nu = 0.17 # Poisson's ratio for masonry
rho = 0.0000710 # Masonry density (kci)
model.add_material('Masonry', E, 0.4*E, nu, rho)

# Choose a desired mesh size. The program will try to stick to this as best as it can.
mesh_size = 6 # in
Expand All @@ -26,29 +31,25 @@
# Generate the rectangular mesh
# The effects of cracked masonry can be modeled by adjusting the `ky_mod` factor. For this example
# uncracked masonry will be used to match the textbook problem.
mesh = RectangleMesh(mesh_size, width, height, t, E, nu, kx_mod=1, ky_mod=1, origin=[0, 0, 0],
plane='XY', start_node='N1', start_element='R1', element_type='Rect')
model.add_rectangle_mesh('MSH1', mesh_size, width, height, t, 'Masonry', kx_mod=1, ky_mod=1,
origin=[0, 0, 0], plane='XY', element_type='Rect')

# Add a 4' wide x 12' tall door opening to the mesh
mesh.add_rect_opening(name='Door 1', x_left=2*12, y_bott=0*12, width=4*12, height=12*12)
model.Meshes['MSH1'].add_rect_opening(name='Door 1', x_left=2*12, y_bott=0*12, width=4*12, height=12*12)

# Add a 4' wide x 4' tall window opening to the mesh
mesh.add_rect_opening(name='Window 1', x_left=8*12, y_bott=8*12, width=4*12, height=4*12)
model.Meshes['MSH1'].add_rect_opening(name='Window 1', x_left=8*12, y_bott=8*12, width=4*12, height=4*12)

# Add another 4' wide x 4' tall window opening to the mesh
mesh.add_rect_opening(name='Window 2', x_left=14*12, y_bott=8*12, width=4*12, height=4*12)
model.Meshes['MSH1'].add_rect_opening(name='Window 2', x_left=14*12, y_bott=8*12, width=4*12, height=4*12)

# Add another 4' wide x 12' tall door opening to the mesh
mesh.add_rect_opening(name='Door 2', x_left=20*12, y_bott=0*12, width=4*12, height=12*12)

# Generate the mesh now that we've defined all the openings
mesh.generate()

# Create a finite element model
model = FEModel3D()
model.Meshes['MSH1'].add_rect_opening(name='Door 2', x_left=20*12, y_bott=0*12, width=4*12, height=12*12)

# Add the mesh to the model
model.add_mesh(mesh)
# Generate the mesh now that we've defined all the openings. Pynite automatically generates all
# meshes when analyzing, but generating it early with give us the chance to work with it prior to
# analysis.
model.Meshes['MSH1'].generate()

# Shear at the top of the wall
V = 100 # kip
Expand Down
Loading

0 comments on commit e69c847

Please sign in to comment.