def __init__(self, grid: MultiCircuit, verbose=False): self.grid = grid self.problem = AcOPFBlackBox(grid, verbose=verbose) self.numerical_circuit = self.problem.numerical_circuit self.converged = False self.result = None self.load_shedding = np.zeros(len(grid.get_load_names()))
def get_connectivity(file_name): circuit = MultiCircuit() circuit.load_file(file_name) circuit.compile() # form C threshold = 1e-5 m = len(circuit.branches) n = len(circuit.buses) C = lil_matrix((m, n), dtype=int) buses_dict = {bus: i for i, bus in enumerate(circuit.buses)} branches_to_keep_idx = list() branches_to_remove_idx = list() states = np.zeros(m, dtype=int) br_idx = [None] * m graph = Graph() for i in range(len(circuit.branches)): # get the from and to bus indices f = buses_dict[circuit.branches[i].bus_from] t = buses_dict[circuit.branches[i].bus_to] graph.add_edge(f, t) C[i, f] = 1 C[i, t] = -1 br_idx[i] = i rx = circuit.branches[i].R + circuit.branches[i].X if circuit.branches[i].branch_type == BranchType.Branch: branches_to_remove_idx.append(i) states[i] = 0 else: branches_to_keep_idx.append(i) states[i] = 1 C = csc_matrix(C) return circuit, states, C, C.transpose() * C, graph
def get_branches_of_bus(B, j): """ Get the indices of the branches connected to the bus j :param B: Branch-bus CSC matrix :param j: bus index :return: list of branches in the bus """ return [B.indices[k] for k in range(B.indptr[j], B.indptr[j + 1])] if __name__ == '__main__': fname = 'D:\\GitHub\\GridCal\\Grids_and_profiles\\grids\\Reduction Model 2.xlsx' circuit = MultiCircuit() circuit.load_file(fname) circuit.compile() # form C threshold = 1e-5 m = len(circuit.branches) n = len(circuit.buses) C = lil_matrix((m, n), dtype=int) buses_dict = {bus: i for i, bus in enumerate(circuit.buses)} branches_to_keep_idx = list() branches_to_remove_idx = list() states = np.zeros(m, dtype=int) br_idx = [None] * m graph = Graph()
d = {1: 'PQ', 2: 'PV', 3: 'VD'} tpe_str = array([d[i] for i in tpe], dtype=object) data = c_[tpe_str, Sbus.real, Sbus.imag, vm, va] cols = ['Type', 'P', 'Q', '|V|', 'angle'] df = pd.DataFrame(data=data, columns=cols) return df if __name__ == '__main__': from GridCal.Engine.calculation_engine import MultiCircuit, PowerFlowOptions, PowerFlow, SolverType from matplotlib import pyplot as plt grid = MultiCircuit() # grid.load_file('lynn5buspq.xlsx') # grid.load_file('lynn5buspv.xlsx') # grid.load_file('IEEE30.xlsx') grid.load_file( '/home/santi/Documentos/GitHub/GridCal/Grids_and_profiles/grids/IEEE 14.xlsx' ) # grid.load_file('/home/santi/Documentos/GitHub/GridCal/Grids_and_profiles/grids/IEEE39.xlsx') # grid.load_file('/home/santi/Documentos/GitHub/GridCal/Grids_and_profiles/grids/1354 Pegase.xlsx') grid.compile() circuit = grid.circuits[0] print('\nYbus:\n', circuit.power_flow_input.Ybus.todense()) print('\nSbus:\n', circuit.power_flow_input.Sbus)
def __init__(self, multi_circuit: MultiCircuit, verbose=False): ################################################################################################################ # Compilation ################################################################################################################ self.verbose = verbose self.multi_circuit = multi_circuit self.numerical_circuit = self.multi_circuit.compile_snapshot() self.islands = self.numerical_circuit.compute() # indices of generators that contribute to the static power vector 'S' self.gen_s_idx = np.where((np.logical_not(self.numerical_circuit.controlled_gen_dispatchable) * self.numerical_circuit.controlled_gen_enabled) == True)[0] self.bat_s_idx = np.where((np.logical_not(self.numerical_circuit.battery_dispatchable) * self.numerical_circuit.battery_enabled) == True)[0] # indices of generators that are to be optimized via the solution vector 'x' self.gen_x_idx = np.where((self.numerical_circuit.controlled_gen_dispatchable * self.numerical_circuit.controlled_gen_enabled) == True)[0] self.bat_x_idx = np.where((self.numerical_circuit.battery_dispatchable * self.numerical_circuit.battery_enabled) == True)[0] # compute the problem dimension dim = len(self.gen_x_idx) + len(self.bat_x_idx) # get the limits of the devices to control gens = np.array(multi_circuit.get_generators()) bats = np.array(multi_circuit.get_batteries()) gen_x_up = np.array([elm.Pmax for elm in gens[self.gen_x_idx]]) gen_x_low = np.array([elm.Pmin for elm in gens[self.gen_x_idx]]) bat_x_up = np.array([elm.Pmax for elm in bats[self.bat_x_idx]]) bat_x_low = np.array([elm.Pmin for elm in bats[self.bat_x_idx]]) # form S static ################################################################################################ # all the loads apply self.Sfix = self.numerical_circuit.C_load_bus.T * ( - self.numerical_circuit.load_power / self.numerical_circuit.Sbase * self.numerical_circuit.load_enabled) # static generators (all apply) self.Sfix += self.numerical_circuit.C_sta_gen_bus.T * ( self.numerical_circuit.static_gen_power / self.numerical_circuit.Sbase * self.numerical_circuit.static_gen_enabled) # controlled generators self.Sfix += (self.numerical_circuit.C_ctrl_gen_bus[self.gen_s_idx, :]).T * ( self.numerical_circuit.controlled_gen_power[self.gen_s_idx] / self.numerical_circuit.Sbase) # batteries self.Sfix += (self.numerical_circuit.C_batt_bus[self.bat_s_idx, :]).T * ( self.numerical_circuit.battery_power[self.bat_s_idx] / self.numerical_circuit.Sbase) # build A_sys per island ####################################################################################### for island in self.islands: island.build_linear_ac_sys_mat() # builds the A matrix factorization and stores it internally ################################################################################################################ # internal variables for PySOT ################################################################################################################ self.xlow = np.r_[gen_x_low, bat_x_low] / self.multi_circuit.Sbase self.xup = np.r_[gen_x_up, bat_x_up] / self.multi_circuit.Sbase self.dim = dim self.info = str(dim) + "-dimensional OPF problem" self.min = 0 self.integer = [] self.continuous = np.arange(0, dim) check_opt_prob(self)
def get_generation_shedding(self): return self.result.generation_shedding def get_voltage(self): return self.result.voltage def get_overloads(self): return self.result.overloads if __name__ == '__main__': main_circuit = MultiCircuit() fname = 'D:\\GitHub\\GridCal\\Grids_and_profiles\\grids\\IEEE 30 Bus with storage.xlsx' # fname = '/home/santi/Documentos/GitHub/GridCal/Grids_and_profiles/grids/IEEE 30 Bus with storage.xlsx' print('Reading...') main_circuit.load_file(fname) # (1) Optimization problem problem = AcOPFBlackBox(main_circuit, verbose=False) # solve val_opt, x_res = solve_opf_dycors_serial(problem, verbose=True) # solve # val_opt, x_res = solve_opf_dycors_parallel(problem, verbose=True)
circuit.branches.pop(br_idx) branch_names.pop(br_idx) # delete the bus f from the circuit # circuit.buses.pop(f) print('\tRemoving:', bus_f) circuit.buses.remove(bus_f) C[:, t] += abs(C[:, f]) C = csc_matrix(np.delete(C.toarray(), f, 1)) graph.remove_node(f) bus_names.pop(f) dfc = pd.DataFrame(data=C.toarray(), columns=bus_names, index=branch_names) print(dfc) print(list(graph.edges)) if __name__ == '__main__': from matplotlib import pyplot as plt fname = 'D:\\GitHub\\GridCal\\Grids_and_profiles\\grids\\Reduction Model 2.xlsx' circuit_ = MultiCircuit() circuit_.load_file(fname) # circuit.compile() reduce_grid(circuit=circuit_, rx_criteria=False, rx_threshold=1e-5, type_criteria=True, selected_type=BranchType.Branch) # circuit_.compile() # circuit_.plot_graph() # plt.show()
d = {1: 'PQ', 2: 'PV', 3: 'VD'} tpe_str = array([d[i] for i in tpe], dtype=object) data = c_[tpe_str, Sbus.real, Sbus.imag, vm, va] cols = ['Type', 'P', 'Q', '|V|', 'angle'] df = pd.DataFrame(data=data, columns=cols) return df if __name__ == '__main__': from GridCal.Engine.calculation_engine import MultiCircuit, PowerFlowOptions, PowerFlow, SolverType from matplotlib import pyplot as plt grid = MultiCircuit() # grid.load_file('lynn5buspq.xlsx') # grid.load_file('lynn5buspv.xlsx') # grid.load_file('IEEE30.xlsx') # grid.load_file('/home/santi/Documentos/GitHub/GridCal/Grids_and_profiles/grids/IEEE 14.xlsx') # grid.load_file('/home/santi/Documentos/GitHub/GridCal/Grids_and_profiles/grids/IEEE39.xlsx') # grid.load_file('/home/santi/Documentos/GitHub/GridCal/Grids_and_profiles/grids/1354 Pegase.xlsx') grid.load_file( '/home/santi/Documentos/GitHub/GridCal/UnderDevelopment/GridCal/Monash2.xlsx' ) grid.compile() circuit = grid.circuits[0] print('\nYbus:\n', circuit.power_flow_input.Ybus.todense())
return V, converged, normF, Scalc ######################################################################################################################## # MAIN ######################################################################################################################## if __name__ == "__main__": from GridCal.Engine.calculation_engine import MultiCircuit, PowerFlowOptions, PowerFlow, SolverType import pandas as pd pd.set_option('display.max_rows', 500) pd.set_option('display.max_columns', 500) pd.set_option('display.width', 1000) grid = MultiCircuit() # grid.load_file('lynn5buspq.xlsx') grid.load_file('IEEE30.xlsx') # grid.load_file('/home/santi/Documentos/GitHub/GridCal/Grids_and_profiles/grids/IEEE 145 Bus.xlsx') grid.compile() circuit = grid.circuits[0] print('\nYbus:\n', circuit.power_flow_input.Ybus.todense()) print('\nYseries:\n', circuit.power_flow_input.Yseries.todense()) print('\nYshunt:\n', circuit.power_flow_input.Yshunt) print('\nSbus:\n', circuit.power_flow_input.Sbus) print('\nIbus:\n', circuit.power_flow_input.Ibus) print('\nVbus:\n', circuit.power_flow_input.Vbus) print('\ntypes:\n', circuit.power_flow_input.types) print('\npq:\n', circuit.power_flow_input.pq)