示例#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 parse_loads(self, cim: CIMCircuit, circuit: MultiCircuit, busbar_dict):
        """

        :param cim:
        :param circuit:
        :param busbar_dict:
        :return:
        """
        cim_loads = ['ConformLoad', 'EnergyConsumer', 'NonConformLoad']
        if any_in_dict(cim.elements_by_type, cim_loads):
            for elm in get_elements(cim.elements_by_type, cim_loads):

                b1 = elm.get_bus()
                B1 = try_bus(b1, busbar_dict)

                if B1 is not None:

                    p, q = elm.get_pq()

                    load = gcdev.Load(idtag=elm.uuid,
                                      name=str(elm.name),
                                      G=0,
                                      B=0,
                                      Ir=0,
                                      Ii=0,
                                      P=p if p is not None else 0,
                                      Q=q if q is not None else 0)
                    circuit.add_load(B1, load)
                else:
                    self.logger.add_error('Bus not found', elm.rfid)
示例#3
0
def interpret_data_v1(circuit: MultiCircuit, data,
                      logger: Logger) -> 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 = parse_areas_data(circuit, data, logger)

    # parse buses
    bus_idx_dict = parse_buses_data(circuit, data, area_idx_dict, logger)

    # parse generators
    parse_generators(circuit, data, bus_idx_dict, logger)

    # parse branches
    parse_branches_data(circuit, data, bus_idx_dict, logger)

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

    return circuit
示例#4
0
    def parse_switches(self, cim: CIMCircuit, circuit: MultiCircuit,
                       busbar_dict):
        """

        :param cim:
        :param circuit:
        :param busbar_dict:
        :return:
        """
        EPS = 1e-20
        cim_switches = ['Switch', 'Disconnector', 'Breaker', 'LoadBreakSwitch']
        if any_in_dict(cim.elements_by_type, cim_switches):
            for elm in get_elements(cim.elements_by_type, cim_switches):
                b1, b2 = elm.get_buses()
                B1, B2 = try_buses(b1, b2, busbar_dict)

                if B1 is not None and B2 is not None:
                    state = True
                    line = gcdev.Switch(idtag=elm.uuid,
                                        bus_from=B1,
                                        bus_to=B2,
                                        name=str(elm.name),
                                        r=EPS,
                                        x=EPS,
                                        rate=EPS,
                                        active=state)

                    circuit.add_switch(line)
                else:
                    self.logger.add_error('Bus not found', elm.rfid)
示例#5
0
def parse_matpower_file(filename, export=False) -> MultiCircuit:
    """

    Args:
        filename:
        export:

    Returns:

    """

    # open the file as text
    with open(filename, 'r') as myfile:
        text = myfile.read().replace('\n', '')

    # split the file into its case variables (the case variables always start with 'mpc.')
    chunks = text.split('mpc.')

    # declare circuit
    circuit = MultiCircuit()

    data = dict()

    # further process the loaded text
    for chunk in chunks:

        vals = chunk.split('=')
        key = vals[0].strip()

        if key == "baseMVA":
            v = find_between(chunk, '=', ';')
            circuit.Sbase = float(v)

        elif key == "bus":
            if chunk.startswith("bus_name"):
                v = txt2mat(find_between(chunk, '{', '}'),
                            line_splitter=';',
                            to_float=False)
                v = np.ndarray.flatten(v)
                data['bus_names'] = v
            else:
                data['bus'] = txt2mat(find_between(chunk, '[', ']'),
                                      line_splitter=';')

        elif key == "gencost":
            data['gen_cost'] = txt2mat(find_between(chunk, '[', ']'),
                                       line_splitter=';')

        elif key == "gen":
            data['gen'] = txt2mat(find_between(chunk, '[', ']'),
                                  line_splitter=';')

        elif key == "branch":
            data['branch'] = txt2mat(find_between(chunk, '[', ']'),
                                     line_splitter=';')

    circuit = interpret_data_v1(circuit, data)

    return circuit
