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, circuit: MultiCircuit, options: PowerFlowOptions, max_iter=1000, callback=None): self.circuit = circuit self.options = options self.callback = callback # initialize the power flow self.power_flow = PowerFlowDriver(self.circuit, self.options) # compile circuits self.numerical_circuit = self.circuit.compile() self.numerical_input_islands = self.numerical_circuit.compute() n = len(self.circuit.buses) m = len(self.circuit.branches) self.max_eval = max_iter # the dimension is the number of nodes self.dim = self.numerical_circuit.n_ctrl_gen self.x0 = np.abs(self.numerical_circuit.generator_voltage) - np.ones( self.dim) self.min = 0 self.minimum = np.zeros(self.dim) self.lb = -0.1 * np.ones(self.dim) self.ub = 0.1 * np.ones(self.dim) self.int_var = np.array([]) self.cont_var = np.arange(0, self.dim) self.info = str( self.dim) + "Generators voltage set points optimization" # results self.results = MonteCarloResults(n, m, self.max_eval, name='Set point optimization') self.all_f = list() self.it = 0
def remove_probability_based(numerical_circuit: TimeCircuit, results: MonteCarloResults, max_val, min_prob): """ Remove branches based on their chance of overload :param numerical_circuit: :param results: :param max_val: :param min_prob: :return: list of indices actually removed """ idx, val, prob, loading = results.get_index_loading_cdf( max_val=max_val) any_removed = False indices = list() criteria = 'None' for i, idx_val in enumerate(idx): if prob[i] >= min_prob: any_removed = True numerical_circuit.branch_active[idx_val] = False indices.append(idx_val) criteria = 'Overload probability > ' + str(min_prob) if not any_removed: if len(loading) > 0: if len(idx) > 0: # pick a random value idx_val = np.random.randint(0, len(idx)) criteria = 'Random with overloads' else: # pick the most loaded idx_val = int(np.where(loading == max(loading))[0][0]) criteria = 'Max loading, Overloads not seen' numerical_circuit.branch_active[idx_val] = False indices.append(idx_val) else: indices = [] criteria = 'No branches' return indices, criteria
def __init__(self, circuit: MultiCircuit, options: PowerFlowOptions, max_iter=1000, callback=None): self.circuit = circuit self.options = options self.callback = callback # initialize the power flow self.power_flow = PowerFlowDriver(self.circuit, self.options) n = len(self.circuit.buses) m = len(self.circuit.branches) self.max_eval = max_iter # the dimension is the number of nodes self.dim = n self.min = 0 self.minimum = np.zeros(self.dim) self.lb = -15 * np.ones(self.dim) self.ub = 20 * np.ones(self.dim) self.int_var = np.array([]) self.cont_var = np.arange(0, self.dim) self.info = str(self.dim) + "Voltage collapse optimization" # results self.results = MonteCarloResults(n, m, self.max_eval, name='Voltage optimization') # compile circuits self.numerical_circuit = self.circuit.compile() self.numerical_input_islands = self.numerical_circuit.compute( ignore_single_node_islands=options.ignore_single_node_islands) self.it = 0
def run_single_thread(self): """ Run the monte carlo simulation @return: """ self.__cancel__ = False # initialize the grid time series results # we will append the island results with another function self.circuit.time_series_results = TimeSeriesResults(0, 0, 0, 0, 0) Sbase = self.circuit.Sbase it = 0 variance_sum = 0.0 std_dev_progress = 0 v_variance = 0 n = len(self.circuit.buses) m = len(self.circuit.branches) # compile circuits numerical_circuit = self.circuit.compile() # perform the topological computation calc_inputs_dict = numerical_circuit.compute_ts( branch_tolerance_mode=self.options.branch_impedance_tolerance_mode, ignore_single_node_islands=self.options.ignore_single_node_islands) mc_results = MonteCarloResults(n, m) avg_res = PowerFlowResults() avg_res.initialize(n, m) v_sum = zeros(n, dtype=complex) self.progress_signal.emit(0.0) while (std_dev_progress < 100.0) and (it < self.max_mc_iter) and not self.__cancel__: self.progress_text.emit('Running Monte Carlo: Variance: ' + str(v_variance)) mc_results = MonteCarloResults(n, m, self.batch_size) # for each partition of the profiles... for t_key, calc_inputs in calc_inputs_dict.items(): # For every island, run the time series for island_index, numerical_island in enumerate(calc_inputs): # set the time series as sampled monte_carlo_input = make_monte_carlo_input( numerical_island) mc_time_series = monte_carlo_input( self.batch_size, use_latin_hypercube=False) Vbus = numerical_island.Vbus # run the time series for t in range(self.batch_size): # set the power values Y, I, S = mc_time_series.get_at(t) res = single_island_pf( circuit=numerical_island, Vbus=Vbus, Sbus=S / Sbase, Ibus=I / Sbase, branch_rates=numerical_island.branch_rates, options=self.options, logger=self.logger) mc_results.S_points[ t, numerical_island.original_bus_idx] = res.Sbus mc_results.V_points[ t, numerical_island.original_bus_idx] = res.voltage mc_results.I_points[ t, numerical_island.original_branch_idx] = res.Ibranch mc_results.loading_points[ t, numerical_island.original_branch_idx] = res.loading mc_results.losses_points[ t, numerical_island.original_branch_idx] = res.losses # short cut the indices b_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx self.progress_text.emit('Compiling results...') mc_results.compile() # compute the island branch results island_avg_res = numerical_island.compute_branch_results( mc_results.voltage[b_idx]) # apply the island averaged results avg_res.apply_from_island(island_avg_res, b_idx=b_idx, br_idx=br_idx) # Compute the Monte Carlo values it += self.batch_size mc_results.append_batch(mc_results) v_sum += mc_results.get_voltage_sum() v_avg = v_sum / it v_variance = abs( (power(mc_results.V_points - v_avg, 2.0) / (it - 1)).min()) # progress variance_sum += v_variance err = variance_sum / it if err == 0: err = 1e-200 # to avoid division by zeros mc_results.error_series.append(err) # emmit the progress signal std_dev_progress = 100 * self.mc_tol / err if std_dev_progress > 100: std_dev_progress = 100 self.progress_signal.emit( max((std_dev_progress, it / self.max_mc_iter * 100))) # print(iter, '/', max_mc_iter) # print('Vmc:', Vavg) # print('Vstd:', Vvariance, ' -> ', std_dev_progress, ' %') # compile results mc_results.sbranch = avg_res.Sbranch # mc_results.losses = avg_res.losses mc_results.bus_types = numerical_circuit.bus_types # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return mc_results
def run_multi_thread(self): """ Run the monte carlo simulation @return: """ # print('LHS run') self.__cancel__ = False # initialize vars batch_size = self.sampling_points n = len(self.circuit.buses) m = len(self.circuit.branches) n_cores = multiprocessing.cpu_count() self.progress_signal.emit(0.0) self.progress_text.emit( 'Running Latin Hypercube Sampling in parallel using ' + str(n_cores) + ' cores ...') lhs_results = MonteCarloResults(n, m, batch_size) avg_res = PowerFlowResults() avg_res.initialize(n, m) # compile # print('Compiling...', end='') numerical_circuit = self.circuit.compile() numerical_islands = numerical_circuit.compute( branch_tolerance_mode=self.options.branch_impedance_tolerance_mode) lhs_results.bus_types = numerical_circuit.bus_types max_iter = batch_size * len(numerical_islands) Sbase = self.circuit.Sbase it = 0 # For every circuit, run the time series for numerical_island in numerical_islands: # try: # set the time series as sampled in the circuit monte_carlo_input = make_monte_carlo_input(numerical_island) mc_time_series = monte_carlo_input(batch_size, use_latin_hypercube=True) Vbus = numerical_island.Vbus # short cut the indices b_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx manager = multiprocessing.Manager() return_dict = manager.dict() t = 0 while t < batch_size and not self.__cancel__: k = 0 jobs = list() # launch only n_cores jobs at the time while k < n_cores + 2 and (t + k) < batch_size: # set the power values Y, I, S = mc_time_series.get_at(t) # run power flow at the circuit p = multiprocessing.Process( target=power_flow_worker, args=(t, self.options, numerical_island, Vbus, S / Sbase, I / Sbase, return_dict)) jobs.append(p) p.start() k += 1 t += 1 # wait for all jobs to complete for proc in jobs: proc.join() progress = ((t + 1) / batch_size) * 100 self.progress_signal.emit(progress) # collect results self.progress_text.emit('Collecting results...') for t in return_dict.keys(): # store circuit results at the time index 't' res = return_dict[t] lhs_results.S_points[ t, numerical_island.original_bus_idx] = res.Sbus lhs_results.V_points[ t, numerical_island.original_bus_idx] = res.voltage lhs_results.I_points[ t, numerical_island.original_branch_idx] = res.Ibranch lhs_results.loading_points[ t, numerical_island.original_branch_idx] = res.loading lhs_results.losses_points[ t, numerical_island.original_branch_idx] = res.losses # except Exception as ex: # print(c.name, ex) if self.__cancel__: break # compile MC results self.progress_text.emit('Compiling results...') lhs_results.compile() # compute the island branch results island_avg_res = numerical_island.compute_branch_results( lhs_results.voltage[b_idx]) # apply the island averaged results avg_res.apply_from_island(island_avg_res, b_idx=b_idx, br_idx=br_idx) # lhs_results the averaged branch magnitudes lhs_results.sbranch = avg_res.Sbranch lhs_results.losses = avg_res.losses self.results = lhs_results # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return lhs_results
def run_single_thread(self): """ Run the monte carlo simulation @return: """ # print('LHS run') self.__cancel__ = False # initialize the power flow power_flow = PowerFlowMP(self.circuit, self.options) # initialize the grid time series results # we will append the island results with another function self.circuit.time_series_results = TimeSeriesResults(0, 0, 0, 0, 0) batch_size = self.sampling_points n = len(self.circuit.buses) m = len(self.circuit.branches) self.progress_signal.emit(0.0) self.progress_text.emit('Running Latin Hypercube Sampling...') lhs_results = MonteCarloResults(n, m, batch_size) avg_res = PowerFlowResults() avg_res.initialize(n, m) # compile the numerical circuit numerical_circuit = self.circuit.compile() numerical_input_islands = numerical_circuit.compute( branch_tolerance_mode=self.options.branch_impedance_tolerance_mode) max_iter = batch_size * len(numerical_input_islands) Sbase = numerical_circuit.Sbase it = 0 # For every circuit, run the time series for numerical_island in numerical_input_islands: # try: # set the time series as sampled in the circuit # build the inputs monte_carlo_input = make_monte_carlo_input(numerical_island) mc_time_series = monte_carlo_input(batch_size, use_latin_hypercube=True) Vbus = numerical_island.Vbus # short cut the indices b_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx # run the time series for t in range(batch_size): # set the power values from a Monte carlo point at 't' Y, I, S = mc_time_series.get_at(t) # Run the set monte carlo point at 't' res = power_flow.run_pf(circuit=numerical_island, Vbus=Vbus, Sbus=S / Sbase, Ibus=I / Sbase) # Gather the results lhs_results.S_points[ t, numerical_island.original_bus_idx] = res.Sbus lhs_results.V_points[ t, numerical_island.original_bus_idx] = res.voltage lhs_results.I_points[ t, numerical_island.original_branch_idx] = res.Ibranch lhs_results.loading_points[ t, numerical_island.original_branch_idx] = res.loading lhs_results.losses_points[ t, numerical_island.original_branch_idx] = res.losses it += 1 self.progress_signal.emit(it / max_iter * 100) if self.__cancel__: break if self.__cancel__: break # compile MC results self.progress_text.emit('Compiling results...') lhs_results.compile() # compute the island branch results island_avg_res = numerical_island.compute_branch_results( lhs_results.voltage[b_idx]) # apply the island averaged results avg_res.apply_from_island(island_avg_res, b_idx=b_idx, br_idx=br_idx) # lhs_results the averaged branch magnitudes lhs_results.sbranch = avg_res.Sbranch lhs_results.bus_types = numerical_circuit.bus_types # Ibranch = avg_res.Ibranch # loading = avg_res.loading # lhs_results.losses = avg_res.losses # flow_direction = avg_res.flow_direction # Sbus = avg_res.Sbus self.results = lhs_results # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return lhs_results
def run_multi_thread(self): """ Run the monte carlo simulation @return: """ # print('LHS run') self.__cancel__ = False # initialize vars batch_size = self.sampling_points n = len(self.circuit.buses) m = self.circuit.get_branch_number() n_cores = multiprocessing.cpu_count() self.pool = multiprocessing.Pool() self.progress_signal.emit(0.0) self.progress_text.emit( 'Running Latin Hypercube Sampling in parallel using ' + str(n_cores) + ' cores ...') lhs_results = MonteCarloResults(n, m, batch_size, name='Latin Hypercube') avg_res = PowerFlowResults() avg_res.initialize(n, m) # compile the multi-circuit numerical_circuit = self.circuit.compile_time_series() # perform the topological computation calc_inputs_dict = numerical_circuit.compute( branch_tolerance_mode=self.options.branch_impedance_tolerance_mode, ignore_single_node_islands=self.options.ignore_single_node_islands) # for each partition of the profiles... for t_key, calc_inputs in calc_inputs_dict.items(): # For every island, run the time series for island_index, numerical_island in enumerate(calc_inputs): lhs_results.bus_types = numerical_circuit.bus_types monte_carlo_input = make_monte_carlo_input(numerical_island) mc_time_series = monte_carlo_input(batch_size, use_latin_hypercube=True) Vbus = numerical_island.Vbus branch_rates = numerical_island.branch_rates # short cut the indices b_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx # Start jobs self.returned_results = list() t = 0 while t < batch_size and not self.__cancel__: Ysh, Ibus, Sbus = mc_time_series.get_at(t) args = (t, self.options, numerical_island, Vbus, Sbus, Ibus, branch_rates) self.pool.apply_async(power_flow_worker_args, (args, ), callback=self.update_progress_mt) # wait for all jobs to complete self.pool.close() self.pool.join() # collect results self.progress_text.emit('Collecting results...') for t, res in self.returned_results: # store circuit results at the time index 't' lhs_results.S_points[ t, numerical_island.original_bus_idx] = res.Sbus lhs_results.V_points[ t, numerical_island.original_bus_idx] = res.voltage lhs_results.Sbr_points[ t, numerical_island.original_branch_idx] = res.Sf lhs_results.loading_points[ t, numerical_island.original_branch_idx] = res.loading lhs_results.losses_points[ t, numerical_island.original_branch_idx] = res.losses # compile MC results self.progress_text.emit('Compiling results...') lhs_results.compile() # compute the island branch results island_avg_res = numerical_island.compute_branch_results( lhs_results.voltage[b_idx]) # apply the island averaged results avg_res.apply_from_island(island_avg_res, b_idx=b_idx, br_idx=br_idx) # lhs_results the averaged branch magnitudes lhs_results.sbranch = avg_res.Sf lhs_results.losses = avg_res.losses self.results = lhs_results # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return lhs_results
def run_single_thread(self): """ Run the monte carlo simulation @return: """ # print('LHS run') self.__cancel__ = False # initialize the grid time series results # we will append the island results with another function # batch_size = self.sampling_points self.progress_signal.emit(0.0) self.progress_text.emit('Running Latin Hypercube Sampling...') # compile the multi-circuit numerical_circuit = compile_time_circuit( circuit=self.circuit, apply_temperature=False, branch_tolerance_mode=BranchImpedanceMode.Specified, opf_results=self.opf_time_series_results) # do the topological computation calculation_inputs = numerical_circuit.split_into_islands( ignore_single_node_islands=self.options.ignore_single_node_islands) lhs_results = MonteCarloResults( n=numerical_circuit.nbus, m=numerical_circuit.nbr, p=self.sampling_points, bus_names=numerical_circuit.bus_names, branch_names=numerical_circuit.branch_names, bus_types=numerical_circuit.bus_types, name='Latin Hypercube') avg_res = PowerFlowResults( n=numerical_circuit.nbus, m=numerical_circuit.nbr, n_tr=numerical_circuit.ntr, n_hvdc=numerical_circuit.nhvdc, bus_names=numerical_circuit.bus_names, branch_names=numerical_circuit.branch_names, transformer_names=numerical_circuit.tr_names, hvdc_names=numerical_circuit.hvdc_names, bus_types=numerical_circuit.bus_types) it = 0 # For every island, run the time series for island_index, numerical_island in enumerate(calculation_inputs): # try: # set the time series as sampled in the circuit # build the inputs monte_carlo_input = make_monte_carlo_input(numerical_island) mc_time_series = monte_carlo_input(self.sampling_points, use_latin_hypercube=True) Vbus = numerical_island.Vbus[:, 0] # short cut the indices bus_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx # run the time series for t in range(self.sampling_points): # set the power values from a Monte carlo point at 't' Y, I, S = mc_time_series.get_at(t) # Run the set monte carlo point at 't' res = single_island_pf( circuit=numerical_island, Vbus=Vbus, Sbus=S, Ibus=I, branch_rates=numerical_island.branch_rates, options=self.options, logger=self.logger) # Gather the results lhs_results.S_points[t, bus_idx] = S lhs_results.V_points[t, bus_idx] = res.voltage lhs_results.Sbr_points[t, br_idx] = res.Sf lhs_results.loading_points[t, br_idx] = res.loading lhs_results.losses_points[t, br_idx] = res.losses it += 1 self.progress_signal.emit(it / self.sampling_points * 100) if self.__cancel__: break if self.__cancel__: break # compile MC results self.progress_text.emit('Compiling results...') lhs_results.compile() # compute the island branch results Sfb, Stb, If, It, Vbranch, loading, \ losses, flow_direction, Sbus = power_flow_post_process(numerical_island, Sbus=lhs_results.S_points.mean(axis=0)[bus_idx], V=lhs_results.V_points.mean(axis=0)[bus_idx], branch_rates=numerical_island.branch_rates) # apply the island averaged results avg_res.Sbus[bus_idx] = Sbus avg_res.voltage[bus_idx] = lhs_results.voltage[bus_idx] avg_res.Sf[br_idx] = Sfb avg_res.St[br_idx] = Stb avg_res.If[br_idx] = If avg_res.It[br_idx] = It avg_res.Vbranch[br_idx] = Vbranch avg_res.loading[br_idx] = loading avg_res.losses[br_idx] = losses avg_res.flow_direction[br_idx] = flow_direction self.results = lhs_results # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return lhs_results
def run_single_thread(self): """ Run the monte carlo simulation @return: """ # print('LHS run') self.__cancel__ = False # initialize the grid time series results # we will append the island results with another function batch_size = self.sampling_points n = len(self.circuit.buses) m = len(self.circuit.branches) self.progress_signal.emit(0.0) self.progress_text.emit('Running Latin Hypercube Sampling...') lhs_results = MonteCarloResults(n, m, batch_size, name='Latin Hypercube') avg_res = PowerFlowResults() avg_res.initialize(n, m) # compile the multi-circuit numerical_circuit = self.circuit.compile() # perform the topological computation calc_inputs_dict = numerical_circuit.compute_ts( branch_tolerance_mode=self.options.branch_impedance_tolerance_mode, ignore_single_node_islands=self.options.ignore_single_node_islands) it = 0 # for each partition of the profiles... for t_key, calc_inputs in calc_inputs_dict.items(): # For every island, run the time series for island_index, numerical_island in enumerate(calc_inputs): # try: # set the time series as sampled in the circuit # build the inputs monte_carlo_input = make_monte_carlo_input(numerical_island) mc_time_series = monte_carlo_input(batch_size, use_latin_hypercube=True) Vbus = numerical_island.Vbus # short cut the indices b_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx # run the time series for t in range(batch_size): # set the power values from a Monte carlo point at 't' Y, I, S = mc_time_series.get_at(t) # Run the set monte carlo point at 't' res = single_island_pf( circuit=numerical_island, Vbus=Vbus, Sbus=S, Ibus=I, branch_rates=numerical_island.branch_rates, options=self.options, logger=self.logger) # Gather the results lhs_results.S_points[ t, numerical_island.original_bus_idx] = res.Sbus lhs_results.V_points[ t, numerical_island.original_bus_idx] = res.voltage lhs_results.I_points[ t, numerical_island.original_branch_idx] = res.Ibranch lhs_results.loading_points[ t, numerical_island.original_branch_idx] = res.loading lhs_results.losses_points[ t, numerical_island.original_branch_idx] = res.losses it += 1 self.progress_signal.emit(it / batch_size * 100) if self.__cancel__: break if self.__cancel__: break # compile MC results self.progress_text.emit('Compiling results...') lhs_results.compile() # compute the island branch results island_avg_res = numerical_island.compute_branch_results( lhs_results.voltage[b_idx]) # apply the island averaged results avg_res.apply_from_island(island_avg_res, b_idx=b_idx, br_idx=br_idx) # lhs_results the averaged branch magnitudes lhs_results.sbranch = avg_res.Sbranch lhs_results.bus_types = numerical_circuit.bus_types self.results = lhs_results # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return lhs_results
def run_multi_thread(self): """ Run the monte carlo simulation @return: MonteCarloResults instance """ self.__cancel__ = False # initialize the grid time series results # we will append the island results with another function self.circuit.time_series_results = TimeSeriesResults(0, 0, []) self.pool = multiprocessing.Pool() it = 0 variance_sum = 0.0 std_dev_progress = 0 v_variance = 0 n = len(self.circuit.buses) m = self.circuit.get_branch_number() mc_results = MonteCarloResults(n, m, name='Monte Carlo') avg_res = PowerFlowResults() avg_res.initialize(n, m) # compile circuits numerical_circuit = self.circuit.compile_time_series() # perform the topological computation calc_inputs_dict = numerical_circuit.compute(branch_tolerance_mode=self.options.branch_impedance_tolerance_mode, ignore_single_node_islands=self.options.ignore_single_node_islands) mc_results.bus_types = numerical_circuit.bus_types v_sum = zeros(n, dtype=complex) self.progress_signal.emit(0.0) while (std_dev_progress < 100.0) and (it < self.max_mc_iter) and not self.__cancel__: self.progress_text.emit('Running Monte Carlo: Variance: ' + str(v_variance)) mc_results = MonteCarloResults(n, m, self.batch_size, name='Monte Carlo') # for each partition of the profiles... for t_key, calc_inputs in calc_inputs_dict.items(): # For every island, run the time series for island_index, numerical_island in enumerate(calc_inputs): # set the time series as sampled monte_carlo_input = make_monte_carlo_input(numerical_island) mc_time_series = monte_carlo_input(self.batch_size, use_latin_hypercube=False) Vbus = numerical_island.Vbus branch_rates = numerical_island.branch_rates # short cut the indices b_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx self.returned_results = list() t = 0 while t < self.batch_size and not self.__cancel__: Ysh, Ibus, Sbus = mc_time_series.get_at(t) args = (t, self.options, numerical_island, Vbus, Sbus, Ibus, branch_rates) self.pool.apply_async(power_flow_worker_args, (args,), callback=self.update_progress_mt) # wait for all jobs to complete self.pool.close() self.pool.join() # collect results self.progress_text.emit('Collecting batch results...') for t, res in self.returned_results: # store circuit results at the time index 't' mc_results.S_points[t, numerical_island.original_bus_idx] = res.Sbus mc_results.V_points[t, numerical_island.original_bus_idx] = res.voltage mc_results.Sbr_points[t, numerical_island.original_branch_idx] = res.Sbranch mc_results.loading_points[t, numerical_island.original_branch_idx] = res.loading mc_results.losses_points[t, numerical_island.original_branch_idx] = res.losses # compile MC results self.progress_text.emit('Compiling results...') mc_results.compile() # compute the island branch results island_avg_res = numerical_island.compute_branch_results(mc_results.voltage[b_idx]) # apply the island averaged results avg_res.apply_from_island(island_avg_res, b_idx=b_idx, br_idx=br_idx) # Compute the Monte Carlo values it += self.batch_size mc_results.append_batch(mc_results) v_sum += mc_results.get_voltage_sum() v_avg = v_sum / it v_variance = abs((power(mc_results.V_points - v_avg, 2.0) / (it - 1)).min()) # progress variance_sum += v_variance err = variance_sum / it if err == 0: err = 1e-200 # to avoid division by zeros mc_results.error_series.append(err) # emmit the progress signal std_dev_progress = 100 * self.mc_tol / err if std_dev_progress > 100: std_dev_progress = 100 self.progress_signal.emit(max((std_dev_progress, it / self.max_mc_iter * 100))) # compute the averaged branch magnitudes mc_results.sbranch = avg_res.Sbranch mc_results.losses = avg_res.losses # print('V mc: ', mc_results.voltage) # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return mc_results
def run_multi_thread(self): """ Run the monte carlo simulation @return: """ self.__cancel__ = False # initialize the grid time series results # we will append the island results with another function self.circuit.time_series_results = TimeSeriesResults(0, 0, 0, 0, 0) Sbase = self.circuit.Sbase n_cores = multiprocessing.cpu_count() it = 0 variance_sum = 0.0 std_dev_progress = 0 v_variance = 0 n = len(self.circuit.buses) m = len(self.circuit.branches) mc_results = MonteCarloResults(n, m) avg_res = PowerFlowResults() avg_res.initialize(n, m) # compile circuits numerical_circuit = self.circuit.compile() numerical_input_islands = numerical_circuit.compute(branch_tolerance_mode=self.options.branch_impedance_tolerance_mode) mc_results.bus_types = numerical_circuit.bus_types v_sum = zeros(n, dtype=complex) self.progress_signal.emit(0.0) while (std_dev_progress < 100.0) and (it < self.max_mc_iter) and not self.__cancel__: self.progress_text.emit('Running Monte Carlo: Variance: ' + str(v_variance)) mc_results = MonteCarloResults(n, m, self.batch_size) # For every circuit, run the time series for numerical_island in numerical_input_islands: # set the time series as sampled monte_carlo_input = make_monte_carlo_input(numerical_island) mc_time_series = monte_carlo_input(self.batch_size, use_latin_hypercube=False) Vbus = numerical_island.Vbus manager = multiprocessing.Manager() return_dict = manager.dict() # short cut the indices b_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx t = 0 while t < self.batch_size and not self.__cancel__: k = 0 jobs = list() # launch only n_cores jobs at the time while k < n_cores + 2 and (t + k) < self.batch_size: # set the power values Y, I, S = mc_time_series.get_at(t) # run power flow at the circuit p = multiprocessing.Process(target=power_flow_worker, args=(t, self.options, numerical_island, Vbus, S / Sbase, I / Sbase, return_dict)) jobs.append(p) p.start() k += 1 t += 1 # wait for all jobs to complete for proc in jobs: proc.join() # progress = ((t + 1) / self.batch_size) * 100 # self.progress_signal.emit(progress) # collect results self.progress_text.emit('Collecting batch results...') for t in return_dict.keys(): # store circuit results at the time index 't' res = return_dict[t] mc_results.S_points[t, numerical_island.original_bus_idx] = res.Sbus mc_results.V_points[t, numerical_island.original_bus_idx] = res.voltage mc_results.I_points[t, numerical_island.original_branch_idx] = res.Ibranch mc_results.loading_points[t, numerical_island.original_branch_idx] = res.loading mc_results.losses_points[t, numerical_island.original_branch_idx] = res.losses # compile MC results self.progress_text.emit('Compiling results...') mc_results.compile() # compute the island branch results island_avg_res = numerical_island.compute_branch_results(mc_results.voltage[b_idx]) # apply the island averaged results avg_res.apply_from_island(island_avg_res, b_idx=b_idx, br_idx=br_idx) # Compute the Monte Carlo values it += self.batch_size mc_results.append_batch(mc_results) v_sum += mc_results.get_voltage_sum() v_avg = v_sum / it v_variance = abs((power(mc_results.V_points - v_avg, 2.0) / (it - 1)).min()) # progress variance_sum += v_variance err = variance_sum / it if err == 0: err = 1e-200 # to avoid division by zeros mc_results.error_series.append(err) # emmit the progress signal std_dev_progress = 100 * self.mc_tol / err if std_dev_progress > 100: std_dev_progress = 100 self.progress_signal.emit(max((std_dev_progress, it / self.max_mc_iter * 100))) # print(iter, '/', max_mc_iter) # print('Vmc:', Vavg) # print('Vstd:', Vvariance, ' -> ', std_dev_progress, ' %') # compute the averaged branch magnitudes mc_results.sbranch = avg_res.Sbranch mc_results.losses = avg_res.losses # print('V mc: ', mc_results.voltage) # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return mc_results
def run_single_thread(self): """ Run the monte carlo simulation @return: """ self.__cancel__ = False # initialize the grid time series results # we will append the island results with another function # self.circuit.time_series_results = TimeSeriesResults(0, 0, []) # Sbase = self.circuit.Sbase it = 0 variance_sum = 0.0 std_dev_progress = 0 v_variance = 0 # n = len(self.circuit.buses) # m = self.circuit.get_branch_number() # # # compile circuits # numerical_circuit = self.circuit.compile_time_series() # # # perform the topological computation # calc_inputs_dict = numerical_circuit.compute(branch_tolerance_mode=self.options.branch_impedance_tolerance_mode, # ignore_single_node_islands=self.options.ignore_single_node_islands) # # mc_results = MonteCarloResults(n, m, name='Monte Carlo') # avg_res = PowerFlowResults() # avg_res.initialize(n, m) # compile the multi-circuit numerical_circuit = compile_time_circuit( circuit=self.circuit, apply_temperature=False, branch_tolerance_mode=BranchImpedanceMode.Specified, opf_results=self.opf_time_series_results) # do the topological computation calculation_inputs = split_time_circuit_into_islands( numeric_circuit=numerical_circuit, ignore_single_node_islands=self.options.ignore_single_node_islands) mc_results_master = MonteCarloResults( n=numerical_circuit.nbus, m=numerical_circuit.nbr, p=self.max_mc_iter, bus_names=numerical_circuit.bus_names, branch_names=numerical_circuit.branch_names, bus_types=numerical_circuit.bus_types, name='Monte Carlo') avg_res = PowerFlowResults( n=numerical_circuit.nbus, m=numerical_circuit.nbr, n_tr=numerical_circuit.ntr, n_hvdc=numerical_circuit.nhvdc, bus_names=numerical_circuit.bus_names, branch_names=numerical_circuit.branch_names, transformer_names=numerical_circuit.tr_names, hvdc_names=numerical_circuit.hvdc_names, bus_types=numerical_circuit.bus_types) n = numerical_circuit.nbus m = numerical_circuit.nbr v_sum = zeros(n, dtype=complex) self.progress_signal.emit(0.0) while (std_dev_progress < 100.0) and (it < self.max_mc_iter) and not self.__cancel__: self.progress_text.emit('Running Monte Carlo: Variance: ' + str(v_variance)) batch_results = MonteCarloResults( n=numerical_circuit.nbus, m=numerical_circuit.nbr, p=self.max_mc_iter, bus_names=numerical_circuit.bus_names, branch_names=numerical_circuit.branch_names, bus_types=numerical_circuit.bus_types, name='Monte Carlo') # For every island, run the time series for island_index, numerical_island in enumerate( calculation_inputs): # short cut the indices bus_idx = numerical_island.original_bus_idx br_idx = numerical_island.original_branch_idx # set the time series as sampled monte_carlo_input = make_monte_carlo_input(numerical_island) mc_time_series = monte_carlo_input(self.batch_size, use_latin_hypercube=False) Vbus = numerical_island.Vbus[0, :] # run the time series for t in range(self.batch_size): # set the power values Y, I, S = mc_time_series.get_at(t) res = single_island_pf( circuit=numerical_island, Vbus=Vbus, Sbus=S, Ibus=I, branch_rates=numerical_island.branch_rates[0, :], options=self.options, logger=self.logger) batch_results.S_points[t, bus_idx] = res.Sbus batch_results.V_points[t, bus_idx] = res.voltage batch_results.Sbr_points[t, br_idx] = res.Sbranch batch_results.loading_points[t, br_idx] = res.loading batch_results.losses_points[t, br_idx] = res.losses self.progress_text.emit('Compiling results...') batch_results.compile() # compute the island branch results Sbranch, Ibranch, Vbranch, loading, \ losses, flow_direction, Sbus = power_flow_post_process(numerical_island, Sbus=batch_results.S_points.mean(axis=0)[bus_idx], V=batch_results.V_points.mean(axis=0)[bus_idx], branch_rates=numerical_island.branch_rates[0, :]) # apply the island averaged results avg_res.Sbus[bus_idx] = Sbus avg_res.voltage[bus_idx] = batch_results.voltage[bus_idx] avg_res.Sbranch[br_idx] = Sbranch avg_res.Ibranch[br_idx] = Ibranch avg_res.Vbranch[br_idx] = Vbranch avg_res.loading[br_idx] = loading avg_res.losses[br_idx] = losses avg_res.flow_direction[br_idx] = flow_direction # Compute the Monte Carlo values it += self.batch_size mc_results_master.append_batch(batch_results) v_sum += mc_results_master.get_voltage_sum() v_avg = v_sum / it v_variance = abs((power(mc_results_master.V_points - v_avg, 2.0) / (it - 1)).min()) # progress variance_sum += v_variance err = variance_sum / it if err == 0: err = 1e-200 # to avoid division by zeros mc_results_master.error_series.append(err) # emmit the progress signal std_dev_progress = 100 * self.mc_tol / err if std_dev_progress > 100: std_dev_progress = 100 self.progress_signal.emit( max((std_dev_progress, it / self.max_mc_iter * 100))) # compile results mc_results_master.bus_types = numerical_circuit.bus_types # send the finnish signal self.progress_signal.emit(0.0) self.progress_text.emit('Done!') self.done_signal.emit() return mc_results_master