def single_island_pf(circuit: SnapshotData, Vbus, Sbus, Ibus, branch_rates, options: PowerFlowOptions, logger: Logger) -> "PowerFlowResults": """ Run a power flow for a circuit. In most cases, the **run** method should be used instead. :param circuit: SnapshotData instance :param Vbus: Initial voltage at each bus in complex per unit :param Sbus: Power injection at each bus in complex MVA :param Ibus: Current injection at each bus in complex MVA :param branch_rates: array of branch rates :param options: PowerFlowOptions instance :param logger: Logger instance :return: PowerFlowResults instance """ # solve the power flow results = outer_loop_power_flow(circuit=circuit, options=options, voltage_solution=Vbus, Sbus=Sbus, Ibus=Ibus, branch_rates=branch_rates, logger=logger) # did it worked? worked = np.all(results.converged) if not worked: logger.append('Did not converge, even after retry!, Error:' + str(results.error)) return results
def __init__(self, circuit: MultiCircuit, file_name, sleep_time): """ :param circuit: current circuit :param file_name: name of the file to sync :param sleep_time: seconds between executions """ QThread.__init__(self) self.circuit = circuit self.file_name = file_name self.sleep_time = sleep_time self.issues = list() self.version_conflict = False self.highest_version = 0 self.logger = Logger() self.error_msg = '' self.__cancel__ = False self.__pause__ = False
def save(self): """ Save the file in the corresponding format :return: logger with information """ if self.file_name.endswith('.xlsx'): logger = self.save_excel() elif self.file_name.endswith('.gridcal'): logger = self.save_zip() elif self.file_name.endswith('.sqlite'): logger = self.save_sqlite() elif self.file_name.endswith('.json'): logger = self.save_json() elif self.file_name.endswith('.xml'): logger = self.save_cim() elif self.file_name.endswith('.gch5'): logger = self.save_h5() else: logger = Logger() logger.add_error('File path extension not understood', self.file_name) return logger
def __init__(self, grid: MultiCircuit, options: NMinusKOptions, pf_options: PowerFlowOptions): """ N - k class constructor @param grid: MultiCircuit Object @param options: N-k options @:param pf_options: power flow options """ QThread.__init__(self) # Grid to run self.grid = grid # Options to use self.options = options # power flow options self.pf_options = pf_options # OPF results self.results = NMinusKResults(0, 0, 0) # set cancel state self.__cancel__ = False self.all_solved = True self.logger = Logger() self.elapsed = 0.0 self.branch_names = list()
def power_flow_worker(variation: int, nbus, nbr, n_tr, bus_names, branch_names, transformer_names, bus_types, calculation_inputs: List[SnapshotData], options: PowerFlowOptions, dP, return_dict): """ Run asynchronous power flow :param variation: variation id :param nbus: number of buses :param nbr: number of branches :param n_tr: :param bus_names: :param branch_names: :param transformer_names: :param bus_types: :param calculation_inputs: list of CalculationInputs' instances :param options: PowerFlowOptions instance :param dP: delta of active power (array of values of size nbus) :param return_dict: dictionary to return values :return: Nothing because it is a worker, the return is done via the return_dict variable """ # create new results pf_results = PowerFlowResults(n=nbus, m=nbr, n_tr=n_tr, n_hvdc=0, bus_names=bus_names, branch_names=branch_names, transformer_names=transformer_names, hvdc_names=(), bus_types=bus_types) logger = Logger() # simulate each island and merge the results for i, calculation_input in enumerate(calculation_inputs): if len(calculation_input.vd) > 0: # run circuit power flow res = single_island_pf(circuit=calculation_input, Vbus=calculation_input.Vbus, Sbus=calculation_input.Sbus - dP[calculation_input.original_bus_idx], Ibus=calculation_input.Ibus, branch_rates=calculation_input.branch_rates, options=options, logger=Logger()) # merge the results from this island pf_results.apply_from_island( results=res, b_idx=calculation_input.original_bus_idx, br_idx=calculation_input.original_branch_idx, tr_idx=calculation_input.original_tr_idx) else: logger.add_info('No slack nodes in the island', str(i)) return_dict[variation] = (pf_results, logger)
def __init__(self, grid: MultiCircuit, options: OptimalPowerFlowOptions, start_=0, end_=None): """ PowerFlowDriver class constructor @param grid: MultiCircuit Object @param options: OPF options """ QThread.__init__(self) # Grid to run a power flow in self.grid = grid # Options to use self.options = options # power flow options self.pf_options = options.power_flow_options # compile the circuit into a numerical equivalent for this simulation self.numerical_circuit = compile_opf_time_circuit( circuit=self.grid, apply_temperature=self.pf_options.apply_temperature_correction, branch_tolerance_mode=self.pf_options. branch_impedance_tolerance_mode) # OPF results self.results = OptimalPowerFlowTimeSeriesResults( bus_names=self.numerical_circuit.bus_names, branch_names=self.numerical_circuit.branch_names, load_names=self.numerical_circuit.load_names, generator_names=self.numerical_circuit.generator_names, battery_names=self.numerical_circuit.battery_names, n=self.grid.get_bus_number(), m=self.grid.get_branch_number(), nt=len(self.grid.time_profile), ngen=len(self.grid.get_generators()), nbat=len(self.grid.get_batteries()), nload=len(self.grid.get_loads()), time=self.grid.time_profile, bus_types=self.numerical_circuit.bus_types) self.start_ = start_ if end_ is not None: self.end_ = end_ else: self.end_ = len(self.grid.time_profile) self.logger = Logger() # set cancel state self.__cancel__ = False self.all_solved = True self.elapsed = 0.0
def __init__(self, file_name): """ File open handler :param file_name: name of the file """ self.file_name = file_name self.circuit = MultiCircuit() self.logger = Logger()
def __init__(self, name, logs: Logger()): super(LogsDialogue, self).__init__() self.setObjectName("self") self.setContextMenuPolicy(QtCore.Qt.NoContextMenu) self.layout = QtWidgets.QVBoxLayout(self) # logs_list self.logs_table = QtWidgets.QTableView() model = LogsModel(logs) self.logs_table.setModel(model) for i in range(model.columnCount()): self.logs_table.horizontalHeader().setSectionResizeMode( i, QtWidgets.QHeaderView.Stretch) # accept button self.accept_btn = QtWidgets.QPushButton() self.accept_btn.setText('Accept') self.accept_btn.clicked.connect(self.accept_click) # add all to the GUI self.layout.addWidget(QtWidgets.QLabel("Logs")) self.layout.addWidget(self.logs_table) self.layout.addWidget(self.accept_btn) self.setLayout(self.layout) self.setWindowTitle(name) h = 400 self.resize(int(1.61 * h), h)
def __init__(self, grid: MultiCircuit, options: NMinusKOptions): """ N - k class constructor @param grid: MultiCircuit Object @param options: N-k options @:param pf_options: power flow options """ QThread.__init__(self) # Grid to run self.grid = grid # Options to use self.options = options # N-K results self.results = NMinusKResults(n=0, m=0, bus_names=(), branch_names=(), bus_types=()) self.numerical_circuit = None # set cancel state self.__cancel__ = False self.logger = Logger() self.elapsed = 0.0 self.branch_names = list()
def __init__(self, grid: MultiCircuit, options: PowerFlowOptions, opf_time_series_results=None, number_of_steps=10): """ TimeSeries constructor @param grid: MultiCircuit instance @param options: PowerFlowOptions instance """ QThread.__init__(self) # reference the grid directly self.grid = grid self.options = options self.opf_time_series_results = opf_time_series_results self.results = None self.number_of_steps = number_of_steps self.elapsed = 0 self.logger = Logger() self.returned_results = list() self.pool = None self.steps = self.sample_steps() self.__cancel__ = False
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 run(self): """ run the file save procedure @return: """ # try: path, fname = os.path.split(self.file_name) self.progress_text.emit('Flushing ' + fname + ' into ' + fname + '...') self.logger = Logger() file_handler = FileSave(self.circuit, self.file_name, text_func=self.progress_text.emit, progress_func=self.progress_signal.emit) self.logger = file_handler.save() self.valid = True # post events self.progress_text.emit('Done!') # except: # self.valid = False # exc_type, exc_value, exc_traceback = sys.exc_info() # self.logger.append(str(exc_traceback) + '\n' + str(exc_value)) self.done_signal.emit()
def __init__(self, grid: MultiCircuit, options: PTDFOptions, pf_options: PowerFlowOptions, opf_results=None): """ Power Transfer Distribution Factors class constructor @param grid: MultiCircuit Object @param options: OPF options """ QThread.__init__(self) # Grid to run self.grid = grid # Options to use self.options = options # power flow options self.pf_options = pf_options self.opf_results = opf_results # OPF results self.results = None # set cancel state self.__cancel__ = False self.all_solved = True self.elapsed = 0.0 self.logger = Logger()
def __init__(self, grid: MultiCircuit, options: PowerFlowOptions, opf_time_series_results=None, start_=0, end_=None): """ TimeSeries constructor @param grid: MultiCircuit instance @param options: PowerFlowOptions instance """ QThread.__init__(self) # reference the grid directly self.grid = grid self.options = options self.opf_time_series_results = opf_time_series_results self.results = None self.start_ = start_ self.end_ = end_ self.elapsed = 0 self.logger = Logger() self.returned_results = list() self.pool = multiprocessing.Pool() self.__cancel__ = False
def __init__(self, n_br=0, n_bus=0, br_names=(), bus_names=(), bus_types=()): """ PTDF and LODF results class :param n_br: number of branches :param n_bus: number of buses :param br_names: branch names :param bus_names: bus names :param bus_types: bus types array """ self.name = 'Linear Analysis' # number of branches self.n_br = n_br self.n_bus = n_bus # names of the branches self.br_names = br_names self.bus_names = bus_names self.bus_types = bus_types self.logger = Logger() self.PTDF = np.zeros((n_br, n_bus)) self.LODF = np.zeros((n_br, n_br)) self.available_results = [ResultTypes.PTDFBranchesSensitivity, ResultTypes.OTDF]
def power_flow_worker_args(args): """ Power flow worker to schedule parallel power flows args -> t, options: PowerFlowOptions, circuit: Circuit, Vbus, Sbus, Ibus, return_dict **t: execution index **options: power flow options **circuit: circuit **Vbus: Voltages to initialize **Sbus: Power injections **Ibus: Current injections **return_dict: parallel module dictionary in which to return the values :return: """ t, options, circuit, Vbus, Sbus, Ibus, branch_rates = args res = single_island_pf(circuit=circuit, Vbus=Vbus, Sbus=Sbus, Ibus=Ibus, branch_rates=branch_rates, options=options, logger=Logger()) return t, res
def run(self): """ run the file open procedure """ self.circuit = MultiCircuit() if isinstance(self.file_name, list): path, fname = os.path.split(self.file_name[0]) self.progress_text.emit('Loading ' + fname + '...') else: path, fname = os.path.split(self.file_name) self.progress_text.emit('Loading ' + fname + '...') self.logger = Logger() file_handler = FileOpen(file_name=self.file_name) self.circuit = file_handler.open( text_func=self.progress_text.emit, progress_func=self.progress_signal.emit) self.logger += file_handler.logger self.valid = True # post events self.progress_text.emit('Done!') self.done_signal.emit()
def run(self): """ run the file save procedure @return: """ path, fname = os.path.split(self.file_name) self.progress_text.emit('Flushing ' + fname + ' into ' + fname + '...') self.logger = Logger() file_handler = FileSave(self.circuit, self.file_name, text_func=self.progress_text.emit, progress_func=self.progress_signal.emit, simulation_drivers=self.simulation_drivers, sessions=self.sessions) self.logger = file_handler.save() self.valid = True # post events self.progress_text.emit('Done!') self.done_signal.emit()
def __init__(self, circuit: MultiCircuit, file_name, simulation_drivers=list(), sessions=list()): """ Constructor :param circuit: MultiCircuit instance :param file_name: name of the file where to save :param simulation_drivers: List of Simulation Drivers """ QThread.__init__(self) self.circuit = circuit self.file_name = file_name self.valid = False self.simulation_drivers = simulation_drivers self.sessions = sessions self.logger = Logger() self.error_msg = '' self.__cancel__ = False
def __init__(self, grid: MultiCircuit, options: PowerFlowOptions, opf_results: OptimalPowerFlowResults = None): """ PowerFlowDriver class constructor :param grid: MultiCircuit instance :param options: PowerFlowOptions instance :param opf_results: OptimalPowerFlowResults instance """ QThread.__init__(self) # Grid to run a power flow in self.grid = grid # Options to use self.options = options self.opf_results = opf_results self.results = PowerFlowResults(n=0, m=0, n_tr=0, n_hvdc=0, bus_names=(), branch_names=(), transformer_names=(), hvdc_names=(), bus_types=()) self.logger = Logger() self.convergence_reports = list() self.__cancel__ = False
def __init__(self, n_variations=0, n_br=0, br_names=()): """ Number of variations :param n_variations: :param n_br: number of branches: """ # number of variations self.n_variations = n_variations # number of branches self.n_br = n_br # names of the branches self.br_names = br_names # default power flow results self.default_pf_results = None # results of the variation self.pf_results = [None] * n_variations # definition of the variation self.variations = [None] * n_variations self.logger = Logger() self.sensitivity_matrix = None self.available_results = [ResultTypes.PTDFBranchesSensitivity]
def __init__(self, grid: MultiCircuit, options: ShortCircuitOptions, pf_options: PowerFlowOptions, pf_results: PowerFlowResults, opf_results=None): """ PowerFlowDriver class constructor @param grid: MultiCircuit Object """ DriverTemplate.__init__(self, grid=grid) # power flow results self.pf_results = pf_results self.pf_options = pf_options self.opf_results = opf_results # Options to use self.options = options self.results = None self.logger = Logger() self.__cancel__ = False self._is_running = False
def __init__(self, grid: MultiCircuit, options: ShortCircuitOptions, pf_options: PowerFlowOptions, pf_results: PowerFlowResults, opf_results=None): """ PowerFlowDriver class constructor @param grid: MultiCircuit Object """ QRunnable.__init__(self) # Grid to run a power flow in self.grid = grid # power flow results self.pf_results = pf_results self.pf_options = pf_options self.opf_results = opf_results # Options to use self.options = options self.results = None self.logger = Logger() self.__cancel__ = False
def __init__(self, grid: MultiCircuit, options: PowerFlowOptions, mc_tol=1e-3, batch_size=100, max_mc_iter=10000): """ Monte Carlo simulation constructor :param grid: MultiGrid instance :param options: Power flow options :param mc_tol: monte carlo std.dev tolerance :param batch_size: size of the batch :param max_mc_iter: maximum monte carlo iterations in case of not reach the precission """ QThread.__init__(self) self.circuit = grid self.options = options self.mc_tol = mc_tol self.batch_size = batch_size self.max_mc_iter = max_mc_iter n = len(self.circuit.buses) m = self.circuit.get_branch_number() self.results = MonteCarloResults(n, m, name='Monte Carlo') self.logger = Logger() self.pool = None self.returned_results = list() self.__cancel__ = False
def __init__(self, grid: MultiCircuit, options: PowerFlowOptions, sampling_points=1000, opf_time_series_results=None): """ Latin Hypercube constructor Args: grid: MultiCircuit instance options: Power flow options sampling_points: number of sampling points """ QThread.__init__(self) self.circuit = grid self.options = options self.sampling_points = sampling_points self.opf_time_series_results = opf_time_series_results self.results = None self.logger = Logger() self.pool = None self.returned_results = list() self.__cancel__ = False
def __init__(self, grid: MultiCircuit, options: LinearAnalysisOptions): """ Power Transfer Distribution Factors class constructor @param grid: MultiCircuit Object @param options: OPF options """ QThread.__init__(self) # Grid to run self.grid = grid # Options to use self.options = options # OPF results self.results = LinearAnalysisResults(n_br=0, n_bus=0, br_names=[], bus_names=[], bus_types=[]) # set cancel state self.__cancel__ = False self.all_solved = True self.elapsed = 0.0 self.logger = Logger()
def __init__(self, grid: MultiCircuit, pf_options: PowerFlowOptions, start_=0, end_=None, power_delta=10): """ TimeSeries constructor @param grid: MultiCircuit instance @param pf_options: PowerFlowOptions instance """ QThread.__init__(self) # reference the grid directly self.grid = grid self.pf_options = pf_options self.results = None self.ptdf_driver = None self.start_ = start_ self.end_ = end_ self.power_delta = power_delta self.elapsed = 0 self.logger = Logger() self.__cancel__ = False
def read_data_frame_from_zip(file_pointer, extension, index_col=None, logger=Logger()): """ read DataFrame :param file_pointer: Pointer to the file within the zip file :param extension: Extension, just to determine the reader method :param index_col: Index col (only for config file) :param logger: :return: DataFrame """ try: if extension == '.csv': return pd.read_csv(file_pointer, index_col=index_col) elif extension == '.pkl': try: return pd.read_pickle(file_pointer) except ValueError as e: logger.add_error(str(e), device=file_pointer.name) return None except AttributeError as e: logger.add_error(str(e) + ' Upgrading pandas might help.', device=file_pointer.name) return None except EOFError: return None except zipfile.BadZipFile: return None
def __init__(self, grid: MultiCircuit, options: OptimalPowerFlowOptions): """ PowerFlowDriver class constructor @param grid: MultiCircuit Object @param options: OPF options """ QThread.__init__(self) # Grid to run a power flow in self.grid = grid # Options to use self.options = options # OPF results self.results = None # set cancel state self.__cancel__ = False self.all_solved = True self.elapsed = 0.0 self.logger = Logger()
def __init__(self, text_func=None, progress_func=None, logger=Logger()): """ CIM circuit constructor """ self.elements = list() self.elm_dict = dict() self.elements_by_type = dict() self.logger = logger self.text_func = text_func self.progress_func = progress_func # classes to read, theo others are ignored self.classes = [ "ACLineSegment", "Analog", "BaseVoltage", "Breaker", "BusbarSection", "ConformLoad", "ConformLoadSchedule", "ConnectivityNode", "Control", "CurrentLimit", "DayType", "Disconnector", "Discrete", "EnergyConsumer", "EquivalentInjection", "EquivalentNetwork", "EquipmentContainer", "GeneratingUnit", "GeographicalRegion", "SubGeographicalRegion", "IEC61970CIMVersion", "Line", "LoadBreakSwitch", "LoadResponseCharacteristic", "Location", "Model", "OperationalLimitSet", "PerLengthSequenceImpedance", "PositionPoint", "PowerTransformer", "PowerTransformerEnd", "PSRType", "RatioTapChanger", "RegulatingControl", "Season", "SeriesCompensator", "ShuntCompensator", "Substation", "Switch", "SynchronousMachine", "Terminal", "TopologicalNode", "TransformerWinding", "VoltageLevel", "VoltageLimit" ]