示例#6
0
    def __init__(self, file_name):
        """
        File open handler
        :param file_name: name of the file
        """
        self.file_name = file_name

        self.circuit = MultiCircuit()

        self.logger = list()
示例#7
0
    def parse_model(self, cim: CIMCircuit, circuit: MultiCircuit):
        """

        :param cim:
        :param circuit:
        :return:
        """
        if 'Model' in cim.elements_by_type.keys():
            for elm in cim.elements_by_type['Model']:
                if 'description' in elm.properties.keys():
                    circuit.comments = elm.properties['description']

                if 'name' in elm.properties.keys():
                    circuit.name = elm.properties['name']
示例#8
0
    def parse_power_transformer(self, cim: CIMCircuit, circuit: MultiCircuit,
                                busbar_dict):
        """

        :param cim:
        :param circuit:
        :param busbar_dict:
        :return:
        """
        if 'PowerTransformer' in cim.elements_by_type.keys():
            for elm in cim.elements_by_type['PowerTransformer']:
                b1, b2 = elm.get_buses()
                B1, B2 = try_buses(b1, b2, busbar_dict)

                if B1 is not None and B2 is not None:
                    R, X, G, B = elm.get_pu_values()
                    rate = elm.get_rate()

                    voltages = elm.get_voltages()
                    voltages.sort()

                    if len(voltages) == 2:
                        lv, hv = voltages
                    else:
                        lv = 1
                        hv = 1
                        self.logger.add_error(
                            'Could not parse transformer nominal voltages',
                            self.name)

                    line = gcdev.Transformer2W(idtag=cimdev.rfid2uuid(
                        elm.rfid),
                                               bus_from=B1,
                                               bus_to=B2,
                                               name=str(elm.name),
                                               r=R,
                                               x=X,
                                               g=G,
                                               b=B,
                                               rate=rate,
                                               tap=1.0,
                                               shift_angle=0,
                                               active=True,
                                               HV=hv,
                                               LV=lv)

                    circuit.add_branch(line)
                else:
                    self.logger.add_error('Bus not found', elm.rfid)
示例#9
0
def get_static_generator_data(circuit: MultiCircuit, bus_dict, time_series=False, ntime=1):
    """

    :param circuit:
    :param bus_dict:
    :param time_series:
    :return:
    """
    devices = circuit.get_static_generators()

    data = StaticGeneratorData(nstagen=len(devices), nbus=len(circuit.buses), ntime=ntime)

    for k, elm in enumerate(devices):

        i = bus_dict[elm.bus]

        data.static_generator_names[k] = elm.name

        if time_series:
            data.static_generator_active[k, :] = elm.active_prof
            data.static_generator_s[k, :] = elm.P_prof + 1j * elm.Q_prof
        else:
            data.static_generator_active[k] = elm.active
            data.static_generator_s[k] = complex(elm.P, elm.Q)

        data.C_bus_static_generator[i, k] = 1

    return data
