Skip to content

Some enhancements on compatibility with PSS/E and MATPOWER #600

Description

@jinningwang

Is your feature request related to a problem? Please describe.
Interoperation with PSS/E and MATPOWER.

Describe the solution you'd like
Functions to export PSS/E dict to DYR file.

  • A function to write MATPOEWR mpc to M file.
  • A function to write Power Flow data to RAW file.
  • A function to write PSSE dict to DYR file.
  • A function to replace unsupported models with supported ones

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context

Two example code snippets for reference:

def write_dict_dyr(dyr_dict: Dict[str, pd.DataFrame], outfile: str):
    """
    Write a dictionary of dynamic models to a DYR file.

    This function takes a dictionary where the keys are model names (e.g., 'REGCA1', 'REECA1') 
    and the values are pandas DataFrames containing the model parameters. It writes the data 
    to a DYR file in the correct format, ensuring the following:
    - The first column (IBUS) is an integer representing the bus index.
    - The second column is the model name, enclosed in single quotes.
    - The third column (ID) is an integer representing the device index.
    - Remaining columns are the model parameters, written as space-separated values.
    - Each line ends with a trailing slash ('/').

    Models 'Toggle' are skipped during the writing process.

    Parameters:
    -----------
    dyr_dict : Dict[str, pd.DataFrame]
        A dictionary where each key is a model name and each value is a pandas DataFrame 
        containing the parameters for that model. The DataFrame must have the following structure:
        - Column 0: IBUS (integer)
        - Column 1: ID (integer)
        - Columns 2+: Model parameters (various types).
    
    outfile : str
        The path to the output DYR file where the formatted data will be written.

    Returns:
    --------
    None
        The function writes the data to the specified file and prints a success message.

    Notes:
    ------
    - The function skips models with the name 'Toggle' and prints a message for each skipped model.
    - A blank line is not added between models in the output file.
    - Ensure the input DataFrames are properly formatted to avoid runtime errors.

    Example:
    --------
    >>> dyr_dict = {
    ...     'REGCA1': pd.DataFrame([
    ...         [1004, 1, 1.0, 0.01, 10, 0.9, 0.5],
    ...         [1006, 1, 1.0, 0.02, 10, 0.9, 0.5]
    ...     ]),
    ...     'REECA1': pd.DataFrame([
    ...         [1004, 1, 0, 0, 1, 1, 1],
    ...         [1006, 1, 0, 0, 1, 1, 1]
    ...     ])
    ... }
    >>> write_dict_dyr(dyr_dict, './output.dyr')
    Data successfully written to ./output.dyr
    """
    with open(outfile, 'w') as f:
        for model_name, df in dyr_dict.items():
            if model_name in ['Toggle']:
                print(f"Skipped {model_name}")
                continue
            for _, row in df.iterrows():
                ibus = int(row.iloc[0])  # format IBUS as integer
                model = f"'{model_name}'"  # model name
                device_id = int(row.iloc[1])  # format ID as integer
                # format the rest parameters
                params = ' '.join(map(str, row.iloc[2:].values))
                # Combine all parts into a formatted line
                formatted_line = f"{ibus} {model} {device_id} {params} /"
                # Write the formatted line to the file
                f.write(formatted_line + '\n')

    print(f"Data successfully written to {outfile}")

Replace PSS2A with ST2CUT

# PSS2A -> ST2CUT, there are 22 columns in ST2CUT
ST2CUT = pd.DataFrame()

ST2CUT[0] = dyr['PSS2A'][0]  # IBUS
ST2CUT[1] = dyr['PSS2A'][1]  # ID

ST2CUT[2] = dyr['PSS2A'][2]  # M, IC1 <- M, ICS1
ST2CUT[3] = dyr['PSS2A'][3]  # M+1, IB1 <- M+1, REMBUS1
ST2CUT[4] = dyr['PSS2A'][4]  # M+2, IB2 <- M+2, ICS2
ST2CUT[5] = dyr['PSS2A'][5]  # M+3, IB3 <- M+3, REMBUS2

ST2CUT[6] = 1  # J, K1 <- 1
# J+1, K2 <- J+6, Ks2 * J+7, Ks3
ST2CUT[7] = dyr['PSS2A'][14] * dyr['PSS2A'][15]
ST2CUT[8] = dyr['PSS2A'][10]  # J+2, T1 <- J+2, T6
ST2CUT[9] = dyr['PSS2A'][13]  # J+3, T2 <- J+5, T7
ST2CUT[10] = sa.ST2CUT.T3.default  # J+4, T3 <- default
ST2CUT[11] = sa.ST2CUT.T4.default  # J+5, T4 <- default
ST2CUT[12] = dyr['PSS2A'][19]  # J+6, T5 <- J+11, T1
ST2CUT[13] = dyr['PSS2A'][20]  # J+7, T6 <- J+12, T2
ST2CUT[14] = dyr['PSS2A'][21]  # J+8, T7 <- J+13, T3
ST2CUT[15] = dyr['PSS2A'][22]  # J+9, T8 <- J+14, T4
ST2CUT[16] = sa.ST2CUT.T9.default  # J+10, T9 <- default
ST2CUT[17] = ST2CUT[16]  # J+11, T10 <- copy of T9
ST2CUT[18] = dyr['PSS2A'][23]  # J+12, LSMAX <- J+15, VSTMAX
ST2CUT[19] = dyr['PSS2A'][24]  # J+13, LSMIN <- J+16, VSTMIN
ST2CUT[20] = sa.ST2CUT.VCU.default  # J+14, VCU <- default
ST2CUT[21] = sa.ST2CUT.VCL.default  # J+15, VCL <- default

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions