Results Module#

The results module provides structured data classes for storing and accessing optimization results.

OptimizationResults Class#

The OptimizationResults dataclass is the primary container for all optimization results returned by run_solver().

class sdom.results.OptimizationResults(termination_condition: str = '', solver_status: str = '', total_cost: float = 0.0, gen_mix_target: float = 0.0, generation_df: ~pandas.core.frame.DataFrame = <factory>, storage_df: ~pandas.core.frame.DataFrame = <factory>, thermal_generation_df: ~pandas.core.frame.DataFrame = <factory>, installed_plants_df: ~pandas.core.frame.DataFrame = <factory>, summary_df: ~pandas.core.frame.DataFrame = <factory>, problem_info: dict = <factory>, capacity: dict = <factory>, storage_capacity: dict = <factory>, generation_totals: dict = <factory>, cost_breakdown: dict = <factory>)[source]#

Data class containing all optimization results from SDOM.

This class stores the complete results from an SDOM optimization run, organized into DataFrames for different result categories (generation, storage, summary) and provides convenient accessors for specific metrics.

termination_condition#

The solver termination condition (e.g., ‘optimal’, ‘infeasible’).

Type:

str

solver_status#

The solver status (e.g., ‘ok’, ‘warning’).

Type:

str

total_cost#

The total objective value (cost) from the optimization.

Type:

float

gen_mix_target#

The generation mix target value used in this run.

Type:

float

generation_df#

Hourly generation dispatch results for all technologies.

Type:

pd.DataFrame

storage_df#

Hourly storage operation results (charge, discharge, SOC).

Type:

pd.DataFrame

thermal_generation_df#

Disaggregated hourly thermal generation by plant.

Type:

pd.DataFrame

installed_plants_df#

Installed capacity for each individual power plant (solar, wind, thermal).

Type:

pd.DataFrame

summary_df#

Summary metrics including capacities, costs, and totals.

Type:

pd.DataFrame

problem_info#

Solver problem information (constraints, variables, etc.).

Type:

dict

capacity#

Installed capacity by technology.

Type:

dict

storage_capacity#

Storage capacity details (charge, discharge, energy).

Type:

dict

generation_totals#

Total generation by technology.

Type:

dict

cost_breakdown#

Detailed cost breakdown (CAPEX, OPEX, FOM, VOM).

Type:

dict

termination_condition: str = ''#
solver_status: str = ''#
total_cost: float = 0.0#
gen_mix_target: float = 0.0#
generation_df: DataFrame#
storage_df: DataFrame#
thermal_generation_df: DataFrame#
installed_plants_df: DataFrame#
summary_df: DataFrame#
problem_info: dict#
capacity: dict#
storage_capacity: dict#
generation_totals: dict#
cost_breakdown: dict#
property is_optimal: bool#

Check if the solution is optimal.

property total_cap_thermal: float#

Total installed thermal capacity (MW).

property total_cap_pv: float#

Total installed solar PV capacity (MW).

property total_cap_wind: float#

Total installed wind capacity (MW).

property total_cap_storage_charge: dict#

Storage charging power capacity by technology (MW).

property total_cap_storage_discharge: dict#

Storage discharging power capacity by technology (MW).

property total_cap_storage_energy: dict#

Storage energy capacity by technology (MWh).

property total_gen_pv: float#

Total solar PV generation (MWh).

property total_gen_wind: float#

Total wind generation (MWh).

property total_gen_thermal: float#

Total thermal generation (MWh).

get_generation_dataframe() DataFrame[source]#

Get the hourly generation dispatch DataFrame.

Returns:

DataFrame with columns: Scenario, Hour, Solar PV Generation (MW), Solar PV Curtailment (MW), Wind Generation (MW), Wind Curtailment (MW), All Thermal Generation (MW), Hydro Generation (MW), Nuclear Generation (MW), Other Renewables Generation (MW), Imports (MW), Storage Charge/Discharge (MW), Exports (MW), Load (MW).

Return type:

pd.DataFrame

get_storage_dataframe() DataFrame[source]#

Get the hourly storage operation DataFrame.

Returns:

DataFrame with columns: Hour, Technology, Charging power (MW), Discharging power (MW), State of charge (MWh).

Return type:

pd.DataFrame

get_thermal_generation_dataframe() DataFrame[source]#

Get the disaggregated hourly thermal generation DataFrame.

Returns:

DataFrame with columns: Hour, and one column per thermal plant.

Return type:

pd.DataFrame

get_summary_dataframe() DataFrame[source]#

Get the summary metrics DataFrame.

Returns:

DataFrame with columns: Metric, Technology, Run, Optimal Value, Unit.

Return type:

pd.DataFrame

get_installed_plants_dataframe() DataFrame[source]#

Get the installed power plants capacity DataFrame.

Returns:

DataFrame with columns: Plant ID, Technology, Installed Capacity (MW), Max Capacity (MW), Capacity Fraction.

Return type:

pd.DataFrame

get_problem_info() dict[source]#

Get solver problem information.

Returns:

Dictionary with keys: Number of constraints, Number of variables, Number of binary variables, Number of objectives, Number of nonzeros.

Return type:

dict

__init__(termination_condition: str = '', solver_status: str = '', total_cost: float = 0.0, gen_mix_target: float = 0.0, generation_df: ~pandas.core.frame.DataFrame = <factory>, storage_df: ~pandas.core.frame.DataFrame = <factory>, thermal_generation_df: ~pandas.core.frame.DataFrame = <factory>, installed_plants_df: ~pandas.core.frame.DataFrame = <factory>, summary_df: ~pandas.core.frame.DataFrame = <factory>, problem_info: dict = <factory>, capacity: dict = <factory>, storage_capacity: dict = <factory>, generation_totals: dict = <factory>, cost_breakdown: dict = <factory>) None#