示例#10
0
def colour_the_schematic(circuit: MultiCircuit, Sbus, Sf, voltages, loadings,
                         types=None, losses=None, St=None,
                         hvdc_sending_power=None, hvdc_losses=None, hvdc_loading=None,
                         failed_br_idx=None, loading_label='loading',
                         ma=None,
                         theta=None,
                         Beq=None,
                         use_flow_based_width=False,
                         min_branch_width=1,
                         max_branch_width=1,
                         min_bus_width=20,
                         max_bus_width=20,
                         file_name=None):
    """
    Color the grid based on the results passed
    :param circuit:
    :param Sbus:  Buses power
    :param Sf: Branches power seen from the "from" bus
    :param voltages: Buses voltage
    :param loadings: Branches load
    :param types: Buses type
    :param losses: Branches losses
    :param St: power seen from the "to" bus
    :param hvdc_sending_power:
    :param hvdc_losses:
    :param hvdc_loading:
    :param failed_br_idx: failed branches
    :param loading_label:
    :param ma
    :param theta
    :param Beq
    :param file_name: Completely ignore this. It exist for interface compatibility
    :return:
    """

    colour_sub_schematic(Sbase=circuit.Sbase,
                         buses=circuit.buses,
                         branches=circuit.get_branches_wo_hvdc(),
                         hvdc_lines=circuit.hvdc_lines,
                         Sbus=Sbus,
                         Sf=Sf,
                         St=St if St is not None else Sf,
                         voltages=voltages,
                         loadings=loadings,
                         types=types,
                         losses=losses,
                         hvdc_sending_power=hvdc_sending_power,
                         hvdc_losses=hvdc_losses,
                         hvdc_loading=hvdc_loading,
                         failed_br_idx=failed_br_idx,
                         loading_label=loading_label,
                         ma=ma,
                         theta=theta,
                         Beq=Beq,
                         use_flow_based_width=use_flow_based_width,
                         min_branch_width=min_branch_width,
                         max_branch_width=max_branch_width,
                         min_bus_width=min_bus_width,
                         max_bus_width=max_bus_width,
                         )
示例#11
0
    def run(self):
        """
        run the file open procedure
        """
        self.circuit = MultiCircuit()

        path, fname = os.path.split(self.file_name)

        self.progress_text.emit('Loading ' + fname + '...')

        self.logger = list()

        file_handler = FileOpen(file_name=self.file_name)

        self.circuit = file_handler.open(
            text_func=self.progress_text.emit,
            progress_func=self.progress_signal.emit)

        self.logger += file_handler.logger
        self.valid = True

        # post events
        self.progress_text.emit('Done!')

        self.done_signal.emit()
示例#12
0
def get_shunt_data(circuit: MultiCircuit,
                   bus_dict,
                   time_series=False,
                   ntime=1):
    """

    :param circuit:
    :param bus_dict:
    :param time_series:
    :return:
    """
    devices = circuit.get_shunts()

    data = ShuntData(nshunt=len(devices), nbus=len(circuit.buses), ntime=ntime)

    for k, elm in enumerate(devices):

        i = bus_dict[elm.bus]

        data.shunt_names[k] = elm.name

        if time_series:
            data.shunt_active[k, :] = elm.active_prof
            data.shunt_admittance[k, :] = elm.G_prof + 1j * elm.B_prof
        else:
            data.shunt_active[k] = elm.active
            data.shunt_admittance[k] = complex(elm.G, elm.B)

        data.C_bus_shunt[i, k] = 1

    return data
示例#13
0
def select_branches_to_reduce(circuit: MultiCircuit, rx_criteria=True, rx_threshold=1e-5,
                              selected_types=BranchType.Branch):
    """
    Find branches to remove
    Args:
        circuit: Circuit to modify in-place
        rx_criteria: use the r+x threshold to select branches?
        rx_threshold: r+x threshold
        selected_types: branch types to select
    """

    branches_to_remove_idx = list()
    branches = circuit.get_branches()
    for i in range(len(branches)):

        # is this branch of the selected type?
        if branches[i].branch_type in selected_types:

            # Am I filtering by r+x threshold?
            if rx_criteria:

                # compute the r+x ratio
                rx = branches[i].R + branches[i].X

                # if the r+x criteria is met, add it
                if rx < rx_threshold:
                    print(i, '->', rx, '<', rx_threshold)
                    branches_to_remove_idx.append(i)

            else:
                # Add the branch because it was selected and there is no further criteria
                branches_to_remove_idx.append(i)

    return branches_to_remove_idx
