STRUCTURAL_FEA
Overview
The PyniteFEA package used in this function provides a Python interface for 3D static analysis of elastic structures. This example function only returns support reactions for 3D frames and beams, but much more is possible with the library. See the PyniteFEA documentation for details.
This example function is provided as-is without any representation or warranty of correctness. DO NOT USE for production applications without your own testing and validation.
Usage
To use this function in Excel, provide lists of nodes, members, materials, sections, supports, and loads as 2D arrays.
=STRUCTURAL_FEA(nodes, members, materials, sections, supports, nodal_loads)
Arguments
Argument | Type | Required | Description | Example |
---|---|---|---|---|
nodes | list[list] | Required | List of nodes: [name, x, y, z] | [[“N1”,0,0,0],[“N2”,168,0,0]] |
members | list[list] | Required | List of members: [name, i-node, j-node, material, section] | [[“M1”,“N1”,“N2”,“Steel”,“W8x24”]] |
materials | list[list] | Required | List of materials: [name, E, G, nu, rho] | [[“Steel”,29000,11200,0.3,0.284/12**3]] |
sections | list[list] | Required | List of sections: [name, A, Iy, Iz, J] | [[“W8x24”,7.08,18.3,82.7,0.346]] |
supports | list[list] | Required | List of supports: [node, DX, DY, DZ, RX, RY, RZ] (bools) | [[“N1”,TRUE,TRUE,TRUE,TRUE,FALSE,FALSE]] |
nodal_loads | list[list] | Required | List of nodal loads: [node, direction, value] | [[“N2”,“FY”,-5]] |
Returns
Output Type | Type | Description | Example |
---|---|---|---|
reactions | list[list] | Support reactions: [node, DX, DY, DZ, RX, RY, RZ] | [[“N1”,0.0,5.0,0.0,0.0,0.0,0.0]] |
error | varies | Error message if calculation fails | ”Error: Invalid input” |
Example
Space Frame Nodal Loads
nodes:
name | x | y | z |
---|---|---|---|
N1 | 0 | 0 | 0 |
N2 | -100 | 0 | 0 |
N3 | 0 | 0 | -100 |
N4 | 0 | -100 | 0 |
members:
name | i-node | j-node | material | section |
---|---|---|---|---|
M1 | N2 | N1 | Steel | MySection |
M2 | N3 | N1 | Steel | MySection |
M3 | N4 | N1 | Steel | MySection |
materials:
name | E | G | nu | rho |
---|---|---|---|---|
Steel | 30000 | 10000 | 0.3 | 0.0002836 |
sections:
name | A | Iy | Iz | J |
---|---|---|---|---|
MySection | 10 | 100 | 100 | 50 |
supports:
node | DX | DY | DZ | RX | RY | RZ |
---|---|---|---|---|---|---|
N2 | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE |
N3 | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE |
N4 | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE |
nodal_loads:
node | direction | value |
---|---|---|
N1 | FY | -50 |
N1 | MX | -1000 |
Output: reactions
node | DX | DY | DZ | RX | RY | RZ |
---|---|---|---|---|---|---|
N2 | -0.213 | 0.318 | 0.0526 | 19.98 | -3.17 | 19.0 |
N3 | 0.0295 | 7.70 | 7.06 | -265 | 0.940 | 0.517 |
N4 | 0.183 | 42.0 | -7.11 | -236 | -0.0890 | -6.07 |
Python Code
import micropip
await micropip.install('PyniteFEA')
from Pynite import FEModel3D
def structural_fea(nodes, members, materials, sections, supports, nodal_loads):
"""
Performs 3D finite element analysis using the Pynite package and returns support reactions. This function is provided as an example only without any representation or warranty of correctness. DO NOT rely on for production use without your own testing and validation.
Args:
nodes (list[list]): List of nodes: [name, x, y, z].
members (list[list]): List of members: [name, i-node, j-node, material, section].
materials (list[list]): List of materials: [name, E, G, nu, rho].
sections (list[list]): List of sections: [name, A, Iy, Iz, J].
supports (list[list]): List of supports: [node, DX, DY, DZ, RX, RY, RZ] (bools).
nodal_loads (list[list]): List of nodal loads: [node, direction, value].
Returns:
reactions (list[list]): Support reactions: [node, DX, DY, DZ, RX, RY, RZ].
If an error occurs, returns a list[list[str]] with the error message.
"""
try:
model = FEModel3D()
# Add materials
for m in materials:
model.add_material(str(m[0]), float(m[1]), float(m[2]), float(m[3]), float(m[4]))
# Add sections
for s in sections:
model.add_section(str(s[0]), float(s[1]), float(s[2]), float(s[3]), float(s[4]))
# Add nodes
for n in nodes:
model.add_node(str(n[0]), float(n[1]), float(n[2]), float(n[3]))
# Add members
for mem in members:
model.add_member(str(mem[0]), str(mem[1]), str(mem[2]), str(mem[3]), str(mem[4]))
# Add supports
for sup in supports:
model.def_support(str(sup[0]), bool(sup[1]), bool(sup[2]), bool(sup[3]), bool(sup[4]), bool(sup[5]), bool(sup[6]))
# Add nodal loads
for ld in nodal_loads:
model.add_node_load(str(ld[0]), str(ld[1]), float(ld[2]))
# Analyze
model.analyze()
# Get reactions
reactions = []
for sup in supports:
node = model.nodes[str(sup[0])]
reactions.append([
str(sup[0]),
float(node.RxnFX['Combo 1']),
float(node.RxnFY['Combo 1']),
float(node.RxnFZ['Combo 1']),
float(node.RxnMX['Combo 1']),
float(node.RxnMY['Combo 1']),
float(node.RxnMZ['Combo 1'])
])
return reactions
except Exception as e:
# Return error as list[list[str]] to match output format
return [[str(e)]]
Live Notebook
Edit this function in a live notebook .
Live Demo
Last updated on