OpenIPSL.Examples.Tutorial.Example_4.InstructionsThe system parameters for the static power flow model are listed below:
|
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).
| Name | Description |
|---|---|
| Assembling a SMIB System | |
| Creating the PF Structure | |
| Installing GridCal | |
| Populating PF Records | |
| More Detailed GU Models | |
| Automating Analysis |
OpenIPSL.Examples.Tutorial.Example_4.Instructions.SMIBSystemAssemblySMIB. Make sure to unselect the option to save the contents of the package in one file.
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. 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;
BaseNetwork, create a new partial model called SMIBPartial. 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.
GeneratorOnly. Your package should look as follows:
InfiniteBus, drag and drop a GENCLS generator model from OpenIPSL.Electrical.Machines.PSSE. GENCLS component to pwPin. GENROE generator model from OpenIPSL.Electrical.Machines.PSSE to GeneratorOnly.
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
GENCLS block inside the InfiniteBus model. Be sure to enter all the machine parameters in the figure below:
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;
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.
SMIBPartial model. Drag and drop the following components:
OpenIPSL.Buses.Bus (you could also work with OpenIPSL.Buses.BusExt); OpenIPSL.Branches.PwLine; Load from OpenIPSL.Electrical.Loads.PSSE; PwFault from OpenIPSL.Electrical.Events; SystemBase from OpenIPSL.Electrical.SystemBase. Set the base frequency to 50 Hz and the base to 100 MVA; InfiniteBus generation unit.
B01 component and select the option to display the power flow. Do the same for the remaining buses and the generation unit component. pwFault block and fill in the parameters as indicated below:
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:
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. genunit to bus B01. The model should look as follows:
SMIB. Extends from Modelica.Icons.Information (Icon for general information packages).
OpenIPSL.Examples.Tutorial.Example_4.Instructions.PFRecordCreationAfter completing the instructions in Assembling a SMIB System, you should have a SMIB folder inside your working directory.
SMIB_Example at the same level where the SMIB folder is located. models below your new SMIB_Example folder. SMIB folder below the previously added models folder. pf2rec folder from Resources to the SMIB_Example folder. 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
| ...
SMIB and name it Utilities. 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.
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
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. create_records Python script is placed and execute it as indicated below.
python create_records.py
) the SMIB package.
📌 The Python script create_records should have created a new package inside your model that looks like this
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.
| 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.
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.InstallingGridCalAt 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:
📌 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.
📌 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.
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>
<<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.
<<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>
pip cache.
python -m pip cache purge
(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>
(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.
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.
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.PopulatingRecordsThe 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.
SMIB_Example/models/SMIB folder.
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
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.
PF0000.mo inside your PFData folder. In fact, there should be a new file in every subfolder too.
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;
To see the power flow values in Dymola, click on the square button
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.
Inside each field, we can detail the power flow results
Extends from Modelica.Icons.Information (Icon for general information packages).
OpenIPSL.Examples.Tutorial.Example_4.Instructions.DefiningGenerationGroupsLet us now proceed to create alternative representations of a generation unit so that we can use them in our experiments.
GenerationUnits package and duplicate the GeneratorOnly model to create a new model called GeneratorTurbGov that also has a turbine/governor block.
IEEEG1 turbine/governor block from OpenIPSL.Electrical.Controls.PSSE.TG.
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:
IEEEG1 parameters:
SMIB experiment model and double-click the genunit component. OpenIPSL.Interfaces.Generator from the drop-down list.
📌 The GenerationUnit icon should now turn into
SMIB model and right-click the genunit block to change the class to the " Machine with Turbine and Governor" option.
GeneratorTurbGovAVR. For this to be done make sure you duplicate the GeneratorTurbGov model.
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.
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.
| GENROE Machine | EEST1A |
|---|---|
ETERM |
VT |
ETERM |
ECOMP |
EFD0 |
EFD0 |
XADIFD |
XADIFD |
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:
SMIB experiment model and change the class of the genunit component so that it now uses the model with the excitation system. 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.
SMIB model for 10 seconds.
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).
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. VOTHSG input of the excitation system component. Now this input should be connected to the output of the PSS2A block. 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:
PSS2A component in order to update the parameters as indicated below:
Extends from Modelica.Icons.Information (Icon for general information packages).
OpenIPSL.Examples.Tutorial.Example_4.Instructions.AutomatingAnalysisSMIBPartial model. Remember that this model is located in the following path: SMIB.BaseModels.BaseNetwork.
. From the package tree select OpenIPSL.Electrical.Loads.PSSE.BaseClasses.baseLoad as shown in the figure below.
Experiments package, create a new model by duplicating SMIB and name it SMIBVarLoad.
SMIBVarLoad model and change the class to PSS/E Load with variation as indicated in the following picture:
SMIBVarLoad model to the GeneratorTurbGovAVRPSS model. You will find it as "Machine with Turbine, Governor, Excitation System and PSS".
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.
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:
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";
...
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;
RunAndCompare function, select the Call Function... option and then press OK. If everything goes well you will get the plots shown below.
Extends from Modelica.Icons.Information (Icon for general information packages).
Automatically generated Thu Feb 26 06:55:58 2026.