pownet.core package
Submodules
pownet.core.data_processor module
data_processor.py: This file contains the DataProcessor class that processes the data provided by the user.
- class pownet.core.data_processor.DataProcessor(input_folder, model_name, year, frequency)[source]
Bases:
object- calc_line_capacity()[source]
Calculate the capacity of line segments. The unit is in MW. Line capacity is the minimum of the thermal limit and the steady-state stability limit (a function of distance).
Note the calculated values are overwritten by user provided values in the transmission.csv file.
- Return type:
None
- calc_line_susceptance()[source]
Calculate the susceptance of line segments. The unit is in Siemens (S).
- Return type:
None
- calc_stability_limit(source_kv, sink_kv, distance, n_circuits)[source]
Calculates the theoretical steady-state stability limit of the transmission line.
This method applies the classical Power Transfer Equation for a lossless line (Chapter 5 of Power System Analysis and Design, Eq. 5.4.27).
Formula: P_max_circuit = (V_S * V_R) / X_total
Where: P_max_circuit: The maximum Real Power transfer per circuit in MW.
(Assumes Power Factor = 1.0, so MW = MVA).
V_S, V_R: The Line-to-Line voltages at sending and receiving ends in kV. X_total: The total reactance of the line in Ohms.
Calculated as (Reactance_per_km * distance).
Note on “Perfect Condition”: This calculates the static stability limit (steady-state). Practical operations typically constrain flow to a safety margin (e.g., 30-45 degrees load angle) well below this theoretical maximum.
- Parameters:
source_kv (int) – Voltage level of the source bus in kV.
sink_kv (int) – Voltage level of the sink bus in kV.
distance (float) – Length of the transmission line in km.
n_circuits (int) – Number of parallel circuits (e.g., 2 for double-circuit).
- Returns:
- The combined stability limit for all circuits in MW.
Returns infinity if distance is 0 (co-located buses).
- Return type:
int
- calc_thermal_limit(source_kv, sink_kv, n_circuits)[source]
Calculates the thermal rating (MVA) of the transmission line based on conductor ampacity (Chapter 5 of Power System Analysis and Design 5th See Example 5.6b).
Let ‘n_conductors’ parameter in ‘transmission_params’ represents the number of sub-conductors per phase (bundling factor).
Formula: S_thermal = sqrt(3) * V_line_LL * I_phase_max
- Return type:
int
Where: S_thermal: The total Apparent Power capacity of the circuit in MVA.
(Note: S_thermal = P_real_power only when Power Factor = 1.0)
V_line_LL: The Line-to-Line voltage in kV (the standard voltage rating, e.g., 115 kV). I_phase_max: The maximum current capacity per phase in kilo-Amps (kA).
Calculated as (Ampacity per wire * Bundling Factor).
Args: source_kv (int): Voltage level of the source bus (kV). sink_kv (int): Voltage level of the sink bus (kV). n_circuits (int): Number of distinct circuits (e.g., double circuit tower = 2).
Returns: int: The maximum thermal capacity in MVA.
- check_user_line_capacities()[source]
The user can provide their own line capacities under user_line_cap column in transmission.csv. If this is the case, then it will be used instead of the calculated line capacities.
- Return type:
None
- create_cycle_map()[source]
Create a cycle map for the power system. This is used to create the cycle constraints in the optimization model. The cycle map is a dictionary where the key is the cycle name and the value is a list of nodes in the cycle.
- Return type:
None
- create_ess_derate_factors(derate_factor=1.0)[source]
Creates derate factors for ESS units.
- Return type:
None
- create_ess_derated_capacity()[source]
Creates a dataframe of hourly derated capacity of ess units.
- Return type:
None
- create_thermal_derate_factors(derate_factor=1.0)[source]
Creates derate factors for thermal units.
- Return type:
None
- create_thermal_derated_capacity()[source]
Creates a dataframe of hourly derated capacity of thermal units.
- Return type:
None
- write_cycle_map()[source]
Save the cycle map to a json file in model_library/{model_name}. The key is the cycle name and the value is a list of nodes in the cycle.
- Return type:
None
pownet.core.model_builder module
builder.py: This module contains the ModelBuilder class, which is responsible for constructing and updating the optimization model for the power system.
- class pownet.core.model_builder.ModelBuilder(inputs)[source]
Bases:
object- build(step_k, init_conds)[source]
Build the initial optimization model by delegating to specialized builders.
- Return type:
- update(step_k, init_conds)[source]
Update the existing model for a new step_k by delegating to specialized builders.
- Return type:
pownet.core.output module
output.py: the OutputProcessor class processes modeling outputs in typical formats.
- class pownet.core.output.OutputProcessor[source]
Bases:
object- get_co2_emission(hourly_generation, co2_map=None)[source]
Return the CO2 emissions for timestep. From Chowdhury, Dang, Nguyen, Koh, & Galelli. (2021).
coal: 1.04 Mton/MWh gas: 0.47 Mton/MWh oil : 0.73 Mton/MWh solid_waste: 0.170 Mton/MWh
From https://www.eia.gov/environment/emissions/co2_vol_mass.php: solid_waste: 49.89 kg/MMBtu (From 49.89 kg/MMBtu * 3.412 MMBtu/MWh * 1 Mton/1000 kg = 0.170 Mton/MWh)
- get_contract_hourly_cost(node_variables, unit_contract, contract_costs)[source]
- Return type:
DataFrame
- get_fuel_mix(hourly_generation)[source]
Return the fuel mix (%) for the whole simulation period.
- Return type:
DataFrame
- get_gen_by_fuel(hourly_generation)[source]
Return the total generation for the whole simulation period.
- Return type:
DataFrame
- get_import_values(node_variables)[source]
Return the import values for each timestep. Columns are generators. Index is the hour in the simulation year
- Return type:
DataFrame
- get_max_line_usage(flow_variables, line_locations, rated_line_capacities)[source]
Calculates the maximum utilization for each transmission line.
This function takes the flow results from an optimization model, determines the peak flow on each line over the entire simulation horizon, and then calculates the utilization of each line as a percentage of its rated capacity. It also merges location data for the lines.
- Parameters:
flow_variables (pd.DataFrame) – DataFrame containing flow values for each line at each timestep. Expected columns: ‘node_a’, ‘node_b’, ‘value’ (flow magnitude), and ‘hour’.
line_locations (pd.DataFrame) – DataFrame containing location or other metadata for each line. Expected to be indexed by a MultiIndex (‘source’, ‘sink’).
rated_line_capacities (dict[tuple[str, str], int]) – Dictionary mapping line tuples (source_node, sink_node) to their rated power capacity (e.g., in MW).
- Returns:
- A DataFrame indexed by (‘source’, ‘sink’) with columns
including ‘max_line_usage’ (peak flow / rated capacity), columns from line_locations, and ‘rated_capacity’.
- Return type:
pd.DataFrame
- get_nondispatch_hourly_capacity_factor(unit_type, node_variables, contracted_capacities, energy_storage_attach)[source]
Return the capacity factor which is a function of generation and storage charging.
- Return type:
DataFrame
- get_thermal_unit_daily_duration(node_variables)[source]
Return the daily online duration of each thermal unit. Rows are days and columns are units.
- Return type:
DataFrame
- get_thermal_unit_daily_startup_frequency(node_variables)[source]
Return the frequency of startups for each thermal unit over the whole simulation period.
- Return type:
DataFrame
- get_thermal_unit_mean_hourly_status(node_variables)[source]
The hourly status of thermal units for each hour over the simulation period.
- Return type:
DataFrame
- get_thermal_unit_startup_frequency(node_variables)[source]
Return the frequency of startups for each thermal unit over the whole simulation period.
- Return type:
DataFrame
- get_thermal_unit_total_duration(node_variables)[source]
Return the total online duration of each thermal unit over the whole simulation period.
- Return type:
DataFrame
- get_thermal_unit_total_duration_and_frequency(node_variables)[source]
Return data for histogram of frequency of startups and duration of committed hours in a year.
- Return type:
DataFrame
pownet.core.record module
record.py: The SystemRecord class processes stores the modeling outputs from each iteration. TODO: self.current_hydro, self.current_import for model coupling
- class pownet.core.record.SystemRecord(system_input, batch_mode=True, keep_record_each_step=False)[source]
Bases:
objectThis class stores modeling outputs from each iteration. The results are stored in three dataframes: node_vars, flow_vars, and syswide_vars. The initial conditions are also stored in the class.
- get_init_conds()[source]
Return the initial conditions for the simulation.
- Return type:
dict[str,dict]
- get_node_variables()[source]
Return node-specific variables. These variables include dispatch, unit status, unit switching, etc.
- Return type:
DataFrame
- get_systemwide_variables()[source]
Return the system variables. We currently only have the system-wide spinning reserve shortfall.
- Return type:
DataFrame
- keep(runtime, objval, solution, step_k, lmp=None)[source]
Keep the simulation results at the current simulation period step_k.
- Parameters:
runtime (float) – The runtime of the model.
objval (float) – The objective value of the model.
solution (pd.DataFrame) – The solution dataframe from the model.
step_k (int) – The current simulation period.
lmp (dict[str, float], optional) – The locational marginal prices. Defaults to None.
- Return type:
None- Returns:
None
pownet.core.simulation module
simulation.py: Main class to run the simulation of the power system model
- class pownet.core.simulation.Simulator(input_folder, model_name, model_year, frequency=50, use_spin_var=True, dc_opf='kirchhoff', spin_reserve_factor=0.15, spin_reserve_mw=None, line_loss_factor=0.075, line_capacity_factor=0.9, load_shortfall_penalty_factor=1000, load_curtail_penalty_factor=10, spin_shortfall_penalty_factor=1000)[source]
Bases:
objectMain class to run the simulation of the power system model
- plot_fuelmix(chart_type, output_folder=None)[source]
Plot the fuel mix of the power system
- Parameters:
chart_type (str) – The type of chart to plot. Choose between ‘bar’ and ‘area’.
output_folder (str) – The folder to save the plot.
- Return type:
None- Returns:
None
- plot_lmp(output_folder=None)[source]
Plot the locational marginal prices
- Parameters:
output_folder (str) – The folder to save the plot.
- Return type:
None- Returns:
None
- plot_thermal_units(output_folder=None)[source]
Plot the status of the thermal units
- Parameters:
output_folder (str) – The folder to save the plot.
- Return type:
None- Returns:
None
- run(sim_horizon, steps_to_run, num_sim_days=365, to_process_inputs=True, solver='gurobi', log_to_console=True, mipgap=0.001, timelimit=600, num_threads=0, find_lmp=False)[source]
Run the simulation of the power system model
- Parameters:
sim_horizon (int) – The simulation horizon in hours.
steps_to_run (int) – The number of steps to run the simulation.
to_process_inputs (bool) – Whether to process the input data.
solver (str) – The solver to use for optimization.
log_to_console (bool) – Whether to log the optimization output to the console.
mipgap (float) – The MIP gap for the optimization.
timelimit (int) – The time limit for the optimization in seconds.
num_threads (int) – The number of threads to use for optimization.
find_lmp (bool) – Whether to find the locational marginal prices.
- Returns:
The system record object containing the simulation results.
- Return type:
pownet.core.user_constraint module
pownet.core.visualizer module
visualizer.py: This module contains the Visualizer class, which provides methods to visualize the output from PowNet.
- class pownet.core.visualizer.Visualizer(model_id)[source]
Bases:
object- plot_fuelmix_area(dispatch, demand, output_folder=None)[source]
Create an area plot of the fuel mix.
- Parameters:
dispatch (pd.DataFrame) – The dispatch of each generator.
demand (pd.Series) – The demand of the system.
output_folder (str) – If specified, then the plot is saved in the folder.
- Return type:
None- Returns:
None
- plot_fuelmix_bar(dispatch, demand, output_folder=None)[source]
Create a bar plot of the fuel mix.
- Parameters:
dispatch (pd.DataFrame) – The dispatch of each generator.
demand (pd.Series) – The demand of the system.
output_folder (str) – If specified, then the plot is saved in the folder.
- Return type:
None- Returns:
None
- plot_line_usage(max_line_usage, output_folder=None)[source]
Flow variables must have the max_line_usage column
- Return type:
None
- plot_lmp(lmp_df, output_folder=None, max_ylim=200)[source]
Plots unique locational marginal price (LMP) timeseries. For each unique LMP timeseries, a representative node is chosen based on ordering in the dataframe.
- Parameters:
lmp_df (pd.DataFrame) – LMP timeseries.
output_folder (str) – If specified, then the plot is saved in the folder.
max_ylim (float) – Maximum y-axis limit.
- Return type:
None- Returns:
None
- plot_mean_thermal_unit_hourly_status(thermal_unit_mean_hourly_status, output_folder=None)[source]
- Return type:
None
- plot_power_flow(flow_variables, figsize_per_line=(10, 2), fixed_legend_height_inches=0.5)[source]
Plots the power flow on transmission lines over time.
Each unique transmission line (node_a to node_b) gets its own subplot. The y-axis label for each subplot is the line segment name. Legend is placed at the top center of the figure, occupying a fixed absolute height. Power flow is colored: - Green: Positive flow - Red: Negative flow - Black: Zero flow
- Parameters:
flow_variables (pd.DataFrame) – DataFrame with simulation results. Expected columns: ‘node_a’, ‘node_b’, ‘value’, ‘type’ (‘fwd’ or ‘bwd’), ‘hour’.
figsize_per_line (tuple) – Tuple specifying (width, height_for_each_subplot_plot_area).
fixed_legend_height_inches (float) – Absolute height in inches for the legend area at the top.
- Return type:
None
- plot_thermal_units(thermal_dispatch, unit_status, thermal_rated_capacity, output_folder=None)[source]
Plot the on/off status of individual thermal units
- Parameters:
thermal_dispatch (pd.DataFrame) – The dispatch of each thermal unit.
unit_status (pd.DataFrame) – The status of each thermal unit.
thermal_rated_capacity (dict[str, float]) – Rated capacity of each thermal unit.
output_folder (str) – If specified, then the plot is saved in the folder.
- Return type:
None- Returns:
None
- plot_unit_storage_state(hourly_storage_charge, hourly_storage_discharge, hourly_storage_state, output_folder=None)[source]
Plot the hourly activity of the energy storage units.
- Parameters:
hourly_storage_charge (pd.Series) – Hourly charge data.
hourly_storage_discharge (pd.Series) – Hourly discharge data.
hourly_storage_state (pd.Series) – Hourly storage state data.
- Return type:
None