Finite Element Analysis in Python – Billboard Support Frame
ENME302 · Team of 2 · Python / NumPy / Jupyter
Summary
Built a finite element analysis tool in Python to analyse a 10-element billboard support structure under point loading and wind loading. Working in a team of two, I implemented both a bar (pin-joint) model and a 2D frame model, then compared results to test whether the pin-joint assumption was valid for this structure. The frame model was used to assess wind loading and determine the maximum rated wind speed at a factor of safety of 2.5. I also re-analysed the maximum wind case using a Timoshenko formulation to check whether shear deformation materially changed the results.
More Information
The goal was to go beyond "use a solver" and build the analysis workflow from first principles: element stiffness formulation, coordinate transformation, global assembly, boundary conditions, and extracting forces and stresses from the solved displacement vector. The structure was modelled with 10 elements and two fixed supports.
Bar elements vs frame elements: I implemented both modelling approaches to test the pin-joint assumption. The bar model carries axial load only and assumes free rotation at joints; the frame model includes axial and bending behaviour and enforces rotational compatibility. Comparing reactions and element forces showed large discrepancies between the two approaches, indicating the pin-joint assumption was not appropriate. That outcome drove the decision to proceed with the frame-element model for the wind loading case.
Python implementation: The workflow was implemented in Jupyter notebooks using NumPy. Core steps: generating local stiffness matrices (bar and frame formulations), building rotation transforms and forming global element stiffness matrices, assembling the global stiffness matrix via explicit assembly matrices, applying boundary conditions via reduced DOF sets, and solving for nodal displacements before back-calculating member forces and stresses.
Wind loading and design checks: Wind pressure was applied as a UDL on the vertical members supporting the sign face. From the solved internal force resultants I computed combined normal stress (axial + bending) and identified the governing element. Maximum stress occurred at the base element below the wind-loaded members, consistent with expected overturning behaviour. Wind speed was increased iteratively until peak stress exceeded the allowable stress (yield limit / FoS 2.5), giving a maximum rated wind speed of approximately 230 km/h.
Euler–Bernoulli vs Timoshenko sensitivity: I re-analysed the maximum wind case using a Timoshenko beam formulation to include shear deformation. Differences were sub-percent for deflection and a few percent for rotation and support actions, confirming the Euler–Bernoulli assumption was appropriate for the main analysis.
Artifacts
Assignment brief / submission (PDF)
Jupyter notebook — bar point loading (.ipynb)
Jupyter notebook — frame point loading (.ipynb)
Key Skills & Tools
Analysis & Engineering
- Finite Element Method (bar and 2D frame elements)
- Global stiffness assembly and DOF management
- Internal force recovery and combined stress checks
- Wind load modelling (UDL) and FoS capacity checks
- Model validation via assumption testing
- Euler–Bernoulli vs Timoshenko sensitivity
Software
- Python
- NumPy (matrix assembly and solving)
- Jupyter Notebooks
Project Skills
- Structured verification against expected load paths
- Clear reporting of assumptions and model choice
- Team-based development (pair project)