示例#1
0
    def run_single_thread(self) -> TimeSeriesResults:
        """
        Run single thread time series
        :return: TimeSeriesResults instance
        """

        # 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 = self.number_of_steps
        time_series_results = TimeSeriesResults(
            n,
            m,
            nt,
            start=0,
            end=self.number_of_steps,
            time_array=self.grid.time_profile[self.steps])

        # compile the multi-circuit
        numerical_circuit = self.grid.compile(
            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,
            ignore_single_node_islands=self.options.ignore_single_node_islands)

        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, 0, nt)
                    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(self.steps):

                        # 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[:, t]
                        I = calculation_input.Ibus_prof[:, t]
                        S = calculation_input.Sbus_prof[:, t]
                        branch_rates = calculation_input.branch_rates_prof[
                            t, :]

                        # 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 = single_island_pf(circuit=calculation_input,
                                               Vbus=last_voltage,
                                               Sbus=S,
                                               Ibus=I,
                                               branch_rates=branch_rates,
                                               options=self.options,
                                               logger=self.logger)

                        # Recycle voltage solution
                        # last_voltage = res.voltage

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

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

                    if self.__cancel__:
                        # merge the circuit's results
                        time_series_results.apply_from_island(
                            results,
                            bus_original_idx,
                            branch_original_idx,
                            np.array(
                                range(self.number_of_steps)
                            ),  #np.array(calculation_input.original_time_idx)[self.steps],
                            '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,
                        np.array(range(self.number_of_steps)), 'TS')

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

        return time_series_results
示例#2
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

        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 = split_time_circuit_into_islands(
            numeric_circuit=numerical_circuit,
            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[0, :],
                    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.Sbranch
                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
            Sbranch, Ibranch, 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[0, :])

            # apply the island averaged results
            avg_res.Sbus[bus_idx] = Sbus
            avg_res.voltage[bus_idx] = lhs_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

        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
示例#3
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, [])
        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)

        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

                    # 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,
                                               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.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

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

        # 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
示例#4
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
        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,
                                        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)

        Sbase = numerical_circuit.Sbase
        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 / Sbase,
                        Ibus=I / Sbase,
                        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
示例#5
0
    def n_minus_k_mt(self,
                     k=1,
                     indices=None,
                     vmin=200,
                     states_number_limit=None):
        """
        Run N-K simulation in series
        :param k: Parameter level (1 for n-1, 2 for n-2, etc...)
        :param indices: time indices {np.array([0])}
        :param vmin: minimum nominal voltage to allow (filters out branches and buses below)
        :param states_number_limit: limit the amount of states
        :return: Nothing, saves a report
        """
        self.progress_text.emit("Filtering elements by voltage")

        # filter branches
        branch_names = list()
        branch_index = list()
        branches = list()  # list of filtered branches
        for i, branch in enumerate(self.grid.branches):
            if branch.bus_from.Vnom > vmin or branch.bus_to.Vnom > vmin:
                branch_names.append(branch.name)
                branch_index.append(i)
                branches.append(branch)
        branch_index = np.array(branch_index)

        # filter buses
        bus_names = list()
        bus_index = list()
        for i, bus in enumerate(self.grid.buses):
            if bus.Vnom > vmin:
                bus_names.append(bus.name)
                bus_index.append(i)
        bus_index = np.array(bus_index)

        # get N-k states
        self.progress_text.emit("Enumerating states")
        states, failed_indices = enumerate_states_n_k(m=len(branch_names), k=k)

        # limit states for memory reasons
        if states_number_limit is not None:
            states = states[:states_number_limit, :]
            failed_indices = failed_indices[:states_number_limit]

        # compile the multi-circuit
        self.progress_text.emit("Compiling assets...")
        self.progress_signal.emit(0)
        numerical_circuit = self.grid.compile(use_opf_vals=False,
                                              opf_time_series_results=None)

        # if no base profile time is given, pick the base values
        if indices is None:
            time_indices = np.array([0])
            numerical_circuit.set_base_profile()
        else:
            time_indices = indices

        # re-index the profile (this is essential for time-compatibility)
        self.progress_signal.emit(100)
        # construct the profile indices
        profile_indices = np.tile(time_indices, len(states))
        numerical_circuit.re_index_time(t_idx=profile_indices)

        # set the branch states
        numerical_circuit.branch_active_prof[:, branch_index] = np.tile(
            states, (len(time_indices), 1))

        # initialize the power flow
        pf_options = PowerFlowOptions(solver_type=SolverType.LACPF)

        # 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(profile_indices)

        n_k_results = NMinusKResults(n,
                                     m,
                                     nt,
                                     time_array=numerical_circuit.time_array,
                                     states=states)

        # do the topological computation
        self.progress_text.emit("Compiling topology...")
        self.progress_signal.emit(0.0)
        calc_inputs_dict = numerical_circuit.compute_ts(
            ignore_single_node_islands=pf_options.ignore_single_node_islands)

        n_k_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):

                # 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
                    nt = len(calculation_input.original_time_idx)
                    n = calculation_input.nbus
                    m = calculation_input.nbr
                    partial_results = NMinusKResults(n, m, nt)
                    last_voltage = calculation_input.Vbus

                    # traverse the time profiles of the partition and simulate each time step
                    for it, t in enumerate(
                            calculation_input.original_time_idx):
                        self.progress_signal.emit(it / nt * 100.0)

                        # 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]
                        branch_rates = calculation_input.branch_rates_prof[
                            it, :]

                        # run power flow at the circuit
                        res = single_island_pf(circuit=calculation_input,
                                               Vbus=last_voltage,
                                               Sbus=S,
                                               Ibus=I,
                                               branch_rates=branch_rates,
                                               options=pf_options,
                                               logger=self.logger)

                        # Recycle voltage solution
                        last_voltage = res.voltage

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

                    # merge the circuit's results

                    n_k_results.apply_from_island(
                        partial_results, bus_original_idx, branch_original_idx,
                        calculation_input.original_time_idx, 'TS')
                else:
                    self.progress_text.emit('There are no profiles')
                    self.logger.append('There are no profiles')

        return n_k_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
