EngiBench

A Framework for Data-Driven Engineering Design Research

Florian Felten, Gabriel Apaza, Gerhard Bräunlich, Cashen Diniz, Xuliang Dong, Arthur Drake, Milad Habibi, Nathaniel Hoffman, Matthew Keeler, Soheyl Massoudi, Francis VanGessel, Mark Fuge

Aug 21, 2025

The Lab

Ideal IDEAL Lab

markfuge
Mark Fuge
Professor
fgvangessel-umd.png
Frank VanGessel
Assistant Research Professor
martina-koch
Martina Koch-Jetzer
Administrative Staff
ffelten
Florian Felten
Postdoc
SoheylM
Soheyl Massoudi
Postdoc
mschlafly
Millicent Schlafly
Postdoc
gapaza
Gabriel Apaza
Postdoc
cashend
Cashen Diniz
PhD Student
mkeeler43
Matthew Keeler
PhD Student
arthurdrake1
Arthur Drake
PhD Student
MiladHB
Milad Habibi
PhD Student
njhoffman11
Nathaniel Hoffman
PhD Student
liangXD523
Xuliang Dong
PhD Student

SIS ETH Zürich

brgerhar
Gerhard Bräunlich
RSE

Lab Page

The Project

Daily Business

  1. Computational model of the problem
    🥵 Setting up the simulator takes domain expertise and time.
  2. Dataset extracted from the above
    🥵 Thousands of hours of compute.
  3. Baseline algorithms to compare to
    🥵 Hours of implementation. No real way to be sure your implementation is right.
  4. Your contribution
    😀 This is the new thing!
  5. Metrics implementations
    🥵 Which one to choose?
  1. Fixed cost for each paper

😭 and then reviewer 2 asks to run the experiments on another problem

The Software

A set of engineering design problems under a unified Python API

Problem = Dataset + Simulation

Implemented Problems

Thermo-elastic Beam
Thermo-elastic Beam
Airfoil
Airfoil
Beams
Beams

Implemented Problems

Heat Conduction
Heat Conduction
Photonics
Photonics
Power electronics
Power electronics

Simulators

MachAero
MachAero
NGSpice
NGSpice
Dolfin FEniCS
Dolfin FEniCS
Python
Python

Datasets

🤗 https://huggingface.co/IDEALLab

API

from engibench.problems.airfoil.v0 import Airfoil

problem = Airfoil()
problem.reset(seed=42)
problem.design_space # {"angle_of_attack": Box(0.0, 1.0)), "coords": …},
problem.objectives # (("drag_coefficient", "MINIMIZE"))
problem.conditions # (("mach", 0.8), ("reynolds",1e6), …))

problem.dataset
# inverse_model = train_inverse(problem.dataset)

desired_conds = {"mach": 0.45, "reynolds": 4e6}
# generated_design = inverse_model.predict(desired_conds)
random_design, _ = problem.random_design()

violated_constraints = problem.check_constraints(random_design, desired_conds)
if len(violated_constraints) == 0:
    objs = problem.simulate(random_design, desired_conds)
    opt_design, history = problem.optimize(random_design, desired_conds)
    problem.render(opt_design)

Companion Project: EngiOpt

A set of high quality implementations of:

generative models, surrogate models, optimization baselines, and
GANs, Diffusion, Bayesian optimization, NSGA-II, …

metrics relevant to engineering Cumulative optimality gap, determinant point processes, ratio of violated constraints, maximum mean discrepancy, …

compatible with EngiBench

Contribution

  • Code quality tools
  • Code architecture
  • Python ↔︎ Slurm adapter
  • Container abstraction (podman 🦭, apptainer (singularity) 🅰️, docker 🐋)
  • Support even during lab outings!!!

Slurm adapter

Why not using a lib?

Users just want a “map / reduce” workflow.

Our API

parameter_space = [
    {"volfrac": volfrac, "forcedist": forcedist}
    for forcedist in [0.0, 0.5]
    for volfrac in [0.1, 0.25, 0.8]
]
result = slurm.sbatch_map(
    f_simulate,
    args=parameter_space,
    slurm_args=slurm_args,
).reduce(f_reduce)
  • map and reduce only
  • Serialize / Deserialize from and to individual processes in job arrays
  • Error handling
  • < 500 lines of code / no dependencies

engibench.ethz.ch

Slurm API

The End

Snake-in-the-Box Problem

📊 Slides: ✨ Live version / 📖 Source