# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
from __future__ import annotations
from typing import Union, TYPE_CHECKING
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from VeraGridEngine.Simulations.OPF.opf_results import OptimalPowerFlowResults
from VeraGridEngine.Simulations.results_table import ResultsTable
from VeraGridEngine.Simulations.results_template import ResultsTemplate, ResultsProperty
from VeraGridEngine.basic_structures import IntVec, Vec, StrVec, CxMat, Mat, BoolVec
from VeraGridEngine.enumerations import StudyResultsType, ResultTypes, DeviceType
if TYPE_CHECKING: # Only imports the below statements during type checking
from VeraGridEngine.Simulations.Clustering.clustering_results import ClusteringResults
from VeraGridEngine.DataStructures.numerical_circuit import NumericalCircuit
[docs]
class OptimalPowerFlowTimeSeriesResults(ResultsTemplate):
"""
Optimal power flow time series results
"""
LOCAL_RESULTS_DECLARATIONS = (
ResultsProperty(name='bus_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='branch_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='load_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='generator_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='battery_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='shunt_like_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='hvdc_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='vsc_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='fuel_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='emission_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='technology_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='bus_types', tpe=IntVec, old_names=list(), expandable=False),
ResultsProperty(name='fluid_node_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='fluid_path_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='fluid_injection_names', tpe=StrVec, old_names=list(), expandable=False),
ResultsProperty(name='voltage', tpe=CxMat, old_names=list(), expandable=True),
ResultsProperty(name='Sbus', tpe=CxMat, old_names=list(), expandable=True),
ResultsProperty(name='bus_shadow_prices', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='load_power', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='load_shedding', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='load_shedding_cost', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='Sf', tpe=CxMat, old_names=list(), expandable=True),
ResultsProperty(name='St', tpe=CxMat, old_names=list(), expandable=True),
ResultsProperty(name='loading', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='losses', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='tap_angle', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='tap_module', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='overloads', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='overloads_cost', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='rates', tpe=Vec, old_names=list(), expandable=False),
ResultsProperty(name='contingency_rates', tpe=Vec, old_names=list(), expandable=False),
ResultsProperty(name='contingency_flows_list', tpe=list, old_names=list(), expandable=False),
ResultsProperty(name='contingency_indices_list', tpe=list, old_names=list(), expandable=False),
ResultsProperty(name='contingency_flows_slacks_list', tpe=list, old_names=list(), expandable=False),
ResultsProperty(name='hvdc_Pf', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='hvdc_loading', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='vsc_Pf', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='vsc_loading', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='fluid_node_current_level', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='fluid_node_flow_in', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='fluid_node_flow_out', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='fluid_node_p2x_flow', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='fluid_node_spillage', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='fluid_path_flow', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='fluid_injection_flow', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='generator_power', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='generator_reactive_power', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='generator_shedding', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='generator_cost', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='generator_producing', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='generator_starting_up', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='generator_shutting_down', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='generator_invested', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='shunt_like_reactive_power', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='battery_power', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='battery_energy', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='battery_invested', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='system_fuel', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='system_emissions', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='system_energy_cost', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='system_total_energy_cost', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='power_by_technology', tpe=Mat, old_names=list(), expandable=True),
ResultsProperty(name='converged', tpe=BoolVec, old_names=list(), expandable=True),
)
__slots__ = (
"bus_names",
"branch_names",
"load_names",
"generator_names",
"battery_names",
"shunt_like_names",
"hvdc_names",
"vsc_names",
"fuel_names",
"emission_names",
"technology_names",
"bus_types",
"fluid_node_names",
"fluid_path_names",
"fluid_injection_names",
"voltage",
"Sbus",
"bus_shadow_prices",
"Sf",
"St",
"loading",
"losses",
"tap_angle",
"tap_module",
"overloads",
"overloads_cost",
"rates",
"contingency_rates",
"contingency_flows_list",
"contingency_indices_list",
"contingency_flows_slacks_list",
"hvdc_Pf",
"hvdc_loading",
"vsc_Pf",
"vsc_loading",
"load_power",
"load_shedding",
"load_shedding_cost",
"generator_power",
"generator_reactive_power",
"generator_shedding",
"generator_cost",
"generator_producing",
"generator_starting_up",
"generator_shutting_down",
"generator_invested",
"shunt_like_reactive_power",
"battery_power",
"battery_energy",
"battery_invested",
"fluid_node_current_level",
"fluid_node_flow_in",
"fluid_node_flow_out",
"fluid_node_p2x_flow",
"fluid_node_spillage",
"fluid_path_flow",
"fluid_injection_flow",
"converged",
"system_fuel",
"system_emissions",
"system_energy_cost",
"system_total_energy_cost",
"power_by_technology",
)
def __init__(self,
bus_names: StrVec,
branch_names: StrVec,
load_names: StrVec,
generator_names: StrVec,
battery_names: StrVec,
shunt_like_names: StrVec,
hvdc_names: StrVec,
vsc_names: StrVec,
fuel_names: StrVec,
emission_names: StrVec,
technology_names: StrVec,
fluid_node_names: StrVec,
fluid_path_names: StrVec,
fluid_injection_names: StrVec,
nt: int,
time_array=None,
bus_types=(),
clustering_results: Union[None, ClusteringResults] = None):
"""
:param bus_names:
:param branch_names:
:param load_names:
:param generator_names:
:param battery_names:
:param shunt_like_names:
:param hvdc_names:
:param fuel_names:
:param emission_names:
:param technology_names:
:param fluid_node_names:
:param fluid_path_names:
:param fluid_injection_names:
:param nt:
:param time_array:
:param bus_types:
:param clustering_results:
"""
ResultsTemplate.__init__(self,
name='OPF time series',
available_results={ResultTypes.BusResults: [ResultTypes.BusVoltageModule,
ResultTypes.BusVoltageAngle,
ResultTypes.BusShadowPrices],
ResultTypes.GeneratorResults: [ResultTypes.GeneratorPower,
ResultTypes.GeneratorReactivePower,
ResultTypes.GeneratorShedding,
ResultTypes.GeneratorCost,
ResultTypes.GeneratorProducing,
ResultTypes.GeneratorStartingUp,
ResultTypes.GeneratorShuttingDown,
ResultTypes.GeneratorInvested,
],
ResultTypes.ShuntResults: [ResultTypes.ShuntReactivePower],
ResultTypes.BatteryResults: [ResultTypes.BatteryPower,
ResultTypes.BatteryEnergy,
ResultTypes.BatteryInvested, ],
ResultTypes.LoadResults: [ResultTypes.LoadPower,
ResultTypes.LoadShedding,
ResultTypes.LoadSheddingCost],
ResultTypes.BranchResults: [ResultTypes.BranchActivePowerFrom,
ResultTypes.BranchLoading,
ResultTypes.BranchOverloads,
ResultTypes.BranchOverloadsCost,
ResultTypes.BranchTapAngle,
ResultTypes.BranchTapModule],
ResultTypes.ReportsResults: [ResultTypes.ContingencyFlowsReport],
ResultTypes.HvdcResults: [ResultTypes.HvdcPowerFrom,
ResultTypes.HvdcLoading],
ResultTypes.FluidNodeResults: [ResultTypes.FluidCurrentLevel,
ResultTypes.FluidFlowIn,
ResultTypes.FluidFlowOut,
ResultTypes.FluidP2XFlow,
ResultTypes.FluidSpillage],
ResultTypes.FluidPathResults: [ResultTypes.FluidFlowPath],
ResultTypes.FluidInjectionResults: [ResultTypes.FluidFlowInjection],
ResultTypes.SystemResults: [ResultTypes.SystemFuel,
ResultTypes.SystemEmissions,
ResultTypes.SystemEnergyCost,
ResultTypes.SystemEnergyTotalCost,
ResultTypes.PowerByTechnology],
ResultTypes.SpecialPlots: [
ResultTypes.OpfBalancePlot,
# ResultTypes.OpfTechnologyPlot
],
},
time_array=time_array,
clustering_results=clustering_results,
study_results_type=StudyResultsType.OptimalPowerFlowTimeSeries)
self.bus_names = bus_names
self.branch_names = branch_names
self.load_names = load_names
self.generator_names = generator_names
self.battery_names = battery_names
self.shunt_like_names = shunt_like_names
self.hvdc_names = hvdc_names
self.vsc_names = vsc_names
self.fuel_names = fuel_names
self.emission_names = emission_names
self.technology_names = technology_names
self.bus_types = bus_types
self.fluid_node_names = fluid_node_names
self.fluid_path_names = fluid_path_names
self.fluid_injection_names = fluid_injection_names
n = len(bus_names)
m = len(branch_names)
ngen = len(generator_names)
nbat = len(battery_names)
nsh = len(shunt_like_names)
nload = len(load_names)
nhvdc = len(hvdc_names)
nvsc = len(vsc_names)
n_fluid_node = len(fluid_node_names)
n_fluid_path = len(fluid_path_names)
n_fluid_injection = len(fluid_injection_names)
nfuels = len(fuel_names)
nemissions = len(emission_names)
ntech = len(technology_names)
nsh = len(shunt_like_names)
self.voltage = np.zeros((nt, n), dtype=complex)
self.Sbus = np.zeros((nt, n), dtype=complex)
self.bus_shadow_prices = np.zeros((nt, n), dtype=float)
self.Sf = np.zeros((nt, m), dtype=complex)
self.St = np.zeros((nt, m), dtype=complex)
self.loading = np.zeros((nt, m), dtype=float)
self.losses = np.zeros((nt, m), dtype=float)
self.tap_angle = np.zeros((nt, m), dtype=float)
self.tap_module = np.ones((nt, m), dtype=float)
self.overloads = np.zeros((nt, m), dtype=float)
self.overloads_cost = np.zeros((nt, m), dtype=float)
self.rates = np.zeros(m)
self.contingency_rates = np.zeros(m)
self.contingency_flows_list = list()
self.contingency_indices_list = list() # [(t, m, c), ...]
self.contingency_flows_slacks_list = list()
self.hvdc_Pf = np.zeros((nt, nhvdc), dtype=float)
self.hvdc_loading = np.zeros((nt, nhvdc), dtype=float)
self.vsc_Pf = np.zeros((nt, nvsc), dtype=float)
self.vsc_loading = np.zeros((nt, nvsc), dtype=float)
self.load_power = np.zeros((nt, nload), dtype=float)
self.load_shedding = np.zeros((nt, nload), dtype=float)
self.load_shedding_cost = np.zeros((nt, nload), dtype=float)
self.generator_power = np.zeros((nt, ngen), dtype=float)
self.generator_reactive_power = np.zeros((nt, ngen), dtype=float)
self.generator_shedding = np.zeros((nt, ngen), dtype=float)
self.generator_cost = np.zeros((nt, ngen), dtype=float)
self.generator_producing = np.zeros((nt, ngen), dtype=bool)
self.generator_starting_up = np.zeros((nt, ngen), dtype=bool)
self.generator_shutting_down = np.zeros((nt, ngen), dtype=bool)
self.generator_invested = np.zeros((nt, ngen), dtype=bool)
self.shunt_like_reactive_power = np.zeros((nt, nsh), dtype=float)
self.battery_power = np.zeros((nt, nbat), dtype=float)
self.battery_energy = np.zeros((nt, nbat), dtype=float)
self.battery_invested = np.zeros((nt, nbat), dtype=bool)
self.fluid_node_current_level = np.zeros((nt, n_fluid_node), dtype=float)
self.fluid_node_flow_in = np.zeros((nt, n_fluid_node), dtype=float)
self.fluid_node_flow_out = np.zeros((nt, n_fluid_node), dtype=float)
self.fluid_node_p2x_flow = np.zeros((nt, n_fluid_node), dtype=float)
self.fluid_node_spillage = np.zeros((nt, n_fluid_node), dtype=float)
self.fluid_path_flow = np.zeros((nt, n_fluid_path), dtype=float)
self.fluid_injection_flow = np.zeros((nt, n_fluid_injection), dtype=float)
self.converged = np.empty(nt, dtype=bool)
self.system_fuel = np.empty((nt, nfuels), dtype=float)
self.system_emissions = np.empty((nt, nemissions), dtype=float)
self.system_energy_cost = np.empty(nt, dtype=float)
self.system_total_energy_cost = np.empty(nt, dtype=float)
self.power_by_technology = np.empty((nt, ntech), dtype=float)
@property
def phase_shift(self) -> Mat:
"""
Cover for old API
:return: tap angles in rad
"""
return self.tap_angle
[docs]
def apply_new_time_series_rates(self, nc: NumericalCircuit):
"""
:param nc:
"""
rates = nc.passive_branch_data.rates.T
self.loading = self.Sf / (rates + 1e-9)
[docs]
def set_at(self, t, res: OptimalPowerFlowResults):
"""
Set the results
:param t: time index
:param res: OptimalPowerFlowResults instance
"""
self.voltage[t, :] = res.voltage
self.load_shedding[t, :] = res.load_shedding
self.loading[t, :] = np.abs(res.loading)
self.overloads[t, :] = np.abs(res.overloads)
self.losses[t, :] = np.abs(res.losses)
self.Sbus[t, :] = res.Sbus
self.Sf[t, :] = res.Sf
[docs]
def mdl(self, result_type) -> ResultsTable:
"""
Plot the results
:param result_type:
:return:
"""
if result_type == ResultTypes.BusVoltageModule:
return ResultsTable(data=np.abs(self.voltage),
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.bus_names,
cols_device_type=DeviceType.BusDevice,
title=str(result_type.value),
ylabel='(p.u.)',
xlabel='',
units='(p.u.)')
elif result_type == ResultTypes.BusVoltageAngle:
return ResultsTable(data=np.angle(self.voltage, deg=True),
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.bus_names,
cols_device_type=DeviceType.BusDevice,
title=str(result_type.value),
ylabel='(deg)',
xlabel='',
units='(deg)')
elif result_type == ResultTypes.BusShadowPrices:
return ResultsTable(data=self.bus_shadow_prices,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.bus_names,
cols_device_type=DeviceType.BusDevice,
title=str(result_type.value),
ylabel='(currency / MW)',
xlabel='',
units='(currency / MW)')
elif result_type == ResultTypes.BusPower:
return ResultsTable(data=self.Sbus.real,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.bus_names,
cols_device_type=DeviceType.BusDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.BranchActivePowerFrom:
return ResultsTable(data=self.Sf.real,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.branch_names,
cols_device_type=DeviceType.BranchDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.BranchLoading:
return ResultsTable(data=np.abs(self.loading * 100.0),
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.branch_names,
cols_device_type=DeviceType.BranchDevice,
title=str(result_type.value),
ylabel='(%)',
xlabel='',
units='(%)')
elif result_type == ResultTypes.BranchOverloads:
return ResultsTable(data=np.abs(self.overloads),
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.branch_names,
cols_device_type=DeviceType.BranchDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.BranchOverloadsCost:
return ResultsTable(data=np.abs(self.overloads_cost),
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.branch_names,
cols_device_type=DeviceType.BranchDevice,
title=str(result_type.value),
ylabel='(Currency)',
xlabel='',
units='(Currency)')
elif result_type == ResultTypes.BranchLosses:
return ResultsTable(data=self.losses.real,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.branch_names,
cols_device_type=DeviceType.BranchDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.BranchTapAngle:
return ResultsTable(data=np.rad2deg(self.tap_angle),
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.branch_names,
cols_device_type=DeviceType.BranchDevice,
title=str(result_type.value),
ylabel='(deg)',
xlabel='',
units='(deg)')
elif result_type == ResultTypes.BranchTapModule:
return ResultsTable(data=np.rad2deg(self.tap_module),
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.branch_names,
cols_device_type=DeviceType.BranchDevice,
title=str(result_type.value),
ylabel='(deg)',
xlabel='',
units='(deg)')
elif result_type == ResultTypes.HvdcPowerFrom:
return ResultsTable(data=self.hvdc_Pf,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.hvdc_names,
cols_device_type=DeviceType.HVDCLineDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.HvdcLoading:
return ResultsTable(data=self.hvdc_loading * 100.0,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.hvdc_names,
cols_device_type=DeviceType.HVDCLineDevice,
title=str(result_type.value),
ylabel='(%)',
xlabel='',
units='(%)')
elif result_type == ResultTypes.FluidCurrentLevel:
return ResultsTable(data=self.fluid_node_current_level * 1e-6, # convert m3 to hm3,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.fluid_node_names,
cols_device_type=DeviceType.FluidNodeDevice,
title=str(result_type.value),
ylabel='(hm3)',
xlabel='',
units='(hm3)')
elif result_type == ResultTypes.FluidFlowIn:
return ResultsTable(data=self.fluid_node_flow_in,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.fluid_node_names,
cols_device_type=DeviceType.FluidNodeDevice,
title=str(result_type.value),
ylabel='(m3/s)',
xlabel='',
units='(m3/s)')
elif result_type == ResultTypes.FluidFlowOut:
return ResultsTable(data=self.fluid_node_flow_out,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.fluid_node_names,
cols_device_type=DeviceType.FluidNodeDevice,
title=str(result_type.value),
ylabel='(m3/s)',
xlabel='',
units='(m3/s)')
elif result_type == ResultTypes.FluidP2XFlow:
return ResultsTable(data=self.fluid_node_p2x_flow,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.fluid_node_names,
cols_device_type=DeviceType.FluidNodeDevice,
title=str(result_type.value),
ylabel='(m3/s)',
xlabel='',
units='(m3/s)')
elif result_type == ResultTypes.FluidSpillage:
return ResultsTable(data=self.fluid_node_spillage,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.fluid_node_names,
cols_device_type=DeviceType.FluidNodeDevice,
title=str(result_type.value),
ylabel='(m3/s)',
xlabel='',
units='(m3/s)')
elif result_type == ResultTypes.FluidFlowPath:
return ResultsTable(data=self.fluid_path_flow,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.fluid_path_names,
cols_device_type=DeviceType.FluidPathDevice,
title=str(result_type.value),
ylabel='(m3/s)',
xlabel='',
units='(m3/s)')
elif result_type == ResultTypes.FluidFlowInjection:
return ResultsTable(data=self.fluid_injection_flow,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.fluid_injection_names,
cols_device_type=DeviceType.FluidInjectionDevice,
title=str(result_type.value),
ylabel='(m3/s)',
xlabel='',
units='(m3/s)')
elif result_type == ResultTypes.LoadPower:
return ResultsTable(data=self.load_power,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.load_names,
cols_device_type=DeviceType.LoadLikeDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.LoadShedding:
return ResultsTable(data=self.load_shedding,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.load_names,
cols_device_type=DeviceType.LoadLikeDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.LoadSheddingCost:
return ResultsTable(data=self.load_shedding_cost,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.load_names,
cols_device_type=DeviceType.LoadLikeDevice,
title=str(result_type.value),
ylabel='(Currency)',
xlabel='',
units='(Currency)')
elif result_type == ResultTypes.GeneratorPower:
return ResultsTable(data=self.generator_power,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.generator_names,
cols_device_type=DeviceType.GeneratorDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.GeneratorReactivePower:
return ResultsTable(data=self.generator_reactive_power,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.generator_names,
cols_device_type=DeviceType.GeneratorDevice,
title=str(result_type.value),
ylabel='(MVAr)',
xlabel='',
units='(MVAr)')
elif result_type == ResultTypes.GeneratorShedding:
return ResultsTable(data=self.generator_shedding,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.generator_names,
cols_device_type=DeviceType.GeneratorDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.GeneratorCost:
return ResultsTable(data=self.generator_cost,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.generator_names,
cols_device_type=DeviceType.GeneratorDevice,
title=str(result_type.value),
ylabel='(Currency)',
xlabel='',
units='(Currency)')
elif result_type == ResultTypes.GeneratorProducing:
return ResultsTable(data=self.generator_producing,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.generator_names,
cols_device_type=DeviceType.GeneratorDevice,
title=str(result_type.value),
ylabel='',
xlabel='',
units='')
elif result_type == ResultTypes.GeneratorStartingUp:
return ResultsTable(data=self.generator_starting_up,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.generator_names,
cols_device_type=DeviceType.GeneratorDevice,
title=str(result_type.value),
ylabel='',
xlabel='',
units='')
elif result_type == ResultTypes.GeneratorShuttingDown:
return ResultsTable(data=self.generator_shutting_down,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.generator_names,
cols_device_type=DeviceType.GeneratorDevice,
title=str(result_type.value),
ylabel='',
xlabel='',
units='')
elif result_type == ResultTypes.GeneratorInvested:
return ResultsTable(data=self.generator_invested,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.generator_names,
cols_device_type=DeviceType.GeneratorDevice,
title=str(result_type.value),
ylabel='',
xlabel='',
units='')
elif result_type == ResultTypes.ShuntReactivePower:
return ResultsTable(data=self.shunt_like_reactive_power,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.shunt_like_names,
cols_device_type=DeviceType.ShuntLikeDevice,
title=str(result_type.value),
ylabel='(MVAr)',
xlabel='',
units='(MVAr)')
elif result_type == ResultTypes.BatteryPower:
return ResultsTable(data=self.battery_power,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.battery_names,
cols_device_type=DeviceType.BatteryDevice,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.BatteryEnergy:
return ResultsTable(data=self.battery_energy,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.battery_names,
cols_device_type=DeviceType.BatteryDevice,
title=str(result_type.value),
ylabel='(MWh)',
xlabel='',
units='(MWh)')
elif result_type == ResultTypes.BatteryInvested:
return ResultsTable(data=self.battery_invested,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.battery_names,
cols_device_type=DeviceType.BatteryDevice,
title=str(result_type.value),
ylabel='(MWh)',
xlabel='',
units='(MWh)')
elif result_type == ResultTypes.SystemFuel:
return ResultsTable(data=self.system_fuel,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.fuel_names,
cols_device_type=DeviceType.FuelDevice,
title=str(result_type.value),
ylabel='(t)',
xlabel='',
units='(t)')
elif result_type == ResultTypes.SystemEmissions:
return ResultsTable(data=self.system_emissions,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.emission_names,
cols_device_type=DeviceType.EmissionGasDevice,
title=str(result_type.value),
ylabel='(t)',
xlabel='',
units='(t)')
elif result_type == ResultTypes.SystemEnergyCost:
return ResultsTable(data=self.system_energy_cost,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=['System cost'],
cols_device_type=DeviceType.NoDevice,
title=str(result_type.value),
ylabel='(Currency/MWh)',
xlabel='',
units='(Currency/MWh)')
elif result_type == ResultTypes.SystemEnergyTotalCost:
return ResultsTable(data=self.system_total_energy_cost,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=['System cost'],
cols_device_type=DeviceType.NoDevice,
title=str(result_type.value),
ylabel='(Currency)',
xlabel='',
units='(Currency)')
elif result_type == ResultTypes.PowerByTechnology:
return ResultsTable(data=self.power_by_technology,
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=self.technology_names,
cols_device_type=DeviceType.Technology,
title=str(result_type.value),
ylabel='(MW)',
xlabel='',
units='(MW)')
elif result_type == ResultTypes.ContingencyFlowsReport:
y = list()
index = list()
for i in range(len(self.contingency_flows_list)):
if self.contingency_flows_list[i] != 0.0:
t, m, c = self.contingency_indices_list[i]
y.append((t, m, c,
str(self.time_array[t]), self.branch_names[m], self.branch_names[c],
self.contingency_flows_list[i], self.Sf[t, m].real,
self.contingency_flows_list[i] / self.contingency_rates[c, t] * 100,
self.Sf[t, m].real / self.rates[m, t] * 100))
index.append(i)
columns = ['Time index', 'Monitored idx ', 'Contingency idx',
'Time', 'Monitored', 'Contingency',
'ContingencyFlow (MW)', 'Base flow (MW)',
'ContingencyFlow (%)', 'Base flow (%)']
return ResultsTable(data=np.array(y, dtype=object),
index=index,
idx_device_type=DeviceType.NoDevice,
columns=np.array(columns),
cols_device_type=DeviceType.NoDevice,
title=str(result_type.value))
elif result_type == ResultTypes.OpfBalancePlot:
# the generation already accounts for the shedding
generation = self.generator_power.sum(axis=1) + self.battery_power.sum(axis=1)
load = self.load_power.sum(axis=1) - self.load_shedding.sum(axis=1)
if self.plotting_allowed():
plt.ion()
fig = plt.figure(figsize=(8, 6))
ax3 = plt.subplot(1, 1, 1)
ax3.plot(generation, label='Generation')
ax3.plot(load, label='Load')
ax3.legend()
fig.suptitle(str(result_type.value))
plt.tight_layout()
plt.show()
return ResultsTable(data=np.c_[generation, load],
index=pd.to_datetime(self.time_array),
idx_device_type=DeviceType.TimeDevice,
columns=np.array(['Generation (MW)', 'Load (MW)']),
cols_device_type=DeviceType.NoDevice,
title=result_type.value,
ylabel='(MW)',
units='(MW)')
else:
raise Exception('Result type not understood:' + str(result_type))