示例#14
0
def get_allowed_sheets(circuit=MultiCircuit()):
    """

    :param circuit:
    :return:
    """
    ########################################################################################################
    # declare objects to iterate  name: [sample object, list of objects, headers]
    ########################################################################################################
    object_types = get_objects_dictionary(circuit)

    ########################################################################################################
    # generic object iteration
    ########################################################################################################

    allowed_data_sheets = {
        'Conf': None,
        'config': None,
        'wires': None,
        'overhead_line_types': None,
        'underground_cable_types': None,
        'sequence_line_types': None,
        'transformer_types': None,
        'time': None,
        'load_Sprof': complex,
        'load_Iprof': complex,
        'load_Zprof': complex,
        'static_generator': None,
        'static_generator_Sprof': complex,
        'static_generator_P_prof': complex,
        'static_generator_Q_prof': complex,
        'battery': None,
        'battery_Vset_profiles': float,
        'battery_P_profiles': float,
        'controlled_generator': None,
        'CtrlGen_Vset_profiles': float,
        'CtrlGen_P_profiles': float,
        'shunt_Y_profiles': complex,
        'tower_wires': None
    }

    for object_type_name in object_types.keys():

        object_sample, lists_of_objects = object_types[object_type_name]

        for main_property, profile_property in object_sample.properties_with_profile.items(
        ):

            if profile_property not in allowed_data_sheets.keys():
                # create the profile
                allowed_data_sheets[
                    object_type_name + '_' +
                    profile_property] = object_sample.editable_headers[
                        main_property].tpe

        # declare the DataFrames for the normal data
        allowed_data_sheets[object_type_name] = None

    return allowed_data_sheets
示例#15
0
def get_load_data(circuit: MultiCircuit,
                  bus_dict,
                  opf_results=None,
                  time_series=False,
                  opf=False,
                  ntime=1):
    """

    :param circuit:
    :param bus_dict:
    :param opf_results:
    :param time_series:
    :param opf:
    :param ntime:
    :return:
    """

    devices = circuit.get_loads()

    if opf:
        data = LoadOpfData(nload=len(devices),
                           nbus=len(circuit.buses),
                           ntime=ntime)
    else:
        data = LoadData(nload=len(devices),
                        nbus=len(circuit.buses),
                        ntime=ntime)

    for k, elm in enumerate(devices):

        i = bus_dict[elm.bus]

        data.load_names[k] = elm.name
        data.load_active[k] = elm.active

        if time_series:
            data.load_s[k, :] = elm.P_prof + 1j * elm.Q_prof

            if opf:
                data.load_cost[k, :] = elm.Cost_prof

            if opf_results is not None:
                data.load_s[k, :] -= opf_results.load_shedding[:, k]

        else:
            data.load_s[k] = complex(elm.P, elm.Q)

            if opf:
                data.load_cost[k] = elm.Cost

            if opf_results is not None:
                data.load_s[k] -= opf_results.load_shedding[k]

        data.C_bus_load[i, k] = 1

    return data
示例#16
0
    def __init__(
        self,
        parent=None,
    ):
        """

        :param parent:
        """
        QDialog.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowTitle('Grid Generator')

        self.g = RpgAlgorithm()
        self.circuit = MultiCircuit()
        self.applied = False

        self.ui.applyButton.clicked.connect(self.apply)
        self.ui.previewButton.clicked.connect(self.preview)
    def collect_measurements(circuit: MultiCircuit, bus_idx, branch_idx):
        """
        Form the input from the circuit measurements
        :return: nothing, the input object is stored in this class
        """
        se_input = StateEstimationInput()

        # collect the bus measurements
        for i in bus_idx:

            for m in circuit.buses[i].measurements:

                if m.measurement_type == MeasurementType.Pinj:
                    se_input.p_inj_idx.append(i)
                    se_input.p_inj.append(m)

                elif m.measurement_type == MeasurementType.Qinj:
                    se_input.q_inj_idx.append(i)
                    se_input.q_inj.append(m)

                elif m.measurement_type == MeasurementType.Vmag:
                    se_input.vm_m_idx.append(i)
                    se_input.vm_m.append(m)

                else:
                    raise Exception('The bus ' + str(circuit.buses[i]) +
                                    ' contains a measurement of type ' +
                                    str(m.measurement_type))

        # collect the branch measurements
        branches = circuit.get_branches()
        for i in branch_idx:

            # branch = circuit.branches[i]

            for m in branches[i].measurements:

                if m.measurement_type == MeasurementType.Pflow:
                    se_input.p_flow_idx.append(i)
                    se_input.p_flow.append(m)

                elif m.measurement_type == MeasurementType.Qflow:
                    se_input.q_flow_idx.append(i)
                    se_input.q_flow.append(m)

                elif m.measurement_type == MeasurementType.Iflow:
                    se_input.i_flow_idx.append(i)
                    se_input.i_flow.append(m)

                else:
                    raise Exception('The branch ' + str(branches[i]) +
                                    ' contains a measurement of type ' +
                                    str(m.measurement_type))

        return se_input
