Пример #1
0
def parse_areas_data(circuit: MultiCircuit, data, logger: Logger):
    """
    Parse Matpower / FUBM Matpower area data into GridCal
    :param circuit: MultiCircuit instance
    :param data: data dictionary
    :return: area index -> object dictionary
    """
    area_idx_dict = dict()
    if 'areas' in data.keys():
        table = data['areas']

        if table.shape[0] > 0:
            # if there are areas declared, clean the default areas
            circuit.areas = list()

        for i in range(table.shape[0]):
            area_idx = int(table[i, 0])
            area_ref_bus_idx = table[i, 1]
            a = Area(name='Area ' + str(area_idx), code=str(area_idx))
            area_idx_dict[area_idx] = (a, area_ref_bus_idx)
            circuit.add_area(a)

            if i == 0:
                # set the default area
                circuit.default_area = circuit.areas[0]

    return area_idx_dict
Пример #2
0
def interpret_data_v1(circuit: MultiCircuit, data) -> MultiCircuit:
    """
    Pass the loaded table-like data to the  structures
    :param circuit:
    :param data: Data dictionary
    :return:
    """

    circuit.clear()

    # time profile
    if 'master_time' in data.keys():
        master_time_array = data['master_time']
    else:
        master_time_array = None

    # areas
    area_idx_dict = dict()
    if 'areas' in data.keys():
        table = data['areas']

        if table.shape[0] > 0:
            # if there are areas declared, clean the default areas
            circuit.areas = list()

        for i in range(table.shape[0]):
            area_idx = int(table[i, 0])
            area_ref_bus_idx = table[i, 1]
            a = Area(name='Area ' + str(area_idx),
                     code=str(area_idx))
            area_idx_dict[area_idx] = (a, area_ref_bus_idx)
            circuit.add_area(a)

            if i == 0:
                # set the default area
                circuit.default_area = circuit.areas[0]

    import GridCal.Engine.IO.matpower_bus_definitions as e
    # Buses
    table = data['bus']

    n = table.shape[0]

    # load profiles
    if 'Lprof' in data.keys():
        Pprof = data['Lprof']
        Qprof = data['LprofQ']
        are_load_prfiles = True
        print('There are load profiles')
    else:
        are_load_prfiles = False

    if 'bus_names' in data.keys():
        names = data['bus_names']
    else:
        names = ['bus ' + str(int(table[i, e.BUS_I])) for i in range(n)]

    # Buses
    bus_idx_dict = dict()
    for i in range(n):
        # Create bus
        area_idx = int(table[i, e.BUS_AREA])
        bus_idx = int(table[i, e.BUS_I])
        is_slack = False

        if area_idx in area_idx_dict.keys():
            area, ref_idx = area_idx_dict[area_idx]
            if ref_idx == bus_idx:
                is_slack = True
        else:
            area = circuit.default_area

        code = str(bus_idx)

        bus = Bus(name=names[i],
                  code=code,
                  vnom=table[i, e.BASE_KV],
                  vmax=table[i, e.VMAX],
                  vmin=table[i, e.VMIN],
                  area=area,
                  is_slack=is_slack)

        # store the given bus index in relation to its real index in the table for later
        bus_idx_dict[table[i, e.BUS_I]] = i

        # determine if the bus is set as slack manually
        tpe = table[i, e.BUS_TYPE]
        if tpe == e.REF:
            bus.is_slack = True
        else:
            bus.is_slack = False

        # Add the load
        if table[i, e.PD] != 0 or table[i, e.QD] != 0:
            load = Load(P=table[i, e.PD], Q=table[i, e.QD])
            load.bus = bus
            bus.loads.append(load)

        # Add the shunt
        if table[i, e.GS] != 0 or table[i, e.BS] != 0:
            shunt = Shunt(G=table[i, e.GS], B=table[i, e.BS])
            shunt.bus = bus
            bus.shunts.append(shunt)

        # Add the bus to the circuit buses
        circuit.add_bus(bus)

    import GridCal.Engine.IO.matpower_gen_definitions as e
    # Generators
    table = data['gen']
    n = len(table)
    # load profiles
    if 'Gprof' in data.keys():
        Gprof = data['Gprof']
        are_gen_prfiles = True
        print('There are gen profiles')
    else:
        are_gen_prfiles = False

    if 'gen_names' in data.keys():
        names = data['gen_names']
    else:
        names = ['gen ' + str(i) for i in range(n)]
    for i in range(len(table)):
        bus_idx = bus_idx_dict[int(table[i, e.GEN_BUS])]
        gen = Generator(name=names[i],
                        active_power=table[i, e.PG],
                        voltage_module=table[i, e.VG],
                        Qmax=table[i, e.QMAX],
                        Qmin=table[i, e.QMIN])

        # Add the generator to the bus
        gen.bus = circuit.buses[bus_idx]
        circuit.buses[bus_idx].controlled_generators.append(gen)

    import GridCal.Engine.IO.matpower_branch_definitions as e
    # Branches
    table = data['branch']
    n = len(table)
    if 'branch_names' in data.keys():
        names = data['branch_names']
    else:
        names = ['branch ' + str(i) for i in range(n)]
    for i in range(len(table)):
        f = circuit.buses[bus_idx_dict[int(table[i, e.F_BUS])]]
        t = circuit.buses[bus_idx_dict[int(table[i, e.T_BUS])]]

        if table.shape[1] == 37:  # FUBM model

            # converter type (I, II, III)
            matpower_converter_mode = table[i, e.CONV_A]

            if matpower_converter_mode > 0:  # it is a converter

                # set the from bus as a DC bus
                # this is by design of the matpower FUBM model,
                # if it is a converter,
                # the DC bus is always the "from" bus
                f.is_dc = True

                # determine the converter control mode
                Pfset = table[i, e.PF]
                Ptset = table[i, e.PT]
                Vac_set = table[i, e.VT_SET]
                Vdc_set = table[i, e.VF_SET]
                Qfset = table[i, e.QF]
                Qtset = table[i, e.QT]
                m = table[i, e.TAP] if table[i, e.TAP] > 0 else 1.0

                if matpower_converter_mode == 1:

                    if Pfset != 0.0:

                        if Qtset != 0.0:
                            control_mode = ConverterControlType.type_I_2

                        elif Vac_set != 0.0:
                            control_mode = ConverterControlType.type_I_3

                        else:
                            control_mode = ConverterControlType.type_I_1

                    else:
                        control_mode = ConverterControlType.type_0_free

                elif matpower_converter_mode == 2:

                    if Vac_set == 0.0:
                        control_mode = ConverterControlType.type_II_4
                    else:
                        control_mode = ConverterControlType.type_II_5

                elif matpower_converter_mode == 3:
                    control_mode = ConverterControlType.type_III_6

                elif matpower_converter_mode == 4:
                    control_mode = ConverterControlType.type_III_7

                else:
                    control_mode = ConverterControlType.type_0_free

                branch = VSC(bus_from=f,
                             bus_to=t,
                             name='VSC' + str(len(circuit.vsc_devices) + 1),
                             active=bool(table[i, e.BR_STATUS]),
                             r1=table[i, e.BR_R],
                             x1=table[i, e.BR_X],
                             m=m,
                             m_max=table[i, e.MA_MAX],
                             m_min=table[i, e.MA_MIN],
                             theta=table[i, e.SHIFT],
                             theta_max=np.deg2rad(table[i, e.ANGMAX]),
                             theta_min=np.deg2rad(table[i, e.ANGMIN]),
                             G0=table[i, e.GSW],
                             Beq=table[i, e.BEQ],
                             Beq_max=table[i, e.BEQ_MAX],
                             Beq_min=table[i, e.BEQ_MIN],
                             rate=max(table[i, [e.RATE_A, e.RATE_B, e.RATE_C]]),
                             kdp=table[i, e.KDP],
                             k=table[i, e.K2],
                             control_mode=control_mode,
                             Pfset=Pfset,
                             Qfset=Qfset,
                             Vac_set=Vac_set if Vac_set > 0 else 1.0,
                             Vdc_set=Vdc_set if Vdc_set > 0 else 1.0,
                             alpha1=table[i, e.ALPHA1],
                             alpha2=table[i, e.ALPHA2],
                             alpha3=table[i, e.ALPHA3])
                circuit.add_vsc(branch)

            else:

                if f.Vnom != t.Vnom or (table[i, e.TAP] != 1.0 and table[i, e.TAP] != 0) or table[i, e.SHIFT] != 0.0:

                    branch = Transformer2W(bus_from=f,
                                           bus_to=t,
                                           name=names[i],
                                           r=table[i, e.BR_R],
                                           x=table[i, e.BR_X],
                                           g=0,
                                           b=table[i, e.BR_B],
                                           rate=table[i, e.RATE_A],
                                           tap=table[i, e.TAP],
                                           shift_angle=table[i, e.SHIFT],
                                           active=bool(table[i, e.BR_STATUS]))
                    circuit.add_transformer2w(branch)

                else:
                    branch = Line(bus_from=f,
                                  bus_to=t,
                                  name=names[i],
                                  r=table[i, e.BR_R],
                                  x=table[i, e.BR_X],
                                  b=table[i, e.BR_B],
                                  rate=table[i, e.RATE_A],
                                  active=bool(table[i, e.BR_STATUS]))
                    circuit.add_line(branch)

        else:

            if f.Vnom != t.Vnom or (table[i, e.TAP] != 1.0 and table[i, e.TAP] != 0) or table[i, e.SHIFT] != 0.0:

                branch = Transformer2W(bus_from=f,
                                       bus_to=t,
                                       name=names[i],
                                       r=table[i, e.BR_R],
                                       x=table[i, e.BR_X],
                                       g=0,
                                       b=table[i, e.BR_B],
                                       rate=table[i, e.RATE_A],
                                       tap=table[i, e.TAP],
                                       shift_angle=table[i, e.SHIFT],
                                       active=bool(table[i, e.BR_STATUS]))
                circuit.add_transformer2w(branch)

            else:
                branch = Line(bus_from=f,
                              bus_to=t,
                              name=names[i],
                              r=table[i, e.BR_R],
                              x=table[i, e.BR_X],
                              b=table[i, e.BR_B],
                              rate=table[i, e.RATE_A],
                              active=bool(table[i, e.BR_STATUS]))
                circuit.add_line(branch)

    # convert normal lines into DC-lines if needed
    for line in circuit.lines:

        if line.bus_to.is_dc and line.bus_from.is_dc:
            dc_line = DcLine(bus_from=line.bus_from,
                             bus_to=line.bus_to,
                             name=line.name,
                             active=line.active,
                             rate=line.rate,
                             r=line.R,
                             active_prof=line.active_prof,
                             rate_prof=line.rate_prof)

            # add device to the circuit
            circuit.add_dc_line(dc_line)

            # delete the line from the circuit
            circuit.delete_line(line)

    # add the profiles
    if master_time_array is not None:
        circuit.format_profiles(master_time_array)

    return circuit