Result Collection Function#

sdom.results.collect_results_from_model(model, solver_result, case_name: str = 'run') OptimizationResults[source]#

Collect all optimization results from a solved Pyomo model.

This function extracts all relevant results from a solved SDOM model and organizes them into an OptimizationResults dataclass. It combines the functionality previously split between collect_results() and export_results().

Parameters:
  • model (pyomo.core.base.PyomoModel.ConcreteModel) – The solved Pyomo model instance.

  • solver_result (pyomo.opt.SolverResults) – The solver results object from solver.solve().

  • case_name (str, optional) – Case identifier for the scenario column. Defaults to “run”.

Returns:

A dataclass containing all optimization results.

Return type:

OptimizationResults

Example Usage#

Basic Result Access#

from sdom import load_data, initialize_model, run_solver, get_default_solver_config_dict

# Load and solve model
data = load_data('./Data/scenario/')
model = initialize_model(data, n_hours=168)
solver_config = get_default_solver_config_dict(solver_name="highs")

# Run optimization - returns OptimizationResults
results = run_solver(model, solver_config)

# Check solution status
if results.is_optimal:
    print(f"Optimization successful!")
    print(f"Total Cost: ${results.total_cost:,.2f}")
else:
    print(f"Solver terminated with: {results.termination_condition}")

Accessing Capacities#

# Generation capacities
print(f"Solar PV Capacity: {results.total_cap_pv:.2f} MW")
print(f"Wind Capacity: {results.total_cap_wind:.2f} MW")
print(f"Thermal Capacity: {results.total_cap_thermal:.2f} MW")

# Storage capacities by technology
for tech, cap in results.total_cap_storage_charge.items():
    print(f"{tech} Charge Capacity: {cap:.2f} MW")

for tech, energy in results.total_cap_storage_energy.items():
    print(f"{tech} Energy Capacity: {energy:.2f} MWh")

Accessing DataFrames#

# Get hourly generation dispatch
gen_df = results.get_generation_dataframe()
print(gen_df.head())

# Get storage operation details
storage_df = results.get_storage_dataframe()

# Get summary metrics
summary_df = results.get_summary_dataframe()

# Get disaggregated thermal generation (if multiple plants)
thermal_df = results.get_thermal_generation_dataframe()

Accessing Cost Breakdown#

# CAPEX by technology
capex = results.cost_breakdown["capex"]
print(f"Solar CAPEX: ${capex['Solar PV']:,.2f}")
print(f"Wind CAPEX: ${capex['Wind']:,.2f}")

# Storage costs
power_capex = results.cost_breakdown["power_capex"]
energy_capex = results.cost_breakdown["energy_capex"]

# Operating costs
fom = results.cost_breakdown["fom"]
vom = results.cost_breakdown["vom"]

# Import/export costs
print(f"Import Cost: ${results.cost_breakdown['imports_cost']:,.2f}")
print(f"Export Revenue: ${results.cost_breakdown['exports_revenue']:,.2f}")

Accessing Problem Information#

# Solver problem statistics
problem_info = results.get_problem_info()
print(f"Constraints: {problem_info['Number of constraints']}")
print(f"Variables: {problem_info['Number of variables']}")
print(f"Binary Variables: {problem_info['Number of binary variables']}")

OptimizationResults Attributes#

Solver Information#

Attribute

Type

Description

termination_condition

str

Solver termination status (e.g., ‘optimal’, ‘infeasible’)

solver_status

str

Overall solver status (e.g., ‘ok’, ‘warning’)

is_optimal

bool

Property: True if solution is optimal

Core Results#

Attribute

Type

Description

total_cost

float

Total objective value ($)

gen_mix_target

float

Generation mix target used

Capacity Results#

Attribute

Type

Description

capacity

dict

Generation capacities by technology (MW)

storage_capacity

dict

Nested dict with ‘charge’, ‘discharge’, ‘energy’ by technology

total_cap_pv

float

Property: Solar PV capacity (MW)

total_cap_wind

float

Property: Wind capacity (MW)

total_cap_thermal

float

Property: Thermal capacity (MW)

total_cap_storage_charge

dict

Property: Storage charge capacity by tech (MW)

total_cap_storage_discharge

dict

Property: Storage discharge capacity by tech (MW)

total_cap_storage_energy

dict

Property: Storage energy capacity by tech (MWh)

Generation Results#

Attribute

Type

Description

generation_totals

dict

Total generation by technology (MWh)

total_gen_pv

float

Property: Total PV generation (MWh)

total_gen_wind

float

Property: Total wind generation (MWh)

total_gen_thermal

float

Property: Total thermal generation (MWh)

Cost Breakdown#

Attribute

Type

Description

cost_breakdown

dict

Nested dict with ‘capex’, ‘power_capex’, ‘energy_capex’, ‘fom’, ‘vom’, ‘fuel_cost’, ‘imports_cost’, ‘exports_revenue’

DataFrames#

Attribute

Type

Description

generation_df

pd.DataFrame

Hourly generation dispatch

storage_df

pd.DataFrame

Hourly storage operation

thermal_generation_df

pd.DataFrame

Disaggregated thermal generation

summary_df

pd.DataFrame

Summary metrics