示例#18
0
def open_h5(file_path):

    circuit = MultiCircuit()

    store = pd.HDFStore(file_path)

    dfs = dict()
    for group in store.root:
        dfs[group._v_name] = pd.read_hdf(store, group._v_pathname)

    return dfs
示例#19
0
    def __init__(self, file_name, cim_tp_file_name='', cim_eq_file_name=''):
        """
        File open handler
        :param file_name: name of the file
        """
        self.file_name = file_name
        self.cim_tp_file_name = cim_tp_file_name
        self.cim_eq_file_name = cim_eq_file_name

        self.circuit = MultiCircuit()

        self.logger = Logger()
示例#20
0
    def parse_bus_bars(self, cim: CIMCircuit, circuit: MultiCircuit):
        """

        :param cim:
        :param circuit:
        :return:
        """

        busbar_dict = dict()

        if 'BusbarSection' in cim.elements_by_type.keys():
            for elm in cim.elements_by_type['BusbarSection']:

                obj = gcdev.Bus(name=str(elm.name), idtag=elm.uuid)

                circuit.add_bus(obj)

                busbar_dict[elm] = obj
        else:
            self.logger.add_error(
                "No BusbarSections: There is no chance to reduce the grid")

        return busbar_dict
示例#21
0
    def parse_ac_line_segment(self, cim: CIMCircuit, circuit: MultiCircuit,
                              busbar_dict):
        """

        :param cim:
        :param circuit:
        :param busbar_dict:
        :return:
        """

        if 'ACLineSegment' in cim.elements_by_type.keys():
            for elm in cim.elements_by_type['ACLineSegment']:

                b1, b2 = elm.get_buses()

                B1, B2 = try_buses(b1, b2, busbar_dict)

                if B1 is not None and B2 is not None:
                    R, X, G, B = elm.get_pu_values()
                    rate = elm.get_rate()

                    # create AcLineSegment (Line)
                    line = gcdev.Line(idtag=elm.uuid,
                                      bus_from=B1,
                                      bus_to=B2,
                                      name=str(elm.name),
                                      r=R,
                                      x=X,
                                      b=B,
                                      rate=rate,
                                      active=True,
                                      mttf=0,
                                      mttr=0)

                    circuit.add_line(line)
                else:
                    self.logger.add_error('Bus not found', elm.rfid)
示例#22
0
def save_json_file(file_path, circuit: MultiCircuit):
    """
    Save JSON file
    :param file_path: file path 
    :param circuit: GridCal MultiCircuit element
    """
    elements = list()  # list of
    key = 0
    bus_key_dict = dict()
    logger = list()

    # add the circuit
    circuit_dict = circuit.get_json_dict(key)
    elements.append(circuit_dict)
    key += 1

    # add the buses
    for bus in circuit.buses:

        # pack the bus data into a dictionary
        dictionary = bus.get_json_dict(key)
        dictionary['circuit'] = circuit_dict[
            'id']  # add the circuit id on each bus
        elements.append(dictionary)
        bus_key_dict[bus] = key
        key += 1

        # pack all the elements within the bus
        for device in bus.loads + bus.controlled_generators + bus.static_generators + bus.batteries + bus.shunts:
            dictionary = device.get_json_dict(key, bus_key_dict)
            elements.append(dictionary)
            key += 1

    # branches
    for branch in circuit.branches:
        # pack the branch data into a dictionary
        dictionary = branch.get_json_dict(key, bus_key_dict)
        elements.append(dictionary)
        key += 1

    # convert the list of dictionaries to json
    json_str = json.dumps(elements, indent=True)

    # Save json to a text file file
    text_file = open(file_path, "w")
    text_file.write(json_str)
    text_file.close()

    return logger
