OpenIPSL.Examples.Tutorial.Example_4.Instructions OpenIPSL.Examples.Tutorial.Example_4.Instructions

Before You Start

Prerequisites
System Parameters

The system parameters for the static power flow model are listed below:

* A three-phase fault is to be set at bus FAULT

Bus No.

Bus Name

Type

V (pu)

Angle

P (MW)

Q (Mvar)

1

B01

PV

1.0000

From PF

40.0000

From PF

2

B02

Slack

1.0000

0.0000

From PF

From PF

3

B03*

PQ

From PF

From PF

0.0000

0.0000

4

B04

PQ

From PF

From PF

50.0000

10.0000

 

Line Name

From Bus

To Bus

R (pu)

X (pu)

B (pu)

line_01

B01

B03

0.0010

0.2000

0.0000

line_02

B03

B02

0.0010

0.2000

0.0000

line_03

B03

B04

0.0005

0.1000

0.0000

line_04

B04

B02

0.0005

0.1000

0.0000

 

For the dynamic part of the simulation, the parameters of the models are:

Generator (Bus)

Generator Type

Exciter

Turbine Governor

Stabilizer

1

GENROE

None

None

None

3

GENCLS

None

None

None

 

Generator (Bus)

Parameter

Value

GENROE

Mbase

100 MVA

T'do (> 0)

5.0000

T''do (> 0)

0.0700

T'qo (> 0)

0.9000

T''qo (> 0)

0.0900

H, Inertia

4.2800

D, Speed Damping

0.0000

Xd

1.8400

Xq

1.7500

X'd

0.4100

X'q

0.6000

X''d = X''q

0.2000

Xl

0.1200

S(1.0)

0.1100

S(1.2)

0.3900

Ra

0.0000

Xsource (= Xpq)

0.2000

GENCLS

Mbase

100 MVA

Inertia H

5.0000

Damping Constant D

0.0000

Ra

0.0000

XSource

0.2000

Extends from Modelica.Icons.Information (Icon for general information packages).

Package Content

Name Description
OpenIPSL.Examples.Tutorial.Example_4.Instructions.SMIBSystemAssembly SMIBSystemAssembly Assembling a SMIB System
OpenIPSL.Examples.Tutorial.Example_4.Instructions.PFRecordCreation PFRecordCreation Creating the PF Structure
OpenIPSL.Examples.Tutorial.Example_4.Instructions.InstallingGridCal InstallingGridCal Installing GridCal
OpenIPSL.Examples.Tutorial.Example_4.Instructions.PopulatingRecords PopulatingRecords Populating PF Records
OpenIPSL.Examples.Tutorial.Example_4.Instructions.DefiningGenerationGroups DefiningGenerationGroups More Detailed GU Models
OpenIPSL.Examples.Tutorial.Example_4.Instructions.AutomatingAnalysis AutomatingAnalysis Automating Analysis

OpenIPSL.Examples.Tutorial.Example_4.Instructions.SMIBSystemAssembly OpenIPSL.Examples.Tutorial.Example_4.Instructions.SMIBSystemAssembly

