def __init__(self, grid: MultiCircuit, options: LinearAnalysisOptions, start_=0, end_=None): """ TimeSeries constructor @param grid: MultiCircuit instance @param options: LinearAnalysisOptions instance """ QThread.__init__(self) # reference the grid directly self.grid = grid self.options = options self.results = PtdfTimeSeriesResults(n=0, m=0, time_array=[], bus_names=[], bus_types=[], branch_names=[]) self.ptdf_driver = LinearAnalysis(grid=self.grid, distributed_slack=self.options.distribute_slack) self.start_ = start_ self.end_ = end_ self.indices = pd.to_datetime(self.grid.time_profile) self.elapsed = 0 self.logger = Logger() self.__cancel__ = False
def n_minus_k(self): """ Run N-1 simulation in series :return: returns the results """ self.progress_text.emit("Filtering elements by voltage") self.numerical_circuit = compile_snapshot_circuit(self.grid) results = NMinusKResults( m=self.numerical_circuit.nbr, n=self.numerical_circuit.nbus, branch_names=self.numerical_circuit.branch_names, bus_names=self.numerical_circuit.bus_names, bus_types=self.numerical_circuit.bus_types) self.progress_text.emit('Analyzing outage distribution factors...') linear_analysis = LinearAnalysis( grid=self.grid, distributed_slack=self.options.distributed_slack, correct_values=self.options.correct_values) linear_analysis.run() Pbus = self.numerical_circuit.get_injections(False).real[:, 0] PTDF = linear_analysis.results.PTDF LODF = linear_analysis.results.LODF # compute the branch flows in "n" flows_n = np.dot(PTDF, Pbus) self.progress_text.emit('Computing flows...') nl = self.numerical_circuit.nbr for c in range(nl): # branch that fails (contingency) # for m in range(nl): # branch to monitor # results.Sf[m, c] = flows_n[m] + LODF[m, c] * flows_n[c] # results.loading[m, c] = results.Sf[m, c] / (self.numerical_circuit.branch_rates[m] + 1e-9) results.Sbranch[:, c] = flows_n[:] + LODF[:, c] * flows_n[c] results.loading[:, c] = results.Sbranch[:, c] / ( self.numerical_circuit.branch_rates + 1e-9) results.S[c, :] = Pbus self.progress_signal.emit((c + 1) / nl * 100) results.otdf = LODF return results
def run(self): """ Run the time series simulation @return: """ self.__cancel__ = False a = time.time() if self.end_ is None: self.end_ = len(self.grid.time_profile) + 1 time_indices = np.arange(self.start_, self.end_) ts_numeric_circuit = compile_time_circuit(self.grid) self.results = PtdfTimeSeriesResults( n=ts_numeric_circuit.nbus, m=ts_numeric_circuit.nbr, time_array=ts_numeric_circuit.time_array[time_indices], bus_names=ts_numeric_circuit.bus_names, bus_types=ts_numeric_circuit.bus_types, branch_names=ts_numeric_circuit.branch_names) self.indices = pd.to_datetime( ts_numeric_circuit.time_array[time_indices]) self.progress_text.emit('Computing PTDF...') ptdf_analysis = LinearAnalysis( grid=self.grid, distributed_slack=self.options.distribute_slack) ptdf_analysis.run() self.progress_text.emit('Computing branch flows...') Pbus_0 = ts_numeric_circuit.get_power_injections().real[:, time_indices] self.results.Sbranch = ptdf_analysis.get_branch_time_series(Pbus_0) # compute post process self.results.loading = self.results.Sbranch / ( ptdf_analysis.numerical_circuit.branch_rates + 1e-9) self.results.S = Pbus_0.T self.elapsed = time.time() - a # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit()
class PtdfTimeSeries(QThread): progress_signal = Signal(float) progress_text = Signal(str) done_signal = Signal() name = 'PTDF Time Series' def __init__(self, grid: MultiCircuit, options: LinearAnalysisOptions, start_=0, end_=None): """ TimeSeries constructor @param grid: MultiCircuit instance @param options: LinearAnalysisOptions instance """ QThread.__init__(self) # reference the grid directly self.grid = grid self.options = options self.results = PtdfTimeSeriesResults(n=0, m=0, time_array=[], bus_names=[], bus_types=[], branch_names=[]) self.ptdf_driver = LinearAnalysis(grid=self.grid, distributed_slack=self.options.distribute_slack) self.start_ = start_ self.end_ = end_ self.indices = pd.to_datetime(self.grid.time_profile) self.elapsed = 0 self.logger = Logger() self.__cancel__ = False def get_steps(self): """ Get time steps list of strings """ return [l.strftime('%d-%m-%Y %H:%M') for l in self.indices] def run(self): """ Run the time series simulation @return: """ self.__cancel__ = False a = time.time() if self.end_ is None: self.end_ = len(self.grid.time_profile) + 1 time_indices = np.arange(self.start_, self.end_) ts_numeric_circuit = compile_time_circuit(self.grid) self.results = PtdfTimeSeriesResults(n=ts_numeric_circuit.nbus, m=ts_numeric_circuit.nbr, time_array=ts_numeric_circuit.time_array[time_indices], bus_names=ts_numeric_circuit.bus_names, bus_types=ts_numeric_circuit.bus_types, branch_names=ts_numeric_circuit.branch_names) self.indices = pd.to_datetime(ts_numeric_circuit.time_array[time_indices]) self.progress_text.emit('Computing PTDF...') ptdf_analysis = LinearAnalysis(grid=self.grid, distributed_slack=self.options.distribute_slack) ptdf_analysis.run() self.progress_text.emit('Computing branch flows...') Pbus_0 = ts_numeric_circuit.Sbus.real[:, time_indices] self.results.Sf = ptdf_analysis.get_branch_time_series(Pbus_0) # compute post process self.results.loading = self.results.Sf / (ptdf_analysis.numerical_circuit.branch_rates + 1e-9) self.results.S = Pbus_0.T self.elapsed = time.time() - a # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() def cancel(self): """ Cancel the simulation """ self.__cancel__ = True if self.ptdf_driver is not None: self.ptdf_driver.cancel() if self.pool is not None: self.pool.terminate() self.progress_signal.emit(0.0) self.progress_text.emit('Cancelled!') self.done_signal.emit()