Exemplo n.º 1
0
def add_branch_loading_restriction(problem: pl.LpProblem, theta_f, theta_t, Bseries, rating, FSlack1, FSlack2):
    """
    Add the branch loading restrictions
    :param problem: LpProblem instance
    :param theta_f: voltage angles at the "from" side of the branches (m)
    :param theta_t: voltage angles at the "to" side of the branches (m)
    :param Bseries: Array of branch susceptances (m)
    :param rating: Array of branch ratings (m)
    :param FSlack1: Array of branch loading slack variables in the from-to sense
    :param FSlack2: Array of branch loading slack variables in the to-from sense
    :return: load_f and load_t arrays (LP+float)
    """

    load_f = Bseries * (theta_f - theta_t)
    load_t = Bseries * (theta_t - theta_f)

    # from-to branch power restriction
    pl.lpAddRestrictions2(problem=problem,
                          lhs=load_f,
                          rhs=rating + FSlack1,  # rating + FSlack1
                          name='from_to_branch_rate',
                          op='<=')

    # to-from branch power restriction
    pl.lpAddRestrictions2(problem=problem,
                          lhs=load_t,
                          rhs=rating + FSlack2,  # rating + FSlack2
                          name='to_from_branch_rate',
                          op='<=')

    return load_f, load_t
Exemplo n.º 2
0
def add_dc_nodal_power_balance(numerical_circuit, problem: pl.LpProblem, theta, P):
    """
    Add the nodal power balance
    :param numerical_circuit: NumericalCircuit instance
    :param problem: LpProblem instance
    :param theta: Voltage angles LpVars (n, nt)
    :param P: Power injection at the buses LpVars (n, nt)
    :return: Nothing, the restrictions are added to the problem
    """

    # do the topological computation
    calculation_inputs = numerical_circuit.split_into_islands()

    nodal_restrictions = np.empty(numerical_circuit.nbus, dtype=object)

    # simulate each island and merge the results
    for i, calc_inpt in enumerate(calculation_inputs):

        # if there is a slack it means that there is at least one generator,
        # otherwise these equations do not make sense
        if len(calc_inpt.vd) > 0:

            # find the original indices
            bus_original_idx = np.array(calc_inpt.original_bus_idx)

            # re-pack the variables for the island and time interval
            P_island = P[bus_original_idx]  # the sizes already reflect the correct time span
            theta_island = theta[bus_original_idx]  # the sizes already reflect the correct time span
            B_island = calc_inpt.Ybus.imag

            pqpv = calc_inpt.pqpv
            vd = calc_inpt.vd

            # Add nodal power balance for the non slack nodes
            idx = bus_original_idx[pqpv]
            nodal_restrictions[idx] = pl.lpAddRestrictions2(problem=problem,
                                                            lhs=pl.lpDot(B_island[np.ix_(pqpv, pqpv)], theta_island[pqpv]),
                                                            rhs=P_island[pqpv],
                                                            name='Nodal_power_balance_pqpv_is' + str(i),
                                                            op='=')

            # Add nodal power balance for the slack nodes
            idx = bus_original_idx[vd]
            nodal_restrictions[idx] = pl.lpAddRestrictions2(problem=problem,
                                                            lhs=pl.lpDot(B_island[vd, :], theta_island),
                                                            rhs=P_island[vd],
                                                            name='Nodal_power_balance_vd_is' + str(i),
                                                            op='=')

            # slack angles equal to zero
            pl.lpAddRestrictions2(problem=problem,
                                  lhs=theta_island[vd],
                                  rhs=np.zeros(len(vd)),
                                  name='Theta_vd_zero_is' + str(i),
                                  op='=')

    return nodal_restrictions
Exemplo n.º 3
0
def set_fix_generation(problem, Pg, P_fix, enabled_for_dispatch):
    """
    Set the generation fixed at the non dispatchable generators
    :param problem: LP problem instance
    :param Pg: Array of generation variables
    :param P_fix: Array of fixed generation values
    :param enabled_for_dispatch: array of "enables" for dispatching generators
    :return: Nothing
    """

    idx = np.where(enabled_for_dispatch == False)[0]

    pl.lpAddRestrictions2(problem=problem,
                          lhs=Pg[idx],
                          rhs=P_fix[idx],
                          name='fixed_generation',
                          op='=')