Esempio n. 1
0
    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
Esempio n. 2
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
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
    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