Trade Model Setup - High-Level Overview¶
Purpose¶
The trade model optimizes global steel and iron trade flows by solving a linear programming (LP) problem. It determines the most cost-effective way to route materials from suppliers through production facilities to demand centers, subject to capacity constraints, trade policies, and physical limitations.
Core Concept¶
The model represents the global steel value chain as a network:
Nodes: Suppliers (mines), production facilities (furnaces), and demand centers (regions)
Edges: Valid material flows between compatible technologies
Objective: Minimize total cost (production + transport + tariffs + carbon)
Constraints: Capacity limits, trade policies, distance restrictions, feedstock ratios
Main Functions¶
1. set_up_steel_trade_lp() - Build the Optimization Model¶
What it does: Constructs the complete LP model structure from simulation data.
Process:
Initializes an empty LP model with solver tolerance settings
Adds all commodities being modeled (steel, iron, etc.)
Creates process centers for suppliers, production facilities, and demand
Defines valid connections between process types
Applies optional constraints (tariffs, distance limits, feedstock ratios)
Adds location-specific transportation costs if available
Key decisions:
Only includes active furnace groups (configurable status filter)
Scales production capacity by safety factor (typically 95%)
Reuses process definitions across multiple furnaces with same technology
Outputs: A fully configured TradeLPModel ready for optimization
2. Helper Functions - Building Model Components¶
create_process_from_furnace_group()¶
Purpose: Converts a furnace group’s technology specifications into an LP process definition.
What it captures:
Input-output relationships (bill of materials)
Minimum/maximum feedstock ratios
Secondary feedstock requirements
Energy costs per input type
Handles edge cases:
Skips feedstocks with missing or invalid data
Warns about technologies with no primary outputs
Reuses existing BOM elements when possible
add_furnace_groups_as_process_centers()¶
Purpose: Represents each steel production facility as an LP node.
What it models:
Production capacity (scaled by availability factor)
Geographic location for distance calculations
Production cost (carbon cost)
Soft minimum utilization target
Filters: Only includes furnaces with active operating status
add_demand_centers_as_process_centers()¶
Purpose: Represents regional steel demand as LP nodes.
What it models:
Regional demand quantity for the simulation year
Geographic center of demand region
Single shared demand process (all regions demand “steel”)
add_suppliers_as_process_centers()¶
Purpose: Represents raw material sources (mines, scrap yards) as LP nodes.
What it models:
Supply capacity for the simulation year
Geographic location
Production/extraction cost
One process type per commodity (e.g., all scrap sources “scrap_supply”)
3. Constraint Functions¶
enforce_trade_tariffs_on_allocations()¶
Purpose: Applies trade policy restrictions to cross-border flows.
Supports three tariff types:
Volume quotas: Maximum tons per year on a route
Absolute taxes: Fixed cost per ton ($/ton)
Percentage taxes: Cost based on commodity price (% of market price)
Features:
Wildcard support for country groups (e.g., “any country to EU”)
Handles iron product families (hot metal, pig iron, DRI → “iron”)
Accumulates multiple taxes on same route
fix_to_zero_allocations_where_distance_doesnt_match_commodity()¶
Purpose: Enforces physical distance constraints on commodity transport.
Logic:
Hot metal: Can only travel short distances (~100km) due to cooling
Pig iron/steel: Made for long-distance transport
Fixes LP variables to zero for infeasible distance-commodity pairs
Applied before solving and reduces model size.
Secondary Feedstock & Aggregated Constraints¶
Purpose: Limits scrap availability and enforces technology-specific feedstock ratios.
Secondary feedstock constraints:
Regional limits on scrap, recycled materials
Example: “Europe can only source 50M tons scrap/year”
Aggregated constraints:
Technology-level min/max ratios
Example: “EAF must use 50-90% scrap, 10-50% DRI”
4. solve_steel_trade_lp_and_return_commodity_allocations() - Solve & Extract Results¶
What it does:
Solves the LP optimization problem using Pyomo/HiGHS solver
Extracts optimal allocation values from solver variables
Maps LP results back to domain objects (plants, suppliers, demand centers)
Filters out negligible allocations (< 0.0001 tons)
Error handling:
Returns empty allocations if solver fails to find optimal solution
Logs detailed error messages with termination condition
Continues simulation rather than crashing
Debug output:
Writes
trade_lp_variables.csvwith all allocation detailsLogs statistics on non-zero allocations per commodity
Outputs: Dictionary mapping each commodity to its optimal allocation flows
5. Post-Processing Functions¶
identify_bottlenecks()¶
Purpose: Analyzes results to find capacity-constrained facilities.
What it detects:
Furnace groups operating at or near maximum capacity
Potential supply chain chokepoints
Useful for understanding why demand might not be fully met
Note: Currently logs warnings but doesn’t return structured data.
adapt_allocation_costs_for_carbon_border_mechanisms()¶
Purpose: Applies carbon border adjustment mechanisms (CBAM) to trade costs.
What it models:
Export rebates when high-carbon-price region exports to low-carbon-price region
Import adjustments when low-carbon-price region exports to high-carbon-price region
Prevents double-counting when countries belong to multiple policy regions
Generalized design: Works with any carbon border mechanism (EU CBAM, OECD, etc.), not just EU-specific.
Note: Called separately from main setup, typically in allocation workflow.
Configuration¶
Key SimulationConfig Parameters¶
Model behavior:
lp_epsilon: Solver tolerance (1e-3) - how close to constraints is acceptablecapacity_limit: Production safety factor (0.95) - models realistic availabilityactive_statuses: Which furnace states to include (e.g., [“operating”, “mothballed”])
Physical constraints:
hot_metal_radius: Maximum hot metal transport distance (~100km)closely_allocated_products: Commodities limited to short distancesdistantly_allocated_products: Commodities requiring long transport
Economic data:
primary_products: Which commodities to optimize ([“steel”, “iron”])transport_kpis: Location-specific transport costs and emissions
Integration with Simulation¶
The trade model is called during each simulation time step:
Allocation Model prepares input data (plants, demand, suppliers for current year)
Setup phase builds LP model with
set_up_steel_trade_lp()Optional adjustments apply carbon border mechanisms
Solve phase optimizes with
solve_steel_trade_lp_and_return_commodity_allocations()Analysis phase identifies bottlenecks and validates results
Allocations are returned to simulation for plant-level profit calculations
For Detailed Implementation¶
For implementation details, parameter types, and code examples, see the comprehensive docstrings in each function within src/steelo/domain/trade_modelling/set_up_steel_trade_lp.py.