示例#7
0
    def run_single_thread(self, time_indices) -> TimeSeriesResults:
        """
        Run single thread time series
        :param time_indices: array of time indices to consider
        :return: TimeSeriesResults instance
        """

        # compile the multi-circuit
        time_circuit = compile_time_circuit(
            circuit=self.grid,
            apply_temperature=False,
            branch_tolerance_mode=BranchImpedanceMode.Specified,
            opf_results=self.opf_time_series_results)

        # do the topological computation
        time_islands = time_circuit.split_into_islands(
            ignore_single_node_islands=self.options.ignore_single_node_islands)

        # initialize the grid time series results we will append the island results with another function
        time_series_results = TimeSeriesResults(
            n=time_circuit.nbus,
            m=time_circuit.nbr,
            n_tr=time_circuit.ntr,
            n_hvdc=time_circuit.nhvdc,
            bus_names=time_circuit.bus_names,
            branch_names=time_circuit.branch_names,
            transformer_names=time_circuit.tr_names,
            hvdc_names=time_circuit.hvdc_names,
            bus_types=time_circuit.bus_types,
            time_array=self.grid.time_profile[time_indices])

        time_series_results.bus_types = time_circuit.bus_types

        # For every island, run the time series
        for island_index, calculation_input in enumerate(time_islands):

            # fill in Vbus, Sbus Ibus
            # calculation_input.consolidate()

            # 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

            # declare a results object for the partition
            results = TimeSeriesResults(
                n=calculation_input.nbus,
                m=calculation_input.nbr,
                n_tr=calculation_input.ntr,
                n_hvdc=calculation_input.nhvdc,
                bus_names=calculation_input.bus_names,
                branch_names=calculation_input.branch_names,
                transformer_names=calculation_input.tr_names,
                hvdc_names=calculation_input.hvdc_names,
                bus_types=time_circuit.bus_types,
                time_array=self.grid.time_profile[time_indices])

            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(time_indices):

                # set the power values
                # if the storage dispatch option is active, the batteries power is not included
                # therefore, it shall be included after processing
                V = calculation_input.Vbus[:, it]
                # Ysh = calculation_input.Yshunt_from_devices[:, it]
                I = calculation_input.Ibus[:, it]
                S = calculation_input.Sbus[:, it]
                branch_rates = calculation_input.Rates[:, 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

                # run power flow at the circuit
                res = single_island_pf(circuit=calculation_input,
                                       Vbus=V,
                                       Sbus=S,
                                       Ibus=I,
                                       branch_rates=branch_rates,
                                       options=self.options,
                                       logger=self.logger)

                # Recycle voltage solution
                # last_voltage = res.voltage

                # store circuit results at the time index 'it'
                results.set_at(it, 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]))

                if self.__cancel__:
                    # merge the circuit's results
                    time_series_results.apply_from_island(
                        results, bus_original_idx, branch_original_idx,
                        time_indices, '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,
                                                  time_indices, 'TS')

        # set the HVDC results here since the HVDC is not a branch in this modality
        time_series_results.hvdc_Pf = -time_circuit.hvdc_Pf.T
        time_series_results.hvdc_Pt = -time_circuit.hvdc_Pt.T
        time_series_results.hvdc_loading = time_circuit.hvdc_loading.T
        time_series_results.hvdc_losses = time_circuit.hvdc_losses.T

        return time_series_results
示例#8
0
def time_series_worker(n, m, time_profile, namespace,
                       options: PowerFlowOptions, time_indices,
                       logger: Logger) -> (TimeSeriesResults, np.array):
    """

    :param n:
    :param m:
    :param time_profile:
    :param options:
    :param time_indices:  array of time indices to consider
    :param logger:
    :return: TimeSeriesResults instance
    """

    # initialize the grid time series results we will append the island results with another function
    time_series_results = TimeSeriesResults(
        n, m, time_array=time_profile[time_indices])

    calc_inputs_dict = namespace.calc_inputs_dict
    time_series_results.bus_types = namespace.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):

            # 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 time_profile is not None:

                # declare a results object for the partition
                results = TimeSeriesResults(
                    n=calculation_input.nbus,
                    m=calculation_input.nbr,
                    time_array=time_profile[time_indices])
                last_voltage = calculation_input.Vbus

                # 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(time_indices):

                    # 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]
                    branch_rates = calculation_input.branch_rates_prof[it, :]

                    # add the controlled storage power if we are controlling the storage devices
                    if 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

                    # run power flow at the circuit
                    res = single_island_pf(circuit=calculation_input,
                                           Vbus=last_voltage,
                                           Sbus=S,
                                           Ibus=I,
                                           branch_rates=branch_rates,
                                           options=options,
                                           logger=logger)

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

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