Source code for VeraGridEngine.Simulations.ContingencyAnalysis.contingency_analysis_results

# 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


import numpy as np
from VeraGridEngine.DataStructures.numerical_circuit import NumericalCircuit
from VeraGridEngine.Simulations.results_table import ResultsTable
from VeraGridEngine.Simulations.results_template import ResultsTemplate, ResultsProperty
from VeraGridEngine.Simulations.ContingencyAnalysis.contingencies_report import ContingencyResultsReport
from VeraGridEngine.basic_structures import IntVec, StrVec, CxMat, Mat, Vec, CxVec
from VeraGridEngine.enumerations import StudyResultsType, ResultTypes, DeviceType


[docs] class ContingencyAnalysisResults(ResultsTemplate): """ Contingency analysis results """ LOCAL_RESULTS_DECLARATIONS = ( ResultsProperty(name='branch_names', tpe=StrVec, old_names=list(), expandable=False), ResultsProperty(name='bus_names', tpe=StrVec, old_names=list(), expandable=False), ResultsProperty(name='con_names', tpe=StrVec, old_names=list(), expandable=False), ResultsProperty(name='bus_types', tpe=IntVec, old_names=list(), expandable=False), ResultsProperty(name='voltage', tpe=CxMat, old_names=list(), expandable=False), ResultsProperty(name='Sbus', tpe=CxMat, old_names=list(), expandable=False), ResultsProperty(name='Sf_base', tpe=Vec, old_names=list(), expandable=False), ResultsProperty(name='Sf', tpe=CxMat, old_names=list(), expandable=False), ResultsProperty(name='loading', tpe=CxMat, old_names=list(), expandable=False), ResultsProperty(name='srap_used_power', tpe=Mat, old_names=list(), expandable=False), ResultsProperty(name='report', tpe=ContingencyResultsReport, old_names=list(), expandable=False), ) __slots__ = ( "branch_names", "bus_names", "bus_types", "con_names", "voltage", "Sbus", "Sf_base", "Sf", "loading", "srap_used_power", "report", ) def __init__(self, ncon: int, nbus: int, nbr: int, bus_names: StrVec, branch_names: StrVec, bus_types: IntVec, con_names: StrVec): """ ContingencyAnalysisResults :param ncon: number of contingencies :param nbus: number of buses :param nbr: number of Branches :param bus_names: bus names :param branch_names: branch names :param bus_types: bus types array :param con_names: contingency names """ ResultsTemplate.__init__( self, name='Contingency Analysis Results', available_results=[ ResultTypes.BusActivePower, ResultTypes.BranchActivePowerFromBase, ResultTypes.BranchActivePowerFrom, ResultTypes.BranchLoading, ResultTypes.ContingencyAnalysisReport, ResultTypes.SrapUsedPower ], time_array=None, clustering_results=None, study_results_type=StudyResultsType.ContingencyAnalysis ) self.branch_names = branch_names self.bus_names = bus_names self.bus_types = bus_types self.con_names = con_names self.voltage: CxMat = np.ones((ncon, nbus), dtype=complex) self.Sbus: CxMat = np.zeros((ncon, nbus), dtype=complex) self.Sf_base: CxVec = np.zeros(nbr, dtype=complex) self.Sf: CxMat = np.zeros((ncon, nbr), dtype=complex) self.loading: CxMat = np.zeros((ncon, nbr), dtype=complex) self.srap_used_power = np.zeros((nbr, nbus), dtype=float) self.report: ContingencyResultsReport = ContingencyResultsReport()
[docs] def apply_new_rates(self, nc: NumericalCircuit): """ Apply new rates :param nc: NumericalCircuit """ rates = nc.Rates self.loading = self.Sf / (rates + 1e-9)
[docs] @staticmethod def get_steps(): """ Get the simulation steps :return: """ return list()
# def get_dict(self): # """ # Returns a dictionary with the results sorted in a dictionary # :return: dictionary of 2D numpy arrays (probably of complex numbers) # """ # data = { # 'Vm': np.abs(self.voltage).tolist(), # 'Va': np.angle(self.voltage).tolist(), # 'P': self.Sbus.real.tolist(), # 'Q': self.Sbus.imag.tolist(), # 'Sbr_real': self.Sf.real.tolist(), # 'Sbr_imag': self.Sf.imag.tolist(), # 'loading': np.abs(self.loading).tolist() # } # return data
[docs] def mdl(self, result_type: ResultTypes): """ Plot the results :param result_type: :return: """ index = ['# ' + x for x in self.con_names] if result_type == ResultTypes.BusVoltageModule: return ResultsTable( data=np.abs(self.voltage), index=index, columns=self.bus_names, title=result_type.value, units='(p.u.)', cols_device_type=DeviceType.ContingencyDevice, idx_device_type=DeviceType.BusDevice ) elif result_type == ResultTypes.BusVoltageAngle: return ResultsTable( data=np.angle(self.voltage, deg=True), index=index, columns=self.bus_names, title=result_type.value, units='(deg)', cols_device_type=DeviceType.ContingencyDevice, idx_device_type=DeviceType.BusDevice ) elif result_type == ResultTypes.BusActivePower: return ResultsTable( data=self.Sbus.real, index=index, columns=self.bus_names, title=result_type.value, units='(MW)', cols_device_type=DeviceType.ContingencyDevice, idx_device_type=DeviceType.BusDevice ) elif result_type == ResultTypes.BranchActivePowerFromBase: return ResultsTable( data=self.Sf_base.real, index=self.branch_names, columns=['Base case (MW)'], title=result_type.value, units='(MW)', cols_device_type=DeviceType.NoDevice, idx_device_type=DeviceType.BranchDevice ) elif result_type == ResultTypes.BranchActivePowerFrom: return ResultsTable( data=self.Sf.real, index=index, columns=self.branch_names, title=result_type.value, units='(MW)', cols_device_type=DeviceType.ContingencyDevice, idx_device_type=DeviceType.BranchDevice ) elif result_type == ResultTypes.BranchLoading: return ResultsTable( data=self.loading.real * 100, index=index, columns=self.branch_names, title=result_type.value, units='(%)', cols_device_type=DeviceType.ContingencyDevice, idx_device_type=DeviceType.BranchDevice ) elif result_type == ResultTypes.SrapUsedPower: return ResultsTable( data=self.srap_used_power, index=self.branch_names, columns=self.bus_names, title=result_type.value, units="(MW)", cols_device_type=DeviceType.BusDevice, idx_device_type=DeviceType.BranchDevice ) elif result_type == ResultTypes.ContingencyAnalysisReport: return ResultsTable( data=self.report.get_data(), index=self.report.get_index(), columns=self.report.get_headers(), title=result_type.value, cols_device_type=DeviceType.NoDevice, idx_device_type=DeviceType.NoDevice ) else: raise Exception('Result type not understood:' + str(result_type))