Assembling a SMIB System
  1. Open Dymola.
  2. Load the OpenIPSL library.
  3. Create a new package called SMIB. Make sure to unselect the option to save the contents of the package in one file.

    SMIBPackageCreation

  4. Inside SMIB create two sub-packages named Experiments and BaseModels. Then add two sub-packages inside BaseModels called GenerationUnits and BaseNetwork. Once again, remember to keep the option to " save the contents of the package in one file" unselected.
  5. To follow the structure and appearance convention of packages in Modelica, we can add an icon to the Experiments package. Double-click the Experiments package and go to the text layer to add the following line of class extension:
    package Experiments
       extends Modelica.Icons.Example;
    
    end Experiments;
        
  6. Inside BaseNetwork, create a new partial model called SMIBPartial.
  7. Go to the Package Browser, navigate to OpenIPSL.Interfaces.Generator, and right-click the icon to create a new model by class extension. Name the new model InfiniteBus and place it inside GenerationUnits.

    InfiniteBusModelCreation

  8. Repeat the procedure to create a new model called GeneratorOnly. Your package should look as follows:

    InitialPackageStructure

  9. Inside InfiniteBus, drag and drop a GENCLS generator model from OpenIPSL.Electrical.Machines.PSSE.
  10. Connect the blue pin of the GENCLS component to pwPin.
  11. Now drag and drop a GENROE generator model from OpenIPSL.Electrical.Machines.PSSE to GeneratorOnly.

    AddingGENROEBlock

  12. Connect the output pin PMECH0 on the right to the input pin PMECH on the left of the GENROE block. Do the same for the EFD0 output and input EFD on the bottom. Also, connect the blue pin to pwPin. Your connections should look as follows

    DefaultGENROEConnections

  13. Double click the GENCLS block inside the InfiniteBus model. Be sure to enter all the machine parameters in the figure below:

    GENCLSMachineParameters

  14. Switch to the Modelica Text of the InfiniteBus model. Propagate the power flow parameters one layer up as indicated in the highlighted text of the following code chunk:
    model InfiniteBus
      extends OpenIPSL.Interfaces.Generator;
      OpenIPSL.Electrical.Machines.PSSE.GENCLS gENCLS(P_0=P_0,
        Q_0=Q_0,
        v_0=v_0,
        angle_0=angle_0,
        M_b=100000000,
        H=5.0000,
        D=0.0000,
        R_a=0.0000,
        X_d=0.2000)
        a..;
    equation
      connect(gENCLS.p, pwPin)
        a..;
    end InfiniteBus;
        
  15. Go to the diagram layer of the GeneratorOnly model, double click the GENROE component and fill in the power flow data fields. Notice that no explicit values should be passed to v_0 ( V_0 in OpenIPSL 1.5), angle_0, P_0, and Q_0. These values are propagated from an upper layer.

    GENROEParameterPropagation

  16. Similarly, pass the dynamical machine parameters to the generator model

    GENROEMachineParameters

  17. Go now to the diagram layer of the SMIBPartial model. Drag and drop the following components:


  18. Connect and name the different components as shown below:

    SMIBModelConnections

  19. Enter the parameters for each of the four lines, as indicated in the corresponding table at the beginning of this document. For example, lines 1 and 2 should have the following parameters:

    LineParameters

  20. Click the B01 component and select the option to display the power flow. Do the same for the remaining buses and the generation unit component.
  21. Double click the pwFault block and fill in the parameters as indicated below:

    FaultBlockParameters

  22. Inside Experiments create a new model named SMIB by extending the SMIBPartial model. Although not entirely required, add the following line to the Modelica text to include an icon to the model:
    model SMIB
      extends Modelica.Icons.Example;
      extends BaseModels.BaseNetwork.SMIBPartial;
    end SMIB;
        

    📌 You should have a package structure similar to this:

    UpdatedPackageStructure


  23. Drag-and-drop a GeneratorOnly component from the GenerationUnits package to the diagram layer of the SMIB model. Name it genunit and make sure that the Display power flow option inside its parameters window is checked.
  24. Connect genunit to bus B01. The model should look as follows:

    FinalSMIBModel

  25. Save your models. You should see several .mo files accompanying the model inside a folder called SMIB.
  26. Close Dymola or unload your SMIB model.

Extends from Modelica.Icons.Information (Icon for general information packages).

OpenIPSL.Examples.Tutorial.Example_4.Instructions.PFRecordCreation OpenIPSL.Examples.Tutorial.Example_4.Instructions.PFRecordCreation

Creating and Integrating the Power Flow Structure

After completing the instructions in Assembling a SMIB System, you should have a SMIB folder inside your working directory.

  1. Create a directory called SMIB_Example at the same level where the SMIB folder is located.
  2. Create a directory called models below your new SMIB_Example folder.
  3. Move the SMIB folder below the previously added models folder.
  4. Copy the pf2rec folder from Resources to the SMIB_Example folder.
  5. Move the create_records.py and run_pf.py Python files one level up (i.e., to the SMIB_Example folder). The tree below shows how your folder structure should look like:
    C:\Users\...>tree /f /a SMIB_Example
    Folder PATH listing
    Volume serial number is ...
    C:\USERS\...\SMIB_Example
    |   create_records.py
    |   run_pf.py
    +---models
    |   \---SMIB
    |       |   ...
    |
    \---pf2rec
        |   create_pf_records.py
        |   generate_component_list.py
        |   gridcal2rec.py
        |   __init__.py
        |   ...
        
  6. Reload your model or run Dymola, depending on what you did at the end of the previous section. Create a package inside the root package SMIB and name it Utilities.
  7. Add a new function inside Utilities called saveTotalSMIBModel. Remember that the procedure for creating functions is the same as for other kinds of classes such as Package, Model or Record.
  8. Go to the Modelica text of the function and type the following code:
    function saveTotalSMIBModel "Save the SMIB package as a total model"
      extends Modelica.Icons.Function;
      output Boolean ok "= true if succesful";
    protected
      String targetDir = "C:/Users/Miguel/SMIB_Example/models/SMIB";
    algorithm
      ok := saveTotalModel(targetDir + "/" + "SMIBTotal.mo", "SMIB", true);
    end saveTotalSMIBModel;
        

    🔨 Update the targetDir variable value with the appropriate path to reach the SMIB folder.

    📌 This function has no inputs and only one boolean output. The modelica standard function saveTotalModel is called inside the algorithm section with predefined arguments. You can check the information view of saveTotalModel to get to know the proper use of each of its parameters. To do that, make sure the DymolaCommands library is loaded within the Package Browser. Then navigate as shown in the picture below

    SaveTotalModelFunction


  9. Right-click the saveTotalSMIBModel function from the Package Browser. Select the " Call Function..." option and then click the OK button. As a result, you should be able to see a new file called SMIBTotal.mo in the same folder where your model files are being stored.
  10. Go to the system terminal, change the current directory to the location where the create_records Python script is placed and execute it as indicated below.
    python create_records.py
        
  11. Go back to Dymola and refresh ( RefreshButton) the SMIB package.

    📌 The Python script create_records should have created a new package inside your model that looks like this

    PFDataPackageStructure


  12. Double-click the SMIBPartial model to open its diagram view. From the new PFData package, drag and drop one PowerFlow element on your canvas. For convenience, rename it as pf.

    PowerFlowRecordInstantiation

  13. Link the power flow variables to the different components as indicated below. Yes, unfortunately you must type them!

    ComponentReferenceToPFRecord

    Component V_0 A_0 P_0 Q_0
    B01 (bus) pf.powerflow.bus.v1 pf.powerflow.bus.A1 N/A N/A
    B02 (bus) pf.powerflow.bus.v2 pf.powerflow.bus.A2 N/A N/A
    B03 (bus) pf.powerflow.bus.v3 pf.powerflow.bus.A3 N/A N/A
    B04 (bus) pf.powerflow.bus.v4 pf.powerflow.bus.A4 N/A N/A
    load (load) pf.powerflow.bus.v3 pf.powerflow.bus.A3 pf.powerflow.load.PL1 pf.powerflow.load.QL1
    InfiniteBus (gen) pf.powerflow.bus.v2 pf.powerflow.bus.A2 pf.powerflow.machine.PG2 pf.powerflow.machine.QG2

         If you check your model now, you should see an error because we have not defined the power flow values. We have just pointed to the container which will have it. Next, we generate the power flow results using GridCal.

  14. Now open the diagram layer of your SMIB model inside the Experiments package. Link the power flow variables to genunit as specified in the following table:
    Component V_0 A_0 P_0 Q_0
    genunit (gen) pf.powerflow.bus.v1 pf.powerflow.bus.A1 pf.powerflow.machine.PG1 pf.powerflow.machine.QG1

