def __init__(self, multi_circuit: MultiCircuit, verbose=False): ################################################################################################################ # Compilation ################################################################################################################ self.verbose = verbose self.multi_circuit = multi_circuit self.numerical_circuit = self.multi_circuit.compile() 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_controlled_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 __init__(self, multi_circuit: MultiCircuit, options: PowerFlowOptions, verbose=False, break_at_value=True, good_enough_value=0): self.break_at_value = break_at_value self.good_enough_value = good_enough_value self.multi_circuit = multi_circuit self.numerical_circuit = self.multi_circuit.compile() self.calculation_inputs = self.numerical_circuit.compute(add_storage=False, add_generation=True) self.pf = PowerFlowMP(self.multi_circuit, options) # 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] self.n_batteries = len(self.numerical_circuit.battery_power) self.n_controlled_gen = len(self.numerical_circuit.controlled_gen_power) # compute the problem dimension self.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_controlled_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]]) self.ngen = len(self.gen_x_idx) 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.range = self.xup - self.xlow # form S static ################################################################################################ # all the loads apply self.Sfix = None self.set_default_state() # build Sfix self.Vbus = np.ones(self.numerical_circuit.nbus, dtype=complex) self.Ibus = np.zeros(self.numerical_circuit.nbus, dtype=complex) # other vars needed ############################################################################################ self.converged = False self.result = None self.force_batteries_to_charge = False self.x = np.zeros(self.dim) self.fx = 0 self.t = 0 self.Emin = None self.Emax = None self.E = None self.bat_idx = None self.battery_loading_pu = 0.01 self.dt = 0