{
 "generated": "2026-10-12 23:10 UTC",
 "hardware": {
  "cpu": "Intel(R) Xeon(R) Processor @ 2.80GHz",
  "cores": 2,
  "ram_gb": 7.8,
  "os": "Linux 6.18.44-fc-v114",
  "machine": "x86_64"
 },
 "software": {
  "python": "3.13.16",
  "node": "v22.22.0",
  "pvlib": "0.16.1",
  "pandapower": "3.5.5",
  "numpy": "2.4.6",
  "rasterio": "1.5.2",
  "ifcopenshell": "0.9.0",
  "pandas": "2.3.3",
  "PyNiteFEA": "3.2.0"
 },
 "repetitions": 20,
 "conditions": "Build machine (container), one process, operations run sequentially; one warm-up run per operation excluded; local files only, no network; browser engines timed in Node (same code as in the browser), Python engines called as functions of the calculation server (no HTTP). sag_tension runs 5 × N times.",
 "caveat": "Measured on one machine, one process, sequentially, after a warm-up run. Series throughput is theoretical and real project time depends on data preparation, dependencies, parallelism and review.",
 "command": "WAIMAP_ATLAS_DIR=<atlas folder> python tools/benchmarks/run_benchmarks.py -n 20",
 "items": [
  {
   "id": "sag_tension",
   "name": "Sag-tension of one tension section",
   "engine": "WaiLineMech.sagTension (JavaScript in Node)",
   "workload": "10 spans 380–420 m, ACSR Cardinal, 6 load cases (EDS, minimum temperature, extreme wind, ice, ice + wind, maximum temperature), initial and final (creep)",
   "n": 100,
   "median_ms": 0.044,
   "p95_ms": 0.295,
   "min_ms": 0.029,
   "max_ms": 1.038,
   "series_per_hour_theoretical": 81818181,
   "series_unit": "tension sections"
  },
  {
   "id": "tower_fem",
   "name": "Lattice tower structure check",
   "engine": "PyNiteFEA 3D frame through the worker (fem_frame) — model from WaiFEM.latticeTower",
   "workload": "Typical square lattice suspension tower: 46 nodes, 178 members, 1 load combinations; displacements, member forces, EN 1993-1-1 style utilisation",
   "n": 5,
   "median_ms": 1919.165,
   "p95_ms": 1928.255,
   "min_ms": 1787.882,
   "max_ms": 1929.843,
   "series_per_hour_theoretical": 1875,
   "series_unit": "towers"
  },
  {
   "id": "line_design_10km",
   "name": "10 km line section — spotting and mechanics",
   "engine": "WaiLineMech.design (JavaScript in Node)",
   "workload": "400 kV, triple ACSR Cardinal, 2 OPGW, one 30° angle point, level profile at 50 m stations: simple spotting, sag-tension per tension section, clearance, tower loads, quantities",
   "n": 20,
   "median_ms": 2.053,
   "p95_ms": 4.312,
   "min_ms": 1.069,
   "max_ms": 5.918,
   "series_per_hour_theoretical": 1753531,
   "series_unit": "10 km sections"
  },
  {
   "id": "line_optimise_10km",
   "name": "10 km line section — optimum tower spotting",
   "engine": "WaiLineMech.optimise (JavaScript in Node)",
   "workload": "The same 10 km: dynamic programming over candidate stations every 25 m × tower types × extensions, exact weight / wind spans, clearance per tension section (alternatives off)",
   "n": 10,
   "median_ms": 258.829,
   "p95_ms": 299.264,
   "min_ms": 241.545,
   "max_ms": 323.032,
   "series_per_hour_theoretical": 13908,
   "series_unit": "10 km sections"
  },
  {
   "id": "pv_year",
   "name": "Yearly PV yield (8,760 hours)",
   "engine": "pvlib ModelChain through the worker (pv_yield)",
   "workload": "50 MWp fixed tilt, hourly clear-sky year generated in the call, PVWatts DC / AC, SAPM cell temperature, physical AOI",
   "n": 20,
   "median_ms": 174.029,
   "p95_ms": 201.668,
   "min_ms": 166.286,
   "max_ms": 208.782,
   "series_per_hour_theoretical": 20686,
   "series_unit": "yearly yields"
  },
  {
   "id": "loadflow",
   "name": "Load flow + short circuit of a sample grid",
   "engine": "pandapower through the worker (grid_loadflow)",
   "workload": "50 MW plant: 3 MV feeders, main transformer, 10 km HV line, external grid; Newton-Raphson load flow and IEC 60909",
   "n": 20,
   "median_ms": 319.312,
   "p95_ms": 383.691,
   "min_ms": 287.282,
   "max_ms": 636.465,
   "series_per_hour_theoretical": 11274,
   "series_unit": "load flows"
  },
  {
   "id": "atlas_point",
   "name": "Atlas point sample (all installed layers)",
   "engine": "worker atlas.point (rasterio on the atlas COGs)",
   "workload": "17 installed atlas COGs (solar, wind, population, built-up 1975–2030, flood) read at one point, warm file cache",
   "n": 20,
   "median_ms": 59.978,
   "p95_ms": 62.715,
   "min_ms": 56.235,
   "max_ms": 62.798,
   "series_per_hour_theoretical": 60022,
   "series_unit": "points"
  },
  {
   "id": "ifc_structure",
   "name": "IFC structure read of the sample model",
   "engine": "IfcOpenShell + worker cadbim.ifc_structure",
   "workload": "WaiMAP sample IFC 4.3 model (6 KB): open, units, storeys, rooms, element classes, checks",
   "n": 20,
   "median_ms": 0.673,
   "p95_ms": 0.813,
   "min_ms": 0.59,
   "max_ms": 1.072,
   "series_per_hour_theoretical": 5349182,
   "series_unit": "models"
  }
 ]
}