Extends from Modelica.Icons.Information (Icon for general information packages).

OpenIPSL.Examples.Tutorial.Example_4.Instructions.InstallingGridCal OpenIPSL.Examples.Tutorial.Example_4.Instructions.InstallingGridCal

Installing GridCal

At this point, we have a record structure to keep the power flow solutions linked to the SMIB power system elements. It is our next task to populate the records and for that to be done we need a Python script that runs a library called GridCal which computes the power flow. To properly install GridCal please follow the steps listed below:

  1. Download Python and install it. Note that GridCal developpers encourage to install the latest version of Python here.

    📌 To install Python for all users you must first run the installer as administrator. Then, you need to choose the Customize installation option. Click the Next button, which will open the Advanced Options window. Finally, tick the Install Python 3.x for all users checkbox before clicking the Install button.

    📌 Choosing the Customize installation option will also allow you to customize the install location.

    📌 If you want Python to be recognized as a command in every console/command window you need to add it to PATH. This can be done by clicking the Add python.exe to PATH checkbox from the initial window.


  2. (Optional) Create a new Python virtual environment to encapsulate the GridCal Installation and its dependencies.

    📌 Virtual environments allow you to separate particular experimental setups from the generic Python installation. This way, you can install GridCal and its dependencies on a virtual environment, which could later be removed without affecting your main Python installation.


    1. Open a command window/console and browse to the path where you want to create the virtual environment.
    2. Install the virtualenv tool by using the following command:
      python -m pip install virtualenv
              
      Example:
      C:\Users\Miguel\SMIB_Example>python -m pip list
      Package Version
      ------- -------
      pip 24.2
      
      C:\Users\Miguel\SMIB_Example>python -m pip install virtualenv
      Collecting virtualenv
        Downloading virtualenv-20.27.0-py3-none-any.whl.metadata (4.5 kB)
      ...
      Installing collected packages: distlib, platformdirs, filelock, virtualenv
      Successfully installed distlib-0.3.9 filelock-3.16.1 platformdirs-4.3.6 virtualenv-20.27.0
      
      C:\Users\Miguel\SMIB_Example>
              
    3. Type the following command where <<env_name>> should be replaced by the actual name you want to give to the environment (e.g., openipsl_tutorial).
      python -m venv <<env_name>>
              

      📌 A folder with the same name as your virtual environment (i.e., <<env_name>>) will be created in your current directory.


  3. (Optional) Activate the environment by calling the activate script located under .\<<env_name>>\Scripts\:
    C:\Users\Miguel\SMIB_Example>.\openipsl_tutorial\Scripts\activate
    
    (openipsl_tutorial) C:\Users\Miguel\SMIB_Example>
        

    📌 Please notice that whenever you want to use your environment again and your environment session is no longer open, you first need to open a command prompt/console, then locate the path where the environment is and finally call the activate script as indicated above. An environment session is typically finalized by calling the deactivate script.


    After successfully activating a virtual environment you will see the name of the environment enclosed in parenthesis as shown below

    (openipsl_tutorial) C:\Users\Miguel\SMIB_Example>
        
  4. Clean pip cache.
    python -m pip cache purge
        
  5. Install the gridcal python package as follows:
    (openipsl_tutorial) C:\Users\Miguel\SMIB_Example>python -m pip install gridcal
    Collecting gridcal
      Using cached GridCal-5.1.52.tar.gz (1.0 MB)
      Installing build dependencies ... done
      Getting requirements to build wheel ... done
      Preparing metadata (pyproject.toml) ... done
    Collecting setuptools>=41.0.1 (from gridcal)
      Using cached setuptools-75.2.0-py3-none-any.whl.metadata (6.9 kB)
    Collecting wheel>=0.37.2 (from gridcal)
    ...
    Successfully built gridcal GridCalEngine grapheme
    Installing collected packages: xlwt, wcwidth, pywin32, pytz, py4j, pure-eval, grapheme, xlrd, wrapt, wheel, websockets, urllib3, tzdata, traitlets, tornado, threadpoolctl, six, shiboken6, setuptools, pyzmq, pyqtdarktheme, pyparsing, pygments, psutil, prompt-toolkit, pluggy, platformdirs, pillow, parso, packaging, numpy, networkx, nest-asyncio, llvmlite, kiwisolver, joblib, iniconfig, idna, html5lib-modern, geographiclib, future, fonttools, executing, et-xmlfile, dill, decorator, debugpy, darkdetect, cycler, colorama, cloudpickle, charset-normalizer, chardet, certifi, about-time, tqdm, scipy, requests, rdflib, qtpy, python-dateutil, pytest, PySide6-Essentials, pyproj, pyarrow, openpyxl, opencv-python, numba, nptyping, matplotlib-inline, jupyter-core, jedi, highspy, h5py, geopy, Deprecated, contourpy, comm, cma, autograd, asttokens, alive-progress, stack-data, scikit-learn, PySide6-Addons, pandas, matplotlib, jupyter-client, hyperopt, windpowerlib, PySide6, pymoo, pvlib, ipython, ipykernel, qtconsole, GridCalEngine, gridcal
    Successfully installed Deprecated-1.2.14 GridCalEngine-5.1.52 PySide6-6.6.3.1 PySide6-Addons-6.6.3.1 PySide6-Essentials-6.6.3.1 about-time-4.2.1 alive-progress-3.1.5 asttokens-2.4.1 autograd-1.7.0 certifi-2024.8.30 chardet-5.2.0 charset-normalizer-3.4.0 cloudpickle-3.1.0 cma-3.2.2 colorama-0.4.6 comm-0.2.2 contourpy-1.3.0 cycler-0.12.1 darkdetect-0.8.0 debugpy-1.8.7 decorator-5.1.1 dill-0.3.9 et-xmlfile-1.1.0 executing-2.1.0 fonttools-4.54.1 future-1.0.0 geographiclib-2.0 geopy-2.4.1 grapheme-0.6.0 gridcal-5.1.52 h5py-3.12.1 highspy-1.8.0 html5lib-modern-1.2 hyperopt-0.2.7 idna-3.10 iniconfig-2.0.0 ipykernel-6.29.5 ipython-8.28.0 jedi-0.19.1 joblib-1.4.2 jupyter-client-8.6.3 jupyter-core-5.7.2 kiwisolver-1.4.7 llvmlite-0.43.0 matplotlib-3.9.2 matplotlib-inline-0.1.7 nest-asyncio-1.6.0 networkx-3.4.2 nptyping-2.5.0 numba-0.60.0 numpy-1.26.4 opencv-python-4.10.0.84 openpyxl-3.1.5 packaging-24.1 pandas-2.2.3 parso-0.8.4 pillow-11.0.0 platformdirs-4.3.6 pluggy-1.5.0 prompt-toolkit-3.0.48 psutil-6.1.0 pure-eval-0.2.3 pvlib-0.11.1 py4j-0.10.9.7 pyarrow-17.0.0 pygments-2.18.0 pymoo-0.6.1.3 pyparsing-3.2.0 pyproj-3.7.0 pyqtdarktheme-0.1.7 pytest-8.3.3 python-dateutil-2.9.0.post0 pytz-2024.2 pywin32-308 pyzmq-26.2.0 qtconsole-5.6.0 qtpy-2.4.1 rdflib-7.1.0 requests-2.32.3 scikit-learn-1.5.2 scipy-1.14.1 setuptools-75.2.0 shiboken6-6.6.3.1 six-1.16.0 stack-data-0.6.3 threadpoolctl-3.5.0 tornado-6.4.1 tqdm-4.66.5 traitlets-5.14.3 tzdata-2024.2 urllib3-2.2.3 wcwidth-0.2.13 websockets-13.1 wheel-0.44.0 windpowerlib-0.2.2 wrapt-1.16.0 xlrd-2.0.1 xlwt-1.3.0
    
    (openipsl_tutorial) C:\Users\Miguel\SMIB_Example>
        
  6. Verify that the Python packages were installed correctly, especially GridCal v5.1.52 or newer:
    (openipsl_tutorial) C:\Users\Miguel\SMIB_Example>python -m pip list
    Package Version
    ------------------ -----------
    about-time 4.2.1
    alive-progress 3.1.5
    asttokens 2.4.1
    ...
    grapheme 0.6.0
    GridCal 5.1.52
    GridCalEngine 5.1.52
    ...
    ipykernel 6.29.5
    ipython 8.28.0
    ...
    jupyter_core 5.7.2
    ...
    matplotlib 3.9.2
    matplotlib-inline 0.1.7
    nest-asyncio 1.6.0
    networkx 3.4.2
    ...
    numpy 1.26.4
    openpyxl 3.1.5
    ...
    pandas 2.2.3
    ...
    pywin32 308
    pyzmq 26.2.0
    qtconsole 5.6.0
    QtPy 2.4.1
    ...
    scipy 1.14.1
    setuptools 75.2.0
    ...
    xlrd 2.0.1
    xlwt 1.3.0
        

    📌 Remember that GridCal has only been installed in the current environment. Therefore, whenever you use a script that requires this library the environment should be activated.


  7. Test your installation running this Python command:
    import GridCalEngine.api as gce
        
    (openipsl_tutorial) C:\Users\Miguel\SMIB_Example>python
    Python 3.12.7 (tags/v3.12.7:0b05ead, Oct 1 2024, 03:06:41) [MSC v.1941 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import GridCalEngine.api as gce
    >>>
        

    As shown above you should not get any errors.

  8. (Optional but recommended) Install JupyterLab by using pip inside of your environment:
    pip install jupyterlab
        

    You can deactivate your environment at any time when you no longer require GridCal by using the following command:

    .\<<env_name>>\Scripts\deactivate
        

Extends from Modelica.Icons.Information (Icon for general information packages).

OpenIPSL.Examples.Tutorial.Example_4.Instructions.PopulatingRecords OpenIPSL.Examples.Tutorial.Example_4.Instructions.PopulatingRecords

Populating Power Flows with GridCal

The next step is to populate our model with power flow results generated from GridCal. For simplicity, we will create a power flow model from an accompanying PSS/E .raw. However, it is possible to run the power flows from a native GridCal model.

  1. Create a new PSSE_Files folder within SMIB_Example/models/SMIB folder.

    PSSEFilesFolder

  2. Create a new PSS/E raw file called SMIB_Base_Case.raw within the PSSE_Files folder. Copy and paste the following text inside the file and save it:
    0,   100.00, 33, 0, 1, 50.00     / PSS(R)E-33.4    FRI, FEB 26 2021  16:31
    SMIB
    
         1,'B01         ', 100.0000,2,   1,   1,   1,1.00000,   4.0463,1.10000,0.90000,1.10000,0.90000
         2,'B02         ', 100.0000,3,   1,   1,   1,1.00000,   0.0000,1.10000,0.90000,1.10000,0.90000
         3,'B03         ', 100.0000,1,   1,   1,   1,0.99598,  -0.2870,1.10000,0.90000,1.10000,0.90000
         4,'B04         ', 100.0000,1,   1,   1,   1,0.99199,  -0.5763,1.10000,0.90000,1.10000,0.90000
    0 / END OF BUS DATA, BEGIN LOAD DATA
         4,'1 ',1,   1,   1,    50.000,    10.000,     0.000,     0.000,     0.000,     0.000,   1,1,0
    0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA
    0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA
         1,'1 ',    40.000,     5.417,    60.000,     0.000,1.00000,     0,   100.000, 0.00000E+0, 2.00000E-1, 0.00000E+0, 0.00000E+0,1.00000,1,  100.0,    80.000,     0.000,   1,1.0000
         2,'1 ',    10.017,     8.007,    60.000,     0.000,1.00000,     0,   100.000, 0.00000E+0, 2.00000E-1, 0.00000E+0, 0.00000E+0,1.00000,1,  100.0,    80.000,     0.000,   1,1.0000
    0 / END OF GENERATOR DATA, BEGIN BRANCH DATA
         1,     4,'1 ', 1.00000E-3, 2.00000E-1,   0.00000,    0.00,    0.00,    0.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1,   0.00,   1,1.0000
         2,     3,'1 ', 5.00000E-4, 1.00000E-1,   0.00000,    0.00,    0.00,    0.00,  0.00000,  0.00000,  0.00000,  0.00000,1,2,   0.00,   1,1.0000
         2,     4,'1 ', 1.00000E-3, 2.00000E-1,   0.00000,    0.00,    0.00,    0.00,  0.00000,  0.00000,  0.00000,  0.00000,1,2,   0.00,   1,1.0000
         3,     4,'1 ', 5.00000E-4, 1.00000E-1,   0.00000,    0.00,    0.00,    0.00,  0.00000,  0.00000,  0.00000,  0.00000,1,2,   0.00,   1,1.0000
    0 / END OF BRANCH DATA, BEGIN TRANSFORMER DATA
    0 / END OF TRANSFORMER DATA, BEGIN AREA DATA
    0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA
    0 / END OF TWO-TERMINAL DC DATA, BEGIN VSC DC LINE DATA
    0 / END OF VSC DC LINE DATA, BEGIN IMPEDANCE CORRECTION DATA
    0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA
    0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA
    0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA
    0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA
    0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA
    0 / END OF OWNER DATA, BEGIN FACTS DEVICE DATA
    0 / END OF FACTS DEVICE DATA, BEGIN SWITCHED SHUNT DATA
    0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DATA
    0 / END OF GNE DATA, BEGIN INDUCTION MACHINE DATA
    0 / END OF INDUCTION MACHINE DATA
    Q
        
  3. Execute run_pf.py from a terminal.
    python run_pf.py SMIB
    
    (openipsl_tutorial) c:\Users\Miguel\SMIB_Example>python run_pf.py SMIB
    It 0, error 0.5, converged False, x [0. 0. 0. 1. 1.], dx not computed yet
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Iter: 1
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    It 1, error 0.016918884074426793, converged False, x [ 0.07000175 -0.00498304 -0.00996608  0.99658333  0.99316667], dx [ 0.07000175 -0.00498304 -0.00996608 -0.00341667 -0.00683333]
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Iter: 2
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    It 2, error 2.1358057256101737e-05, converged False, x [ 0.07061997 -0.00500866 -0.01005764  0.99598493  0.99199502], dx [ 0.00061822 -0.00002562 -0.00009156 -0.00059841 -0.00117164]
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Iter: 3
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    It 3, error 3.453681785003937e-11, converged False, x [ 0.0706208  -0.00500868 -0.01005778  0.99598418  0.99199354], dx [ 0.00000083 -0.00000002 -0.00000014 -0.00000075 -0.00000148]
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Iter: 4
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    It 4, error 3.802513859341161e-15, converged True, x [ 0.0706208  -0.00500868 -0.01005778  0.99598418  0.99199354], dx [ 0. -0. -0. -0. -0.]
    
    (openipsl_tutorial) c:\Users\Miguel\SMIB_Example>
    
        

    📌 A new power flow record called PF00000 should be generated inside the PFData subfolder.


  4. Refresh your model. You should get a new file called PF0000.mo inside your PFData folder. In fact, there should be a new file in every subfolder too.

    FilesAfterPFPopulation

  5. In the diagram layer of your SMIB model, double click the power flow component pf. Select the newly created power flow PF00000 as the value for the PowerFlow field. By doing so, we are specifying that the model will initialize using the power flow results in that specific container.

    📌 You can alternatively modify the Modelica Text of the SMIB Experiment model as follows:

    model SMIB
      extends Modelica.Icons.Example;
      extends BaseModels.BaseNetwork.SMIBPartial(pf(redeclare record PowerFlow = PFData.PF00000));
      replaceable BaseModels.GeneratingUnits.GeneratorOnly       genunit...
    equation
      ...
      annotation ...
    end SMIB;
        

    ChoosePopulatedPFRecord

    To see the power flow values in Dymola, click on the square button EditButton on the left of the PowerFlow selection menu.

    You should see that the power flow record is composed of four fields: bus, load, machine and transformer.

    InspectPFRecordValues

    Inside each field, we can detail the power flow results

    BusVoltageAndAngleValuesExample

  6. Simulate the SMIB model for 2 seconds. Plot the voltage buses. Notice that the power flow solution initializes the dynamical simulation in an equilibrium (i.e., flat) so that the states of the system are not changing.

    SimulationResultsWithInitialSSResponse

Extends from Modelica.Icons.Information (Icon for general information packages).

OpenIPSL.Examples.Tutorial.Example_4.Instructions.DefiningGenerationGroups OpenIPSL.Examples.Tutorial.Example_4.Instructions.DefiningGenerationGroups

Adding Generation Unit Models in More Detail

Let us now proceed to create alternative representations of a generation unit so that we can use them in our experiments.

  1. Expand your GenerationUnits package and duplicate the GeneratorOnly model to create a new model called GeneratorTurbGov that also has a turbine/governor block.

    GeneratorTurbGovModelCreation

  2. Go to the diagram layer of the model and drag-and-drop a IEEEG1 turbine/governor block from OpenIPSL.Electrical.Controls.PSSE.TG.
  3. It is highly recommended that you increase the dimensions of the canvas so that the components could be better distributed. One way of achieving this is by right-clicking the diagram layer and choosing the Attributes option. In the Graphics tab modify the coordinates as indicated below:

    AdjustDiagramCoordinates

  4. Remove the connection between the PMECH0 output and the PMECH input of the machine. Be aware that we now have a turbine block, therefore connect its HP-stage mechanical power output to the corresponding input of the machine. Your model should look like this:

    ConnectingTurbineGovernorBlock

  5. Provide the following values for the IEEEG1 parameters:

    SettingIEEEG1Parameters

  6. Check the model and make sure that everything is fine.
  7. Open the diagram layer of your SMIB experiment model and double-click the genunit component.
  8. Go to the Attributes tab and click the replaceable option. Then click the Constraining Clause checkbox and select OpenIPSL.Interfaces.Generator from the drop-down list.

    ReplaceableGenerator


    📌 The GenerationUnit icon should now turn into

    ReplaceableGenerationUnitIcon


  9. In Simulation Setup go to the Output tab and make sure that you are keeping at least 10 results:

    ResultsToKeep

  10. Go back to the diagram layer for the SMIB model and right-click the genunit block to change the class to the " Machine with Turbine and Governor" option.

    ChangeClassToMachineWithTurbGovernor

  11. Simulate the model again for 2 seconds.
  12. Plot the active power output (P) from genunit and compare it to the result you got from the previous simulation (where the generation unit model did not include the turbine/governor block).
  13. Create a new generation unit model including the electrical machine, the turbine/governor and an excitation system. Name the new model GeneratorTurbGovAVR. For this to be done make sure you duplicate the GeneratorTurbGov model.

    CreateGeneratorTurbGovAVR

  14. Drag-and-drop an ESST1A excitation system block from OpenIPSL.Electrical.Controls.PSSE.ES to the diagram layer of the new model. Add 4 Constant blocks from Modelica.Blocks.Sources too.
  15. Increase the dimensions of the diagram layer as required to comfortably resize and connect your components. Check out what we did in step 3. A suggestion is shown below:

    AdjustDiagramCoordinatesB

  16. In the GENROE machine component, remove the connection between EFD and EFD0. The EFD input of the machine should now be connected to the respective output from the excitation system.
  17. Add the following connections between the machine and the excitation system:

     

    GENROE Machine EEST1A

    ETERM

    VT

    ETERM

    ECOMP

    EFD0

    EFD0

    XADIFD

    XADIFD

     

  18. Use the Constant blocks to set the excitation system inputs to the values indicated in the following table:

     

    Input Value

    VOTHSG

    0

    VOTHSG2

    0

    VUEL

    0

    VOEL

    Modelica.Constants.inf

    VUEL2

    -Modelica.Constants.inf

    VUEL3

    -Modelica.Constants.inf

     

    Your model should now look like this:

    ConnectingExcitationSystemBlock

  19. Double-click the excitation system component and input the parameter values as indicated below:

    SettingESST1AParameters

  20. Check the generation unit model to verify that everything is fine. Then go to the SMIB experiment model and change the class of the genunit component so that it now uses the model with the excitation system.
  21. In the diagram layer of the SMIB model when right-clicking the genunit component, you should now be able to see the new generation unit model among the options for class change. Update the component class so that it uses the most recent generation unit model.

    ChangeClassToMachineWithTurbGovernorPSS

  22. Simulate the SMIB model for 10 seconds.
  23. Plot the active power (P) and the reactive power (Q) outputs from genunit in different diagrams. Then, plot the voltage (V) from all the buses in another window.
  24. Go to the GenerationUnits package and create a new model by duplicating GeneratorTurbGovAVR. Name the new model GeneratorTurbGovAVRPSS. This generation unit model is going to include a power system stabilizer (PSS).

    CreateGeneratorTurbGovAVRPSS

  25. Navigate the OpenIPSL.Electrical.Controls.PSSE.PSS package and locate the PSS2A model (Dual-Input Stabilizer Model [IEEE1992]). Drag-and-drop an instance to the diagram layer of the new generation unit model.
  26. Remove the constant source block that is connected to the VOTHSG input of the excitation system component. Now this input should be connected to the output of the PSS2A block.
  27. Connect the V_S1 and V_S2 inputs of the PSS2A block to the SPEED_HP and PELEC outputs of the machine component, respectively.

    Make sure that your model looks like the figure below:

    ConnectingPSSBlock

  28. Double-click the PSS2A component in order to update the parameters as indicated below:

    SettingPSS2AParameters

Extends from Modelica.Icons.Information (Icon for general information packages).

OpenIPSL.Examples.Tutorial.Example_4.Instructions.AutomatingAnalysis OpenIPSL.Examples.Tutorial.Example_4.Instructions.AutomatingAnalysis

Automating Analysis with Modelica functions
  1. Open the diagram layer of the SMIBPartial model. Remember that this model is located in the following path: SMIB.BaseModels.BaseNetwork.
  2. Double-click the load component and go to the Attributes tab. In the Properties group select the Replaceable option. Then click the Constraining clause checkbox and browse for class by pressing the button ExpandButton. From the package tree select OpenIPSL.Electrical.Loads.PSSE.BaseClasses.baseLoad as shown in the figure below.

    ReplaceableLoad

  3. In the package browser, go to the Experiments package, create a new model by duplicating SMIB and name it SMIBVarLoad.

    CreateSMIBVarLoadModel

  4. Now right-click the load component of the SMIBVarLoad model and change the class to PSS/E Load with variation as indicated in the following picture:

    ChangeClassToLoadWithVariation

  5. Double-click the load component to update its power flow parameters. You can either use the button to insert a component reference or type directly each value according to the following settings:

     

     

  6. Specify a load drop of 0.1 pu starting at t = 10 sec and for a duration of 60 sec.

    SettingVariableLoadParameters

  7. This time we want to see the effect of a perturbation on the load. Therefore, double-click the fault component and change its time parameters so that the fault event occurs after the new simulation stop time (100 sec).

    SettingFaultParameters

  8. Change the class of the genunit component of the SMIBVarLoad model to the GeneratorTurbGovAVRPSS model. You will find it as "Machine with Turbine, Governor, Excitation System and PSS".

    ChangeClassToMachineWithTurbGovernorPSS

  9. Go to the Simulation view and close all the results by right-clicking any of the results from the Variable Browser and then selecting the Close All Results option.

    CloseAllResults

    We would like to automatically simulate the SMIB and SMIBVarLoad models and plot their results for comparative purposes. For this to be done we are going to create and call a Modelica function that includes the right sequence of steps.

  10. Create a new Modelica function inside of the Experiments package. For this to be done you can go to File > New > Function after selecting the package, or alternatively, you can right-click the package and then click on New > Function. Name the function RunAndCompare. The Experiments package should now look like this:

    RunAndCompareFunction

  11. Go to the Modelica text of the RunAndCompare function and create 6 input variables as indicated below:
    function RunAndCompare
      "Runs different instances of the SMIB model to compare their results"
    
      // INPUTS TO THE FUNCTION
      input Modelica.Units.SI.Time tsim=100 "Simulation time";
      input Integer numberOfIntervalsin=10000 "No. of intervals";
      input String methodin = "Dassl" "Solver";
      input Real fixedstepsizein= 1e-3 "Time step - needed only for fixed time step solvers";
    
      // MODELS TO SIMULATE
      input String modelA="SMIB.Experiments.SMIB";
      input String modelB="SMIB.Experiments.SMIBVarLoad";
      ...
        
  12. Add the following code inside of the algorithm section of the function to define the simulation and plotting instructions:
    algorithm 
      simulateModel(
        modelA,
        stopTime=tsim,
        numberOfIntervals=numberOfIntervalsin,
        method = methodin,
        fixedstepsize=fixedstepsizein,
        resultFile="res_casea");
      simulateModel(
        modelB,
        stopTime=tsim,
        numberOfIntervals=numberOfIntervalsin,
        method = methodin,
        fixedstepsize=fixedstepsizein,
        resultFile="res_caseb");
    
      removePlots(true);
      Advanced.FilesToKeep :=10;
      createPlot(id=1, position={15, 15, 678, 703}, y={"B01.V"},
        range={0.0, 10.0, 0.4, 1.4}, grid=true, filename="res_casea.mat",
        colors={{28,108,200}}, displayUnits={"1"});
      createPlot(id=1, position={15, 15, 678, 703}, y={"genunit.P"},
        range={0.0, 10.0, -1.5, 2.0}, grid=true, subPlot=102,
        colors={{28,108,200}}, displayUnits={"1"});
      createPlot(id=1, position={15, 15, 678, 703}, y={"genunit.Q"},
        range={0.0, 10.0, -0.5, 2.0}, grid=true, subPlot=103,
        colors={{28,108,200}}, displayUnits={"1"});
      createPlot(id=1, position={15, 15, 678, 703}, y={"B01.V"},
        range={0.0, 10.0, 0.4, 1.4}, erase=false, grid=true,
        filename="res_caseb.mat", colors={{238,46,47}}, displayUnits={"1"},
        axes={2});
      createPlot(id=1, position={15, 15, 678, 703}, y={"genunit.P"},
        range={0.0, 10.0, -1.5, 2.0}, erase=false, grid=true, subPlot=102,
        colors={{238,46,47}}, displayUnits={"1"},
        axes={2});
      createPlot(id=1, position={15, 15, 678, 703}, y={"genunit.Q"},
        range={0.0, 10.0, -0.5, 2.0}, erase=false, grid=true, subPlot=103,
        colors={{238,46,47}}, displayUnits={"1"},
        axes={2});
    
    end RunAndCompare;
      
  13. Right-click the RunAndCompare function, select the Call Function... option and then press OK. If everything goes well you will get the plots shown below.

    GeneratedPowerAndBusVoltagePlots

Extends from Modelica.Icons.Information (Icon for general information packages).

Automatically generated Thu Feb 26 06:55:58 2026.