PLATE
This function performs plate and shell analysis by building a finite element surface model from material properties, optional generated meshes, optional manually defined plate elements, supports, and pressure loads. It returns nodal displacement/reaction summaries and plate force result tables, depending on the selected output mode.
The solver applies linear elastic finite element equilibrium over plate degrees of freedom:
\mathbf{K}\mathbf{u} = \mathbf{F}
where \mathbf{K} is the assembled plate stiffness matrix, \mathbf{u} contains nodal displacement/rotation unknowns, and \mathbf{F} represents external nodal and equivalent surface load effects. Derived plate quantities (such as moment components) are then evaluated from the solved field.
Excel Usage
=PLATE(materials, meshes, plates, nodes, supports, pressures, pynite_plate_output)
materials(list[list], required): Materials [name, E, nu, rho].meshes(list[list], optional, default: []): Rectangular meshes [name, width, height, div_x, div_y, material, thickness, origin_x, origin_y, origin_z].plates(list[list], optional, default: []): Manual plates [name, n1, n2, n3, n4, material, thickness].nodes(list[list], optional, default: []): Manual nodes [name, x, y, z].supports(list[list], optional, default: []): Supports [node, fix_dx, fix_dy, fix_dz, fix_rx, fix_ry, fix_rz]. Bools.pressures(list[list], optional, default: []): Uniform pressures [plate_or_mesh, pressure].pynite_plate_output(str, optional, default: “Displacements”): Output type.
Returns (list[list]): Analysis results.
Example 1: Mesh nodal displacements under uniform surface pressure
Inputs:
| materials | meshes | supports | pressures | pynite_plate_output | |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Concrete | 3000000 | 0.2 | 0.15 | Mesh1 | 10 | 10 | 2 | 2 | Concrete | 0.5 | 0 | 0 | 0 | Mesh1_N_0_0 | true | true | true | true | true | true | Mesh1 | -10 | Displacements |
Excel formula:
=PLATE({"Concrete",3000000,0.2,0.15}, {"Mesh1",10,10,2,2,"Concrete",0.5,0,0,0}, {"Mesh1_N_0_0",TRUE,TRUE,TRUE,TRUE,TRUE,TRUE}, {"Mesh1",-10}, "Displacements")
Expected output:
| Node | Dx | Dy | Dz |
|---|---|---|---|
| Mesh1_N_0_0 | 0 | 0 | 0 |
| Mesh1_N_0_1 | 0 | 0 | -0.552582 |
| Mesh1_N_0_2 | 0 | 0 | -1.45879 |
| Mesh1_N_1_0 | 0 | 0 | -0.552582 |
| Mesh1_N_1_1 | 0 | 0 | -1.47975 |
| Mesh1_N_1_2 | 0 | 0 | -2.43399 |
| Mesh1_N_2_0 | 0 | 0 | -1.45879 |
| Mesh1_N_2_1 | 0 | 0 | -2.43399 |
| Mesh1_N_2_2 | 0 | 0 | -3.39759 |
Example 2: Supported corner reaction summary for a single mesh panel
Inputs:
| materials | meshes | supports | pressures | pynite_plate_output | |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Concrete | 3000 | 0.2 | 0.15 | M1 | 5 | 5 | 1 | 1 | Concrete | 0.5 | 0 | 0 | 0 | M1_N_0_0 | true | true | true | true | true | true | M1 | -1 | Reactions |
Excel formula:
=PLATE({"Concrete",3000,0.2,0.15}, {"M1",5,5,1,1,"Concrete",0.5,0,0,0}, {"M1_N_0_0",TRUE,TRUE,TRUE,TRUE,TRUE,TRUE}, {"M1",-1}, "Reactions")
Expected output:
| Node | Rx | Ry | Rz |
|---|---|---|---|
| M1_N_0_0 | 0 | 0 | 25 |
| M1_N_0_1 | 0 | 0 | 0 |
| M1_N_1_0 | 0 | 0 | 0 |
| M1_N_1_1 | 0 | 0 | 0 |
Example 3: Plate center force and shear result sample
Inputs:
| materials | nodes | plates | supports | pressures | pynite_plate_output | |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Steel | 29000 | 0.3 | 0.283 | N1 | 0 | 0 | 0 | P1 | N1 | N2 | N3 | N4 | Steel | 0.2 | N1 | true | true | true | true | true | true | P1 | -5 | PlateForces |
| N2 | 10 | 0 | 0 | N2 | true | true | true | true | true | true | ||||||||||||||
| N3 | 10 | 10 | 0 | |||||||||||||||||||||
| N4 | 0 | 10 | 0 |
Excel formula:
=PLATE({"Steel",29000,0.3,0.283}, {"N1",0,0,0;"N2",10,0,0;"N3",10,10,0;"N4",0,10,0}, {"P1","N1","N2","N3","N4","Steel",0.2}, {"N1",TRUE,TRUE,TRUE,TRUE,TRUE,TRUE;"N2",TRUE,TRUE,TRUE,TRUE,TRUE,TRUE}, {"P1",-5}, "PlateForces")
Expected output:
| Plate | Mx | My | Mxy | Qx | Qy |
|---|---|---|---|---|---|
| P1 | 4.34028 | -83.3333 | 1.17832e-14 | -9.32486e-15 | -29.9603 |
Example 4: Combined plate displacement reaction and force output
Inputs:
| materials | meshes | supports | pressures | pynite_plate_output | |||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Concrete | 3000 | 0.2 | 0.15 | M1 | 5 | 5 | 1 | 1 | Concrete | 0.5 | 0 | 0 | 0 | M1_N_0_0 | true | true | true | true | true | true | M1 | -1 | Stacked |
Excel formula:
=PLATE({"Concrete",3000,0.2,0.15}, {"M1",5,5,1,1,"Concrete",0.5,0,0,0}, {"M1_N_0_0",TRUE,TRUE,TRUE,TRUE,TRUE,TRUE}, {"M1",-1}, "Stacked")
Expected output:
| Node | Dx | Dy | Dz | ||
|---|---|---|---|---|---|
| M1_N_0_0 | 0 | 0 | 0 | ||
| M1_N_0_1 | 0 | 0 | -6.16228 | ||
| M1_N_1_0 | 0 | 0 | -6.16228 | ||
| M1_N_1_1 | 0 | 0 | -15.3246 | ||
| Node | Rx | Ry | Rz | ||
| M1_N_0_0 | 0 | 0 | 25 | ||
| M1_N_0_1 | 0 | 0 | 0 | ||
| M1_N_1_0 | 0 | 0 | 0 | ||
| M1_N_1_1 | 0 | 0 | 0 | ||
| Plate | Mx | My | Mxy | Qx | Qy |
| M1_Q_0_0 | -4.16667 | -4.16667 | 0.171327 | -4.77865 | -4.77865 |
Python Code
Show Code
from Pynite import FEModel3D
def plate(materials, meshes=[], plates=[], nodes=[], supports=[], pressures=[], pynite_plate_output='Displacements'):
"""
Analyze 2D plates and shells. Supports rectangular meshing or manual quad definition.
See: https://pynite.readthedocs.io/en/latest/plate.html
This example function is provided as-is without any representation of accuracy.
Args:
materials (list[list]): Materials [name, E, nu, rho].
meshes (list[list], optional): Rectangular meshes [name, width, height, div_x, div_y, material, thickness, origin_x, origin_y, origin_z]. Default is [].
plates (list[list], optional): Manual plates [name, n1, n2, n3, n4, material, thickness]. Default is [].
nodes (list[list], optional): Manual nodes [name, x, y, z]. Default is [].
supports (list[list], optional): Supports [node, fix_dx, fix_dy, fix_dz, fix_rx, fix_ry, fix_rz]. Bools. Default is [].
pressures (list[list], optional): Uniform pressures [plate_or_mesh, pressure]. Default is [].
pynite_plate_output (str, optional): Output type. Valid options: Displacements, Reactions, Plate Forces/Moments, Stacked Results. Default is 'Displacements'.
Returns:
list[list]: Analysis results.
"""
try:
def to2d(x): return [[x]] if not isinstance(x, list) else x
model = FEModel3D()
# Materials
for row in to2d(materials):
if not row: continue
name = str(row[0])
E = float(row[1])
nu = float(row[2])
rho = float(row[3])
G = E / (2 * (1 + nu)) # Calculate G
model.add_material(name, E, G, nu, rho)
# Nodes (Manual)
for row in to2d(nodes):
if not row: continue
model.add_node(str(row[0]), float(row[1]), float(row[2]), float(row[3]))
# Meshes
for row in to2d(meshes):
if not row: continue
name, w, h, div_x, div_y, mat, thick = str(row[0]), float(row[1]), float(row[2]), int(row[3]), int(row[4]), str(row[5]), float(row[6])
ox = float(row[7]) if len(row) > 7 else 0
oy = float(row[8]) if len(row) > 8 else 0
oz = float(row[9]) if len(row) > 9 else 0
dx_inc, dy_inc = w / div_x, h / div_y
# Generate mesh manually for robustness
node_map = {}
for i in range(div_x + 1):
for j in range(div_y + 1):
nx, ny, nz = ox + i * dx_inc, oy + j * dy_inc, oz
n_name = f"{name}_N_{i}_{j}"
model.add_node(n_name, nx, ny, nz)
node_map[(i,j)] = n_name
for i in range(div_x):
for j in range(div_y):
p_name = f"{name}_Q_{i}_{j}"
n1, n2, n3, n4 = node_map[(i,j)], node_map[(i+1,j)], node_map[(i+1,j+1)], node_map[(i,j+1)]
model.add_plate(p_name, n1, n2, n3, n4, thick, mat)
# Manual Plates
for row in to2d(plates):
if not row: continue
model.add_plate(str(row[0]), str(row[1]), str(row[2]), str(row[3]), str(row[4]), float(row[6]), str(row[5]))
# Supports
for row in to2d(supports):
if not row: continue
n = str(row[0])
flags = [bool(x) for x in row[1:7]]
model.def_support(n, *flags)
# Pressures
for row in to2d(pressures):
if not row: continue
target = str(row[0])
press = float(row[1])
# Target could be a single plate or a mesh prefix?
# Simple check:
if target in model.plates:
model.add_plate_surface_pressure(target, press)
else:
# Try prefix match
for p_name in model.plates:
if p_name.startswith(target):
model.add_plate_surface_pressure(p_name, press)
# Add load combination and analyze
model.add_load_combo('Combo 1', {'Case 1': 1.0})
model.analyze(check_statics=False)
# Safe result helper
def get_val(obj, attr, *args):
try:
val = getattr(obj, attr)
if callable(val): val = val(*args)
if isinstance(val, dict): return float(val.get('Combo 1', 0.0))
return float(val)
except: return 0.0
def flatten_result(value):
if hasattr(value, 'flatten'):
value = value.flatten().tolist()
elif isinstance(value, tuple):
value = list(value)
return value
res = []
# max_cols = 6 for Stacked compatibility (PlateForces has 6)
if pynite_plate_output == 'Displacements' or pynite_plate_output == 'Stacked':
header = ['Node', 'Dx', 'Dy', 'Dz']
if pynite_plate_output == 'Stacked': header += [''] * 2
res.append(header)
for n_nm in model.nodes:
n = model.nodes[n_nm]
row = [n_nm, get_val(n, 'DX'), get_val(n, 'DY'), get_val(n, 'DZ')]
if pynite_plate_output == 'Stacked': row += [''] * 2
res.append(row)
if pynite_plate_output == 'Reactions' or pynite_plate_output == 'Stacked':
header = ['Node', 'Rx', 'Ry', 'Rz']
if pynite_plate_output == 'Stacked': header += [''] * 2
res.append(header)
for n_nm in model.nodes:
n = model.nodes[n_nm]
row = [n_nm, get_val(n, 'RxnFX'), get_val(n, 'RxnFY'), get_val(n, 'RxnFZ')]
if pynite_plate_output == 'Stacked': row += [''] * 2
res.append(row)
if pynite_plate_output == 'PlateForces' or pynite_plate_output == 'Stacked':
res.append(['Plate', 'Mx', 'My', 'Mxy', 'Qx', 'Qy'])
for p_nm in model.plates:
p = model.plates[p_nm]
try:
center_x = ((p.j_node.X - p.i_node.X)**2 + (p.j_node.Y - p.i_node.Y)**2 + (p.j_node.Z - p.i_node.Z)**2)**0.5 / 2
center_y = ((p.n_node.X - p.i_node.X)**2 + (p.n_node.Y - p.i_node.Y)**2 + (p.n_node.Z - p.i_node.Z)**2)**0.5 / 2
moment = flatten_result(p.moment(center_x, center_y, combo_name='Combo 1'))
shear = flatten_result(p.shear(center_x, center_y, combo_name='Combo 1'))
res.append([
p_nm,
float(moment[0]),
float(moment[1]),
float(moment[2]),
float(shear[0]),
float(shear[1]),
])
except:
res.append([p_nm, 0, 0, 0, 0, 0])
return res
except Exception as e:
return f"Error: {str(e)}"