A Python framework for automated structural design optimization combining machine learning, metaheuristic search, and constraint satisfaction programming. Developed as part of a Ph.D. dissertation at Stanford University's Center for Integrated Facility Engineering (CIFE).
This framework automates the structural design of typical steel buildings by decomposing the problem into three coupled sub-system modules — composite floor system, lateral frame system, and connections — each solved with tailored algorithms and coordinated through a multi-disciplinary architecture. The optimizer minimizes total installed cost (material, fabrication, and erection) while satisfying strength, drift, vibration, constructability, and ductility constraints per U.S. building codes (AISC 360, ASCE 7) and industry standards. Validated on a 4-story steel building in California, the framework achieved approximately 10% total steel cost savings over the original design, with individual sub-system savings between 5% and 55%, and a design runtime of a few hours versus several weeks of manual engineering.
- Decomposed optimization of gravity, lateral, and connection sub-systems with divide-and-conquer algorithms, scalable to full-size buildings
- Cost objective function based on industry material, labor, and equipment rates from U.S. general contractors and steel fabricators
- Exhaustive composite floor design via dynamic programming over sections, studs, camber, composite action, and shoring
- Energy-based lateral frame sizing that envelopes critical seismic/wind load combinations for cost-optimal member selection
- Connection optimization using nonlinear solvers to size each gravity and lateral connection individually, improving on traditional schedule-based approaches
scripts/
run_mdo.py Main optimization entry point
eval_cost.py Evaluate cost of an existing design
eval_case_study.py Evaluate cost for the case study building
mdo/ Core package
config/config.py All design parameters, material properties, solver settings
analysis/sap.py COM interface to SAP2000/ETABS structural analysis
model/
structure.py Central design model: nodes, members, frames, composites
element.py Individual beam/column/brace elements
node.py Joints and connection definitions
io/utility.py I/O, geometry processing, checkpoints, results output
cost/coster.py Fabrication cost model (steel, studs, welds, bolts, labor)
design/
composite.py Composite beam feasibility and cost optimization
shear_tab.py Shear tab connection design (bolt group ICR method)
deflections.py Beam deflection and moment calculations
plotting/ Post-processing and visualization scripts
plotter.py, frames.py, composite.py, connections.py, case_study.py
data/
sec_info/ AISC section catalogs (W, C, L, HSS round/square)
starter_files/ Pre-built SAP2000/ETABS models for case studies
The optimization workflow runs in three stages:
- Gravity system sizing — composite and non-composite beams for vertical loads
- Lateral frame sizing — iterative strength + stiffness design with seismic drift constraints
- Connection design — shear tab (simple) and RBS (moment) connections with cost evaluation
An optional topology optimization loop can remove low-contribution members between sizing iterations.
- Windows (required for SAP2000/ETABS COM API via
comtypes) - SAP2000 v21+ or ETABS v18+ installed (commercial structural analysis software by CSI)
- Python 3.7+ with the following packages (see
requirements.txt):
| Package | Purpose |
|---|---|
comtypes |
COM interface to SAP2000/ETABS |
numpy |
Numerical computation |
pandas |
Section catalog I/O and result tabulation |
scipy |
Optimization solvers (connection design) |
matplotlib |
Plotting and visualization |
ipython |
Interactive use (optional) |
git clone https://github.com/franalli/AI-MDO-Steel-Buildings.git
cd AI-MDO-Steel-Buildings
pip install -r requirements.txtThe framework connects to SAP2000 or ETABS via its COM API. Set the path to your installation using environment variables:
# For SAP2000:
set SAP2000_PATH=C:\Program Files\Computers and Structures\SAP2000 21\SAP2000.exe
# For ETABS:
set ETABS_PATH=C:\Program Files\Computers and Structures\ETABS 18\ETABS.exeOr edit the default paths directly in mdo/analysis/sap.py.
All parameters are set by editing mdo/config/config.py. The Config class is instantiated with defaults; override individual attributes for each study. Parameters are grouped into the sections below.
| Parameter | Default | Description |
|---|---|---|
analysis_software |
'ETABS' |
Analysis backend: 'ETABS' or 'SAP2000' |
structure_name |
'case_study' |
Folder name under starter_files/ containing the model |
units |
'imperial' |
Unit system: 'imperial' or 'metric' |
dimensionality |
3 |
Structural dimensionality (affects topology stability checks) |
origin_path |
'./starter_files/{name}/model/' |
Path to the input model |
destination_path |
'./SAPMODEL/' |
Path where the active model is loaded and saved |
sec_info_path |
'./starter_files/{name}/sec_info/' |
Path to AISC section catalog files |
elmSta |
51 |
Number of frame output stations (minimum needed to capture beam-girder connections) |
seed |
55 |
Random seed for reproducibility |
saveCheckpoints |
False |
Save pickled checkpoints after each sizing stage |
checkpoint |
None |
Path to a checkpoint file to resume from |
multithread |
False |
Enable multithreading (experimental) |
autoLoadGen |
False |
Automatically generate load combinations in the analysis model |
renameConverged |
True |
Rename sections in the model to encode section/camber/studs after convergence |
| Parameter | Default | Description |
|---|---|---|
size_composite |
True |
Run composite beam sizing |
size_nonComposite |
True |
Run non-composite beam sizing |
size_frames |
True |
Run lateral frame sizing |
size_connections |
True |
Run connection design |
moment_frame |
True |
Enable continuity considerations for moment frames |
| Parameter | Default | Description |
|---|---|---|
topology |
False |
Enable topology optimization loop |
reset_fixity |
False |
Re-fix all frame joints at every topology iteration |
vw_contribution_type |
'max' |
How to aggregate virtual work contributions across load cases |
continuity_rule |
'H' |
Rule for assigning member continuity |
removal_rate |
0.05 |
Fraction of members removed per topology iteration |
dc_limit |
0.01 |
Demand-capacity ratio below which a member is a removal candidate |
vw_limit |
0.0 |
Virtual work contribution below which a member is a removal candidate |
iterations_without_improvement |
3 |
Topology loop stops after this many iterations with no cost improvement |
fv_exp |
1 |
Exponent for virtual work contribution scoring |
min_elements_at_loaded_nodes |
2 |
Minimum members retained at loaded nodes |
min_elements_at_nodes_2D |
3 |
Minimum members retained at each node in 2D models |
min_elements_at_nodes_3D |
3 |
Minimum members retained at each node in 3D models |
| Parameter | Default | Description |
|---|---|---|
sizing_mode |
'interstory' |
Drift check basis: 'interstory' or 'displacement' |
max_sizing_iterations |
100 |
Maximum iterations per sizing loop |
size_for_stiffness |
True |
Size members for drift in addition to strength |
bump_limit |
1.15 |
Max ratio of area increase between consecutive stiffness sections |
stiffness_design_envelope |
True |
Envelope stiffness design with the previous iteration's design |
stiffness_buckets |
False |
Average length and virtual work of continuous members for stiffness sizing |
drift_combos_limit |
-1 |
Max virtual load cases per load combo (-1 = unlimited) |
max_continuous_segments |
2 |
Max segments assigned the same section in continuous members |
max_splice_length |
2 |
Max splice segment length (for splice count) |
bracing_spacing |
3 |
Out-of-plane bracing beam interval (2D frames only) |
excluded_nodes |
[] |
Node IDs excluded from drift design |
LTB |
False |
Check lateral-torsional buckling (set False when floor system provides restraint) |
tau |
0.8 |
Stiffness reduction factor (Direct Method of stability) |
K |
1.0 |
Effective length factor (Direct Method of stability) |
max_LL_deflection_ratio |
360 |
Live load deflection limit as span/ratio |
max_C_deflection_ratio |
360 |
Construction load deflection limit as span/ratio |
max_total_deflection_ratio |
240 |
Total (DL+LL) deflection limit for floor members as span/ratio |
max_NC_deflection_ratio |
180 |
Total deflection limit for roof and non-composite members as span/ratio |
print_VW_info |
True |
Print virtual work diagnostics during frame sizing |
composite_frames |
False |
Account for composite action in moment frame beam stiffness and strength |
frame_stud_rows |
2 |
Stud rows for composite frame beams (1 or 2) |
soft_story_beam_constraint |
True |
Enforce that beams at higher stories have no greater inertia than those below |
SC_WB_constraint |
False |
Enforce strong-column/weak-beam constraint on Zx |
column_size_constraint |
True |
Enforce that column sections are non-decreasing from top to bottom |
sidePlate_constraint |
False |
Enforce SidePlate column/beam compatibility per the Seismic Design Manual |
| Parameter | Default | Description |
|---|---|---|
R |
8.0 |
Seismic response modification factor |
If |
1.0 |
Seismic importance factor |
Cd |
5.5 |
Deflection amplification factor |
SMF |
True |
Enforce Special Moment Frame (highly ductile) requirements |
max_drift_ratio_x |
0.036 |
Allowable interstory drift ratio in X |
max_drift_ratio_y |
0.037 |
Allowable interstory drift ratio in Y |
max_drift_ratio_z |
0.036 |
Allowable interstory drift ratio in Z |
max_frame_depth |
25.0 |
Maximum frame member depth [in] |
shear_factor_cases_X |
['ELFX','RSX'] |
Load case names for ELF and response spectrum in X |
shear_factor_cases_Y |
['ELFY','RSY'] |
Load case names for ELF and response spectrum in Y |
seismic_combos_X |
['EQX','RS_X'] |
Load combination labels in X (for base shear scaling) |
seismic_combos_Y |
['EQY','RS_Y'] |
Load combination labels in Y (for base shear scaling) |
design_combos |
(auto-set) | Load combination names used for strength and drift design. Auto-set based on size_frames and dimensionality: gravity-only (['1.4DEAD', '1.2DEAD+1.6LIVE']) when frames are disabled; gravity + seismic in X (+ Y for 3D) when frames are enabled. Names must match load combinations defined in the analysis model. |
base_shear_scaling_percentage |
0.85 |
Scale response spectrum to this fraction of ELF base shear (ASCE 7-10: 0.85; -1 to disable) |
size_with_RS |
False |
Design strength and drift using response spectrum only (not ELF) |
| Parameter | Default | Description |
|---|---|---|
deck_direction |
'X' |
Direction of deck ribs: 'X' or 'Y' |
composite_constructability |
True |
Enforce beam/girder depth constructability constraints |
max_composite_depth |
25.0 |
Maximum floor beam/girder depth [in] |
min_col_depth |
12.0 |
Minimum column depth [in] |
trib_width |
15 |
Tributary width [ft] for 2D lateral frame beams |
composite_roof |
False |
Apply composite design to roof beams |
Wc |
145.0 |
Concrete unit weight [pcf] (use 115 for lightweight) |
fpc |
3000 |
Concrete compressive strength [psi] (use 2500 for lightweight) |
Yc |
5.5 |
Total slab height [in] |
hr |
2.5 |
Steel deck rib height [in] |
Fu |
65000 |
Steel stud ultimate stress [psi] |
Asa |
0.442 |
Shear stud cross-sectional area [in²] |
reinforcement_ratio |
0.002 |
Ratio of steel reinforcement area to concrete slab area |
construction_shoring |
False |
Assume shored construction |
construction_load_factor |
2.0 |
Ratio of factored to unfactored construction loads |
actions |
['none','full','semi'] |
Composite action levels to consider |
compositeCambers |
[0.0 … 2.0] |
Camber values to enumerate for composite beams [in] |
nonCompositeCambers |
[0.0 … 2.0] |
Camber values to enumerate for non-composite beams [in] |
| Parameter | Default | Description |
|---|---|---|
shear_bolt_d |
1.0 |
Bolt diameter [in] |
shear_bolt_hole |
1.125 |
Bolt hole diameter [in] |
shear_bolt_Fy |
54.0 |
Bolt yield strength [ksi] |
shear_bolt_Fu |
65.0 |
Bolt ultimate strength [ksi] |
shear_plate_Fy |
36.0 |
Shear plate yield strength [ksi] |
shear_plate_Fu |
58.0 |
Shear plate ultimate strength [ksi] |
weld_strength |
70.0 |
Weld electrode strength [ksi] |
shear_plate_ts |
[1/4 … 1] |
Plate thickness options to enumerate [in] |
shear_plate_welds |
[3/16 … 1] |
Weld thickness options to enumerate [in] |
shear_bolt_nx |
3 |
Maximum number of bolt columns |
shear_bolt_ny |
8 |
Maximum number of bolt rows |
shear_bolt_row_space |
3 |
Vertical bolt spacing [in] |
bolt_edge_space |
2 × bolt_d |
Edge distance from bolt center to plate edge [in] |
shear_plate_web_stiffner |
True |
Add top/bottom web stiffeners on beam-to-girder connections |
shear_plate_clearance |
0.625 |
Clearance between beam flange and support [in] |
| Parameter | Default | Description |
|---|---|---|
C0 |
220.0 |
Base connection cost [$] |
Cb |
1.0 |
Crossing brace penalty as fraction of connection cost |
Cw |
0.40 |
Standard joint cost as fraction of weight cost |
Cm |
0.10 |
Member count penalty as fraction of weight cost |
camber_cost |
[65, 75] |
Camber fabrication cost [$]: ≤1 in and >1 in |
splice_cost |
300.0 |
Column splice cost [$/splice] |
single_cope_cost |
50.0 |
Single cope cost [$/cope] |
double_cope_cost |
80.0 |
Double cope cost [$/cope] |
RBS_cut_cost |
100.0 |
RBS (reduced beam section) cut cost [$/cut] |
eta_w |
0.45 |
Rolled steel material cost [$/lb] |
eta_plt |
2.0 |
Shear plate material cost [$/lb] |
eta_d |
2.0 |
Steel deck material cost [$/ft²] |
eta_s |
1.5 |
Shear stud material cost [$/stud] |
eta_bt |
20.0 |
Bolt material cost [$/bolt] |
eta_f |
1.4 |
Coating material cost [$/ft²] |
eta_c |
4.18 |
Concrete material cost [$/ft³] (use 4.89 for lightweight) |
eta_r |
0.55 |
Reinforcement material cost [$/lb] |
eta_st |
0.06 |
Steel transportation cost [$/lb] |
eta_ct |
4.07 |
Concrete transportation cost [$/ft³] |
eta_wld |
2.0/12 |
Weld material cost [$/in] |
nu_wd |
0.5 |
Steel deck and section erection labor [$/lb] |
nu_c |
200.0 |
Concrete labor [$/hr] |
nu_sc |
50.0 |
Connection installation labor [$/hr] |
nu_wld |
50.0 |
Weld placement labor [$/hr] |
nu_dr |
5.0 |
Bolt hole drilling labor [$/hole] |
nu_s |
3.5 |
Shear stud installation labor [$/stud] |
nu_r |
120.0 |
Reinforcement placement labor [$/hr] |
cjp_surplus |
1.2 |
Time multiplier for CJP welds relative to fillet welds |
steel_density |
490.0 |
Steel density [lb/ft³] |
material_metric |
2950.0 |
Rolled steel material cost [$/tonne] (used in metric mode) |
steel_lab_a |
0.0002 |
Steel erection labor cost curve: quadratic coefficient |
steel_lab_b |
0.2 |
Steel erection labor cost curve: linear coefficient |
steel_lab_c |
80.0 |
Steel erection labor cost curve: constant term |
| Parameter | Default | Description |
|---|---|---|
reduceLiveBeams |
True |
Apply live load reduction to beams |
reduceLiveGirders |
True |
Apply live load reduction to girders |
reduceLiveCols |
True |
Apply live load reduction to columns |
| Parameter | Default | Description |
|---|---|---|
P0 |
65.0 |
Excitation force [lb] |
Beta |
0.05 |
Damping ratio |
a0_g |
0.005 |
Acceleration limit as fraction of g |
Imperial (used when units = 'imperial'):
| Parameter | Default | Description |
|---|---|---|
E_imperial |
29,000,000 |
Elastic modulus [psi] |
G_imperial |
11,153,846 |
Shear modulus [psi] |
gravity |
386.1 |
Gravitational acceleration [in/s²] |
gs_module_imperial |
78.74 |
Grid spacing module [in] |
Fy_imperial |
{W:50, ROUND:46, SQUARE:46, C:42, L:42} |
Yield strength by section type [ksi × 1000] |
Metric (used when units = 'metric'):
| Parameter | Default | Description |
|---|---|---|
E_metric |
199,948 |
Elastic modulus [N/mm²] |
G_metric |
76,903 |
Shear modulus [N/mm²] |
gravity_metric |
9,810 |
Gravitational acceleration [mm/s²] |
gs_module_metric |
2,000 |
Grid spacing module [mm] |
Fy_metric |
{W:345, ROUND:315, SQUARE:315, C:290, L:290} |
Yield strength by section type [N/mm²] |
Place a SAP2000 .sdb or ETABS .EDB model in starter_files/<structure_name>/model/. The framework reads the geometry and releases directly from the analysis model and classifies members automatically — no pre-assigned SAP groups are required.
Member labels control how the framework classifies and designs each element. The framework auto-renames any unlabeled member based on geometry, but explicit prefixes take precedence:
| Prefix | Role | Auto-detection rule |
|---|---|---|
CO_ |
Column | Vertical member (x₁ = x₂, y₁ = y₂) |
BE_ |
Beam | Horizontal member (z₁ = z₂) |
BR_H_ |
Horizontal brace | Horizontal diagonal (z₁ = z₂, x₁ ≠ x₂, y₁ ≠ y₂) |
BR_V_ |
Vertical brace | Inclined member (z₁ ≠ z₂, x or y changes) |
NC_ |
Non-composite | Roof beams get this automatically when composite_roof = False; add manually to force non-composite design on any beam |
MF |
Moment frame override | Forces moment frame treatment regardless of end-release conditions |
P |
Parallel to deck | Forces the beam to be treated as running parallel to the deck ribs |
Members assigned the section property DUMMY or None are skipped entirely (use these for fictitious/constraint members).
Gravity load patterns applied to members must contain the following substrings (case-insensitive) so the framework can identify them:
| Substring | Load type |
|---|---|
dead |
Dead load |
construction |
Construction load |
live |
Live load |
rlive |
Reducible live load |
By default the framework uses the full AISC catalogs in data/sec_info/. To restrict the section pool for a specific study, place filtered W.txt, C.txt, L.txt, ROUND.txt, and SQUARE.txt files in starter_files/<structure_name>/sec_info/. See data/sec_info/imperial/ for the required column format.
See the included starter_files/case_study/ folder for a complete example.
python scripts/run_mdo.pyThis will:
- Open the model in SAP2000/ETABS
- Size gravity beams (composite + non-composite)
- Iteratively size lateral frames for strength and drift
- Design connections and compute costs
- Save the optimized model to
SAPMODEL/
After a successful run the following files are written:
Optimized model
| Location | Contents |
|---|---|
SAPMODEL/ |
Optimized SAP2000 (.sdb) or ETABS (.EDB) model |
When renameConverged = True, composite beam labels in the model are updated to the format <member_id> - [<n_studs>] <camber_in> for visual inspection.
Checkpoints (when saveCheckpoints = True)
| Location | Contents |
|---|---|
checkpoints/<label>_<timestamp>/data.pkl |
Pickled [Structure, Coster, topology_iteration] |
checkpoints/<label>_<timestamp>/ |
Copy of the analysis model at that stage |
Resume from a checkpoint by setting config.checkpoint = '<label>_<timestamp>'.
Parametric / post-processing data
Written by utility.savePlotsAndTablesLocally() (called from eval and parametric scripts):
| File | Contents |
|---|---|
parametric/composite/compositePlotData.pkl |
Composite beam sections, actions, cambers, studs, degree of composites, failure counts, cost summaries |
parametric/noncomposite/nonCompositePlotData.pkl |
Non-composite member sections, splice counts, cost summaries |
parametric/frames/framePlotData.pkl |
Frame member sections, splice counts, algorithm convergence info, cost summaries |
parametric/connections/connPlotData.pkl |
Shear tab and RBS bolt/plate/weld takeoffs, connection schedules, cost summaries |
Eval mode writes the same files to parametric/eval/{composite,noncomposite,frames,connections}/.
Additional scripts in scripts/:
eval_cost.py— evaluate cost of an existing design without re-optimizingeval_case_study.py— evaluate cost for the case study building
If you use this software in your research, please cite:
@phdthesis{ranalli2021ai,
title={An Artificial Intelligence Framework for Multi-Disciplinary Design Optimization of Steel Buildings},
author={Ranalli, Filippo},
year={2021},
school={Stanford University},
url={https://purl.stanford.edu/cx146yt9252}
}BSD 3-Clause License
Copyright (c) 2016-2021, The Board of Trustees of the Leland Stanford Junior University All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
Neither the name of Stanford University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This research was conducted at the Center for Integrated Facility Engineering (CIFE), Stanford University, under the guidance of Martin Fischer, Eduardo Miranda, and Ram Rajagopal. Supported by CIFE industrial affiliates.