示例#23
0
    def parse_shunts(self, cim: CIMCircuit, circuit: MultiCircuit,
                     busbar_dict):
        """

        :param cim:
        :param circuit:
        :param busbar_dict:
        :return:
        """
        if 'ShuntCompensator' in cim.elements_by_type.keys():
            for elm in cim.elements_by_type['ShuntCompensator']:
                b1 = elm.get_bus()
                B1 = try_bus(b1, busbar_dict)

                if B1 is not None:
                    g = 0
                    b = 0
                    sh = gcdev.Shunt(idtag=elm.uuid,
                                     name=str(elm.name),
                                     G=g,
                                     B=b)
                    circuit.add_shunt(B1, sh)
                else:
                    self.logger.add_error('Bus not found', elm.rfid)
示例#24
0
    def parse_generators(self, cim: CIMCircuit, circuit: MultiCircuit,
                         busbar_dict):
        """

        :param cim:
        :param circuit:
        :param busbar_dict:
        :return:
        """
        if 'SynchronousMachine' in cim.elements_by_type.keys():
            for elm in cim.elements_by_type['SynchronousMachine']:
                b1 = elm.get_bus()
                B1 = try_bus(b1, busbar_dict)

                if B1 is not None:

                    gen = gcdev.Generator(idtag=elm.uuid,
                                          name=str(elm.name),
                                          active_power=elm.p,
                                          voltage_module=1.0)
                    circuit.add_generator(B1, gen)

                else:
                    self.logger.add_error('Bus not found', elm.rfid)
示例#25
0
def open_sqlite(file_path):

    circuit = MultiCircuit()

    # make connection
    conn = sqlite3.connect(file_path)

    dfs = dict()

    # get the table names
    tables = conn.execute("SELECT name FROM sqlite_master WHERE type='table';")

    names = [t[0] for t in tables]

    check_names(names)

    for key in names:
        dfs[key] = pd.read_sql('select * from ' + key, conn)

    df = dfs['config']
    idx = df['Property'][df['Property'] == 'BaseMVA'].index
    if len(idx) > 0:
        dfs["baseMVA"] = np.double(df.values[idx, 1])
    else:
        dfs["baseMVA"] = 100

    idx = df['Property'][df['Property'] == 'Version'].index
    if len(idx) > 0:
        dfs["version"] = np.double(df.values[idx, 1])

    idx = df['Property'][df['Property'] == 'Name'].index
    if len(idx) > 0:
        dfs["name"] = df.values[idx[0], 1]
    else:
        dfs["name"] = 'Grid'

    idx = df['Property'][df['Property'] == 'Comments'].index
    if len(idx) > 0:
        dfs["Comments"] = df.values[idx[0], 1]
    else:
        dfs["Comments"] = ''

    # fill circuit data
    interpret_excel_v3(circuit, dfs)

    return circuit
示例#26
0
def get_objects_dictionary(circuit=MultiCircuit()):
    """

    :param circuit:
    :return:
    """
    object_types = {
        'bus': [Bus(), circuit.buses],
        'branch': [Branch(None, None), circuit.branches],
        'load': [Load(), circuit.get_loads()],
        'static_generator':
        [StaticGenerator(), circuit.get_static_generators()],
        'battery': [Battery(), circuit.get_batteries()],
        'generator': [Generator(), circuit.get_generators()],
        'shunt': [Shunt(), circuit.get_shunts()]
    }

    return object_types
