Exemplo n.º 1
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
Exemplo n.º 2
0
    def run_single_thread(self) -> TimeSeriesResults:
        """
        Run single thread time series
        :return: TimeSeriesResults instance
        """
        # initialize the power flow
        power_flow = PowerFlowMP(self.grid, self.options)

        # initialize the grid time series results we will append the island results with another function
        n = len(self.grid.buses)
        m = len(self.grid.branches)
        nt = len(self.grid.time_profile)
        time_series_results = TimeSeriesResults(n, m, nt, self.start_, self.end_, time=self.grid.time_profile)
        if self.end_ is None:
            self.end_ = nt

        # compile the multi-circuit
        numerical_circuit = self.grid.compile(use_opf_vals=self.use_opf_vals,
                                              opf_time_series_results=self.opf_time_series_results)

        # do the topological computation
        calc_inputs_dict = numerical_circuit.compute_ts(branch_tolerance_mode=
                                                        self.options.branch_impedance_tolerance_mode)

        time_series_results.bus_types = numerical_circuit.bus_types

        # 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, calculation_input in enumerate(calc_inputs):

                # Are we dispatching storage? if so, generate a dictionary of battery -> bus index
                # to be able to set the batteries values into the vector S
                batteries = list()
                batteries_bus_idx = list()
                if self.options.dispatch_storage:
                    for k, bus in enumerate(self.grid.buses):
                        for battery in bus.batteries:
                            battery.reset()  # reset the calculation values
                            batteries.append(battery)
                            batteries_bus_idx.append(k)

                self.progress_text.emit('Time series at circuit ' + str(island_index) + '...')

                # find the original indices
                bus_original_idx = calculation_input.original_bus_idx
                branch_original_idx = calculation_input.original_branch_idx

                # if there are valid profiles...
                if self.grid.time_profile is not None:

                    # declare a results object for the partition
                    nt = calculation_input.ntime
                    n = calculation_input.nbus
                    m = calculation_input.nbr
                    results = TimeSeriesResults(n, m, nt, self.start_, self.end_)
                    last_voltage = calculation_input.Vbus

                    self.progress_signal.emit(0.0)

                    # default value in case of single-valued profile
                    dt = 1.0

                    # traverse the time profiles of the partition and simulate each time step
                    for it, t in enumerate(calculation_input.original_time_idx):

                        if (t >= self.start_) and (t < self.end_):

                            # set the power values
                            # if the storage dispatch option is active, the batteries power is not included
                            # therefore, it shall be included after processing
                            Ysh = calculation_input.Ysh_prof[:, it]
                            I = calculation_input.Ibus_prof[:, it]
                            S = calculation_input.Sbus_prof[:, it]

                            # add the controlled storage power if we are controlling the storage devices
                            if self.options.dispatch_storage:

                                if (it+1) < len(calculation_input.original_time_idx):
                                    # compute the time delta: the time values come in nanoseconds
                                    dt = (calculation_input.time_array[it + 1]
                                          - calculation_input.time_array[it]).value * 1e-9 / 3600.0

                                for k, battery in enumerate(batteries):

                                    power = battery.get_processed_at(it, dt=dt, store_values=True)

                                    bus_idx = batteries_bus_idx[k]

                                    S[bus_idx] += power / calculation_input.Sbase
                            else:
                                pass

                            # run power flow at the circuit
                            res = power_flow.run_pf(circuit=calculation_input, Vbus=last_voltage, Sbus=S, Ibus=I)

                            # Recycle voltage solution
                            last_voltage = res.voltage

                            # store circuit results at the time index 't'
                            results.set_at(t, res)

                            progress = ((t - self.start_ + 1) / (self.end_ - self.start_)) * 100
                            self.progress_signal.emit(progress)
                            self.progress_text.emit('Simulating island ' + str(island_index)
                                                    + ' at ' + str(self.grid.time_profile[t]))

                        else:
                            pass

                        if self.__cancel__:
                            # merge the circuit's results
                            time_series_results.apply_from_island(results,
                                                                  bus_original_idx,
                                                                  branch_original_idx,
                                                                  calculation_input.time_array,
                                                                  'TS')
                            # abort by returning at this point
                            return time_series_results

                    # merge the circuit's results
                    time_series_results.apply_from_island(results,
                                                          bus_original_idx,
                                                          branch_original_idx,
                                                          calculation_input.time_array,
                                                          'TS')

                else:
                    print('There are no profiles')
                    self.progress_text.emit('There are no profiles')

        return time_series_results
Exemplo n.º 3
0
    def run_single_thread(self):
        """
        Run the monte carlo simulation
        @return:
        """

        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)
        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()
        numerical_input_islands = numerical_circuit.compute(
            branch_tolerance_mode=self.options.branch_impedance_tolerance_mode)

        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 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

                # 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 = powerflow.run_at(t, mc=True)
                    res = power_flow.run_pf(circuit=numerical_island,
                                            Vbus=Vbus,
                                            Sbus=S / Sbase,
                                            Ibus=I / Sbase)

                    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