Skip to content

AEC Algorithms

Purple8 Hyper Graph ships a dedicated AEC (Architecture, Engineering & Construction) algorithm layer as part of Phase 8. It exposes 12 domain-specific sub-modules via the /aec/* REST API, all operating on the same node/edge graph primitives used everywhere else in Purple8.

Every endpoint accepts lightweight NodeIn / EdgeIn JSON — no IFC parser, no BIM authoring tool required. The algorithms run server-side; the optional AEC Algorithms UI page in the dashboard wraps every endpoint with sample fixtures and live result views.


Module overview

PhaseModuleEndpointsDescription
8.1Space Syntax / VGA/aec/vga/*Visibility graph analysis, integration scores, space hierarchy
8.2Structural Topology/aec/structural/*Rigidity, load paths, critical members
8.3BIM Graph/aec/bim/*IFC ingest, change-impact BFS, clash detection
8.4Generative Design/aec/design/*Spatial allocation CSP, egress optimisation
8.5MEP Flow Analysis/aec/mep/*Max-flow, fault isolation, thermal simulation
8.6Graph Grammars/aec/grammar/*Code-compliance generation & validation
8.7Spectral Analysis/aec/spectral/*Fiedler value, spectral bisection, robustness score
8.8Topology Optimisation/aec/topo/*SIMP-on-graph, async job queue
8.9MORL + GCN/aec/morl/*Multi-objective RL agent, Pareto front
8.10MPNN Physics Kernel/aec/mpnn/*Message-passing nodal displacement prediction
8.11Hypergraph/aec/hypergraph/*Clique/star expansion, isomorphism, transversal
8.12IFC Graph Rewriting/aec/ifc/*Grammar-rule transform → VGA / structural / MEP graphs

Shared request schema

Every endpoint that takes a graph accepts the same two arrays.

Node (NodeIn):

json
{
  "node_id": "R1",
  "node_type": "space",
  "x": 0.0,
  "y": 0.0,
  "z": 0.0,
  "properties": { "area": 20 }
}

Valid node_type values: space, room, corridor, zone, joint, support, wall, beam, column, floor, roof, door, window, stair, pump, valve, ahu, panel, junction, outlet, generic.

Edge (EdgeIn):

json
{
  "edge_id": "e01",
  "edge_type": "CORRIDOR",
  "source_id": "R1",
  "target_id": "C1",
  "weight": 1.0,
  "capacity": 1.0,
  "properties": {}
}

8.1 — Space Syntax & Visibility Graph Analysis (VGA)

Analyses movement potential and spatial integration in architectural floor plans.

Build a visibility graph

Constructs a VGA from a vector floor plan (boundary polygon + optional obstacles).

bash
POST /aec/vga/build
json
{
  "floor_plan": {
    "plan_id": "ground-floor",
    "boundary": [[0,0],[20,0],[20,15],[0,15]],
    "obstacles": [[[4,4],[8,4],[8,8],[4,8]]],
    "rooms": {
      "R1": { "label": "Office A" },
      "R2": { "label": "Office B" }
    },
    "entries": [[0, 7]],
    "grid_resolution": 0.5
  }
}

Compute integration scores

Returns mean visual depth (integration) per node — higher = more spatially integrated.

bash
POST /aec/vga/integration
json
{
  "node_ids": ["R1", "R2", "C1", "R3"],
  "adjacency": {
    "R1": ["C1"],
    "R2": ["C1"],
    "R3": ["C1"],
    "C1": ["R1", "R2", "R3"]
  },
  "graph_id": "ground-floor"
}

Response includes: integration_scores, mean_depth, global_integration.

Find articulation points (space hierarchy)

Identifies rooms/corridors whose removal would disconnect the floor plan.

bash
POST /aec/vga/hierarchy
json
{
  "node_ids": ["R1", "R2", "C1", "R3"],
  "adjacency": { "C1": ["R1","R2","R3"], "R1": ["C1"], "R2": ["C1"], "R3": ["C1"] }
}

8.2 — Structural Topology & Load Paths

Analyses structural systems as graphs — joints are nodes, members are edges.

Check rigidity

Tests whether a structure satisfies Maxwell's rule: m ≥ 2j − 3 (2D) or m ≥ 3j − 6 (3D).

bash
POST /aec/structural/rigidity
json
{
  "nodes": [
    { "node_id": "S0", "node_type": "support", "x": 0, "y": 0 },
    { "node_id": "J0", "node_type": "joint",   "x": 0, "y": 4 },
    { "node_id": "J1", "node_type": "joint",   "x": 4, "y": 6 }
  ],
  "edges": [
    { "edge_id": "m0", "edge_type": "MEMBER", "source_id": "S0", "target_id": "J0", "weight": 2 },
    { "edge_id": "m1", "edge_type": "MEMBER", "source_id": "J0", "target_id": "J1", "weight": 5 }
  ],
  "dimension": 2
}

Response includes: is_rigid, member_count, joint_count, maxwell_lhs, maxwell_rhs, redundancies.

Trace load paths

Finds shortest weighted paths from every loaded joint to all support nodes.

bash
POST /aec/structural/load-paths
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "loads": { "J1": 50.0, "J2": 30.0 },
  "weight_property": "stiffness"
}

Identify critical members

Finds bridge edges (Tarjan) whose removal would disconnect the structural graph.

bash
POST /aec/structural/critical-members

8.3 — BIM Graph & Change Propagation

Works with IFC-style building graphs. Nodes represent BIM entities (walls, beams, doors…); edges represent containment, adjacency, or system connections.

Ingest an IFC file

Parses an IFC file (requires ifcopenshell) and builds an in-memory BIM graph.

bash
POST /aec/bim/ingest
json
{
  "file_path": "/data/project.ifc",
  "graph_id": "project-001"
}

Propagate change impact

BFS from a modified element — surfaces all downstream elements that may be affected by the change.

bash
POST /aec/bim/change-impact
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "changed_guid": "C1",
  "max_depth": 5,
  "relation_filter": ["CONTAINS", "ADJACENT_TO"]
}

Response includes: changed_guid, impacted_nodes, impact_depth_map, relation_breakdown.

Detect clashes

Identifies topological clashes between element types (e.g. beams crossing pipes).

bash
POST /aec/bim/clashes
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "type_a": "beam",
  "type_b_prefix": "pipe"
}

8.4 — Generative Design & Spatial Allocation

Allocate rooms

Constraint-propagation (AC-3 + backtracking CSP) solver that assigns rooms to zones subject to adjacency constraints and an area budget.

bash
POST /aec/design/allocate
json
{
  "rooms": ["office", "meeting-room", "reception", "kitchen", "wc"],
  "constraints": [
    { "room_a": "reception", "room_b": "office",       "desirability": 1.0, "required": true },
    { "room_a": "kitchen",   "room_b": "meeting-room", "desirability": 0.8, "required": false }
  ],
  "area_budget": 500.0,
  "max_attempts": 100,
  "seed": 42
}

Response includes: assignments, total_area, constraint_satisfaction_rate, attempts_used.

Optimise egress

Dijkstra / min-cut from all occupiable nodes to designated exit nodes — surfaces bottleneck edges and worst-case evacuation distances.

bash
POST /aec/design/egress
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "exit_node_ids": ["E1", "E2"]
}

8.5 — MEP Flow Analysis & Fault Isolation

Max-flow / min-cut

Edmonds-Karp algorithm on a pipe/duct/cable network — returns maximum flow and the minimum cut edge set.

bash
POST /aec/mep/max-flow
json
{
  "nodes": [
    { "node_id": "SRC",  "node_type": "pump",     "x": 0, "y": 0 },
    { "node_id": "J1",   "node_type": "junction",  "x": 3, "y": 0 },
    { "node_id": "OUT1", "node_type": "outlet",    "x": 6, "y": 0 }
  ],
  "edges": [
    { "edge_id": "p0", "edge_type": "PIPE", "source_id": "SRC",  "target_id": "J1",   "capacity": 10 },
    { "edge_id": "p1", "edge_type": "PIPE", "source_id": "J1",   "target_id": "OUT1", "capacity": 7  }
  ],
  "source_id": "SRC",
  "sink_id": "OUT1",
  "system_type": "water_supply"
}

Response includes: max_flow, min_cut_edges, residual_graph_summary.

Fault isolation

BFS from a faulted component — returns all downstream affected nodes weighted by criticality score.

bash
POST /aec/mep/fault-impact
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "fault_node_id": "J1",
  "criticality_map": { "OUT1": 2.0, "OUT2": 1.5 },
  "system_type": "water_supply"
}

Thermal zone simulation

Iterative steady-state heat-flow simulation across zones until temperatures converge.

bash
POST /aec/mep/thermal/simulate
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "outdoor_temp": -5.0,
  "setpoints": { "SRC": 22.0, "OUT2": 18.0 },
  "max_iterations": 100
}

8.6 — Constrained Graph Grammars

Generate code-compliant floor plans

Generates N floor-plan graphs that satisfy the built-in compliance rule set (minimum room sizes, egress widths, required adjacencies).

bash
POST /aec/grammar/generate
json
{
  "rooms": ["corridor", "office", "wc", "meeting-room"],
  "n": 5,
  "seed": 42,
  "max_attempts": 20
}

Response: array of n plan objects each with rooms, edges, and rule_results.

Validate a floor plan

Runs the compliance rule set against an existing plan graph.

bash
POST /aec/grammar/validate
json
{
  "rooms": [
    { "node_id": "R1", "node_type": "space", "properties": { "area": 20, "label": "office" } },
    { "node_id": "R2", "node_type": "space", "properties": { "area": 5,  "label": "wc" } }
  ],
  "constraints": []
}

Response: { "passed": [...], "failed": { "R2": ["min_area_wc"] }, "all_pass": false }


8.7 — Spectral Graph Theory

Spectral methods applied to structural networks — uses the Laplacian eigendecomposition.

Fiedler value (algebraic connectivity)

Computes λ₂ of the graph Laplacian. Low values → the structure is close to disconnecting; high values → well-connected and robust.

bash
POST /aec/spectral/fiedler
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "normalised": false,
  "safety_threshold": 0.01,
  "graph_id": "truss-A"
}

Response includes: fiedler_value, fiedler_vector, is_connected, below_safety_threshold, natural_frequency_hz.

Spectral bisection / k-partition

Recursively bisects the structure using the Fiedler vector into k partitions — useful for load-zone planning or seismic analysis.

bash
POST /aec/spectral/partition
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "k": 4,
  "graph_id": "truss-A"
}

Response: partitions array, each with partition_id, node_ids, internal_edges, cut_edges.

Structural robustness score

Composite score combining Fiedler value and effective graph resistance. Returns a [0, 1] score: 1.0 = maximally robust.

bash
POST /aec/spectral/robustness

8.8 — Topology Optimisation

SIMP-on-graph: iteratively removes low-utilisation structural members until the target volume fraction is reached. Submitted as a background job because it can take several seconds.

Step 1 — queue the job

bash
POST /aec/topo/optimise
json
{
  "bounding_box": [0, 0, 0, 10, 0, 6],
  "resolution": 1.0,
  "load_node_ids":   ["J1"],
  "support_node_ids": ["S0", "S1"],
  "volume_fraction": 0.3,
  "max_iter": 50
}

Response: { "job_id": "uuid", "status": "pending" }

Step 2 — poll for the result

bash
GET /aec/topo/{job_id}/result

Response (when done):

json
{
  "status": "done",
  "result": {
    "iterations": 34,
    "converged": true,
    "volume_fraction_achieved": 0.301,
    "compliance_initial": 1842.3,
    "compliance_final": 1104.1,
    "compliance_reduction_pct": 40.1,
    "retained_node_ids": [ ... ],
    "removed_edge_ids": [ ... ]
  }
}

You can also build just the volume mesh without running the optimiser:

bash
POST /aec/topo/build-mesh
json
{ "bounding_box": [0,0,0,10,0,6], "resolution": 1.0 }

8.9 — Multi-Objective RL + GCN Agent (MORL)

Trains a GCN policy with REINFORCE to simultaneously optimise three objectives: circulation efficiency, egress safety, and structural stability. Returns a Pareto front of non-dominated layout solutions.

bash
POST /aec/morl/train
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "zone_labels": ["A", "B", "C", "D"],
  "reward_weights": {
    "circulation": 0.4,
    "egress":      0.4,
    "structural":  0.2
  },
  "episodes": 50,
  "seed": 42
}

Response includes: pareto_front (array of non-dominated solutions), best_episode, reward_history, final_weights.

CPU-bound

Training is CPU-bound. Keep episodes ≤ 20 for interactive demos; use a worker process for production training runs.


8.10 — MPNN Physics Kernel

Message Passing Neural Network that propagates physics states (loads, displacements, stresses) across the structural graph — approximating FEM without a full matrix solve.

Full propagation

bash
POST /aec/mpnn/propagate
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "load_vector": {
    "J1": [0, 0, -10],
    "J2": [0, 0, -5]
  },
  "hidden_dim": 16,
  "message_steps": 3,
  "graph_id": "truss-A"
}

Response: node_states map of predicted nodal displacements [dx, dy, dz] per node.

Incremental propagation

Re-propagates only within the k-hop neighbourhood of changed nodes — much faster for small edits.

bash
POST /aec/mpnn/incremental
json
{
  "changed_node_ids": ["J1"],
  "nodes": [ ... ],
  "edges": [ ... ],
  "prev_states": { "J0": [0,0,0], "J1": [0,0,0], "J2": [0,0,0] },
  "k_hop": 2,
  "graph_id": "truss-A"
}

8.11 — Hypergraph Algorithms

AEC systems naturally form hyperedges — e.g. a single HVAC circuit that serves rooms R1, R2, and R3 simultaneously. The hypergraph module expands these into standard graphs for downstream analysis.

Build (expand) a hypergraph

Two expansion strategies:

  • clique — adds a standard edge between every pair of nodes in a hyperedge
  • star — adds a dummy centre node + spoke edges to each member
bash
POST /aec/hypergraph/build
json
{
  "nodes": [ ... ],
  "hyperedges": [
    { "hyperedge_id": "h1", "node_ids": ["R1","R2","C1"], "edge_type": "HVAC_ZONE" },
    { "hyperedge_id": "h2", "node_ids": ["R2","R3","C1"], "edge_type": "HVAC_ZONE" }
  ],
  "method": "clique"
}

Sub-hypergraph isomorphism

Finds all sub-hypergraph matches of a pattern hyperedge set within a larger target.

bash
POST /aec/hypergraph/isomorphism
json
{
  "pattern": [
    { "hyperedge_id": "p1", "node_ids": ["A","B","C"], "edge_type": "ZONE" }
  ],
  "target": [ ... ],
  "max_matches": 10
}

Minimum transversal

Finds the smallest set of nodes that intersects every hyperedge — useful for placing sensors or shut-off valves.

bash
POST /aec/hypergraph/transversal
json
{
  "hyperedges": [
    { "hyperedge_id": "h1", "node_ids": ["R1","R2","C1"] },
    { "hyperedge_id": "h2", "node_ids": ["R2","R3","C1"] },
    { "hyperedge_id": "h3", "node_ids": ["R4","C1","E1"] }
  ]
}

8.12 — IFC Graph Rewriting

Transforms an IFC-style node/edge graph into a clean analytical representation for a specific downstream pipeline using grammar rewriting rules.

bash
POST /aec/ifc/rewrite
json
{
  "nodes": [ ... ],
  "edges": [ ... ],
  "target": "vga"
}

target must be one of:

ValueOutput
vgaFloor-plan graph ready for VGA integration scoring
structuralJoint-and-member graph ready for rigidity / load-path analysis
mepSource-junction-sink graph ready for max-flow / fault analysis

The rewriter handles cross-version IFC property normalisation (IFC2x3 ↔ IFC4 ↔ IFC4.3) and incremental diff-patch for live model updates.


Frontend UI

All 12 modules are accessible in the AEC Algorithms dashboard page at /dashboard/aec. Each tab includes:

  • Pre-loaded sample fixtures (floor plans, structural trusses, MEP networks)
  • All operation variants selectable via radio buttons
  • Configurable parameters (dimension, load node, volume fraction, episode count…)
  • Collapsible JSON result panel with error state highlighting
  • Async job polling for Topology Optimisation (queue → poll pattern)
  • Sample graph preview (expandable JSON of the fixture nodes/edges)

Exit criteria (Phase 8 benchmarks)

ModuleTarget
VGAIntegration score correlation ≥ 0.99 vs depthmapX reference
StructuralRigidity classifier correct on 50-member benchmark set
BIMRound-trip IFC < 120 s for 50 MB file; clash precision ≥ 0.95
MEPMax-Flow matches NetworkX on 500-node pipe network
Grammar≥ 100 code-compliant plans/second
SpectralFiedler value matches NumPy to 6 decimal places
Topo OptConvergence ≤ 50 iterations; compliance reduction ≥ 40%
MORLPareto improvement within 500 training episodes
MPNNMAPE ≤ 5% on FEM test set
HypergraphCorrect isomorphism matches on 50-hyperedge test case
IFC RewritingMatches expert annotation on 5 reference IFC files

Purple8 Graph is proprietary software. All rights reserved.