示例#27
0
    def load_cim_file(self, cim_files):
        """
        Load CIM file
        :param cim_files: list of CIM files (.xml)
        """

        # declare GridCal circuit
        circuit = MultiCircuit()
        EPS = 1e-16

        # declare CIM circuit to process the file(s)
        self.cim = CIMCircuit(text_func=self.text_func,
                              progress_func=self.progress_func,
                              logger=self.logger)

        # import the cim files' content into a dictionary
        data = read_cim_files(cim_files)

        lst2 = sort_cim_files(list(data.keys()))
        # Parse the files
        for f in lst2:
            name, file_extension = os.path.splitext(f)
            self.emit_text('Parsing xml structure of ' + name)

            self.cim.parse_xml_text(text_lines=data[f])

        # replace CIM references in the CIM objects
        self.emit_text('Looking for CIM references...')
        self.cim.find_references()

        # Parse devices into GridCal
        self.emit_text('Converting CIM to GridCal...')
        self.parse_model(self.cim, circuit)
        busbar_dict = self.parse_bus_bars(self.cim, circuit)
        self.parse_ac_line_segment(self.cim, circuit, busbar_dict)
        self.parse_ac_line_segment(self.cim, circuit, busbar_dict)
        self.parse_power_transformer(self.cim, circuit, busbar_dict)
        self.parse_switches(self.cim, circuit, busbar_dict)
        self.parse_loads(self.cim, circuit, busbar_dict)
        self.parse_shunts(self.cim, circuit, busbar_dict)
        self.parse_generators(self.cim, circuit, busbar_dict)

        self.emit_text('Done!')
        return circuit
示例#28
0
def group_generators_by_technology(circuit: MultiCircuit):
    """
    Compose a dictionary of generator groups
    :param circuit: MultiCircuit
    :return: dictionary [Technology] : [generator indices]
    """
    gens = circuit.get_generators()

    groups = dict()

    for i, gen in enumerate(gens):

        if gen.technology in groups.keys():
            arr = np.r_[groups[gen.technology], i]
            groups[gen.technology] = arr

        else:
            groups[gen.technology] = np.array([i])

    return groups
示例#29
0
    def remove_elements(circuit: MultiCircuit, loading_vector, idx=None):
        """
        Remove branches based on loading
        Returns:
            Nothing
        """
        criteria = 'None'
        if idx is None:
            load = abs(loading_vector)
            idx = np.where(load > 1.0)[0]

            if len(idx) == 0:
                criteria = 'Loading'
                idx = np.where(load >= load.max())[0]

        # disable the selected branches
        # print('Removing:', idx, load[idx])
        branches = circuit.get_branches()
        for i in idx:
            branches[i].active = False

        return idx, criteria
示例#30
0
def get_shunt_data(circuit: MultiCircuit, bus_dict, Vbus, logger: Logger, time_series=False, ntime=1):
    """

    :param circuit:
    :param bus_dict:
    :param time_series:
    :return:
    """
    devices = circuit.get_shunts()

    data = ShuntData(nshunt=len(devices), nbus=len(circuit.buses), ntime=ntime)

    for k, elm in enumerate(devices):

        i = bus_dict[elm.bus]

        data.shunt_names[k] = elm.name
        data.shunt_controlled[k] = elm.is_controlled
        data.shunt_b_min[k] = elm.Bmin
        data.shunt_b_max[k] = elm.Bmax

        if time_series:
            data.shunt_active[k, :] = elm.active_prof
            data.shunt_admittance[k, :] = elm.G_prof + 1j * elm.B_prof
        else:
            data.shunt_active[k] = elm.active
            data.shunt_admittance[k] = complex(elm.G, elm.B)

        if Vbus[i, 0].real == 1.0:
            Vbus[i, :] = complex(elm.Vset, 0)
        elif elm.Vset != Vbus[i, 0]:
            logger.add_error('Different set points', elm.bus.name, elm.Vset, Vbus[i, 0])

        data.C_bus_shunt[i, k] = 1

    return data