Home¶
ANDES is a Python-based free software package for power system simulation, control and analysis. It establishes a unique hybrid symbolic-numeric framework for modeling differential algebraic equations (DAEs) for numerical analysis. Main features of ANDES include
- a unique hybrid symbolic-numeric approach to modeling with automatic numerical code generation for simulation
- a rich library of transfer functions and discontinuous components (including limiters, deadbands, and saturation) available for prototyping models, which can be effortlessly instantiated as multiple devices for system analysis
- comes with the Newton method for power flow calculation, the implicit trapezoidal method for time-domain simulation, and full eigenvalue analysis
- strictly verified models with commercial software. ANDES obtains identical time-domain simulation results for IEEE 14-bus and NPCC system with GENROU and multiple controller models. See the verification link for details.
- developed with performance in mind. While written in Python, ANDES comes with a performance package and can finish a 20-second transient simulation of a 2000-bus system in a few seconds on a typical desktop computer
- out-of-the-box PSS/E raw and dyr file support for available models. Once a model is developed, inputs from a dyr file can be immediately supported
- an always up-to-date equation documentation of implemented models
ANDES is currently under active development. Use the following resources, in addition to the tutorial, to get involved.
- Checkout the Notebook examples in the examples folder
- Try ANDES in Jupyter Notebook with Binder
- Read the online manual at https://andes.readthedocs.io
- Download the PDF manual at download
- Report issues in the GitHub issues page
- Learn version control with the command-line git or GitHub Desktop
This work was supported in part by the Engineering Research Center Program of the National Science Foundation and the Department of Energy under NSF Award Number EEC-1041877 and the CURENT Industry Partnership Program. ANDES is made open source as part of the CURENT Large Scale Testbed project.
ANDES is developed and actively maintained by Hantao Cui. See the GitHub repository for a full list of contributors.
Installation¶
ANDES can be installed in Python 3.6+.
Environment¶
Setting Up Miniconda¶
We recommend the Miniconda distribution that includes the conda package manager and Python. Downloaded and install the latest Miniconda (x64, with Python 3) from https://conda.io/miniconda.html.
Step 1: Open the Anaconda Prompt and create an environment for ANDES (recommended)
conda create --name andes python=3.7
Activate the new environment with
conda activate andes
Environment activation needs to be executed every time a new Anaconda Prompt or shell is open.
Step 2: Add the conda-forge
channel and set it as default
conda config --add channels conda-forge
conda config --set channel_priority flexible
Existing Python Environment (Advanced)¶
This is for advanced user only. Please skip it if you have set up a Conda envirnonment. Instead of using Conda, if you prefer an existing Python environment, you can install ANDES with pip:
python3 -m pip install andes
If you see a Permission denied error, you will need to install the packages locally with --user
Install ANDES¶
ANDES can be installed in the user mode and the development mode.
User Mode¶
If you want to use ANDES without modifying the source code, you can install it in the user mode.
In the Anaconda environment, run
conda install andes
Developer Mode (Recommended)¶
If you want to hack into the code and, for example, develop new models or routines, please install it in the development mode (recommended). The development mode has the same usage as the user mode. In addition, changes to the source code will be reflected immediately without having to re-install the package.
Step 1: Get ANDES source code
Download the ANDES source code from
https://github.com/cuihantao/andes and extract all files to the path of your choice.
You can also git clone
the source code (recommended).
git clone https://github.com/cuihantao/andes
Step 2: Install dependencies
In the Anaconda environment, use cd
to change directory to the ANDES root folder.
Install dependencies with
conda install --file requirements.txt
conda install --file requirements-dev.txt
Step 3: Install ANDES in the development mode using
python3 -m pip install -e .
Pip will take care of the rest.
Performance Packages (Advanced)¶
The following two forks of cvxopt
, cvxoptklu
, cvxopt
with spmatrix.ipadd
are optional but can significantly boost the performance of ANDES.
Installation requires a C compiler, openblas
and SuiteSparse
libraries.
Note
Performance packages can be safely skipped and will not affect the functionality of ANDES.
Warning
We have not tried to compile either package on Windows. Refer to the CVXOPT installation instructions for Windows at http://cvxopt.org/install/index.html#windows
cxvoptklu¶
cvxoptklu
is a fork of the CVXOPT with KLU by Uriel Sandoval (@sanurielf).
In addition to UMFPACK, cvxoptklu
interfaces cvxopt
to KLU, which is
roughly 20% faster than UMFPACK for circuit simulation based on our testing.
Warning
There is likely a bug in the KLU interface which, for some cases, may segfault after applying a disturbance. The cause of the issue is currently unknown.
If you encounter a segfault while running time-domain simulation and was using the KLU solver, please switch back to UMFPACK by setting sparselib = umfpack or enable linsolve through linsolve = 1 for KLU, which re-factorizes the Jacobian matrix for each linear system solving step. Another solution is to use fixed time step size and reduce the step size from 1/30 s to 1/60s, but this is case specific.
This issue will not affect users who does not have cvxoptklu installed.
To install cvxoptklu
, on Debian GNU/Linux, one can do
sudo apt install libopenblas-dev libsuitesparse-dev
pip install cvxoptklu
On macOS, one can install with homebrew using
brew install openblas suitesparse
pip install cvxoptklu
To install from source code, use the repository at https://github.com/cuihantao/cvxoptklu.
CVXOPT with ipadd¶
To install our fork of cvxopt
with spmatrix.ipadd
, one need to clone the
repository and compile from source.
git clone https://github.com/curent/cvxopt
cd cvxopt
python setup.py build
The compilation may display some warnings, but make sure there is no error. Then, install it with
python setup.py install
Tutorial¶
ANDES can be used as a command-line tool or a library. The command-line interface (CLI) comes handy to run studies. As a library, it can be used interactively in the IPython shell or the Jupyter Notebook. This chapter describes the most common usages.
Please see the cheat sheet if you are looking for quick help.
Command Line Usage¶
Basic Usage¶
ANDES is invoked from the command line using the command andes
.
Running andes
without any input is equal to andes -h
or andes --help
.
It prints out a preamble with version and environment information and help commands:
_ _ | Version 0.8.4
/_\ _ _ __| |___ ___ | Python 3.7.1 on Darwin, 04/07/2020 10:22:17 PM
/ _ \| ' \/ _` / -_|_-< |
/_/ \_\_||_\__,_\___/__/ | This program comes with ABSOLUTELY NO WARRANTY.
usage: andes [-h] [-v {10,20,30,40,50}]
{run,plot,misc,prepare,doc,selftest} ...
positional arguments:
{run,plot,misc,prepare,doc,selftest}
[run] run simulation routine; [plot] plot simulation
results; [doc] quick documentation; [prepare] run the
symbolic-to-numeric preparation; [misc] miscellaneous
functions.
optional arguments:
-h, --help show this help message and exit
-v {10,20,30,40,50}, --verbose {10,20,30,40,50}
Program logging level in 10-DEBUG, 20-INFO,
30-WARNING, 40-ERROR or 50-CRITICAL.
The first level of commands are chosen from {run,plot,misc,prepare,selftest}
. Each command contains a group
of sub-commands, which can be looked up with -h
. For example, use andes run -h
to look up the sub-commands
in run
. The most commonly used commands will be explained in the following.
andes
has an option for the program verbosity level, controlled by -v
or --verbose
.
Accepted levels are the same as in the logging
module: 10 - DEBUG, 20 - INFO, 30 - WARNING, 40 - ERROR,
50 - CRITICAL.
To show debugging outputs, use -v 10
.
andes selftest¶
After installing ANDES, it is encouraged to use andes selftest
to run tests and check the basic functionality.
It might take a minute to run the whole self-test suite. Results are printed as the tests proceed. An example
output looks like
ANDES 0.8.1 (Git commit id gc954fc1, Python 3.7.3 on Linux)
Session: hcui7, 03/22/2020 11:02:35 AM
This program comes with ABSOLUTELY NO WARRANTY.
test_docs (test_1st_system.TestCodegen) ... ok
test_alter_param (test_case.Test5Bus) ... ok
test_as_df (test_case.Test5Bus) ... ok
test_cache_refresn (test_case.Test5Bus) ... ok
test_count (test_case.Test5Bus) ... ok
test_idx (test_case.Test5Bus) ... ok
test_init_order (test_case.Test5Bus) ... ok
test_names (test_case.Test5Bus) ... ok
test_pflow (test_case.Test5Bus) ... ok
test_pflow_reset (test_case.Test5Bus) ... ok
test_tds_init (test_case.Test5Bus) ... ok
test_eig_run (test_case.TestKundur2Area) ... ok
test_tds_run (test_case.TestKundur2Area) ... ok
test_npcc_raw (test_case.TestNPCCRAW) ... ok
test_npcc_raw_convert (test_case.TestNPCCRAW) ... ok
test_npcc_raw_tds (test_case.TestNPCCRAW) ... No dynamic component loaded.
ok
test_main_doc (test_cli.TestCLI) ... ok
test_misc (test_cli.TestCLI) ... ok
test_limiter (test_discrete.TestDiscrete) ... ok
test_sorted_limiter (test_discrete.TestDiscrete) ... ok
test_switcher (test_discrete.TestDiscrete) ... ok
test_tree (test_paths.TestPaths) ... ok
test_pflow_mpc (test_pflow_matpower.TestMATPOWER) ... ok
----------------------------------------------------------------------
Ran 23 tests in 13.834s
OK
Test cases can grow, and there could be more cases than above. Make sure that all tests have passed.
Warning
ANDES is getting updates frequently. After updating your copy, please run
andes selftest
to confirm the functionality. The command also makes sure the generated code is up to date.
See andes prepare for more details on automatic code generation.
andes prepare¶
The symbolically defined models in ANDES need to be generated into numerical code for simulation.
The code generation can be manually called with andes prepare
.
Generated code are stored in folder .andes/calls.pkl
in your home directory.
In addition, andes selftest
implicitly calls the code generation.
If you are using ANDES as a package in the user mode, you won't need to call it again.
For developers, andes prepare
needs to be called immediately following any model equation
modification. Otherwise, simulation results will not reflect the new equations and will likely lead to an error.
Option -q
or --quick
can be used to speed up the code generation.
It skips the generation of \(\LaTeX\)-formatted equations, which are only used in documentation and the interactive
mode.
Option -i
or --incremental
can be used to further speed up the code generation during model development.
andes prepare -qi
only generates code for models with modified equations.
andes run¶
andes run
is the entry point for power system analysis routines.
andes run
takes one positional argument, filename
, along with other optional keyword arguments.
filename
is the test case path, either relative or absolute.
Without other options, ANDES will run power flow calculation for the provided file.
Routine¶
Option -r
or -routine
is used for specifying the analysis routine, followed by the routine name.
Available routine names include pflow, tds, eig
.
pflow for power flow, tds for time domain simulation, and eig for eigenvalue analysis.
pflow is default even if -r
is not given.
For example, to run time-domain simulation for kundur_full.xlsx
in the current directory, run
andes run kundur_full.xlsx -r tds
The file is located at andes/cases/kundur/kundur_full.xlsx
relative to the source code root folder.
Use cd
to change directory to that folder on your machine.
Two output files, kundur_full_out.lst
and kundur_full_out.npy
will be created for variable names
and values, respectively.
Likewise, to run eigenvalue analysis for kundur_full.xlsx
, use
andes run kundur_full.xlsx -r eig
The eigenvalue report will be written in a text file named kundur_full_eig.txt
.
Power flow¶
To perform a power flow study for test case named kundur_full.xlsx
in the current directory, run
andes run kundur_full.xlsx
The full path to the case file is also accepted, for example,
andes run /home/user/andes/cases/kundur/kundur_full.xlsx
Power flow reports will be saved to the current directory in which andes is called. The power flow report contains four sections: a) system statistics, b) ac bus and dc node data, c) ac line data, and d) the initialized values of other algebraic variables and state variables.
Time-domain simulation¶
To run the time domain simulation (TDS) for kundur_full.xlsx
, run
andes run kundur_full.xlsx -r tds
The output looks like:
ANDES 0.6.8 (Git commit id 0ace2bc0, Python 3.7.6 on Darwin)
Session: hcui7, 02/09/2020 10:35:37 PM
Parsing input file </Users/hcui7/repos/andes/tests/kundur_full.xlsx>
Input file kundur_full.xlsx parsed in 0.5425 second.
-> Power flow calculation with Newton Raphson method:
0: |F(x)| = 14.9283
1: |F(x)| = 3.60859
2: |F(x)| = 0.170093
3: |F(x)| = 0.00203827
4: |F(x)| = 3.76414e-07
Converged in 5 iterations in 0.0080 second.
Report saved to </Users/hcui7/repos/andes/tests/kundur_full_out.txt> in 0.0036 second.
-> Time Domain Simulation:
Initialization tests passed.
Initialization successful in 0.0152 second.
0%| | 0/100 [00:00<?, ?%/s]
<Toggle 0>: Applying status toggle on Line idx=Line_8
100%|██████████████████████████████████████████| 100/100 [00:03<00:00, 28.99%/s]
Simulation completed in 3.4500 seconds.
TDS outputs saved in 0.0377 second.
-> Single process finished in 4.4310 seconds.
This execution first solves the power flow as a starting point. Next, the numerical integration simulates 20 seconds, during which a predefined breaker opens at 2 seconds.
TDS produces two output files by default: a NumPy data file ieee14_syn_out.npy
and a variable name list file ieee14_syn_out.lst
.
The list file contains three columns: variable indices, variable name in plain text, and variable
name in the \(\LaTeX\) format.
The variable indices are needed to plot the needed variable.
Disable output¶
The output files can be disabled with option --no-output
or -n
.
It is useful when only computation is needed without saving the results.
Profiling¶
Profiling is useful for analyzing the computation time and code efficiency.
Option --profile
enables the profiling of ANDES execution.
The profiling output will be written in two files in the current folder, one ending with _prof.txt
and the
other one with _prof.prof
.
The text file can be opened with a text editor, and the .prof
file can be visualized with snakeviz
,
which can be installed with pip install snakeviz
.
If the output is disabled, profiling results will be printed to stdio.
Multiprocessing¶
ANDES takes multiple files inputs or wildcard.
Multiprocessing will be triggered if more than one valid input files are found.
For example, to run power flow for files with a prefix of case5
and a suffix (file extension)
of .m
, run
andes run case5*.m
Test cases that match the pattern, including case5.m
and case57.m
, will be processed.
Option --ncpu NCPU
can be used to specify the maximum number of parallel processes.
By default, all cores will be used. A small number can be specified to increase operation system responsiveness.
Format converter¶
ANDES recognizes a few input formats and can convert input systems into the xlsx
format.
This function is useful when one wants to use models that are unique in ANDES.
The command for converting is --convert
(or -c
),
following the output format (only xlsx
is currently supported).
For example, to convert case5.m
into the xlsx
format, run
andes run case5.m --convert xlsx
The output will look like
ANDES 0.6.8 (Git commit id 0ace2bc0, Python 3.7.6 on Darwin)
Session: hcui7, 02/09/2020 10:22:14 PM
Parsing input file </Users/hcui7/repos/andes/cases/matpower/case5.m>
CASE5 Power flow data for modified 5 bus, 5 gen case based on PJM 5-bus system
Input file case5.m parsed in 0.0033 second.
xlsx file written to </Users/hcui7/repos/andes/cases/matpower/case5.xlsx>
Converted file /Users/hcui7/repos/andes/cases/matpower/case5.xlsx written in 0.5079 second.
-> Single process finished in 0.8765 second.
Note that --convert
will only create sheets for existing models.
In case one wants to create template sheets to add models later, --convert-all
can be used instead.
If one wants to add workbooks to an existing xlsx file,
one can combine option --add-book ADD_BOOK
(or -b ADD_BOOK
),
where ADD_BOOK
can be a single model name or comma-separated
model names (without any space). For example,
andes run wecc.raw -c -b Toggler
will convert file wecc.raw
into an ANDES xlsx file and append
a template workbook for Toggler at the end.
Warning
With --add-book
, the xlsx file will be overwritten.
Any empty or non-existent models will be REMOVED.
PSS/E inputs¶
To work with PSS/E input files (.raw and .dyr), one need to provide the
raw file as casefile
and pass the dyr file to --addfile
. For example,
in andes/andes/cases/wecc
, one can run the power flow using
andes run wecc.raw
and run a no-disturbance time-domain simulation using
andes run wecc.raw --addfile wecc_full.dyr -r tds
To create add a disturbance, there are two options. The recommended option is to convert the PSS/E data into an ANDES xlsx file, edit and run (see the previous subsection).
The alternative is to edit the dyr file and
append lines customized for ANDES models. This is for advanced users after
referring to andes/io/psse-dyr.yaml
, at the end of which one can find
the format of Toggler
:
# === Custom Models ===
Toggler:
inputs:
- model
- dev
- t
To define two Togglers in the dyr file, one can append lines to the end of the file using, for example,
Line 'Toggler' Line_2 1 /
Line 'Toggler' Line_2 1.1 /
which is separated by spaces and ended with a slash. The second parameter is fixed to the model name quoted by a pair of single quotation marks, and the others correspond to the fields defined in the above``inputs``.
Note
When working with PSS/E data, the recommended practice is to edit model dynamic parameters directly in the dyr file so that the data can be easily used by other tools.
andes plot¶
andes plot
is the command-line tool for plotting.
It currently supports time-domain simulation data.
Three positional arguments are required, and a dozen of optional arguments are supported.
positional arguments:
Argument Description filename simulation output file name, which should end with out. File extension can be omitted. x the X-axis variable index, typically 0 for Time y Y-axis variable indices. Space-separated indices or a colon-separated range is accepted
For example, to plot the generator speed variable of synchronous generator 1
omega GENROU 0
versus time, read the indices of the variable (2) and time
(0), run
andes plot kundur_full_out.lst 0 2
In this command, andes plot
is the plotting command for TDS output files.
kundur_full_out.lst
is list file name. 0
is the index of Time
for
the x-axis. 2
is the index of omega GENROU 0
. Note that for the the file name,
either kundur_full_out.lst
or kundur_full_out.npy
works, as the program will
automatically extract the file name.
The y-axis variabla indices can also be specified in the Python range fashion
. For example, andes plot kundur_full_out.npy 0 2:21:6
will plot the
variables at indices 2, 8, 14 and 20.
andes plot
will attempt to render with \(\LaTeX\) if dvipng
program is in the search path.
Figures rendered by \(\LaTeX\) is considerably better in symbols quality but takes much longer time.
In case \(\LaTeX\) is available but fails (frequently happens on Windows), the option -d
can be used to disable
\(\LaTeX\) rendering.
Other optional arguments are listed in the following.
- optional arguments:
Argument Description optional arguments: -h, --help show this help message and exit --xmin LEFT minimum value for X axis --xmax RIGHT maximum value for X axis --ymax YMAX maximum value for Y axis --ymin YMIN minimum value for Y axis --find FIND find variable indices that matches the given pattern --xargs XARGS find variable indices and return as a list of arguments usable with "| xargs andes plot" --exclude EXCLUDE pattern to exclude in find or xargs results -x XLABEL, --xlabel XLABEL x-axis label text -y YLABEL, --ylabel YLABEL y-axis label text -s, --savefig save figure. The default fault is png. -format SAVE_FORMAT format for savefig. Common formats such as png, pdf, jpg are supported --dpi DPI image resolution in dot per inch (DPI) -g, --grid grid on --greyscale greyscale on -d, --no-latex disable LaTeX formatting -n, --no-show do not show the plot window --ytimes YTIMES scale the y-axis values by YTIMES -c, --tocsv convert npy output to csv
andes doc¶
andes doc
is a tool for quick lookup of model and routine documentation.
It is intended as a quick way for documentation.
The basic usage of andes doc
is to provide a model name or a routine name as the positional argument.
For a model, it will print out model parameters, variables, and equations to the stdio.
For a routine, it will print out fields in the Config file.
If you are looking for full documentation, visit andes.readthedocs.io.
For example, to check the parameters for model Toggler
, run
$ andes doc Toggler
Model <Toggler> in Group <TimedEvent>
Time-based connectivity status toggler.
Parameters
Name | Description | Default | Unit | Type | Properties
-------+------------------------------+---------+------+------------+-----------
u | connection status | 1 | bool | NumParam |
name | device name | | | DataParam |
model | Model or Group of the device | | | DataParam | mandatory
| to control | | | |
dev | idx of the device to control | | | IdxParam | mandatory
t | switch time for connection | -1 | | TimerParam | mandatory
| status | | | |
To list all supported models, run
$ andes doc -l
Supported Groups and Models
Group | Models
-----------------+-------------------------------------------
ACLine | Line
ACTopology | Bus
Collection | Area
DCLink | Ground, R, L, C, RCp, RCs, RLs, RLCs, RLCp
DCTopology | Node
Exciter | EXDC2
Experimental | PI2
FreqMeasurement | BusFreq, BusROCOF
StaticACDC | VSCShunt
StaticGen | PV, Slack
StaticLoad | PQ
StaticShunt | Shunt
SynGen | GENCLS, GENROU
TimedEvent | Toggler, Fault
TurbineGov | TG2, TGOV1
To view the Config fields for a routine, run
$ andes doc TDS
Config Fields in [TDS]
Option | Value | Info | Acceptable values
-----------+-------+----------------------------------------+-------------------
sparselib | klu | linear sparse solver name | ('klu', 'umfpack')
tol | 0.000 | convergence tolerance | float
t0 | 0 | simulation starting time | >=0
tf | 20 | simulation ending time | >t0
fixt | 0 | use fixed step size (1) or variable | (0, 1)
| | (0) |
shrinkt | 1 | shrink step size for fixed method if | (0, 1)
| | not converged |
tstep | 0.010 | the initial step step size | float
max_iter | 15 | maximum number of iterations | >=10
andes misc¶
andes misc
contains miscellaneous functions, such as configuration and output cleaning.
Configuration¶
ANDES uses a configuration file to set runtime configs for the system routines, and models.
--save-config
saves all configs to a file. By default, it saves to ~/.andes/andes.conf
file, where ~
is the path to your home directory.
With --edit-config
, you can edit ANDES configuration handy.
The command will automatically save the configuration to the default location if not exist.
The shorter version --edit
can be used instead asn Python automatically matches it with --edit-config
.
You can pass an editor name to --edit
, such as --edit vim
.
If the editor name is not provided, it will use the following defaults:
- Microsoft Windows: notepad.
- GNU/Linux: the $EDITOR
environment variable, or vim
if not exist.
For macOS users, the default is vim.
If not familiar with vim, you can use nano with --edit nano
or TextEdit with
--edit "open -a TextEdit"
.
Cleanup¶
-C, --clean
Option to remove any generated files. Removes files with any of the following
suffix: _out.txt
(power flow report), _out.npy
(time domain data),
_out.lst
(time domain variable list), and _eig.txt
(eigenvalue report).
Interactive Usage¶
This section is a tutorial for using ANDES in an interactive environment. All interactive shells are supported, including Python shell, IPython, Jupyter Notebook and Jupyter Lab. The examples below uses Jupyter Notebook.
Jupyter Notebook¶
Jupyter notebook is used as an example. Jupyter notebook can be installed with
conda install jupyter notebook
After the installation, change directory to the folder that you wish to store notebooks, start the notebook with
jupyter notebook
A browser window should open automatically with the notebook browser loaded. To create a new notebook, use the "New" button at the top right corner.
Import¶
Like other Python libraries, ANDES can be imported into an interactive Python environment.
>>> import andes
>>> andes.config_logger()
The config_logger
is needed to print logging information in the current session.
Otherwise, information messages will be silenced, and only warnings and error will be printed.
To enable debug messages, use
>>> andes.config_logger(stream_level=10)
If you have not run andes prepare
, use the command once to generate code
>>> andes.prepare()
Create Test System¶
Before running studies, a "System" object needs to be create to hold the system data.
The System object can be created by passing the path to the case file the entrypoint function.
For example, to run the file kundur_full.xlsx
in the same directory as the notebook, use
>>> ss = andes.run('kundur_full.xlsx')
This function will parse the input file, run the power flow, and return the system as an object. Outputs will look like
Parsing input file </Users/hcui7/notebooks/kundur/kundur_full.xlsx>
Input file kundur_full.xlsx parsed in 0.4172 second.
-> Power flow calculation with Newton Raphson method:
0: |F(x)| = 14.9283
1: |F(x)| = 3.60859
2: |F(x)| = 0.170093
3: |F(x)| = 0.00203827
4: |F(x)| = 3.76414e-07
Converged in 5 iterations in 0.0222 second.
Report saved to </Users/hcui7/notebooks/kundur_full_out.txt> in 0.0015 second.
-> Single process finished in 0.4677 second.
In this example, ss
is an instance of andes.System
.
It contains member attributes for models, routines, and numerical DAE.
Naming convention for the System
attributes are as follows
- Model attributes share the same name as class names. For example,
ss.Bus
is theBus
instance. - Routine attributes share the same name as class names. For example,
ss.PFlow
andss.TDS
are the routine instances. - The numerical DAE instance is in lower case
ss.dae
.
Inspect Parameter¶
Parameters for the loaded system can be easily inspected in Jupyter Notebook using Pandas.
Input parameters for each model instance is in the cache.df_in
attribute.
For example, to view the input parameters for Bus
, use
>>> ss.Bus.cache.df_in
A table will be printed with the columns being each parameter and the rows being Bus instances. Parameter in the table is the same as the input file without per-unit conversion.
Parameters are converted to per unit values under system base.
To view the per unit values, use the cache.df
attribute.
For example, to view the system-base per unit value of GENROU
, use
>>> ss.GENROU.cache.df
Running Studies¶
Three routines are currently supported: PFlow, TDS and EIG.
Each routine provides a run()
method to execute.
The System instance contains member attributes having the same names.
For example, to run the time-domain simulation for ss
, use
>>> ss.TDS.run()
Plotting TDS Results¶
TDS comes with a plotting utility for interactive usage.
After running the simulation, a plotter
attributed will be created for TDS
.
To use the plotter, provide the attribute instance of the variable to plot.
For example, to plot all the generator speed, use
>>> ss.TDS.plotter.plot(ss.GENROU.omega)
Optional indices is accepted to choose the specific elements to plot.
It can be passed as a tuple to the a
argument
>>> ss.TDS.plotter.plot(ss.GENROU.omega, a=(0, ))
In the above example, the speed of the "zero-th" generator will be plotted.
Scaling¶
A lambda function can be passed to argument ycalc
to scale the values.
This is useful to convert a per-unit variable to nominal.
For example, to plot generator speed in Hertz, use
>>> ss.TDS.plotter.plot(ss.GENROU.omega, a=(0, ),
ycalc=lambda x: 60*x,
)
Formatting¶
A few formatting arguments are supported:
grid = True
to turn on grid displaygreyscale = True
to switch to greyscaleylabel
takes a string for the y-axis label
Pretty Print of Equations¶
Each ANDES models offers pretty print of \(\LaTeX\)-formatted equations in the jupyter notebook environment.
To use this feature, symbolic equations need to be generated in the current session using
import andes
ss = andes.System()
ss.prepare()
Or, more concisely, one can do
import andes
ss = andes.prepare()
This process may take several seconds to complete. Once done, equations can be viewed by accessing
ss.<ModelName>.syms.<PrintName>
, where <ModelName>
is the model name and <PrintName>
is the
equation or Jacobian name.
Note
Pretty print only works for the particular System instance whose prepare()
method is called.
In the above example, pretty print only works for ss
after calling prepare()
.
Supported equation names include the following:
xy
: variables in the order of State, ExtState, Algeb and ExtAlgebf
: the right-hand side of differential equations \(T \dot{\mathbf{x}} = \mathbf{f}\)g
: implicit algebraic equations \(0 = \mathbf{g}\)df
: derivatives off
over all variablesxy
dg
: derivatives ofg
over all variablesxy
s
: the value equations for ConstService
For example, to print the algebraic equations of model GENCLS
, one can use ss.GENCLS.syms.g
.
I/O Formats¶
Input Formats¶
ANDES currently supports the following input formats:
- ANDES Excel (.xlsx)
- PSS/E RAW (.raw) and DYR (.dyr)
- MATPOWER (.m)
ANDES xlsx Format¶
The ANDES xlsx format is a newly introduced format since v0.8.0. This format uses Microsoft Excel for conveniently viewing and editing model parameters. You can use LibreOffice or WPS Office alternatively to Microsoft Excel.
xlsx Format Definition¶
The ANDES xlsx format contains multiple workbooks (tabs at the bottom).
Each workbook contains the parameters of all instances of the model, whose name is the workbook name.
The first row in a worksheet is used for the names of parameters available to the model.
Starting from the second row, each row corresponds to an instance with the parameters in the corresponding columns.
An example of the Bus
workbook is shown in the following.

A few columns are used across all models, including uid
, idx
, name
and u
.
uid
is an internally generated unique instance index. This column can be left empty if the xlsx file is being manually created. Exporting the xlsx file with--convert
will automatically assign theuid
.idx
is the unique instance index for referencing. An uniqueidx
should be provided explicitly for each instance. Accepted types foridx
include numbers and strings without spaces.name
is the instance name.u
is the connectivity status of the instance. Accepted values are 0 and 1. Unexpected behaviors may occur if other numerical values are assigned.
As mentioned above, idx
is the unique index for an instance to be referenced.
For example, a PQ instance can reference a Bus instance so that the PQ is connected to the Bus.
This is done through providing the idx
of the desired bus as the bus
parameter of the PQ.

In the example PQ workbook shown above, there are two PQ instances on buses with idx
being 7 and 8,
respectively.
Convert to xlsx¶
Please refer to the the --convert
command for converting a recognized file to xlsx.
See format converter for more detail.
Data Consistency¶
Input data needs to have consistent types for idx
. Both string and numerical types are allowed
for idx
, but the original type and the referencing type must be the same. For example,
suppose we have a bus and a connected PQ.
The Bus device may use 1
or '1'
as its idx
, as long as the
PQ device uses the same value for its bus
parameter.
The ANDES xlsx reader will try to convert data into numerical types when possible.
This is especially relevant when the input idx
is string literal of numbers,
the exported file will have them converted to numbers.
The conversion does not affect the consistency of data.
Parameter Check¶
The following parameter checks are applied after converting input values to array:
- Any
NaN
values will raise aValueError
- Any
inf
will be replaced with \(10^{8}\), and-inf
will be replaced with \(-10^{8}\).
Cheatsheet¶
A cheatsheet is available for quick lookup of supported commands.
View the PDF version at
https://www.cheatography.com//cuihantao/cheat-sheets/andes-for-power-system-simulation/pdf/
Make Documentation¶
The documentation can be made locally into a variety of formats.
To make HTML documentation, change directory to docs
, and do
make html
After a minute, HTML documentation will be saved to docs/build/html
with the index page being index.html
.
A list of supported formats is as follows. Note that some format require additional compiler or library
html to make standalone HTML files
dirhtml to make HTML files named index.html in directories
singlehtml to make a single large HTML file
pickle to make pickle files
json to make JSON files
htmlhelp to make HTML files and an HTML help project
qthelp to make HTML files and a qthelp project
devhelp to make HTML files and a Devhelp project
epub to make an epub
latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
latexpdf to make LaTeX and PDF files (default pdflatex)
latexpdfja to make LaTeX files and run them through platex/dvipdfmx
text to make text files
man to make manual pages
texinfo to make Texinfo files
info to make Texinfo files and run them through makeinfo
gettext to make PO message catalogs
changes to make an overview of all changed/added/deprecated items
xml to make Docutils-native XML files
pseudoxml to make pseudoxml-XML files for display purposes
linkcheck to check all external links for integrity
doctest to run all doctests embedded in the documentation (if enabled)
coverage to run coverage check of the documentation (if enabled)
Modeling¶
This chapter contains advanced topics on modeling and simulation and how they are implemented in ANDES. It aims to provide an in-depth explanation of how the ANDES framework is set up for symbolic modeling and numerical simulation. It also provides an example for interested users to implement customized DAE models.
System¶
Overview¶
System is the top-level class for organizing power system models and orchestrating calculations.
-
class
andes.system.
System
(case: Optional[str] = None, name: Optional[str] = None, config_path: Optional[str] = None, options: Optional[Dict[KT, VT]] = None, **kwargs)[source] System contains models and routines for modeling and simulation.
System contains a several special OrderedDict member attributes for housekeeping. These attributes include models, groups, routines and calls for loaded models, groups, analysis routines, and generated numerical function calls, respectively.
Notes
System stores model and routine instances as attributes. Model and routine attribute names are the same as their class names. For example, Bus is stored at
system.Bus
, the power flow calculation routine is atsystem.PFlow
, and the numerical DAE instance is atsystem.dae
. See attributes for the list of attributes.Attributes: - dae : andes.variables.dae.DAE
Numerical DAE storage
- files : andes.variables.fileman.FileMan
File path storage
- config : andes.core.Config
System config storage
- models : OrderedDict
model name and instance pairs
- groups : OrderedDict
group name and instance pairs
- routines : OrderedDict
routine name and instance pairs
Note
andes.System is an alias of andes.system.System.
Dynamic Imports¶
System dynamically imports groups, models, and routines at creation. To add new models, groups or routines, edit the corresponding file by adding entries following examples.
-
andes.system.System.
import_models
(self) Import and instantiate models as System member attributes.
Models defined in
models/__init__.py
will be instantiated sequentially as attributes with the same name as the class name. In addition, all models will be stored in dictionarySystem.models
with model names as keys and the corresponding instances as values.Examples
system.Bus
stores the Bus object, andsystem.GENCLS
stores the classical generator object,system.models['Bus']
points the same instance assystem.Bus
.
-
andes.system.System.
import_groups
(self) Import all groups classes defined in
devices/group.py
.Groups will be stored as instances with the name as class names. All groups will be stored to dictionary
System.groups
.
-
andes.system.System.
import_routines
(self) Import routines as defined in
routines/__init__.py
.Routines will be stored as instances with the name as class names. All groups will be stored to dictionary
System.groups
.Examples
System.PFlow
is the power flow routine instance, andSystem.TDS
andSystem.EIG
are time-domain analysis and eigenvalue analysis routines, respectively.
Code Generation¶
Under the hood, all symbolically defined equations need to be generated into anonymous function calls for accelerating numerical simulations. This process is automatically invoked for the first time ANDES is run command line. It takes several seconds up to a minute to finish the generation.
Note
Code generation has been done if one has executed andes
, andes selftest
, or andes prepare
.
Warning
When models are modified (such as adding new models or changing equation strings), code generation needs
to be executed again for consistency. It can be more conveniently triggered from command line with
andes prepare -qi
.
-
andes.system.System.
prepare
(self, quick=False, incremental=False) Generate numerical functions from symbolically defined models.
All procedures in this function must be independent of test case.
Parameters: - quick : bool, optional
True to skip pretty-print generation to reduce code generation time.
- incremental : bool, optional
True to generate only for modified models, incrementally.
Warning
Generated lambda functions will be serialized to file, but pretty prints (SymPy objects) can only exist in the System instance on which prepare is called.
Notes
Option
incremental
compares the md5 checksum of all var and service strings, and only regenerate for updated models.Examples
If one needs to print out LaTeX-formatted equations in a Jupyter Notebook, one need to generate such equations with
import andes sys = andes.prepare()
Alternatively, one can explicitly create a System and generate the code
import andes sys = andes.System() sys.prepare()
Since the process is slow, generated numerical functions (Python Callable) will be serialized into a file
for future speed up.
The package used for serializing/de-serializing numerical calls is dill
.
System has a function called dill
for serializing using the dill
package.
-
andes.system.System.
dill
(self) Serialize generated numerical functions in System.calls with package dill.
The serialized file will be stored to
~/andes/calls.pkl
, where ~ is the home directory path.Notes
This function sets dill.settings['recurse'] = True to serialize the function calls recursively.
-
andes.system.System.
undill
(self) Deserialize the function calls from
~/andes.calls.pkl
with dill.If no change is made to models, future calls to
prepare()
can be replaced withundill()
for acceleration.
DAE Storage¶
System.dae
is an instance of the numerical DAE class.
-
andes.variables.dae.
DAE
(system)[source] Class for storing numerical values of the DAE system, including variables, equations and first order derivatives (Jacobian matrices).
Variable values and equation values are stored as
numpy.ndarray
, while Jacobians are stored ascvxopt.spmatrix
. The defined arrays and descriptions are as follows:DAE Array Description x Array for state variable values y Array for algebraic variable values z Array for 0/1 limiter states (if enabled) f Array for differential equation derivatives Tf Left-hand side time constant array for f g Array for algebraic equation mismatches The defined scalar member attributes to store array sizes are
Scalar Description m The number of algebraic variables/equations n The number of algebraic variables/equations o The number of limiter state flags The derivatives of f and g with respect to x and y are stored in four
cvxopt.spmatrix
sparse matrices: fx, fy, gx, and gy, where the first letter is the equation name, and the second letter is the variable name.Notes
DAE in ANDES is defined in the form of
\[\begin{split}T \dot{x} = f(x, y) \\ 0 = g(x, y)\end{split}\]DAE does not keep track of the association of variable and address. Only a variable instance keeps track of its addresses.
Model and DAE Values¶
ANDES uses a decentralized architecture between models and DAE value arrays.
In this architecture, variables are initialized and equations are evaluated inside each model.
Then, System
provides methods for collecting initial values and equation values into DAE
, as well as
copying solved values to each model.
The collection of values from models needs to follow protocols to avoid conflicts. Details are given in the subsection Variables.
-
andes.system.System.
vars_to_dae
(self, model) Copy variables values from models to System.dae.
This function clears DAE.x and DAE.y and collects values from models.
-
andes.system.System.
vars_to_models
(self) Copy variable values from System.dae to models.
-
andes.system.System.
_e_to_dae
(self, eq_name: str) Helper function for collecting equation values into System.dae.f and System.dae.g.
Parameters: - eq_name : 'x' or 'y'
Equation type name
Matrix Sparsity Patterns¶
The largest overhead in building and solving nonlinear equations is the building of Jacobian matrices. This is especially relevant when we use the implicit integration approach which algebraized the differential equations. Given the unique data structure of power system models, the sparse matrices for Jacobians are built incrementally, model after model.
There are two common approaches to incrementally build a sparse matrix. The first one is to use simple in-place add on sparse matrices, such as doing
self.fx += spmatrix(v, i, j, (n, n), 'd')
Although the implementation is simple, it involves creating and discarding temporary objects on the right hand
side and, even worse, changing the sparse pattern of self.fx
.
The second approach is to store the rows, columns and values in an array-like object and construct the Jacobians at the end. This approach is very efficient but has one caveat: it does not allow accessing the sparse matrix while building.
ANDES uses a pre-allocation approach to avoid the change of sparse patterns by filling values into a known the sparse matrix pattern matrix. System collects the indices of rows and columns for each Jacobian matrix. Before in-place additions, ANDES builds a temporary zero-filled spmatrix, to which the actual Jacobian values are written later. Since these in-place add operations are only modifying existing values, it does not change the pattern and thus avoids memory copying. In addition, updating sparse matrices can be done with the exact same code as the first approach.
Still, this approach creates and discards temporary objects. It is however feasible to write a C function which takes three array-likes and modify the sparse matrices in place. This is feature to be developed, and our prototype shows a promising acceleration up to 50%.
-
andes.system.System.
store_sparse_pattern
(self, models: collections.OrderedDict) Collect and store the sparsity pattern of Jacobian matrices.
This is a runtime function specific to cases.
Notes
For gy matrix, always make sure the diagonal is reserved. It is a safeguard if the modeling user omitted the diagonal term in the equations.
Calling Model Methods¶
System is an orchestrator for calling shared methods of models. These API methods are defined for initialization, equation update, Jacobian update, and discrete flags update.
The following methods take an argument models, which should be an OrderedDict of models with names as keys and instances as values.
-
andes.system.System.
init
(self, models: collections.OrderedDict) Initialize the variables for each of the specified models.
For each model, the initialization procedure is:
- Get values for all ExtService.
- Call the model init() method, which initializes internal variables.
- Copy variables to DAE and then back to the model.
-
andes.system.System.
e_clear
(self, models: collections.OrderedDict) Clear equation arrays in DAE and model variables.
This step must be called before calling f_update or g_update to flush existing values.
-
andes.system.System.
l_update_var
(self, models: collections.OrderedDict) Update variable-based limiter discrete states by calling
l_update_var
of models.This function is must be called before any equation evaluation.
-
andes.system.System.
f_update
(self, models: Union[str, List, collections.OrderedDict, NoneType] = None) Call the differential equation update method for models in sequence.
Notes
Updated equation values remain in models and have not been collected into DAE at the end of this step.
-
andes.system.System.
l_update_eq
(self, models: collections.OrderedDict) First, update equation-dependent limiter discrete components by calling
l_check_eq
of models. Second, force set equations after evaluating equations by callingl_set_eq
of models.This function is must be called after differential equation updates.
-
andes.system.System.
g_update
(self, models: Union[str, List, collections.OrderedDict, NoneType] = None) Call the algebraic equation update method for models in sequence.
Notes
Like f_update, updated values have not collected into DAE at the end of the step.
-
andes.system.System.
j_update
(self, models: collections.OrderedDict) Call the Jacobian update method for models in sequence.
The procedure is - Restore the sparsity pattern with
andes.variables.dae.DAE.restore_sparse()
- For each sparse matrix in (fx, fy, gx, gy), evaluate the Jacobian function calls and add values.Notes
Updated Jacobians are immediately reflected in the DAE sparse matrices (fx, fy, gx, gy).
Configuration¶
System, models and routines have a member attribute config for model-specific or routine-specific configurations. System manages all configs, including saving to a config file and loading back.
-
andes.system.System.
get_config
(self) Collect config data from models.
Returns: - dict
a dict containing the config from devices; class names are keys and configs in a dict are values.
-
andes.system.System.
save_config
(self, file_path=None, overwrite=False) Save all system, model, and routine configurations to an rc-formatted file.
Parameters: - file_path : str, optional
path to the configuration file default to ~/andes/andes.rc.
- overwrite : bool, optional
If file exists, True to overwrite without confirmation. Otherwise prompt for confirmation.
Warning
Saved config is loaded back and populated at system instance creation time. Configs from the config file takes precedence over default config values.
-
andes.system.System.
load_config
(conf_path=None) Load config from an rc-formatted file.
Parameters: - conf_path : None or str
Path to the config file. If is None, the function body will not run.
Returns: - configparse.ConfigParser
Warning
It is important to note that configs from files is passed to model constructors during instantiation.
If one needs to modify config for a run, it needs to be done before instantiating System
, or before running
andes
from command line.
Directly modifying Model.config
may not take effect or have side effect as for the current implementation.
Models¶
This section introduces the modeling of power system devices. The terminology "model" is used to describe the mathematical representation of a type of device, such as synchronous generators or turbine governors. The terminology "device" is used to describe a particular instance of a model, for example, a specific generator.
To define a model in ANDES, two classes, ModelData
and Model
need to be utilized. Class ModelData
is
used for defining parameters that will be provided from input files. It provides API for adding data from
devices and managing the data.
Class Model
is used for defining other non-input parameters, service
variables, and DAE variables. It provides API for converting symbolic equations, storing Jacobian patterns, and
updating equations.
Model Data¶
-
class
andes.core.model.
ModelData
(*args, **kwargs)[source] Class for holding parameter data for a model.
This class is designed to hold the parameter data separately from model equations. Models should inherit this class to define the parameters from input files.
Inherit this class to create the specific class for holding input parameters for a new model. The recommended name for the derived class is the model name with
Data
. For example, data for GENCLS should be named GENCLSData.Parameters should be defined in the
__init__
function of the derived class.Refer to
andes.core.param
for available parameter types.Notes
Two default parameters, u (connection status of type
andes.core.param.NumParam
), andname
(device name of typeandes.core.param.DataParam
) are pre-defined inModelData
, and will be inherited by all models.Examples
If we want to build a class
PQData
(for static PQ load) with three parameters, Vn, p0 and q0, we can use the followingfrom andes.core.model import ModelData, Model from andes.core.param import IdxParam, NumParam class PQData(ModelData): super().__init__() self.Vn = NumParam(default=110, info="AC voltage rating", unit='kV', non_zero=True, tex_name=r'V_n') self.p0 = NumParam(default=0, info='active power load in system base', tex_name=r'p_0', unit='p.u.') self.q0 = NumParam(default=0, info='reactive power load in system base', tex_name=r'q_0', unit='p.u.')
In this example, all the three parameters are defined as
andes.core.param.NumParam
. In the full PQData class, other types of parameters also exist. For example, to store the idx of owner, PQData usesself.owner = IdxParam(model='Owner', info="owner idx")
Attributes: - cache
A cache instance for different views of the internal data.
- flags : dict
Flags to control the routine and functions that get called. If the model is using user-defined numerical calls, set f_num, g_num and j_num properly.
Cache¶
ModelData uses a lightweight class andes.core.model.Cache
for caching its data as a dictionary
or a pandas DataFrame. Four attributes are defined in ModelData.cache:
- dict: all data in a dictionary with the parameter names as keys and v values as arrays.
- dict_in: the same as dict except that the values are from v_in, the original input.
- df: all data in a pandas DataFrame.
- df_in: the same as df except that the values are from v_in.
Other attributes can be added by registering with cache.add_callback.
-
andes.core.model.Cache.
add_callback
(self, name: str, callback) Add a cache attribute and a callback function for updating the attribute.
Parameters: - name : str
name of the cached function return value
- callback : callable
callback function for updating the cached attribute
Define Voltage Ratings¶
If a model is connected to an AC Bus or a DC Node, namely, if bus
, bus1
, node
or node1
exists
as parameter, it must provide the corresponding parameter, Vn
, Vn1
, Vdcn
or Vdcn1
, for rated
voltages.
Controllers not connected to Bus or Node will have its rated voltages omitted and thus Vb = Vn = 1
, unless
one uses andes.core.param.ExtParam
to retrieve the bus/node values.
As a rule of thumb, controllers not directly connected to the network shall use system-base per unit for voltage and current parameters. Controllers (such as a turbine governor) may inherit rated power from controlled models and thus power parameters will be converted consistently.
Define a DAE Model¶
-
class
andes.core.model.
Model
(system=None, config=None)[source] Base class for power system DAE models.
After subclassing ModelData, subclass Model` to complete a DAE model. Subclasses of Model defines DAE variables, services, and other types of parameters, in the constructor
__init__
.Examples
Take the static PQ as an example, the subclass of Model, PQ, should looks like
class PQ(PQData, Model): def __init__(self, system, config): PQData.__init__(self) Model.__init__(self, system, config)
Since PQ is calling the base class constructors, it is meant to be the final class and not further derived. It inherits from PQData and Model and must call constructors in the order of PQData and Model. If the derived class of Model needs to be further derived, it should only derive from Model and use a name ending with Base. See
andes.models.synchronous.GENBASE
.Next, in PQ.__init__, set proper flags to indicate the routines in which the model will be used
self.flags.update({'pflow': True})
Currently, flags pflow and tds are supported. Both are False by default, meaning the model is neither used in power flow nor time-domain simulation. A very common pitfall is forgetting to set the flag.
Next, the group name can be provided. A group is a collection of models with common parameters and variables. Devices idx of all models in the same group must be unique. To provide a group name, use
self.group = 'StaticLoad'
The group name must be an existing class name in
andes.models.group
. The model will be added to the specified group and subject to the variable and parameter policy of the group. If not provided with a group class name, the model will be placed in the Undefined group.Next, additional configuration flags can be added. Configuration flags for models are load-time variables specifying the behavior of a model. It can be exported to an andes.rc file and automatically loaded when creating the System. Configuration flags can be used in equation strings, as long as they are numerical values. To add config flags, use
self.config.add(OrderedDict((('pq2z', 1), )))
It is recommended to use OrderedDict instead of dict, although the syntax is verbose. Note that booleans should be provided as integers (1, or 0), since True or False is interpreted as a string when loaded from the rc file and will cause an error.
Next, it's time for variables and equations! The PQ class does not have internal variables itself. It uses its bus parameter to fetch the corresponding a and v variables of buses. Equation wise, it imposes an active power and a reactive power load equation.
To define external variables from Bus, use
self.a = ExtAlgeb(model='Bus', src='a', indexer=self.bus, tex_name=r'\theta') self.v = ExtAlgeb(model='Bus', src='v', indexer=self.bus, tex_name=r'V')
Refer to the subsection Variables for more details.
The simplest PQ model will impose constant P and Q, coded as
self.a.e_str = "u * p" self.v.e_str = "u * q"
where the e_str attribute is the equation string attribute. u is the connectivity status. Any parameter, config, service or variables can be used in equation strings. An addition variable dae_t for the current simulation time can be used if the model has flag tds.
The above example is overly simplified. Our PQ model wants a feature to switch itself to a constant impedance if the voltage is out of the range (vmin, vmax). To implement this, we need to introduce a discrete component called Limiter, which yields three arrays of binary flags, zi, zl, and zu indicating in range, below lower limit, and above upper limit, respectively.
First, create an attribute vcmp as a Limiter instance
self.vcmp = Limiter(u=self.v, lower=self.vmin, upper=self.vmax, enable=self.config.pq2z)
where self.config.pq2z is a flag to turn this feature on or off. After this line, we can use vcmp_zi, vcmp_zl, and vcmp_zu in other equation strings.
self.a.e_str = "u * (p0 * vcmp_zi + " \ "p0 * vcmp_zl * (v ** 2 / vmin ** 2) + " \ "p0 * vcmp_zu * (v ** 2 / vmax ** 2))" self.v.e_str = "u * (q0 * vcmp_zi + " \ "q0 * vcmp_zl * (v ** 2 / vmin ** 2) + "\ "q0 * vcmp_zu * (v ** 2 / vmax ** 2))"
Note that PQ.a.e_str can use the three variables from vcmp even before defining PQ.vcmp, as long as PQ.vcmp is defined, because vcmp_zi is just a string literal in e_str.
The two equations above implements a piecewise power injection equation. It selects the original power demand if within range, and uses the calculated power when out of range.
Finally, to let ANDES pick up the model, the model name needs to be added to models/__init__.py. Follow the examples in the OrderedDict, where the key is the file name, and the value is the class name.
Attributes: - num_params : OrderedDict
{name: instance} of numerical parameters, including internal and external ones
Dynamicity Under the Hood¶
The magic for automatic creation of variables are all hidden in andes.core.model.Model.__setattr__()
,
and the code is incredible simple.
It sets the name, tex_name, and owner model of the attribute instance and, more importantly,
does the book keeping.
In particular, when the attribute is a andes.core.block.Block
subclass, __setattr__
captures the
exported instances, recursively, and prepends the block name to exported ones.
All these convenience owe to the dynamic feature of Python.
During the code generation phase, the symbols are created by checking the book-keeping attributes, such as states, algebs, and attributes in Model.cache.
In the numerical evaluation phase, Model provides a method, andes.core.model.get_inputs()
, to
collect the variable value arrays in a dictionary, which can be effortlessly passed as arguments to numerical
functions.
Commonly Used Attributes in Models¶
The following Model
attributes are commonly used for debugging.
If the attribute is an OrderedDict, the keys are attribute names in str, and corresponding values are the
instances.
params
andparams_ext
, two OrderedDict for internal (both numerical and non-numerical) and external parameters, respectively.num_params
for numerical parameters, both internal and external.states
andalgebs
, twoOrderedDict
for state variables and algebraic variables, respectively.states_ext
andalgebs_ext
, twoOrderedDict
for external states and algebraics.discrete
, an OrderedDict for discrete components.blocks
, an OrderedDict for blocks.services
, an OrderedDict for services withv_str
.services_ext
, an OrderedDict for externally retrieved services.
Attributes in Model.cache¶
Attributes in Model.cache are additional book-keeping structures for variables, parameters and services. The following attributes are defined.
all_vars
: all the variables.all_vars_names
, a list of all variable names.all_params
, all parameters.all_params_names
, a list of all parameter names.algebs_and_ext
, an OrderedDict of internal and external algebraic variables.states_and_ext
, an OrderedDict of internal and external differential variables.services_and_ext
, an OrderedDict of internal and external service variables.vars_int
, an OrderedDict of all internal variables, states and then algebs.vars_ext
, an OrderedDict of all external variables, states and then algebs.
Equation Generation¶
Model.syms
, an instance of SymProcessor
, handles the symbolic to numeric generation when called. The
equation generation is a multi-step process with symbol preparation, equation generation, Jacobian generation,
initializer generation, and pretty print generation.
-
class
andes.core.model.
SymProcessor
(parent)[source] A helper class for symbolic processing and code generation.
Parameters: - parent : Model
The Model instance to document
Attributes: - xy : sympy.Matrix
variables pretty print in the order of State, ExtState, Algeb, ExtAlgeb
- f : sympy.Matrix
differential equations pretty print
- g : sympy.Matrix
algebraic equations pretty print
- df : sympy.SparseMatrix
df /d (xy) pretty print
- dg : sympy.SparseMatrix
dg /d (xy) pretty print
- inputs_dict : OrderedDict
All possible symbols in equations, including variables, parameters, discrete flags, and config flags. It has the same variables as what
get_inputs()
returns.- vars_dict : OrderedDict
variable-only symbols, which are useful when getting the Jacobian matrices.
- non_vars_dict : OrderedDict
symbols in
input_syms
but not invar_syms
.
-
generate_init
(self)[source] Generate lambda functions for initial values.
-
generate_jacobians
(self)[source] Generate Jacobians and store to corresponding triplets.
The internal indices of equations and variables are stored, alongside the lambda functions.
For example, dg/dy is a sparse matrix whose elements are
(row, col, val)
, whererow
andcol
are the internal indices, andval
is the numerical lambda function. They will be stored torow -> self.calls._igy col -> self.calls._jgy val -> self.calls._vgy
-
generate_symbols
(self)[source] Generate symbols for symbolic equation generations.
This function should run before other generate equations.
Attributes: - inputs_dict : OrderedDict
name-symbol pair of all parameters, variables and configs
- vars_dict : OrderedDict
name-symbol pair of all variables, in the order of (states_and_ext + algebs_and_ext)
- non_vars_dict : OrderedDict
name-symbol pair of all non-variables, namely, (inputs_dict - vars_dict)
Next, function generate_equation
converts each DAE equation set to one numerical function calls and store
it in Model.calls
. The attributes for differential equation set and algebraic equation set are f_lambdify
and g_lambdify
. Differently, service variables will be generated one by one and store in an OrderedDict
in Model.calls.s_lambdify
.
Jacobian Storage¶
Abstract Jacobian Storage¶
Using the .jacobian
method on sympy.Matrix
, the symbolic Jacobians can be easily obtained. The complexity
lies in the storage of the Jacobian elements. Observed that the Jacobian equation generation happens before any
system is loaded, thus only the variable indices in the variable array is available. For each non-zero item in each
Jacobian matrix, ANDES stores the equation index, variable index, and the Jacobian value (either a constant
number or a callable function returning an array).
Note that, again, a non-zero entry in a Jacobian matrix can be either a constant or an expression. For efficiency, constant numbers and lambdified callables are stored separately. Constant numbers, therefore, can be loaded into the sparse matrix pattern when a particular system is given.
Warning
Data structure for the Jacobian storage has changed. Pending documentation update. Please check
andes.core.common.JacTriplet
class for more details.
The triplets, the equation (row) index, variable (column) index, and values (constant numbers or callable) are
stored in Model
attributes with the name of _{i, j, v}{Jacobian Name}{c or None}
, where
{i, j, v}
is a single character for row, column or value, {Jacobian Name}
is a two-character Jacobian
name chosen from fx, fy, gx, and gy
, and {c or None}
is either character c
or no character,
indicating whether it corresponds to the constants or non-constants in the Jacobian.
For example, the triplets for the
constants in Jacobian gy
are stored in _igyc
, _jgyc
, and _vgyc
.
In terms of the non-constant entries in Jacobians, the callable functions are stored in the corresponding
_v{Jacobian Name}
array. Note the differences between, for example, _vgy
an _vgyc
: _vgy
is a
list of callables, while _vgyc
is a list of constant numbers.
Concrete Jacobian Storage¶
When a specific system is loaded and the addresses are assigned to variables, the abstract Jacobian triplets,
more specifically, the rows and columns, are replaced with the array of addresses. The new addresses and values
will be stored in Model
attributes with the names {i, j, v}{Jacobian Name}{c or None}
. Note that there
is no underscore for the concrete Jacobian triplets.
For example, if model PV
has a list of variables [p, q, a, v]
.
The equation associated with p
is - u * p0
, and the equation associated with q
is u * (v0 - v)
.
Therefore, the derivative of equation v0 - v
over v
is -u
. Note that u
is unknown at generation
time, thus the value is NOT a constant and should to go vgy
.
The values in _igy
, _jgy
and _vgy
contains, respectively, 1
, 3
, and a lambda function which
returns -u
.
When a specific system is loaded, for example, a 5-bus system, the addresses for the q
and v
are [11,
13, 15
, and [5, 7, 9]
.
PV.igy
and PV.jgy
will thus query the corresponding address list based on PV._igy
and PV._jgy
and store [11, 13, 15
, and [5, 7, 9]
.
Initialization¶
Value providers such as services and DAE variables need to be initialized. Services are initialized before any DAE variable. Both Services and DAE Variables are initialized sequentially in the order of declaration.
Each Service, in addition to the standard v_str
for symbolic initialization, provides a v_numeric
hook
for specifying a custom function for initialization. Custom initialization functions for DAE variables, are
lumped in a single function in Model.v_numeric
.
ANDES has an experimental Newton-Krylov method based iterative initialization. All DAE variables with v_iter
will be initialized using the iterative approach
Additional Numerical Equations¶
Addition numerical equations are allowed to complete the "hybrid symbolic-numeric" framework. Numerical function calls are useful when the model DAE is non-standard or hard to be generalized. Since the symbolic-to-numeric generation is an additional layer on top of the numerical simulation, it is fundamentally the same as user-provided numerical function calls.
ANDES provides the following hook functions in each Model
subclass for custom numerical functions:
v_numeric
: custom initialization functions_numeric
: custom service value functiong_numeric
: custom algebraic equations; update thee
of the corresponding variable.f_numeric
: custom differential equations; update thee
of the corresponding variable.j_numeric
: custom Jacobian equations; the function should append to_i
,_j
and_v
structures.
For most models, numerical function calls are unnecessary and not recommended as it increases code complexity. However, when the data structure or the DAE are difficult to generalize in the symbolic framework, the numerical equations can be used.
For interested readers, see the COI
symbolic implementation which calculated the
center-of-inertia speed of generators. The COI
could have been implemented numerically with for loops
instead of NumReduce
, NumRepeat
and external variables.
Atom Types¶
ANDES contains three types of atom classes for building DAE models. These types are parameter, variable and service.
Value Provider¶
Before addressing specific atom classes, the terminology v-provider, and e-provider are discussed.
A value provider class (or v-provider for short) references any class with a member attribute named v
,
which should be a list or a 1-dimensional array of values.
For example, all parameter classes are v-providers, since a parameter class should provide
values for that parameter.
Note
In fact, all types of atom classes are v-providers, meaning that an instance of an atom class must contain values.
The values in the v attribute of a particular instance are values that will substitute the instance for computation. If in a model, one has a parameter
self.v0 = NumParam()
self.b = NumParam()
# where self.v0.v = np.array([1., 1.05, 1.1]
# and self.b.v = np.array([10., 10., 10.]
Later, this parameter is used in an equation, such as
self.v = ExtAlgeb(model='Bus', src='v',
indexer=self.bus,
e_str='v0 **2 * b')
While computing v0 ** 2 * b, v0 and b will be substituted with the values in self.v0.v and self.b.v.
Sharing this interface v allows interoperability among parameters and variables and services. In the above example, if one defines v0 as a ConstService instance, such as
self.v0 = ConstService(v_str='1.0')
Calculations will still work without modification.
Equation Provider¶
Similarly, an equation provider class (or e-provider) references any class with a member attribute named e
,
which should be a 1-dimensional array of values.
The values in the e array are the results from the equation and will be summed to the numerical DAE at the addresses
specified by the attribute a.
Note
Currently, only variables are e-provider types.
If a model has an external variable that links to Bus.v (voltage), such as
self.v = ExtAlgeb(model='Bus', src='v',
indexer=self.bus,
e_str='v0 **2 * b')
The addresses of the corresponding voltage variables will be retrieved into self.a, and the equation evaluation results will be stored in self.v.e
Parameters¶
Background¶
Parameter is a type of building atom for DAE models. Most parameters are read directly from an input file and passed to equation, and other parameters can be calculated from existing parameters.
The base class for parameters in ANDES is BaseParam, which defines interfaces for adding values and checking the number of values. BaseParam has its values stored in a plain list, the member attribute v. Subclasses such as NumParam stores values using a NumPy ndarray.
An overview of supported parameters is given below.
Subclasses | Description |
---|---|
DataParam | An alias of BaseParam. Can be used for any non-numerical parameters. |
NumParam | The numerical parameter type. Used for all parameters in equations |
IdxParam | The parameter type for storing idx into other models |
ExtParam | Externally defined parameter |
TimerParam | Parameter for storing the action time of events |
Data Parameters¶
-
class
andes.core.param.
BaseParam
(default: Union[float, str, int, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, mandatory: bool = False, export: bool = True)[source] The base parameter class.
This class provides the basic data structure and interfaces for all types of parameters. Parameters are from input files and in general constant once initialized.
Subclasses should overload the n() method for the total count of elements in the value array.
Parameters: - default : str or float, optional
The default value of this parameter if None is provided
- name : str, optional
Parameter name. If not provided, it will be automatically set to the attribute name defined in the owner model.
- tex_name : str, optional
LaTeX-formatted parameter name. If not provided, tex_name will be assigned the same as name.
- info : str, optional
Descriptive information of parameter
- mandatory : bool
True if this parameter is mandatory
- export : bool
True if the parameter will be exported when dumping data into files. True for most parameters. False for
BackRef
.
Warning
The most distinct feature of BaseParam, DataParam and IdxParam is that values are stored in a list without conversion to array. BaseParam, DataParam or IdxParam are not allowed in equations.
Attributes: - v : list
A list holding all the values. The
BaseParam
class does not convert thev
attribute into NumPy arrays.- property : dict
A dict containing the truth values of the model properties.
-
class
andes.core.param.
DataParam
(default: Union[float, str, int, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, mandatory: bool = False, export: bool = True)[source] An alias of the BaseParam class.
This class is used for string parameters or non-computational numerical parameters. This class does not provide a to_array method. All input values will be stored in v as a list.
See also
andes.core.param.BaseParam
- Base parameter class
-
class
andes.core.param.
IdxParam
(default: Union[float, str, int, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, mandatory: bool = False, unique: bool = False, export: bool = True, model: Optional[str] = None)[source] An alias of BaseParam with an additional storage of the owner model name
This class is intended for storing idx into other models. It can be used in the future for data consistency check.
Notes
This will be useful when, for example, one connects two TGs to one SynGen.
Examples
A PQ model connected to Bus model will have the following code
class PQModel(...): def __init__(...): ... self.bus = IdxParam(model='Bus')
Numeric Parameters¶
-
class
andes.core.param.
NumParam
(default: Union[float, str, Callable, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, vrange: Union[List[T], Tuple, None] = None, Sn: str = 'Sn', Vn: str = 'Vn', non_zero: bool = False, positive: bool = False, mandatory: bool = False, power: bool = False, ipower: bool = False, voltage: bool = False, current: bool = False, z: bool = False, y: bool = False, r: bool = False, g: bool = False, dc_voltage: bool = False, dc_current: bool = False, export: bool = True)[source] A computational numerical parameter.
Parameters defined using this class will have their v field converted to a NumPy array after adding. The original input values will be copied to vin, and the system-base per-unit conversion coefficients (through multiplication) will be stored in pu_coeff.
Parameters: - default : str or float, optional
The default value of this parameter if no value is provided
- name : str, optional
Name of this parameter. If not provided, name will be set to the attribute name of the owner model.
- tex_name : str, optional
LaTeX-formatted parameter name. If not provided, tex_name will be assigned the same as name.
- info : str, optional
A description of this parameter
- mandatory : bool
True if this parameter is mandatory
- unit : str, optional
Unit of the parameter
- vrange : list, tuple, optional
Typical value range
Other Parameters: - Sn : str
Name of the parameter for the device base power.
- Vn : str
Name of the parameter for the device base voltage.
- non_zero : bool
True if this parameter must be non-zero
- positive: bool
True if this parameter must be positive
- mandatory : bool
True if this parameter must not be None
- power : bool
True if this parameter is a power per-unit quantity under the device base
- ipower : bool
True if this parameter is an inverse-power per-unit quantity under the device base
- voltage : bool
True if the parameter is a voltage pu quantity under the device base
- current : bool
True if the parameter is a current pu quantity under the device base
- z : bool
True if the parameter is an AC impedance pu quantity under the device base
- y : bool
True if the parameter is an AC admittance pu quantity under the device base
- r : bool
True if the parameter is a DC resistance pu quantity under the device base
- g : bool
True if the parameter is a DC conductance pu quantity under the device base
- dc_current : bool
True if the parameter is a DC current pu quantity under device base
- dc_voltage : bool
True if the parameter is a DC voltage pu quantity under device base
External Parameters¶
-
class
andes.core.param.
ExtParam
(model: str, src: str, indexer=None, dtype=<class 'float'>, allow_none=False, default=0.0, **kwargs)[source] A parameter whose values are retrieved from an external model or group.
Parameters: - model : str
Name of the model or group providing the original parameter
- src : str
The source parameter name
- indexer : BaseParam
A parameter defined in the model defining this ExtParam instance. indexer.v should contain indices into model.src.v. If is None, the source parameter values will be fully copied. If model is a group name, the indexer cannot be None.
Attributes: - parent_model : Model
The parent model providing the original parameter.
Timer Parameter¶
-
class
andes.core.param.
TimerParam
(callback: Optional[Callable] = None, default: Union[float, str, Callable, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, non_zero: bool = False, mandatory: bool = False, export: bool = True)[source] A parameter whose values are event occurrence times during the simulation.
The constructor takes an additional Callable self.callback for the action of the event. TimerParam has a default value of -1, meaning deactivated.
Examples
A connectivity status toggler class Toggler takes a parameter t for the toggle time. Inside
Toggler.__init__
, one would haveself.t = TimerParam()
The Toggler class also needs to define a method for togging the connectivity status
def _u_switch(self, is_time: np.ndarray): action = False for i in range(self.n): if is_time[i] and (self.u.v[i] == 1): instance = self.system.__dict__[self.model.v[i]] # get the original status and flip the value u0 = instance.get(src='u', attr='v', idx=self.dev.v[i]) instance.set(src='u', attr='v', idx=self.dev.v[i], value=1-u0) action = True return action
Finally, in
Toggler.__init__
, assign the function as the callback for self.tself.t.callback = self._u_switch
Variables¶
DAE Variables, or variables for short, are unknowns to be solved using numerical or analytical methods. A variable stores values, equation values, and addresses in the DAE array. The base class for variables is BaseVar. In this subsection, BaseVar is used to represent any subclass of VarBase list in the table below.
Class | Description |
---|---|
State | A state variable and associated diff. equation \(\textbf{T} \dot{x} = \textbf{f}\) |
Algeb | An algebraic variable and an associated algebraic equation \(0 = \textbf{g}\) |
ExtState | An external state variable and part of the differential equation (uncommon) |
ExtAlgeb | An external algebraic variable and part of the algebraic equation |
BaseVar has two types: the differential variable type State and the algebraic variable type Algeb. State variables are described by differential equations, whereas algebraic variables are described by algebraic equations. State variables can only change continuously, while algebraic variables can be discontinuous.
Based on the model the variable is defined, variables can be internal or external. Most variables are internal and only appear in equations in the same model. Some models have "public" variables that can be accessed by other models. For example, a Bus defines v for the voltage magnitude. Each device attached to a particular bus needs to access the value and impose the reactive power injection. It can be done with ExtAlgeb or ExtState, which links with an existing variable from a model or a group.
Variable, Equation and Address¶
Subclasses of BaseVar are value providers and equation providers. Each BaseVar has member attributes v and e for variable values and equation values, respectively. The initial value of v is set by the initialization routine, and the initial value of e is set to zero. In the process of power flow calculation or time domain simulation, v is not directly modifiable by models but rather updated after solving non-linear equations. e is updated by the models and summed up before solving equations.
Each BaseVar also stores addresses of this variable, for all devices, in its member attribute a. The addresses are 0-based indices into the numerical DAE array, f or g, based on the variable type.
For example, Bus has self.a = Algeb()
as the voltage phase angle variable.
For a 5-bus system, Bus.a.a
stores the addresses of the a variable for all
the five Bus devices. Conventionally, Bus.a.a will be assigned np.array([0, 1, 2, 3, 4]).
Value and Equation Strings¶
The most important feature of the symbolic framework is allowing to define equations using strings. There are three types of strings for a variable, stored in the following member attributes, respectively:
- v_str: equation string for explicit initialization in the form of v = v_str(x, y).
- v_iter: equation string for implicit initialization in the form of v_iter(x, y) = 0
- e_str: equation string for (full or part of) the differential or algebraic equation.
The difference between v_str and v_iter should be clearly noted. v_str evaluates directly into the initial value, while all v_iter equations are solved numerically using the Newton-Krylov iterative method.
Values Between DAE and Models¶
ANDES adopts a decentralized architecture which provides each model a copy of variable values before equation
evaluation. This architecture allows to parallelize the equation evaluation (in theory, or in practice if one
works round the Python GIL). However, this architecture requires a coherent protocol for updating the DAE arrays
and the BaseVar
arrays. More specifically, how the variable and equations values from model VarBase
should be summed up or forcefully set at the DAE arrays needs to be defined.
The protocol is relevant when a model defines subclasses of BaseVar that are supposed to be "public". Other models share this variable with ExtAlgeb or ExtState.
By default, all v and e at the same address are summed up. This is the most common case, such as a Bus connected by multiple devices: power injections from devices should be summed up.
In addition, BaseVar provides two flags, v_setter and e_setter, for cases when one VarBase needs to overwrite the variable or equation values.
Flags for Value Overwriting¶
BaseVar have special flags for handling value initialization and equation values. This is only relevant for public or external variables. The v_setter is used to indicate whether a particular BaseVar instance sets the initial value. The e_setter flag indicates whether the equation associated with a BaseVar sets the equation value.
The v_setter flag is checked when collecting data from models to the numerical DAE array. If v_setter is False, variable values of the same address will be added. If one of the variable or external variable has v_setter is True, it will, at the end, set the values in the DAE array to its value. Only one BaseVar of the same address is allowed to have v_setter == True.
A v_setter Example¶
A Bus is allowed to default the initial voltage magnitude to 1 and the voltage phase angle to 0. If a PV device is connected to a Bus device, the PV should be allowed to override the voltage initial value with the voltage set point.
In Bus.__init__(), one has
self.v = Algeb(v_str='1')
In PV.__init__, one can use
self.v0 = Param()
self.bus = IdxParam(model='Bus')
self.v = ExtAlgeb(src='v',
model='Bus',
indexer=self.bus,
v_str='v0',
v_setter=True)
where an ExtAlgeb is defined to access Bus.v using indexer self.bus. The v_str line sets the initial value to v0. In the variable initialization phase for PV, PV.v.v is set to v0.
During the value collection into DAE.y by the System class, PV.v, as a final v_setter, will overwrite the voltage magnitude for Bus devices with the indices provided in PV.bus.
-
class
andes.core.var.
BaseVar
(name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, discrete: Optional[andes.core.discrete.Discrete] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source] Base variable class.
Derived classes State and Algeb should be used to build model variables.
Parameters: - name : str, optional
Variable name
- info : str, optional
Descriptive information
- unit : str, optional
Unit
- tex_name : str
LaTeX-formatted variable name. If is None, use name instead.
- discrete : Discrete
Associated discrete component. Will call check_var on the discrete component.
Attributes: - a : array-like
variable address
- v : array-like
local-storage of the variable value
- e : array-like
local-storage of the corresponding equation value
- e_str : str
the string/symbolic representation of the equation
-
class
andes.core.var.
ExtVar
(model: str, src: str, indexer: Union[List[T], numpy.ndarray, andes.core.param.BaseParam, andes.core.service.BaseService, None] = None, allow_none: Optional[bool] = False, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source] Externally defined algebraic variable
This class is used to retrieve the addresses of externally- defined variable. The e value of the ExtVar will be added to the corresponding address in the DAE equation.
Parameters: - model : str
Name of the source model
- src : str
Source variable name
- indexer : BaseParam, BaseService
A parameter of the hosting model, used as indices into the source model and variable. If is None, the source variable address will be fully copied.
- allow_none : bool
True to allow None in indexer
Attributes: - parent_model : Model
The parent model providing the original parameter.
- uid : array-like
An array containing the absolute indices into the parent_instance values.
- e_code : str
Equation code string; copied from the parent instance.
- v_code : str
Variable code string; copied from the parent instance.
-
class
andes.core.var.
State
(name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, discrete: Optional[andes.core.discrete.Discrete] = None, t_const: Union[andes.core.param.BaseParam, andes.core.common.DummyValue, None] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source] Differential variable class, an alias of the BaseVar.
Parameters: - t_const : BaseParam, DummyValue
Left-hand time constant for the differential equation. Time constants will not be evaluated as part of the differential equation. They will be collected to array dae.Tf to multiply to the right-hand side dae.f.
Attributes: - e_code : str
Equation code string, equals string literal
f
- v_code : str
Variable code string, equals string literal
x
-
class
andes.core.var.
Algeb
(name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, discrete: Optional[andes.core.discrete.Discrete] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source] Algebraic variable class, an alias of the BaseVar.
Attributes: - e_code : str
Equation code string, equals string literal
g
- v_code : str
Variable code string, equals string literal
y
-
class
andes.core.var.
ExtState
(model: str, src: str, indexer: Union[List[T], numpy.ndarray, andes.core.param.BaseParam, andes.core.service.BaseService, None] = None, allow_none: Optional[bool] = False, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source] External state variable type.
Warning
ExtState
is not allowed to sett_const
, as it will conflict with the sourceState
variable. In fact, one should not sete_str
forExtState
.
-
class
andes.core.var.
ExtAlgeb
(model: str, src: str, indexer: Union[List[T], numpy.ndarray, andes.core.param.BaseParam, andes.core.service.BaseService, None] = None, allow_none: Optional[bool] = False, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source] External algebraic variable type.
Services¶
Services are helper variables outside the DAE variable list. Services are most often used for storing intermediate
constants but can be used for special operations to work around restrictions in the symbolic framework.
Services are value providers, meaning each service has an attribute v
for storing service values. The
base class of services is BaseService
, and the supported services are listed as follows.
Class | Description |
---|---|
ConstService | Internal service for constant values. |
ExtService | External service for retrieving values from value providers. |
NumReduce | The service type for reducing linear 2-D arrays into 1-D arrays |
NumRepeat | The service type for repeating a 1-D array to linear 2-D arrays |
IdxRepeat | The service type for repeating a 1-D list to linear 2-D list |
Internal Constants¶
The most commonly used service is ConstService. It is used to store an array of constants, whose value is evaluated from a provided symbolic string. They are only evaluated once in the model initialization phase, ahead of variable initialization. ConstService comes handy when one wants to calculate intermediate constants from parameters.
For example, a turbine governor has a NumParam R for the
droop. ConstService allows to calculate the inverse of the droop, the gain, and use it in equations. The
snippet from a turbine governor's __init__()
may look like
self.R = NumParam()
self.G = ConstService(v_str='u/R')
where u is the online status parameter. The model can thus use G in subsequent variable or equation strings.
-
class
andes.core.service.
ConstService
(v_str: Optional[str] = None, v_numeric: Optional[Callable] = None, name: Optional[str] = None, tex_name=None, info=None)[source] A type of Service that stays constant once initialized.
ConstService are usually constants calculated from parameters. They are only evaluated once in the initialization phase before variables are initialized. Therefore, uninitialized variables must not be used in v_str`.
Parameters: - name : str
Name of the ConstService
- v_str : str
An equation string to calculate the variable value.
- v_numeric : Callable, optional
A callable which returns the value of the ConstService
Attributes: - v : array-like or a scalar
ConstService value
External Constants¶
Service constants whose value is retrieved from an external model or group. Using ExtService is similar to using external variables. The values of ExtService will be retrieved once during the initialization phase before ConstService evaluation.
For example, a synchronous generator needs to retrieve the p and q values from static generators
for initialization. ExtService is used for this purpose. In the __init__()
of a synchronous generator
model, one can define the following to retrieve StaticGen.p as p0:
self.p0 = ExtService(src='p',
model='StaticGen',
indexer=self.gen,
tex_name='P_0')
-
class
andes.core.service.
ExtService
(model: str, src: str, indexer: andes.core.param.BaseParam, attr='v', allow_none=False, default=0, name: str = None, tex_name: str = None, info=None)[source] Service constants whose value is from an external model or group.
Parameters: - src : str
Variable or parameter name in the source model or group
- model : str
A model name or a group name
- indexer : IdxParam or BaseParam
An "Indexer" instance whose
v
field contains theidx
of devices in the model or group.
Examples
A synchronous generator needs to retrieve the
p
andq
values from static generators for initialization.ExtService
is used for this purpose.In a synchronous generator, one can define the following to retrieve
StaticGen.p
asp0
:class GENCLSModel(Model): def __init__(...): ... self.p0 = ExtService(src='p', model='StaticGen', indexer=self.gen, tex_name='P_0')
Shape Manipulators¶
This section is for advanced model developer.
All generated equations operate on 1-dimensional arrays and can use algebraic calculations only. In some cases, one model would use BackRef to retrieve 2-dimensional indices and will use such indices to retrieve variable addresses. The retrieved addresses usually has a different length of the referencing model and cannot be used directly for calculation. Shape manipulator services can be used in such case.
NumReduce is a helper Service type which reduces a linearly stored 2-D ExtParam into 1-D Service. NumRepeat is a helper Service type which repeats a 1-D value into linearly stored 2-D value based on the shape from a BackRef.
-
class
andes.core.service.
BackRef
(**kwargs)[source] A special type of reference collector.
BackRef is used for collecting device indices of other models referencing the parent model of the BackRef. The v``field will be a list of lists, each containing the `idx of other models referencing each device of the parent model.
BackRef can be passed as indexer for params and vars, or shape for NumReduce and NumRepeat. See examples for illustration.
See also
andes.core.service.NumReduce
- A more complete example using BackRef to build the COI model
Examples
A Bus device has an IdxParam of area, storing the idx of area to which the bus device belongs. In
Bus.__init__()
, one hasself.area = IdxParam(model='Area')
Suppose Bus has the following data
idx area Vn 1 1 110 2 2 220 3 1 345 4 1 500 The Area model wants to collect the indices of Bus devices which points to the corresponding Area device. In
Area.__init__
, one definesself.Bus = BackRef()
where the member attribute name Bus needs to match exactly model name that Area wants to collect idx for. Similarly, one can define
self.ACTopology = BackRef()
to collect devices in the ACTopology group that references Area.The collection of idx happens in
andes.system.System._collect_ref_param()
. It has to be noted that the specific Area entry must exist to collect model idx-dx referencing it. For example, if Area has the following dataidx 1
Then, only Bus 1, 3, and 4 will be collected into self.Bus.v, namely,
self.Bus.v == [ [1, 3, 4] ]
.If Area has data
idx 1 2
Then, self.Bus.v will end up with
[ [1, 3, 4], [2] ]
.
-
class
andes.core.service.
NumReduce
(u, ref: andes.core.service.BackRef, fun: Callable, name=None, tex_name=None, info=None)[source] A helper Service type which reduces a linearly stored 2-D ExtParam into 1-D Service.
NumReduce works with ExtParam whose v field is a list of lists. A reduce function which takes an array-like and returns a scalar need to be supplied. NumReduce calls the reduce function on each of the lists and return all the scalars in an array.
Parameters: - u : ExtParam
Input ExtParam whose
v
contains linearly stored 2-dimensional values- ref : BackRef
The BackRef whose 2-dimensional shapes are used for indexing
- fun : Callable
The callable for converting a 1-D array-like to a scalar
Examples
Suppose one wants to calculate the mean value of the
Vn
in one Area. In theArea
class, one definesclass AreaModel(...): def __init__(...): ... # backward reference from `Bus` self.Bus = BackRef() # collect the Vn in an 1-D array self.Vn = ExtParam(model='Bus', src='Vn', indexer=self.Bus) self.Vn_mean = NumReduce(u=self.Vn, fun=np.mean, ref=self.Bus)
Suppose we define two areas, 1 and 2, the Bus data looks like
idx area Vn 1 1 110 2 2 220 3 1 345 4 1 500 Then, self.Bus.v is a list of two lists
[ [1, 3, 4], [2] ]
. self.Vn.v will be retrieved and linearly stored as[110, 345, 500, 220]
. Based on the shape from self.Bus,numpy.mean()
will be called on[110, 345, 500]
and[220]
respectively. Thus, self.Vn_mean.v will become[318.33, 220]
.
-
class
andes.core.service.
NumRepeat
(u, ref, **kwargs)[source] A helper Service type which repeats a v-provider's value based on the shape from a BackRef
Examples
NumRepeat was originally designed for computing the inertia-weighted average rotor speed (center of inertia speed). COI speed is computed with
\[\omega_{COI} = \frac{ \sum{M_i * \omega_i} } {\sum{M_i}}\]The numerator can be calculated with a mix of BackRef, ExtParam and ExtState. The denominator needs to be calculated with NumReduce and Service Repeat. That is, use NumReduce to calculate the sum, and use NumRepeat to repeat the summed value for each device.
In the COI class, one would have
class COIModel(...): def __init__(...): ... self.SynGen = BackRef() self.SynGenIdx = RefFlatten(ref=self.SynGen) self.M = ExtParam(model='SynGen', src='M', indexer=self.SynGenIdx) self.wgen = ExtState(model='SynGen', src='omega', indexer=self.SynGenIdx) self.Mt = NumReduce(u=self.M, fun=np.sum, ref=self.SynGen) self.Mtr = NumRepeat(u=self.Mt, ref=self.SynGen) self.pidx = IdxRepeat(u=self.idx,ref=self.SynGen)
Finally, one would define the center of inertia speed as
self.wcoi = Algeb(v_str='1', e_str='-wcoi') self.wcoi_sub = ExtAlgeb(model='COI', src='wcoi', e_str='M * wgen / Mtr', v_str='M / Mtr', indexer=self.pidx, )
It is very worth noting that the implementation uses a trick to separate the average weighted sum into n sub-equations, each calculating the \((M_i * \omega_i) / (\sum{M_i})\). Since all the variables are preserved in the sub-equation, the derivatives can be calculated correctly.
-
class
andes.core.service.
IdxRepeat
(u, ref, **kwargs)[source] Helper class to repeat IdxParam.
This class has the same functionality as
andes.core.service.NumRepeat
but only operates on IdxParam, DataParam or NumParam.
-
class
andes.core.service.
RefFlatten
(ref, **kwargs)[source] A service type for flattening
andes.core.service.BackRef
into a 1-D list.Examples
This class is used when one wants to pass BackRef values as indexer.
andes.models.coi.COI
collects referencingandes.models.group.SynGen
withself.SynGen = BackRef(info='SynGen idx lists', export=False)
After collecting BackRefs, self.SynGen.v will become a two-level list of indices, where the first level correspond to each COI and the second level correspond to generators of the COI.
Convert self.SynGen into 1-d as self.SynGenIdx, which can be passed as indexer for retrieving other parameters and variables
self.SynGenIdx = RefFlatten(ref=self.SynGen) self.M = ExtParam(model='SynGen', src='M', indexer=self.SynGenIdx, export=False, )
Device Finder¶
-
class
andes.core.service.
DeviceFinder
(u, link, idx_name, name=None, tex_name=None, info=None)[source] Service for finding indices of optionally linked devices.
If not provided, DeviceFinder will add devices at the beginning of System.setup.
Examples
IEEEST stabilizer takes an optional busf (IdxParam) for specifying the connected BusFreq, which is needed for mode 6. To avoid reimplementing BusFreq within IEEEST, one can do
self.busfreq = DeviceFinder(self.busf, link=self.buss, idx_name='bus')
where self.busf is the optional input, self.buss is the bus indices that busf should measure, and idx_name is the name of a BusFreq parameter through which the measured bus indices are specified. For each None values in self.busf, a BusFreq is created to measure the corresponding bus in self.buss.
That is,
BusFreq.[idx_name].v = [link]
. DeviceFinder will find / create BusFreq devices so that the returned list of BusFreq indices are connected to self.buss, respectively.
Discrete¶
Background¶
The discrete component library contains a special type of block for modeling the discontinuity in power system devices. Such continuities can be device-level physical constraints or algorithmic limits imposed on controllers.
The base class for discrete components is andes.core.discrete.Discrete
.
-
class
andes.core.discrete.
Discrete
(name=None, tex_name=None, info=None)[source] Base discrete class.
Discrete classes export flag arrays (usually boolean) .
The uniqueness of discrete components is the way it works. Discrete components take inputs, criteria, and exports a set of flags with the component-defined meanings. These exported flags can be used in algebraic or differential equations to build piece-wise equations.
For example, Limiter takes a v-provider as input, two v-providers as the upper and the lower bound.
It exports three flags: zi (within bound), zl (below lower bound), and zu (above upper bound).
See the code example in models/pv.py
for an example voltage-based PQ-to-Z conversion.
It is important to note when the flags are updated. Discrete subclasses can use three methods to check and update the value and equations. Among these methods, check_var is called before equation evaluation, but check_eq and set_eq are called after equation update. In the current implementation, check_var updates flags for variable-based discrete components (such as Limiter). check_eq updates flags for equation-involved discrete components (such as AntiWindup). set_var` is currently only used by AntiWindup to store the pegged states.
ANDES includes the following types of discrete components.
Limiters¶
-
class
andes.core.discrete.
Limiter
(u, lower, upper, enable=True, name=None, tex_name=None, info=None, no_upper=False, no_lower=False)[source] Base limiter class.
This class compares values and sets limit values. Exported flags are zi, zl and zu.
Parameters: - u : BaseVar
Input Variable instance
- lower : BaseParam
Parameter instance for the lower limit
- upper : BaseParam
Parameter instance for the upper limit
- no_lower : bool
True to only use the upper limit
- no_upper : bool
True to only use the lower limit
Notes
If not enabled, the default flags are
zu = zl = 0
,zi = 1
.Attributes: - zl : array-like
Flags of elements violating the lower limit; A array of zeros and/or ones.
- zi : array-like
Flags for within the limits
- zu : array-like
Flags for violating the upper limit
-
class
andes.core.discrete.
SortedLimiter
(u, lower, upper, enable=True, n_select: Optional[int] = None, name=None, tex_name=None)[source] A comparer with the top value selection.
-
class
andes.core.discrete.
HardLimiter
(u, lower, upper, enable=True, name=None, tex_name=None, info=None, no_upper=False, no_lower=False)[source] Hard limiter for algebraic or differential variable. This class is an alias of Limiter.
-
class
andes.core.discrete.
AntiWindup
(u, lower, upper, enable=True, name=None, tex_name=None, info=None, state=None)[source] Anti-windup limiter.
Anti-windup limiter prevents the wind-up effect of a differential variable. The derivative of the differential variable is reset if it continues to increase in the same direction after exceeding the limits. During the derivative return, the limiter will be inactive
if x > xmax and x dot > 0: x = xmax and x dot = 0 if x < xmin and x dot < 0: x = xmin and x dot = 0
This class takes one more optional parameter for specifying the equation.
Parameters: - state : State, ExtState
A State (or ExtState) whose equation value will be checked and, when condition satisfies, will be reset by the anti-windup-limiter.
Comparers¶
-
class
andes.core.discrete.
LessThan
(u, bound, equal=False, enable=True, name=None, tex_name=None, cache=False, z0=0, z1=1)[source] Less than (<) comparison function.
Exports two flags: z1 and z0. For elements satisfying the less-than condition, the corresponding z1 = 1. z0 is the element-wise negation of z1.
Notes
The default z0 and z1, if not enabled, can be set through the constructor.
-
class
andes.core.discrete.
Selector
(*args, fun, tex_name=None, info=None)[source] Selection between two variables using the provided reduce function.
The reduce function should take the given number of arguments. An example function is np.maximum.reduce which can be used to select the maximum.
Names are in s0, s1.
Warning
A potential bug when more than two inputs are provided, and values in different inputs are equal. Only two inputs are allowed.
See also
numpy.ufunc.reduce
- NumPy reduce function
andes.core.block.HVGate
andes.core.block.LVGate
Notes
A common pitfall is the 0-based indexing in the Selector flags. Note that exported flags start from 0. Namely, s0 corresponds to the first variable provided for the Selector constructor.
Examples
Example 1: select the largest value between v0 and v1 and put it into vmax.
After the definitions of v0 and v1, define the algebraic variable vmax for the largest value, and a selector vs
self.vmax = Algeb(v_str='maximum(v0, v1)', tex_name='v_{max}', e_str='vs_s0 * v0 + vs_s1 * v1 - vmax') self.vs = Selector(self.v0, self.v1, fun=np.maximum.reduce)
The initial value of vmax is calculated by
maximum(v0, v1)
, which is the element-wise maximum in SymPy and will be generated intonp.maximum(v0, v1)
. The equation of vmax is to select the values based on vs_s0 and vs_s1.
-
class
andes.core.discrete.
Switcher
(u, options: Union[list, Tuple], name: str = None, tex_name: str = None, cache=True)[source] Switcher based on an input parameter.
The switch class takes one v-provider, compares the input with each value in the option list, and exports one flag array for each option. The flags are 0-indexed.
Exported flags are named with _s0, _s1, ..., with a total number of len(options). See the examples section.
Notes
Switches needs to be distinguished from Selector.
Switcher is for generating flags indicating option selection based on an input parameter. Selector is for generating flags at run time based on variable values and a selection function.
Examples
The IEEEST model takes an input for selecting the signal. Options are 1 through 6. One can construct
self.IC = NumParam(info='input code 1-6') # input code self.SW = Switcher(u=self.IC, options=[1, 2, 3, 4, 5, 6])
If the IC values from the data file ends up being
self.IC.v = np.array([1, 2, 2, 4, 6])
Then, the exported flag arrays will be
{'IC_s0': np.array([1, 0, 0, 0, 0]), 'IC_s1': np.array([0, 1, 1, 0, 0]), 'IC_s2': np.array([0, 0, 0, 0, 0]), 'IC_s3': np.array([0, 0, 0, 1, 0]), 'IC_s4': np.array([0, 0, 0, 0, 0]), 'IC_s5': np.array([0, 0, 0, 0, 1]) }
Deadband¶
-
class
andes.core.discrete.
DeadBand
(u, center, lower, upper, enable=True)[source] Dead band with the direction of return.
Parameters: - u : NumParam
The pre-deadband input variable
- center : NumParam
Neutral value of the output
- lower : NumParam
Lower bound
- upper : NumParam
Upper bpund
- enable : bool
Enabled if True; Disabled and works as a pass-through if False.
Notes
Input changes within a deadband will incur no output changes. This component computes and exports five flags.
- Three flags computed from the current input:
- zl: True if the input is below the lower threshold
- zi: True if the input is within the deadband
- zu: True if is above the lower threshold
- Two flags indicating the direction of return:
- zur: True if the input is/has been within the deadband and was returned from the upper threshold
- zlr: True if the input is/has been within the deadband and was returned from the lower threshold
Initial condition:
All five flags are initialized to zero. All flags are updated during check_var when enabled. If the deadband component is not enabled, all of them will remain zero.
Examples
Exported deadband flags need to be used in the algebraic equation corresponding to the post-deadband variable. Assume the pre-deadband input variable is var_in and the post-deadband variable is var_out. First, define a deadband instance db in the model using
self.db = DeadBand(u=self.var_in, center=self.dbc, lower=self.dbl, upper=self.dbu)
To implement a no-memory deadband whose output returns to center when the input is within the band, the equation for var can be written as
var_out.e_str = 'var_in * (1 - db_zi) + \ (dbc * db_zi) - var_out'
To implement a deadband whose output is pegged at the nearest deadband bounds, the equation for var can be provided as
var_out.e_str = 'var_in * (1 - db_zi) + \ dbl * db_zlr + \ dbu * db_zur - var_out'
Blocks¶
Background¶
The block library contains commonly used blocks (such as transfer functions and nonlinear functions).
Variables and equations are pre-defined for blocks to be used as "lego pieces" for scripting DAE models.
The base class for blocks is andes.core.block.Block
.
The supported blocks include Lag
, LeadLag
, Washout
, LeadLagLimit
, PIController
. In addition,
the base class for piece-wise nonlinear functions, PieceWise
is provided. PieceWise
is used for
implementing the quadratic saturation function MagneticQuadSat
and exponential saturation function
MagneticExpSat
.
All variables in a block must be defined as attributes in the constructor, just like variable definition in
models. The difference is that the variables are "exported" from a block to the capturing model. All exported
variables need to placed in a dictionary, self.vars
at the end of the block constructor.
Blocks can be nested as advanced usage. See the following API documentation for more details.
-
class
andes.core.block.
Block
(name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None)[source] Base class for control blocks.
Blocks are meant to be instantiated as Model attributes to provide pre-defined equation sets. Subclasses must overload the __init__ method to take custom inputs. Subclasses of Block must overload the define method to provide initialization and equation strings. Exported variables, services and blocks must be constructed into a dictionary
self.vars
at the end of the constructor.Blocks can be nested. A block can have blocks but itself as attributes and therefore reuse equations. When a block has sub-blocks, the outer block must be constructed with a``name``.
Nested block works in the following way: the parent block modifies the sub-block's
name
attribute by prepending the parent block's name at the construction phase. The parent block then exports the sub-block as a whole. When the parent Model class picks up the block, it will recursively import the variables in the block and the sub-blocks correctly. See the example section for details.Parameters: - name : str, optional
Block name
- tex_name : str, optional
Block LaTeX name
- info : str, optional
Block description.
Warning
It is a good practice to avoid more than one level of nesting, to avoid multi-underscore variable names.
Examples
Example for two-level nested blocks. Suppose we have the following hierarchy
SomeModel instance M | LeadLag A exports (x, y) | Lag B exports (x, y)
SomeModel instance M contains an instance of LeadLag block named A, which contains an instance of a Lag block named B. Both A and B exports two variables
x
andy
.In the code of Model, the following code is used to instantiate LeadLag
class SomeModel: def __init__(...) ... self.A = LeadLag(name='A', u=self.foo1, T1=self.foo2, T2=self.foo3)
To use Lag in the LeadLag code, the following lines are found in the constructor of LeadLag
class LeadLag: def __init__(name, ...) ... self.B = Lag(u=self.y, K=self.K, T=self.T) self.vars = {..., 'A': self.A}
The
__setattr__
magic of LeadLag takes over the construction and assignsA_B
to B.name, given A's name provided at run time. self.A is exported with the internal nameA
at the end.Again, the LeadLag instance name (A in this example) MUST be provided in SomeModel's constructor for the name prepending to work correctly. If there is more than one level of nesting, other than the leaf-level block, all parent blocks' names must be provided at instantiation.
When A is picked up by SomeModel.__setattr__, B is captured from A's exports. Recursively, B's variables are exported, Recall that B.name is now
A_B
, following the naming rule (parent block's name + variable name), B's internal variables becomeA_B_x
andA_B_y
.In this way, B's
define()
needs no modification since the naming rule is the same. For example, B's internal y is always{self.name}_y
, although B has gotten a new nameA_B
.
Transfer Functions¶
The following transfer function blocks have been implemented. They can be imported to build new models.
Algebraic¶
First Order¶
-
class
andes.core.block.
Integrator
(u, T, K, y0, name=None, tex_name=None, info=None)[source] Integrator block.
┌──────┐ u -> │ K/sT │ -> y └──────┘
Exports a differential variable y. The initial output is specified by y0 and default to zero.
-
define
(self)[source] Implemented equation and the initial condition are
\[\begin{split}\dot{y} = K u \\ y^{(0)} = 0\end{split}\]
-
-
class
andes.core.block.
IntegratorAntiWindup
(u, T, K, y0, lower, upper, name=None, tex_name=None, info=None)[source] Integrator block with anti-windup limiter.
upper /¯¯¯¯¯ ┌──────┐ u -> │ K/sT │ -> y └──────┘ _____/ lower
Exports a differential variable y and an AntiWindup lim. The initial output must be specified through y0.
-
define
(self)[source] Implemented equation and the initial condition are
\[\begin{split}\dot{y} = K u \\ y^{(0)} = 0\end{split}\]
-
-
class
andes.core.block.
Lag
(u, T, K, name=None, tex_name=None, info=None)[source] Lag (low pass filter) transfer function.
┌────────┐ │ K │ u -> │ ────── │ -> y │ 1 + sT │ └────────┘
Exports one state variable y as the output.
Parameters: - K
Gain
- T
Time constant
- u
Input variable
-
define
(self)[source] Notes
Equations and initial values are
\[\begin{split}T \dot{y} &= (Ku - y) \\ y^{(0)} &= K u\end{split}\]
-
class
andes.core.block.
LagAntiWindup
(u, T, K, lower, upper, name=None, tex_name=None, info=None)[source] Lag (low pass filter) transfer function block with an anti-windup limiter.
upper /¯¯¯¯¯¯ ┌────────┐ │ K │ u -> │ ────── │ -> y │ 1 + sT │ └────────┘ ______/ lower
Exports one state variable y as the output and one AntiWindup instance lim.
Parameters: - K
Gain
- T
Time constant
- u
Input variable
-
define
(self)[source] Notes
Equations and initial values are
\[\begin{split}T \dot{y} &= (Ku - y) \\ y^{(0)} &= K u\end{split}\]
-
class
andes.core.block.
Washout
(u, T, K, name=None, tex_name=None, info=None)[source] Washout filter (high pass) block.
┌────────┐ │ sK │ u -> │ ────── │ -> y │ 1 + sT │ └────────┘
Exports state x (symbol x') and output algebraic variable y.
-
define
(self)[source] Notes
Equations and initial values:
\[\begin{split}T \dot{x'} &= (u - x') \\ T y &= K (u - x') \\ x'^{(0)} &= u \\ y^{(0)} &= 0\end{split}\]
-
-
class
andes.core.block.
WashoutOrLag
(u, T, K, name=None, zero_out=True, tex_name=None, info=None)[source] Washout with the capability to convert to Lag when K = 0.
Can be enabled with zero_out. Need to provide name to construct.
Exports state x (symbol x'), output algebraic variable y, and a LessThan block LT.
Parameters: - zero_out : bool, optional
If True,
sT
will become 1, and the washout will become a low-pass filter. If False, functions as a regular Washout.
-
define
(self)[source] Notes
Equations and initial values:
\[\begin{split}T \dot{x'} &= (u - x') \\ T y = z_0 K (u - x') + z_1 T x \\ x'^{(0)} &= u \\ y^{(0)} &= 0\end{split}\]where
z_0
is a flag array for the greater-than-zero elements, andz_1
is that for the less-than or equal-to zero elements.
Second Order¶
-
class
andes.core.block.
LeadLag
(u, T1, T2, K=1, zero_out=True, name=None, tex_name=None, info=None)[source] Lead-Lag transfer function block in series implementation
┌───────────┐ │ 1 + sT1 │ u -> │ K ─────── │ -> y │ 1 + sT2 │ └───────────┘
Exports two variables: internal state x and output algebraic variable y.
Parameters: - T1 : BaseParam
Time constant 1
- T2 : BaseParam
Time constant 2
- zero_out : bool
True to allow zeroing out lead-lag as a pass through (when T1=T2=0)
Notes
To allow zeroing out lead-lag as a pure gain, set
zero_out
to True.-
define
(self)[source] Notes
Implemented equations and initial values
\[\begin{split}T_2 \dot{x'} &= (u - x') \\ T_2 y &= K T_1 (u - x') + K T_2 x' + E_2 \, , \text{where} \\ E_2 = & \left\{\begin{matrix} (y - K x') &\text{ if } T_1 = T_2 = 0 \& zero\_out=True \\ 0& \text{ otherwise } \end{matrix}\right. \\ x'^{(0)} & = u\\ y^{(0)} & = Ku\\\end{split}\]
-
class
andes.core.block.
LeadLagLimit
(u, T1, T2, lower, upper, name=None, tex_name=None, info=None)[source] Lead-Lag transfer function block with hard limiter (series implementation)
┌─────────┐ upper │ 1 + sT1 │ /¯¯¯¯¯ u -> │ ─────── │ -> ynl / -> y │ 1 + sT2 │ _____/ └─────────┘ lower
Exports four variables: state x, output before hard limiter ynl, output y, and AntiWindup lim.
-
define
(self)[source] Notes
Implemented control block equations (without limiter) and initial values
\[\begin{split}T_2 \dot{x'} &= (u - x') \\ T_2 y &= T_1 (u - x') + T_2 x' \\ x'^{(0)} &= y^{(0)} = u\end{split}\]
-
-
class
andes.core.block.
Lag2ndOrd
(u, K, T1, T2, name=None, tex_name=None, info=None)[source] Second order lag transfer function (low-pass filter)
┌──────────────────┐ │ K │ u -> │ ──────────────── │ -> y │ 1 + sT1 + s^2 T2 │ └──────────────────┘
Exports one two state variables (x, y), where y is the output.
Parameters: - u
Input
- K
Gain
- T1
First order time constant
- T2
Second order time constant
-
define
(self)[source] Notes
Implemented equations and initial values are
\[\begin{split}T_2 \dot{x} &= Ku - y - T_1 x \\ \dot{y} &= x \\ x^{(0)} &= 0 \\ y^{(0)} &= K u\end{split}\]
-
class
andes.core.block.
LeadLag2ndOrd
(u, T1, T2, T3, T4, zero_out=False, name=None, tex_name=None, info=None)[source] Second-order lead-lag transfer function block
┌──────────────────┐ │ 1 + sT3 + s^2 T4 │ u -> │ ──────────────── │ -> y │ 1 + sT1 + s^2 T2 │ └──────────────────┘
Exports two internal states (x1 and x2) and output algebraic variable y.
# TODO: instead of implementing zero_out using LessThan and an additional term, consider correcting all parameters to 1 if all are 0.
-
define
(self)[source] Notes
Implemented equations and initial values are
\[\begin{split}T_2 \dot{x}_1 &= u - x_2 - T_1 x_1 \\ \dot{x}_2 &= x_1 \\ T_2 y &= T_2 x_2 + T_2 T_3 x_1 + T_4 (u - x_2 - T_1 x_1) + E_2 \, , \text{ where} \\ E_2 = & \left\{\begin{matrix} (y - x_2) &\text{ if } T_1 = T_2 = T_3 = T_4 = 0 \& zero\_out=True \\ 0& \text{ otherwise } \end{matrix}\right. \\ x_1^{(0)} &= 0 \\ x_2^{(0)} &= y^{(0)} = u\end{split}\]
-
Saturation¶
-
class
andes.models.exciter.
ExcExpSat
(E1, SE1, E2, SE2, name=None, tex_name=None, info=None)[source] Exponential exciter saturation block to calculate A and B from E1, SE1, E2 and SE2. Input parameters will be corrected and the user will be warned. To disable saturation, set either E1 or E2 to 0.
Parameters: - E1 : BaseParam
First point of excitation field voltage
- SE1: BaseParam
Coefficient corresponding to E1
- E2 : BaseParam
Second point of excitation field voltage
- SE2: BaseParam
Coefficient corresponding to E2
-
define
(self)[source] Notes
The implementation solves for coefficients A and B which satisfy
\[E_1 S_{E1} = A e^{E1\times B} E_2 S_{E2} = A e^{E2\times B}\]The solutions are given by
\[E_{1} S_{E1} e^{ \frac{E_1 \log{ \left( \frac{E_2 S_{E2}} {E_1 S_{E1}} \right)} } {E_1 - E_2}} - \frac{\log{\left(\frac{E_2 S_{E2}}{E_1 S_{E1}} \right)}}{E_1 - E_2}\]
Others¶
Value Selector¶
-
class
andes.core.block.
HVGate
(u1, u2, name=None, tex_name=None, info=None)[source] High Value Gate. Outputs the maximum of two inputs.
┌─────────┐ u1 -> │ HV Gate │ │ │ -> y u2 -> │ (MAX) │ └─────────┘
-
class
andes.core.block.
LVGate
(u1, u2, name=None, tex_name=None, info=None)[source] Low Value Gate. Outputs the minimum of the two inputs.
┌─────────┐ u1 -> │ LV Gate | │ | -> y u2 -> │ (MIN) | └─────────┘
Examples¶
TGOV1¶
The TGOV1 turbine governor model is shown as a practical example using the library.

This model is composed of a lead-lag transfer function and a first-order lag transfer function with an anti-windup limiter, which are sufficiently complex for demonstration. The corresponding differential equations and algebraic equations are given below.
where LG and LL denote the lag block and the lead-lag block, \(\dot{x}_{LG}\) and \(\dot{x}_{LL}\) are the internal states, \(y_{LL}\) is the lead-lag output, \(\omega\) the generator speed, \(\omega_d\) the generator under-speed, \(P_d\) the droop output, \(\tau_{m0}\) the steady-state torque input, and \(P_{OUT}\) the turbine output that will be summed at the generator.
The code for the above model is demonstrated as follows. The complete code can be found in
andes/models/governor.py
.
def __init__(self):
# 1. Declare parameters from case file inputs.
self.R = NumParam(info='Turbine governor droop',
non_zero=True, ipower=True)
# Other parameters are omitted.
# 2. Declare external variables from generators.
self.omega = ExtState(src='omega',
model='SynGen',
indexer=self.syn,
info='Generator speed')
self.tm = ExtAlgeb(src='tm',
model='SynGen',
indexer=self.syn,
e_str='u*(pout-tm0)',
info='Generator torque input')
# 3. Declare initial values from generators.
self.tm0 = ExtService(src='tm',
model='SynGen',
indexer=self.syn,
info='Initial torque input')
# 4. Declare variables and equations.
self.pref = Algeb(info='Reference power input',
v_str='tm0*R',
e_str='tm0*R-pref')
self.wd = Algeb(info='Generator under speed',
e_str='(1-omega)-wd')
self.pd = Algeb(info='Droop output',
v_str='tm0',
e_str='(wd+pref)/R-pd')
self.LG_x = State(info='State in the lag TF',
v_str='pd',
e_str='LG_lim_zi*(pd-LG_x)/T1')
self.LG_lim = AntiWindup(u=self.LG_x,
lower=self.VMIN,
upper=self.VMAX)
self.LL_x = State(info='State in the lead-lag TF',
v_str='LG_x',
e_str='(LG_x-LL_x)/T3')
self.LL_y = Algeb(info='Lead-lag Output',
v_str='LG_x',
e_str='T2/T3*(LG_x-LL_x)+LL_x-LL_y')
self.pout = Algeb(info='Turbine output power',
v_str='tm0',
e_str='(LL_y+Dt*wd)-pout')
Test Cases¶
Directory¶
ANDES comes with several test cases in the andes/cases/
folder.
Currently, the Kundur's 2-area system, IEEE 14-bus system,
NPCC 140-bus system, and the WECC 179-bus system has been verified
against DSATools TSAT.
The test case library will continue to build as more models get implemented.
A tree view of the test directory is as follows.
cases/
├── 5bus/
│ └── pjm5bus.xlsx
├── GBnetwork/
│ ├── GBnetwork.m
│ ├── GBnetwork.xlsx
│ └── README.md
├── ieee14/
│ ├── ieee14.dyr
│ └── ieee14.raw
├── kundur/
│ ├── kundur_aw.xlsx
│ ├── kundur_coi.xlsx
│ ├── kundur_coi_empty.xlsx
│ ├── kundur_esdc2a.xlsx
│ ├── kundur_esst3a.xlsx
│ ├── kundur_exdc2_zero_tb.xlsx
│ ├── kundur_exst1.xlsx
│ ├── kundur_freq.xlsx
│ ├── kundur_full.dyr
│ ├── kundur_full.raw
│ ├── kundur_full.xlsx
│ ├── kundur_gentrip.xlsx
│ ├── kundur_ieeeg1.xlsx
│ ├── kundur_ieeest.xlsx
│ ├── kundur_sexs.xlsx
│ └── kundur_st2cut.xlsx
├── matpower/
│ ├── case118.m
│ ├── case14.m
│ ├── case300.m
│ └── case5.m
├── nordic44/
│ ├── N44_BC.dyr
│ ├── N44_BC.raw
│ └── README.md
├── npcc/
│ ├── npcc.raw
│ └── npcc_full.dyr
├── wecc/
│ ├── wecc.raw
│ ├── wecc.xlsx
│ ├── wecc_full.dyr
│ ├── wecc_gencls.dyr
└── wscc9/
├── wscc9.raw
└── wscc9.xlsx
MATPOWER Cases¶
MATPOWER cases has been tested in ANDES for power flow calculation. All following cases are calculated with the provided initial values using the full Newton-Raphson iterative approach.
The numerical library used for sparse matrix factorization is KLU.
In addition, Jacobians are updated in place spmatrix.ipadd
.
Computations are performed on macOS 10.15.4 with i9-9980H, 16 GB
2400 MHz DDR4, running ANDES 0.9.1, CVXOPT 1.2.4 and NumPy 1.18.1.
The statistics of convergence, number of iterations, and solution time (including equation evaluation, Jacobian, and factorization time) are reported in the following table. The computation time may vary depending on operating system and hardware.
File Name | Converged? | # of Iterations | Time [s] |
---|---|---|---|
case30.m | 1 | 3 | 0.012 |
case_ACTIVSg500.m | 1 | 3 | 0.019 |
case13659pegase.m | 1 | 5 | 0.531 |
case9Q.m | 1 | 3 | 0.011 |
case_ACTIVSg200.m | 1 | 2 | 0.013 |
case24_ieee_rts.m | 1 | 4 | 0.014 |
case300.m | 1 | 5 | 0.026 |
case6495rte.m | 1 | 5 | 0.204 |
case39.m | 1 | 1 | 0.009 |
case18.m | 1 | 4 | 0.013 |
case_RTS_GMLC.m | 1 | 3 | 0.014 |
case1951rte.m | 1 | 3 | 0.047 |
case6ww.m | 1 | 3 | 0.010 |
case5.m | 1 | 3 | 0.010 |
case69.m | 1 | 3 | 0.014 |
case6515rte.m | 1 | 4 | 0.168 |
case2383wp.m | 1 | 6 | 0.084 |
case30Q.m | 1 | 3 | 0.011 |
case2868rte.m | 1 | 4 | 0.074 |
case1354pegase.m | 1 | 4 | 0.047 |
case2848rte.m | 1 | 3 | 0.063 |
case4_dist.m | 1 | 3 | 0.010 |
case6470rte.m | 1 | 4 | 0.175 |
case2746wp.m | 1 | 4 | 0.074 |
case_SyntheticUSA.m | 1 | 21 | 11.120 |
case118.m | 1 | 3 | 0.014 |
case30pwl.m | 1 | 3 | 0.021 |
case57.m | 1 | 3 | 0.017 |
case89pegase.m | 1 | 5 | 0.024 |
case6468rte.m | 1 | 6 | 0.232 |
case2746wop.m | 1 | 4 | 0.075 |
case85.m | 1 | 3 | 0.011 |
case22.m | 1 | 2 | 0.008 |
case4gs.m | 1 | 3 | 0.012 |
case14.m | 1 | 2 | 0.010 |
case_ACTIVSg10k.m | 1 | 4 | 0.251 |
case2869pegase.m | 1 | 6 | 0.136 |
case_ieee30.m | 1 | 2 | 0.010 |
case2737sop.m | 1 | 5 | 0.087 |
case9target.m | 1 | 5 | 0.013 |
case1888rte.m | 1 | 2 | 0.037 |
case145.m | 1 | 3 | 0.018 |
case_ACTIVSg2000.m | 1 | 3 | 0.059 |
case_ACTIVSg70k.m | 1 | 15 | 7.043 |
case9241pegase.m | 1 | 6 | 0.497 |
case9.m | 1 | 3 | 0.010 |
case141.m | 1 | 3 | 0.012 |
case_ACTIVSg25k.m | 1 | 7 | 1.040 |
case118.m | 1 | 3 | 0.015 |
case1354pegase.m | 1 | 4 | 0.048 |
case13659pegase.m | 1 | 5 | 0.523 |
case14.m | 1 | 2 | 0.011 |
case141.m | 1 | 3 | 0.013 |
case145.m | 1 | 3 | 0.017 |
case18.m | 1 | 4 | 0.012 |
case1888rte.m | 1 | 2 | 0.037 |
case1951rte.m | 1 | 3 | 0.052 |
case22.m | 1 | 2 | 0.011 |
case2383wp.m | 1 | 6 | 0.086 |
case24_ieee_rts.m | 1 | 4 | 0.015 |
case2736sp.m | 1 | 4 | 0.074 |
case2737sop.m | 1 | 5 | 0.108 |
case2746wop.m | 1 | 4 | 0.093 |
case2746wp.m | 1 | 4 | 0.089 |
case2848rte.m | 1 | 3 | 0.065 |
case2868rte.m | 1 | 4 | 0.079 |
case2869pegase.m | 1 | 6 | 0.137 |
case30.m | 1 | 3 | 0.033 |
case300.m | 1 | 5 | 0.102 |
case30Q.m | 1 | 3 | 0.013 |
case30pwl.m | 1 | 3 | 0.013 |
case39.m | 1 | 1 | 0.008 |
case4_dist.m | 1 | 3 | 0.010 |
case4gs.m | 1 | 3 | 0.010 |
case5.m | 1 | 3 | 0.011 |
case57.m | 1 | 3 | 0.015 |
case6468rte.m | 1 | 6 | 0.229 |
case6470rte.m | 1 | 4 | 0.170 |
case6495rte.m | 1 | 5 | 0.198 |
case6515rte.m | 1 | 4 | 0.169 |
case69.m | 1 | 3 | 0.012 |
case6ww.m | 1 | 3 | 0.011 |
case85.m | 1 | 3 | 0.013 |
case89pegase.m | 1 | 5 | 0.020 |
case9.m | 1 | 3 | 0.010 |
case9241pegase.m | 1 | 6 | 0.487 |
case9Q.m | 1 | 3 | 0.013 |
case9target.m | 1 | 5 | 0.015 |
case_ACTIVSg10k.m | 1 | 4 | 0.257 |
case_ACTIVSg200.m | 1 | 2 | 0.014 |
case_ACTIVSg2000.m | 1 | 3 | 0.058 |
case_ACTIVSg25k.m | 1 | 7 | 1.118 |
case_ACTIVSg500.m | 1 | 3 | 0.027 |
case_ACTIVSg70k.m | 1 | 15 | 6.931 |
case_RTS_GMLC.m | 1 | 3 | 0.014 |
case_SyntheticUSA.m | 1 | 21 | 11.103 |
case_ieee30.m | 1 | 2 | 0.010 |
case3375wp.m | 0 | 0.061 | |
case33bw.m | 0 | 0.007 | |
case3120sp.m | 0 | 0.037 | |
case3012wp.m | 0 | 0.082 | |
case3120sp.m | 0 | 0.039 | |
case3375wp.m | 0 | 0.059 | |
case33bw.m | 0 | 0.007 |
Model References¶
Supported Groups and Models
Group | Models |
---|---|
ACLine | Line |
ACTopology | Bus |
Calculation | COI |
Collection | Area |
DCLink | Ground, R, L, C, RCp, RCs, RLs, RLCs, RLCp |
DCTopology | Node |
Exciter | EXDC2, IEEEX1, ESDC2A, EXST1, ESST3A, SEXS |
Experimental | PI2 |
FreqMeasurement | BusFreq, BusROCOF |
PSS | IEEEST, ST2CUT |
StaticACDC | VSCShunt |
StaticGen | PV, Slack |
StaticLoad | PQ |
StaticShunt | Shunt |
SynGen | GENCLS, GENROU |
TimedEvent | Toggler, Fault |
TurbineGov | TG2, TGOV1, IEEEG1 |
ACLine¶
Common Parameters: u, name
Available models: Line
Line¶
Group ACLine
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus1 | idx of from bus | IdxParam | ||||
bus2 | idx of to bus | IdxParam | ||||
Sn | \(S_n\) | Power rating | 100 | NumParam | non_zero | |
fn | \(f\) | rated frequency | 60 | NumParam | ||
Vn1 | \(V_{n1}\) | AC voltage rating | 110 | NumParam | non_zero | |
Vn2 | \(V_{n2}\) | rated voltage of bus2 | 110 | NumParam | non_zero | |
r | \(r\) | line resistance | 0.000 | NumParam | ||
x | \(x\) | line reactance | 0.000 | NumParam | ||
b | shared shunt susceptance | 0 | NumParam | |||
g | shared shunt conductance | 0 | NumParam | |||
b1 | \(b_1\) | from-side susceptance | 0 | NumParam | ||
g1 | \(g_1\) | from-side conductance | 0 | NumParam | ||
b2 | \(b_2\) | to-side susceptance | 0 | NumParam | ||
g2 | \(g_2\) | to-side conductance | 0 | NumParam | ||
trans | transformer branch flag | 0 | NumParam | |||
tap | \(t_{ap}\) | transformer branch tap ratio | 1 | NumParam | ||
phi | \(\phi\) | transformer branch phase shift in rad | 0 | NumParam | ||
owner | owner code | IdxParam | ||||
xcoord | x coordinates | DataParam | ||||
ycoord | y coordinates | DataParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
a1 | \(a_{1}\) | phase angle of the from bus | |||
a2 | \(a_{2}\) | phase angle of the to bus | |||
v1 | \(v_{1}\) | voltage magnitude of the from bus | |||
v2 | \(v_{2}\) | voltage magnitude of the to bus |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
a1 | \(a_{1}\) | ExtAlgeb | \(u \left(- \frac{v_{1} v_{2} \left(- b_{hk} \sin{\left(\phi - a_{1} + a_{2} \right)} + g_{hk} \cos{\left(\phi - a_{1} + a_{2} \right)}\right)}{t_{ap}} + \frac{v_{1}^{2} \left(g_{h} + g_{hk}\right)}{t_{ap}^{2}}\right)\) |
a2 | \(a_{2}\) | ExtAlgeb | \(u \left(v_{2}^{2} \left(g_{h} + g_{hk}\right) - \frac{v_{1} v_{2} \left(b_{hk} \sin{\left(\phi - a_{1} + a_{2} \right)} + g_{hk} \cos{\left(\phi - a_{1} + a_{2} \right)}\right)}{t_{ap}}\right)\) |
v1 | \(v_{1}\) | ExtAlgeb | \(u \left(- \frac{v_{1} v_{2} \left(- b_{hk} \cos{\left(\phi - a_{1} + a_{2} \right)} - g_{hk} \sin{\left(\phi - a_{1} + a_{2} \right)}\right)}{t_{ap}} - \frac{v_{1}^{2} \left(b_{h} + b_{hk}\right)}{t_{ap}^{2}}\right)\) |
v2 | \(v_{2}\) | ExtAlgeb | \(u \left(- v_{2}^{2} \left(b_{h} + b_{hk}\right) + \frac{v_{1} v_{2} \left(b_{hk} \cos{\left(\phi - a_{1} + a_{2} \right)} - g_{hk} \sin{\left(\phi - a_{1} + a_{2} \right)}\right)}{t_{ap}}\right)\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
gh | \(g_h\) | \(0.5 g + g_{1}\) | ConstService |
bh | \(b_h\) | \(0.5 b + b_{1}\) | ConstService |
gk | \(g_k\) | \(0.5 g + g_{2}\) | ConstService |
bk | \(b_k\) | \(0.5 b + b_{2}\) | ConstService |
yh | \(y_h\) | \(u \left(i b_{h} + g_{h}\right)\) | ConstService |
yk | \(y_k\) | \(u \left(i b_{k} + g_{k}\right)\) | ConstService |
yhk | \(y_{hk}\) | \(\frac{u}{r + i \left(x + 1.0 \cdot 10^{-8}\right) + 1.0 \cdot 10^{-8}}\) | ConstService |
ghk | \(g_{hk}\) | \(\operatorname{re}{\left(y_{hk}\right)}\) | ConstService |
bhk | \(b_{hk}\) | \(\operatorname{im}{\left(y_{hk}\right)}\) | ConstService |
ACTopology¶
Common Parameters: u, name
Common Variables: a, v
Available models: Bus
Bus¶
Group ACTopology
AC Bus model.
Power balance equation have the form of
load - injection = 0
. Namely, load is positively summed, while injections are negative.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
Vn | \(V_n\) | AC voltage rating | 110 | kV | NumParam | non_zero |
vmax | \(V_{max}\) | Voltage upper limit | 1.100 | p.u. | NumParam | |
vmin | \(V_{min}\) | Voltage lower limit | 0.900 | p.u. | NumParam | |
v0 | \(V_0\) | initial voltage magnitude | 1 | p.u. | NumParam | non_zero |
a0 | \(\theta_0\) | initial voltage phase angle | 0 | rad | NumParam | |
xcoord | x coordinate (longitude) | 0 | DataParam | |||
ycoord | y coordinate (latitude) | 0 | DataParam | |||
area | Area code | IdxParam | ||||
zone | Zone code | IdxParam | ||||
owner | Owner code | IdxParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
a | \(\theta\) | \(\theta_0 \left(1 - z_{flat}\right) + 1.0 \cdot 10^{-8} z_{flat}\) | voltage angle | rad | v_str |
v | \(V\) | \(V_{0} \left(1 - z_{flat}\right) + z_{flat}\) | voltage magnitude | p.u. | v_str |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
a | \(\theta\) | Algeb | \(0\) |
v | \(V\) | Algeb | \(0\) |
Config Fields in [Bus]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
flat_start | \(z_{flat}\) | 0 | flat start for voltages | (0, 1) |
Calculation¶
Group of classes that calculates based on other models.
Common Parameters: u, name
Available models: COI
COI¶
Group Calculation
Center of inertia calculation class.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
M | Linearly stored SynGen.M | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
wgen | \(\omega_{gen}\) | Linearly stored SynGen.omega | |||
agen | \(\delta_{gen}\) | Linearly stored SynGen.delta | |||
omega | \(\omega_{coi}\) | \(1\) | COI speed | v_str,v_setter | |
delta | \(\delta_{coi}\) | \(\delta_{gen,0,avg}\) | COI rotor angle | v_str,v_setter | |
omega_sub | \(\omega_{sub}\) | COI frequency contribution of each generator | |||
delta_sub | \(\delta_{sub}\) | COI angle contribution of each generator |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
wgen | \(\omega_{gen}\) | ExtState | \(0\) | |
agen | \(\delta_{gen}\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
omega | \(\omega_{coi}\) | Algeb | \(- \omega_{coi}\) |
delta | \(\delta_{coi}\) | Algeb | \(- \delta_{coi}\) |
omega_sub | \(\omega_{sub}\) | ExtAlgeb | \(\frac{M \omega_{gen}}{M_{tr}}\) |
delta_sub | \(\delta_{sub}\) | ExtAlgeb | \(\frac{M \delta_{gen}}{M_{tr}}\) |
Collection¶
Collection of topology models
Common Parameters: u, name
Available models: Area
Area¶
Group Collection
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
Vn | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
a | \(a\) | Bus voltage angle | |||
v | \(v\) | Bus voltage magnitude |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
a | \(a\) | ExtAlgeb | \(0\) |
v | \(v\) | ExtAlgeb | \(0\) |
DCLink¶
Basic DC links
Common Parameters: u, name
Available models: Ground, R, L, C, RCp, RCs, RLs, RLCs, RLCp
Ground¶
Group DCLink
Ground model that sets the voltage of the connected DC node.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node | Node index | IdxParam | mandatory | |||
voltage | \(V_0\) | Ground voltage (typically 0) | 0 | p.u. | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
Idc | \(I_{dc}\) | \(0\) | Ficticious current injection from ground | v_str | |
v | \(v\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Idc | \(I_{dc}\) | Algeb | \(u \left(- V_{0} + v\right)\) |
v | \(v\) | ExtAlgeb | \(- I_{dc}\) |
R¶
Group DCLink
Resistive dc line
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
R | DC line resistance | 0.010 | p.u. | NumParam | non_zero,r |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
Idc | \(I_{dc}\) | \(\frac{u \left(- v_{1} + v_{2}\right)}{R}\) | Current from node 2 to 1 | p.u. | v_str |
v1 | \(v_{1}\) | DC voltage on node 1 | |||
v2 | \(v_{2}\) | DC voltage on node 2 |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Idc | \(I_{dc}\) | Algeb | \(- I_{dc} + \frac{u \left(- v_{1} + v_{2}\right)}{R}\) |
v1 | \(v_{1}\) | ExtAlgeb | \(- I_{dc}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(I_{dc}\) |
L¶
Group DCLink
Inductive dc line
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
L | DC line inductance | 0.001 | p.u. | NumParam | non_zero,r |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
IL | \(I_{L}\) | \(0\) | Inductance current | p.u. | v_str |
v1 | \(v_{1}\) | DC voltage on node 1 | |||
v2 | \(v_{2}\) | DC voltage on node 2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
IL | \(I_{L}\) | State | \(- \frac{u \left(v_{1} - v_{2}\right)}{L}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
v1 | \(v_{1}\) | ExtAlgeb | \(- I_{L}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(I_{L}\) |
C¶
Group DCLink
Capacitive dc branch
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
C | DC capacitance | 0.001 | p.u. | NumParam | non_zero,g |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
vC | \(v_{C}\) | \(0\) | Capacitor current | p.u. | v_str |
Idc | \(I_{dc}\) | \(0\) | Current from node 2 to 1 | p.u. | v_str |
v1 | \(v_{1}\) | DC voltage on node 1 | |||
v2 | \(v_{2}\) | DC voltage on node 2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
vC | \(v_{C}\) | State | \(- \frac{I_{dc} u}{C}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Idc | \(I_{dc}\) | Algeb | \(I_{dc} \left(1 - u\right) + u \left(- v_{1} + v_{2} + v_{C}\right)\) |
v1 | \(v_{1}\) | ExtAlgeb | \(- I_{dc}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(I_{dc}\) |
RCp¶
Group DCLink
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
R | \(R\) | DC line resistance | 0.010 | p.u. | NumParam | non_zero,r |
C | \(C\) | DC capacitance | 0.001 | p.u. | NumParam | non_zero,g |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
vC | \(v_{C}\) | \(v_{1} - v_{2}\) | Capacitor current | p.u. | v_str |
Idc | \(I_{dc}\) | \(\frac{- v_{1} + v_{2}}{R}\) | Current from node 2 to 1 | p.u. | v_str |
v1 | \(v_{1}\) | DC voltage on node 1 | |||
v2 | \(v_{2}\) | DC voltage on node 2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
vC | \(v_{C}\) | State | \(- \frac{u \left(I_{dc} - \frac{v_{C}}{R}\right)}{C}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Idc | \(I_{dc}\) | Algeb | \(I_{dc} \left(1 - u\right) + u \left(- v_{1} + v_{2} + v_{C}\right)\) |
v1 | \(v_{1}\) | ExtAlgeb | \(- I_{dc}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(I_{dc}\) |
RCs¶
Group DCLink
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
R | \(R\) | DC line resistance | 0.010 | p.u. | NumParam | non_zero,r |
C | \(C\) | DC capacitance | 0.001 | p.u. | NumParam | non_zero,g |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
vC | \(v_{C}\) | \(v_{1} - v_{2}\) | Capacitor current | p.u. | v_str |
Idc | \(I_{dc}\) | \(\frac{- v_{1} + v_{2}}{R}\) | Current from node 2 to 1 | p.u. | v_str |
v1 | \(v_{1}\) | DC voltage on node 1 | |||
v2 | \(v_{2}\) | DC voltage on node 2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
vC | \(v_{C}\) | State | \(- \frac{I_{dc} u}{C}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Idc | \(I_{dc}\) | Algeb | \(I_{dc} \left(1 - u\right) + u \left(- I_{dc} R - v_{1} + v_{2} + v_{C}\right)\) |
v1 | \(v_{1}\) | ExtAlgeb | \(- I_{dc}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(I_{dc}\) |
RLs¶
Group DCLink
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
R | \(R\) | DC line resistance | 0.010 | p.u. | NumParam | non_zero,r |
L | \(L\) | DC line inductance | 0.001 | p.u. | NumParam | non_zero,r |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
IL | \(I_{L}\) | \(\frac{v_{1} - v_{2}}{R}\) | Inductance current | p.u. | v_str |
Idc | \(I_{dc}\) | \(- \frac{u \left(v_{1} - v_{2}\right)}{R}\) | Current from node 2 to 1 | p.u. | v_str |
v1 | \(v_{1}\) | DC voltage on node 1 | |||
v2 | \(v_{2}\) | DC voltage on node 2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
IL | \(I_{L}\) | State | \(\frac{u \left(- I_{L} R + v_{1} - v_{2}\right)}{L}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Idc | \(I_{dc}\) | Algeb | \(- I_{L} u - I_{dc}\) |
v1 | \(v_{1}\) | ExtAlgeb | \(- I_{dc}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(I_{dc}\) |
RLCs¶
Group DCLink
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
R | \(R\) | DC line resistance | 0.010 | p.u. | NumParam | non_zero,r |
L | \(L\) | DC line inductance | 0.001 | p.u. | NumParam | non_zero,r |
C | \(C\) | DC capacitance | 0.001 | p.u. | NumParam | non_zero,g |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
IL | \(I_{L}\) | \(0\) | Inductance current | p.u. | v_str |
vC | \(v_{C}\) | \(v_{1} - v_{2}\) | Capacitor current | p.u. | v_str |
Idc | \(I_{dc}\) | \(0\) | Current from node 2 to 1 | p.u. | v_str |
v1 | \(v_{1}\) | DC voltage on node 1 | |||
v2 | \(v_{2}\) | DC voltage on node 2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
IL | \(I_{L}\) | State | \(\frac{u \left(- I_{L} R + v_{1} - v_{2} - v_{C}\right)}{L}\) | |
vC | \(v_{C}\) | State | \(\frac{I_{L} u}{C}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Idc | \(I_{dc}\) | Algeb | \(- I_{L} - I_{dc}\) |
v1 | \(v_{1}\) | ExtAlgeb | \(- I_{dc}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(I_{dc}\) |
RLCp¶
Group DCLink
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
R | \(R\) | DC line resistance | 0.010 | p.u. | NumParam | non_zero,r |
L | \(L\) | DC line inductance | 0.001 | p.u. | NumParam | non_zero,r |
C | \(C\) | DC capacitance | 0.001 | p.u. | NumParam | non_zero,g |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
IL | \(I_{L}\) | \(0\) | Inductance current | p.u. | v_str |
vC | \(v_{C}\) | \(v_{1} - v_{2}\) | Capacitor current | p.u. | v_str |
Idc | \(I_{dc}\) | \(\frac{- v_{1} + v_{2}}{R}\) | Current from node 2 to 1 | p.u. | v_str |
v1 | \(v_{1}\) | DC voltage on node 1 | |||
v2 | \(v_{2}\) | DC voltage on node 2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
IL | \(I_{L}\) | State | \(\frac{u v_{C}}{L}\) | |
vC | \(v_{C}\) | State | \(- \frac{u \left(- I_{L} + I_{dc} - \frac{v_{C}}{R}\right)}{C}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Idc | \(I_{dc}\) | Algeb | \(I_{dc} \left(1 - u\right) + u \left(- v_{1} + v_{2} + v_{C}\right)\) |
v1 | \(v_{1}\) | ExtAlgeb | \(- I_{dc}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(I_{dc}\) |
DCTopology¶
Common Parameters: u, name
Common Variables: v
Available models: Node
Node¶
Group DCTopology
DC Node model.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
Vdcn | \(V_{dcn}\) | DC voltage rating | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
v0 | \(V_{dc0}\) | initial voltage magnitude | 1 | p.u. | NumParam | |
xcoord | x coordinate (longitude) | 0 | DataParam | |||
ycoord | y coordinate (latitude) | 0 | DataParam | |||
area | Area code | IdxParam | ||||
zone | Zone code | IdxParam | ||||
owner | Owner code | IdxParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
v | \(V_{dc}\) | \(V_{dc0} \left(1 - z_{flat}\right) + z_{flat}\) | voltage magnitude | p.u. | v_str |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
v | \(V_{dc}\) | Algeb | \(0\) |
Config Fields in [Node]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
flat_start | \(z_{flat}\) | 0 | flat start for voltages | (0, 1) |
Exciter¶
Exciter group for synchronous generators.
Common Parameters: u, name, syn
Common Variables: vout, vi
Available models: EXDC2, IEEEX1, ESDC2A, EXST1, ESST3A, SEXS
EXDC2¶
Group Exciter
EXDC2 model.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory | |||
TR | \(T_R\) | Sensing time constant | 0.010 | p.u. | NumParam | |
TA | \(T_A\) | Lag time constant in anti-windup lag | 0.040 | p.u. | NumParam | |
TC | \(T_C\) | Lead time constant in lead-lag | 1 | p.u. | NumParam | |
TB | \(T_B\) | Lag time constant in lead-lag | 1 | p.u. | NumParam | |
TE | \(T_E\) | Exciter integrator time constant | 0.800 | p.u. | NumParam | |
TF1 | \(T_{F1}\) | Feedback washout time constant | 1 | p.u. | NumParam | non_zero |
KF1 | \(K_{F1}\) | Feedback washout gain | 0.030 | p.u. | NumParam | |
KA | \(K_A\) | Gain in anti-windup lag TF | 40 | p.u. | NumParam | |
KE | \(K_E\) | Gain added to saturation | 1 | p.u. | NumParam | |
VRMAX | \(V_{RMAX}\) | Maximum excitation limit | 7.300 | p.u. | NumParam | |
VRMIN | \(V_{RMIN}\) | Minimum excitation limit | -7.300 | p.u. | NumParam | |
E1 | \(E_1\) | First saturation point | 0 | p.u. | NumParam | |
SE1 | \(S_{E1}\) | Value at first saturation point | 0 | p.u. | NumParam | |
E2 | \(E_2\) | Second saturation point | 0 | p.u. | NumParam | |
SE2 | \(S_{E2}\) | Value at second saturation point | 0 | p.u. | NumParam | |
Sn | \(S_m\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_m\) | Rated voltage from generator | 0 | kV | ExtParam | |
bus | \(bus\) | Bus idx of the generators | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
vp | \(V_{p}\) | \(v_{f0}\) | Voltage after saturation feedback, before speed term | p.u. | v_str |
LS_y | \(y_{LS}\) | \(1.0 V\) | State in lag transfer function | v_str | |
LL_x | \(x'_{LL}\) | \(V_{i}\) | State in lead-lag | v_str | |
LA_y | \(y_{LA}\) | \(K_{A} y_{LL}\) | State in lag TF | v_str | |
W_x | \(x'_{W}\) | \(V_{p}\) | State in washout filter | v_str | |
omega | \(\omega\) | Generator speed | |||
vout | \(v_{out}\) | \(v_{f0}\) | Exciter final output voltage | v_str | |
vref | \(V_{ref}\) | \(V_{ref0}\) | Reference voltage input | p.u. | v_str |
Se | \(S_e(|V_{out}|)\) | \(S_{e0}\) | saturation output | v_str | |
vi | \(V_{i}\) | \(V_{b0}\) | Total input voltages | p.u. | v_str |
LL_y | \(y_{LL}\) | \(V_{i}\) | Output of lead-lag | v_str | |
W_y | \(y_{W}\) | \(0\) | Output of washout filter | v_str | |
vf | \(v_{f}\) | Excitation field voltage to generator | |||
XadIfd | \(X_{ad}I_{fd}\) | Armature excitation current | |||
a | \(\theta\) | Bus voltage phase angle | |||
v | \(V\) | Bus voltage magnitude |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
vp | \(V_{p}\) | State | \(- K_{E} V_{p} - S_e(|V_{out}|) V_{p} + y_{LA}\) | \(T_E\) |
LS_y | \(y_{LS}\) | State | \(1.0 V - y_{LS}\) | \(T_R\) |
LL_x | \(x'_{LL}\) | State | \(V_{i} - x'_{LL}\) | \(T_B\) |
LA_y | \(y_{LA}\) | State | \(K_{A} y_{LL} - y_{LA}\) | \(T_A\) |
W_x | \(x'_{W}\) | State | \(V_{p} - x'_{W}\) | \(T_{F1}\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
vout | \(v_{out}\) | Algeb | \(V_{p} \omega - v_{out}\) |
vref | \(V_{ref}\) | Algeb | \(V_{ref0} - V_{ref}\) |
Se | \(S_e(|V_{out}|)\) | Algeb | \(\frac{B^q_{SAT} z_{0}^{SL} \left(- A^q_{SAT} + V_{p}\right)^{2}}{V_{p}} - S_e(|V_{out}|)\) |
vi | \(V_{i}\) | Algeb | \(- V_{i} + V_{ref} - y_{LS} - y_{W}\) |
LL_y | \(y_{LL}\) | Algeb | \(LL_{LT1 z1} LL_{LT2 z1} \left(- x'_{LL} + y_{LL}\right) + T_{B} x'_{LL} - T_{B} y_{LL} + T_{C} \left(V_{i} - x'_{LL}\right)\) |
W_y | \(y_{W}\) | Algeb | \(K_{F1} \left(V_{p} - x'_{W}\right) - T_{F1} y_{W}\) |
vf | \(v_{f}\) | ExtAlgeb | \(u \left(- v_{f0} + v_{out}\right)\) |
XadIfd | \(X_{ad}I_{fd}\) | ExtAlgeb | \(0\) |
a | \(\theta\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
SAT_E1 | \(E^{1c}_{SAT}\) | \(E_{1}\) | ConstService |
SAT_E2 | \(E^{2c}_{SAT}\) | \(E_{2}\) | ConstService |
SAT_SE1 | \(SE^{1c}_{SAT}\) | \(S_{E1}\) | ConstService |
SAT_SE2 | \(SE^{2c}_{SAT}\) | \(S_{E2} - 2 z^{SE2}_{SAT} + 2\) | ConstService |
SAT_a | \(a_{SAT}\) | \(\sqrt{\frac{E^{1c}_{SAT} SE^{1c}_{SAT}}{E^{2c}_{SAT} SE^{2c}_{SAT}}} \left(\left(SE^{2c}_{SAT} > 0\right) + \left(SE^{2c}_{SAT} < 0\right)\right)\) | ConstService |
SAT_A | \(A^q_{SAT}\) | \(E^{2c}_{SAT} - \frac{E^{1c}_{SAT} - E^{2c}_{SAT}}{a_{SAT} - 1}\) | ConstService |
SAT_B | \(B^q_{SAT}\) | \(\frac{E^{2c}_{SAT} SE^{2c}_{SAT} \left(a_{SAT} - 1\right)^{2} \left(\left(a_{SAT} > 0\right) + \left(a_{SAT} < 0\right)\right)}{\left(E^{1c}_{SAT} - E^{2c}_{SAT}\right)^{2}}\) | ConstService |
Se0 | \(S_{e0}\) | \(\frac{B^q_{SAT} \left(A^q_{SAT} - v_{f0}\right)^{2} \left(v_{f0} > A^q_{SAT}\right)}{v_{f0}}\) | ConstService |
vr0 | \(V_{r0}\) | \(v_{f0} \left(K_{E} + S_{e0}\right)\) | ConstService |
vb0 | \(V_{b0}\) | \(\frac{V_{r0}}{K_{A}}\) | ConstService |
vref0 | \(V_{ref0}\) | \(V + V_{b0}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
SL | \(SL\) | LessThan | |
LL_LT1 | \(LT_{LL}\) | LessThan | |
LL_LT2 | \(LT_{LL}\) | LessThan | |
LA_lim | \(lim_{LA}\) | AntiWindup | Limiter in Lag |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
SAT | \(SAT\) | ExcQuadSat | Field voltage saturation |
LS | \(LS\) | Lag | Sensing lag TF |
LL | \(LL\) | LeadLag | Lead-lag for internal delays |
LA | \(LA\) | LagAntiWindup | Anti-windup lag |
W | \(W\) | Washout | Signal conditioner |
IEEEX1¶
Group Exciter
IEEEX1 Type 1 exciter (DC)
Derived from EXDC2 by varying the limiter bounds.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory | |||
TR | \(T_R\) | Sensing time constant | 0.010 | p.u. | NumParam | |
TA | \(T_A\) | Lag time constant in anti-windup lag | 0.040 | p.u. | NumParam | |
TC | \(T_C\) | Lead time constant in lead-lag | 1 | p.u. | NumParam | |
TB | \(T_B\) | Lag time constant in lead-lag | 1 | p.u. | NumParam | |
TE | \(T_E\) | Exciter integrator time constant | 0.800 | p.u. | NumParam | |
TF1 | \(T_{F1}\) | Feedback washout time constant | 1 | p.u. | NumParam | non_zero |
KF1 | \(K_{F1}\) | Feedback washout gain | 0.030 | p.u. | NumParam | |
KA | \(K_A\) | Gain in anti-windup lag TF | 40 | p.u. | NumParam | |
KE | \(K_E\) | Gain added to saturation | 1 | p.u. | NumParam | |
VRMAX | \(V_{RMAX}\) | Maximum excitation limit | 7.300 | p.u. | NumParam | |
VRMIN | \(V_{RMIN}\) | Minimum excitation limit | -7.300 | p.u. | NumParam | |
E1 | \(E_1\) | First saturation point | 0 | p.u. | NumParam | |
SE1 | \(S_{E1}\) | Value at first saturation point | 0 | p.u. | NumParam | |
E2 | \(E_2\) | Second saturation point | 0 | p.u. | NumParam | |
SE2 | \(S_{E2}\) | Value at second saturation point | 0 | p.u. | NumParam | |
Sn | \(S_m\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_m\) | Rated voltage from generator | 0 | kV | ExtParam | |
bus | \(bus\) | Bus idx of the generators | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
vp | \(V_{p}\) | \(v_{f0}\) | Voltage after saturation feedback, before speed term | p.u. | v_str |
LS_y | \(y_{LS}\) | \(1.0 V\) | State in lag transfer function | v_str | |
LL_x | \(x'_{LL}\) | \(V_{i}\) | State in lead-lag | v_str | |
LA_y | \(y_{LA}\) | \(K_{A} y_{LL}\) | State in lag TF | v_str | |
W_x | \(x'_{W}\) | \(V_{p}\) | State in washout filter | v_str | |
omega | \(\omega\) | Generator speed | |||
vout | \(v_{out}\) | \(v_{f0}\) | Exciter final output voltage | v_str | |
vref | \(V_{ref}\) | \(V_{ref0}\) | Reference voltage input | p.u. | v_str |
Se | \(S_e(|V_{out}|)\) | \(S_{e0}\) | saturation output | v_str | |
vi | \(V_{i}\) | \(V_{b0}\) | Total input voltages | p.u. | v_str |
LL_y | \(y_{LL}\) | \(V_{i}\) | Output of lead-lag | v_str | |
W_y | \(y_{W}\) | \(0\) | Output of washout filter | v_str | |
vf | \(v_{f}\) | Excitation field voltage to generator | |||
XadIfd | \(X_{ad}I_{fd}\) | Armature excitation current | |||
a | \(\theta\) | Bus voltage phase angle | |||
v | \(V\) | Bus voltage magnitude |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
vp | \(V_{p}\) | State | \(- K_{E} V_{p} - S_e(|V_{out}|) V_{p} + y_{LA}\) | \(T_E\) |
LS_y | \(y_{LS}\) | State | \(1.0 V - y_{LS}\) | \(T_R\) |
LL_x | \(x'_{LL}\) | State | \(V_{i} - x'_{LL}\) | \(T_B\) |
LA_y | \(y_{LA}\) | State | \(K_{A} y_{LL} - y_{LA}\) | \(T_A\) |
W_x | \(x'_{W}\) | State | \(V_{p} - x'_{W}\) | \(T_{F1}\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
vout | \(v_{out}\) | Algeb | \(V_{p} - v_{out}\) |
vref | \(V_{ref}\) | Algeb | \(V_{ref0} - V_{ref}\) |
Se | \(S_e(|V_{out}|)\) | Algeb | \(\frac{B^q_{SAT} z_{0}^{SL} \left(- A^q_{SAT} + V_{p}\right)^{2}}{V_{p}} - S_e(|V_{out}|)\) |
vi | \(V_{i}\) | Algeb | \(- V_{i} + V_{ref} - y_{LS} - y_{W}\) |
LL_y | \(y_{LL}\) | Algeb | \(LL_{LT1 z1} LL_{LT2 z1} \left(- x'_{LL} + y_{LL}\right) + T_{B} x'_{LL} - T_{B} y_{LL} + T_{C} \left(V_{i} - x'_{LL}\right)\) |
W_y | \(y_{W}\) | Algeb | \(K_{F1} \left(V_{p} - x'_{W}\right) - T_{F1} y_{W}\) |
vf | \(v_{f}\) | ExtAlgeb | \(u \left(- v_{f0} + v_{out}\right)\) |
XadIfd | \(X_{ad}I_{fd}\) | ExtAlgeb | \(0\) |
a | \(\theta\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
SAT_E1 | \(E^{1c}_{SAT}\) | \(E_{1}\) | ConstService |
SAT_E2 | \(E^{2c}_{SAT}\) | \(E_{2}\) | ConstService |
SAT_SE1 | \(SE^{1c}_{SAT}\) | \(S_{E1}\) | ConstService |
SAT_SE2 | \(SE^{2c}_{SAT}\) | \(S_{E2} - 2 z^{SE2}_{SAT} + 2\) | ConstService |
SAT_a | \(a_{SAT}\) | \(\sqrt{\frac{E^{1c}_{SAT} SE^{1c}_{SAT}}{E^{2c}_{SAT} SE^{2c}_{SAT}}} \left(\left(SE^{2c}_{SAT} > 0\right) + \left(SE^{2c}_{SAT} < 0\right)\right)\) | ConstService |
SAT_A | \(A^q_{SAT}\) | \(E^{2c}_{SAT} - \frac{E^{1c}_{SAT} - E^{2c}_{SAT}}{a_{SAT} - 1}\) | ConstService |
SAT_B | \(B^q_{SAT}\) | \(\frac{E^{2c}_{SAT} SE^{2c}_{SAT} \left(a_{SAT} - 1\right)^{2} \left(\left(a_{SAT} > 0\right) + \left(a_{SAT} < 0\right)\right)}{\left(E^{1c}_{SAT} - E^{2c}_{SAT}\right)^{2}}\) | ConstService |
Se0 | \(S_{e0}\) | \(\frac{B^q_{SAT} \left(A^q_{SAT} - v_{f0}\right)^{2} \left(v_{f0} > A^q_{SAT}\right)}{v_{f0}}\) | ConstService |
vr0 | \(V_{r0}\) | \(v_{f0} \left(K_{E} + S_{e0}\right)\) | ConstService |
vb0 | \(V_{b0}\) | \(\frac{V_{r0}}{K_{A}}\) | ConstService |
vref0 | \(V_{ref0}\) | \(V + V_{b0}\) | ConstService |
VRTMAX | \(V_{RMAX}V_T\) | \(V V_{RMAX}\) | VarService |
VRTMIN | \(V_{RMIN}V_T\) | \(V V_{RMIN}\) | VarService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
SL | \(SL\) | LessThan | |
LL_LT1 | \(LT_{LL}\) | LessThan | |
LL_LT2 | \(LT_{LL}\) | LessThan | |
LA_lim | \(lim_{LA}\) | AntiWindup | Limiter in Lag |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
SAT | \(SAT\) | ExcQuadSat | Field voltage saturation |
LS | \(LS\) | Lag | Sensing lag TF |
LL | \(LL\) | LeadLag | Lead-lag for internal delays |
LA | \(LA\) | LagAntiWindup | Anti-windup lag |
W | \(W\) | Washout | Signal conditioner |
ESDC2A¶
Group Exciter
ESDC2A model.
This model is implemented as described in the PSS/E manual. Due to saturation, the results may be different from TSAT.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory | |||
TR | \(T_R\) | Sensing time constant | 0.010 | p.u. | NumParam | |
KA | \(K_A\) | Regulator gain | 80 | NumParam | ||
TA | \(T_A\) | Lag time constant in regulator | 0.040 | p.u. | NumParam | |
TB | \(T_B\) | Lag time constant in lead-lag | 1 | p.u. | NumParam | |
TC | \(T_C\) | Lead time constant in lead-lag | 1 | p.u. | NumParam | |
VRMAX | \(V_{RMAX}\) | Max. exc. limit (0-unlimited) | 7.300 | p.u. | NumParam | |
VRMIN | \(V_{RMIN}\) | Min. excitation limit | -7.300 | p.u. | NumParam | |
KE | \(K_E\) | Saturation feedback gain | 1 | p.u. | NumParam | |
TE | \(T_E\) | Integrator time constant | 0.800 | p.u. | NumParam | |
KF | \(K_F\) | Feedback gain | 0.100 | NumParam | ||
TF1 | \(T_{F1}\) | Feedback washout time constant | 1 | p.u. | NumParam | positive |
Switch | \(S_w\) | Switch that PSS/E did not implement | 0 | bool | NumParam | |
E1 | \(E_1\) | First saturation point | 0 | p.u. | NumParam | |
SE1 | \(S_{E1}\) | Value at first saturation point | 0 | p.u. | NumParam | |
E2 | \(E_2\) | Second saturation point | 0 | p.u. | NumParam | |
SE2 | \(S_{E2}\) | Value at second saturation point | 0 | p.u. | NumParam | |
Sn | \(S_m\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_m\) | Rated voltage from generator | 0 | kV | ExtParam | |
bus | \(bus\) | Bus idx of the generators | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
LG_y | \(y_{LG}\) | \(V\) | State in lag transfer function | v_str | |
LL_x | \(x'_{LL}\) | \(V_{i}\) | State in lead-lag | v_str | |
LA_y | \(y_{LA}\) | \(K_{A} y_{LL}\) | State in lag TF | v_str | |
INT_y | \(y_{INT}\) | \(v_{f0}\) | Integrator output | v_str | |
WF_x | \(x'_{WF}\) | \(v_{out}\) | State in washout filter | v_str | |
omega | \(\omega\) | Generator speed | |||
vout | \(v_{out}\) | \(v_{f0}\) | Exciter final output voltage | v_str | |
vref | \(V_{ref}\) | \(V_{ref0}\) | Reference voltage input | p.u. | v_str |
vi | \(V_{i}\) | \(- V + V_{ref0}\) | Total input voltages | p.u. | v_str |
LL_y | \(y_{LL}\) | \(V_{i}\) | Output of lead-lag | v_str | |
UEL | \(U_{EL}\) | \(0\) | Interface var for under exc. limiter | v_str | |
HG_y | \(y_{HG}\) | \(HG_{sl s0} U_{EL} + HG_{sl s1} y_{LL}\) | HVGate output | v_str | |
Se | \(S_e(|V_{out}|)\) | \(S_{e0}\) | saturation output | v_str | |
VFE | \(V_{FE}\) | \(V_{FE0}\) | Combined saturation feedback | p.u. | v_str |
WF_y | \(y_{WF}\) | \(0\) | Output of washout filter | v_str | |
vf | \(v_{f}\) | Excitation field voltage to generator | |||
XadIfd | \(X_{ad}I_{fd}\) | Armature excitation current | |||
a | \(\theta\) | Bus voltage phase angle | |||
v | \(V\) | Bus voltage magnitude |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
LG_y | \(y_{LG}\) | State | \(V - y_{LG}\) | \(T_R\) |
LL_x | \(x'_{LL}\) | State | \(V_{i} - x'_{LL}\) | \(T_B\) |
LA_y | \(y_{LA}\) | State | \(K_{A} y_{LL} - y_{LA}\) | \(T_A\) |
INT_y | \(y_{INT}\) | State | \(- V_{FE} + y_{LA}\) | \(T_E\) |
WF_x | \(x'_{WF}\) | State | \(v_{out} - x'_{WF}\) | \(T_{F1}\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
vout | \(v_{out}\) | Algeb | \(- v_{out} + y_{INT}\) |
vref | \(V_{ref}\) | Algeb | \(V_{ref0} - V_{ref}\) |
vi | \(V_{i}\) | Algeb | \(- V - V_{i} + V_{ref} - y_{WF}\) |
LL_y | \(y_{LL}\) | Algeb | \(LL_{LT1 z1} LL_{LT2 z1} \left(- x'_{LL} + y_{LL}\right) + T_{B} x'_{LL} - T_{B} y_{LL} + T_{C} \left(V_{i} - x'_{LL}\right)\) |
UEL | \(U_{EL}\) | Algeb | \(- U_{EL}\) |
HG_y | \(y_{HG}\) | Algeb | \(HG_{sl s0} U_{EL} + HG_{sl s1} y_{LL} - y_{HG}\) |
Se | \(S_e(|V_{out}|)\) | Algeb | \(\frac{B^q_{SAT} z_{0}^{SL} \left(- A^q_{SAT} + v_{out}\right)^{2}}{v_{out}} - S_e(|V_{out}|)\) |
VFE | \(V_{FE}\) | Algeb | \(- V_{FE} + v_{out} \left(K_{E} + S_e(|V_{out}|)\right)\) |
WF_y | \(y_{WF}\) | Algeb | \(K_{F} \left(v_{out} - x'_{WF}\right) - T_{F1} y_{WF}\) |
vf | \(v_{f}\) | ExtAlgeb | \(u \left(- v_{f0} + v_{out}\right)\) |
XadIfd | \(X_{ad}I_{fd}\) | ExtAlgeb | \(0\) |
a | \(\theta\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
VRMAXc | \(VRMAXc\) | \(V_{RMAX} + 999 z_{VRMAX}\) | ConstService |
SAT_E1 | \(E^{1c}_{SAT}\) | \(E_{1}\) | ConstService |
SAT_E2 | \(E^{2c}_{SAT}\) | \(E_{2}\) | ConstService |
SAT_SE1 | \(SE^{1c}_{SAT}\) | \(S_{E1}\) | ConstService |
SAT_SE2 | \(SE^{2c}_{SAT}\) | \(S_{E2} - 2 z^{SE2}_{SAT} + 2\) | ConstService |
SAT_a | \(a_{SAT}\) | \(\sqrt{\frac{E^{1c}_{SAT} SE^{1c}_{SAT}}{E^{2c}_{SAT} SE^{2c}_{SAT}}} \left(\left(SE^{2c}_{SAT} > 0\right) + \left(SE^{2c}_{SAT} < 0\right)\right)\) | ConstService |
SAT_A | \(A^q_{SAT}\) | \(E^{2c}_{SAT} - \frac{E^{1c}_{SAT} - E^{2c}_{SAT}}{a_{SAT} - 1}\) | ConstService |
SAT_B | \(B^q_{SAT}\) | \(\frac{E^{2c}_{SAT} SE^{2c}_{SAT} \left(a_{SAT} - 1\right)^{2} \left(\left(a_{SAT} > 0\right) + \left(a_{SAT} < 0\right)\right)}{\left(E^{1c}_{SAT} - E^{2c}_{SAT}\right)^{2}}\) | ConstService |
Se0 | \(S_{e0}\) | \(\frac{B^q_{SAT} \left(A^q_{SAT} - v_{f0}\right)^{2} \left(v_{f0} > A^q_{SAT}\right)}{v_{f0}}\) | ConstService |
vfe0 | \(V_{FE0}\) | \(v_{f0} \left(K_{E} + S_{e0}\right)\) | ConstService |
vref0 | \(V_{ref0}\) | \(V + \frac{V_{FE0}}{K_{A}}\) | ConstService |
VRU | \(V_T V_{RMAX}\) | \(V VRMAXc\) | VarService |
VRL | \(V_T V_{RMIN}\) | \(V V_{RMIN}\) | VarService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
LL_LT1 | \(LT_{LL}\) | LessThan | |
LL_LT2 | \(LT_{LL}\) | LessThan | |
HG_sl | \(None_{HG}\) | Selector | HVGate Selector |
LA_lim | \(lim_{LA}\) | AntiWindup | Limiter in Lag |
SL | \(SL\) | LessThan |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
LG | \(LG\) | Lag | Transducer delay |
SAT | \(SAT\) | ExcQuadSat | Field voltage saturation |
LL | \(LL\) | LeadLag | Lead-lag compensator |
HG | \(HG\) | HVGate | HVGate for under excitation |
LA | \(LA\) | LagAntiWindup | Anti-windup lag |
INT | \(INT\) | Integrator | Integrator |
WF | \(WF\) | Washout | Feedback to input |
EXST1¶
Group Exciter
EXST1-type static excitation system.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory | |||
TR | \(T_R\) | Measurement delay | 0.010 | NumParam | ||
VIMAX | \(V_{IMAX}\) | Max. input voltage | 0.200 | NumParam | ||
VIMIN | \(V_{IMIN}\) | Min. input voltage | 0 | NumParam | ||
TC | \(T_C\) | LL numerator | 1 | NumParam | ||
TB | \(T_B\) | LL denominator | 1 | NumParam | ||
KA | \(K_A\) | Regulator gain | 80 | NumParam | ||
TA | \(T_A\) | Regulator delay | 0.050 | NumParam | ||
VRMAX | \(V_{RMAX}\) | Max. regulator output | 8 | NumParam | ||
VRMIN | \(V_{RMIN}\) | Min. regulator output | -3 | NumParam | ||
KC | \(K_C\) | Coef. for Ifd | 0.200 | NumParam | ||
KF | \(K_F\) | Feedback gain | 0.100 | NumParam | ||
TF | \(T_F\) | Feedback delay | 1 | NumParam | positive | |
Sn | \(S_m\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_m\) | Rated voltage from generator | 0 | kV | ExtParam | |
bus | \(bus\) | Bus idx of the generators | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
LG_y | \(y_{LG}\) | \(V\) | State in lag transfer function | v_str | |
LL_x | \(x'_{LL}\) | \(V_{l}\) | State in lead-lag | v_str | |
LR_y | \(y_{LR}\) | \(K_{A} y_{LL}\) | State in lag transfer function | v_str | |
WF_x | \(x'_{WF}\) | \(y_{LR}\) | State in washout filter | v_str | |
omega | \(\omega\) | Generator speed | |||
vout | \(v_{out}\) | \(v_{f0}\) | Exciter final output voltage | v_str | |
vref | \(V_{ref}\) | \(V_{ref0}\) | Reference voltage input | p.u. | v_str |
vi | \(V_{i}\) | \(\frac{v_{f0}}{K_{A}}\) | Total input voltages | p.u. | v_str |
vl | \(V_{l}\) | \(V_{i} z_{i}^{HLI} + V_{IMAX} z_{u}^{HLI} + V_{IMIN} z_{l}^{HLI}\) | Input after limiter | v_str | |
LL_y | \(y_{LL}\) | \(V_{l}\) | Output of lead-lag | v_str | |
WF_y | \(y_{WF}\) | \(0\) | Output of washout filter | v_str | |
vfmax | \(V_{fmax}\) | \(- K_{C} X_{ad}I_{fd} + V_{RMAX}\) | Upper bound of output limiter | v_str | |
vfmin | \(V_{fmin}\) | \(- K_{C} X_{ad}I_{fd} + V_{RMIN}\) | Lower bound of output limiter | v_str | |
vf | \(v_{f}\) | Excitation field voltage to generator | |||
XadIfd | \(X_{ad}I_{fd}\) | Armature excitation current | |||
a | \(\theta\) | Bus voltage phase angle | |||
v | \(V\) | Bus voltage magnitude |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
LG_y | \(y_{LG}\) | State | \(V - y_{LG}\) | \(T_R\) |
LL_x | \(x'_{LL}\) | State | \(V_{l} - x'_{LL}\) | \(T_B\) |
LR_y | \(y_{LR}\) | State | \(K_{A} y_{LL} - y_{LR}\) | \(T_A\) |
WF_x | \(x'_{WF}\) | State | \(- x'_{WF} + y_{LR}\) | \(T_F\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
vout | \(v_{out}\) | Algeb | \(V_{fmax} z_{u}^{HLR} + V_{fmin} z_{l}^{HLR} - v_{out} + y_{LR} z_{i}^{HLR}\) |
vref | \(V_{ref}\) | Algeb | \(V_{ref0} - V_{ref}\) |
vi | \(V_{i}\) | Algeb | \(- V_{i} + V_{ref} - y_{LG} - y_{WF}\) |
vl | \(V_{l}\) | Algeb | \(V_{i} z_{i}^{HLI} - V_{l} + V_{IMAX} z_{u}^{HLI} + V_{IMIN} z_{l}^{HLI}\) |
LL_y | \(y_{LL}\) | Algeb | \(LL_{LT1 z1} LL_{LT2 z1} \left(- x'_{LL} + y_{LL}\right) + T_{B} x'_{LL} - T_{B} y_{LL} + T_{C} \left(V_{l} - x'_{LL}\right)\) |
WF_y | \(y_{WF}\) | Algeb | \(K_{F} \left(- x'_{WF} + y_{LR}\right) - T_{F} y_{WF}\) |
vfmax | \(V_{fmax}\) | Algeb | \(- K_{C} X_{ad}I_{fd} + V_{RMAX} - V_{fmax}\) |
vfmin | \(V_{fmin}\) | Algeb | \(- K_{C} X_{ad}I_{fd} + V_{RMIN} - V_{fmin}\) |
vf | \(v_{f}\) | ExtAlgeb | \(u \left(- v_{f0} + v_{out}\right)\) |
XadIfd | \(X_{ad}I_{fd}\) | ExtAlgeb | \(0\) |
a | \(\theta\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
vref0 | \(V_{ref0}\) | \(V + \frac{v_{f0}}{K_{A}}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
HLI | \(HLI\) | HardLimiter | Hard limiter on input |
LL_LT1 | \(LT_{LL}\) | LessThan | |
LL_LT2 | \(LT_{LL}\) | LessThan | |
HLR | \(HLR\) | HardLimiter | Hard limiter on regulator output |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
LG | \(LG\) | Lag | Sensing delay |
LL | \(LL\) | LeadLag | Lead-lag compensator |
LR | \(LR\) | Lag | Regulator |
WF | \(WF\) | Washout | Stablizing circuit feedback |
ESST3A¶
Group Exciter
Static exciter type 3A model
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory | |||
TR | \(T_R\) | Sensing time constant | 0.010 | p.u. | NumParam | |
VIMAX | \(V_{IMAX}\) | Max. input voltage | 0.800 | NumParam | ||
VIMIN | \(V_{IMIN}\) | Min. input voltage | -0.100 | NumParam | ||
KM | \(K_M\) | Forward gain constant | 500 | NumParam | ||
TC | \(T_C\) | Lead time constant in lead-lag | 3 | NumParam | ||
TB | \(T_B\) | Lag time constant in lead-lag | 15 | NumParam | ||
KA | \(K_A\) | Gain in anti-windup lag TF | 50 | NumParam | ||
TA | \(T_A\) | Lag time constant in anti-windup lag | 0.100 | NumParam | ||
VRMAX | \(V_{RMAX}\) | Maximum excitation limit | 8 | p.u. | NumParam | |
VRMIN | \(V_{RMIN}\) | Minimum excitation limit | 0 | p.u. | NumParam | |
KG | \(K_G\) | Feedback gain of inner field regulator | 1 | NumParam | ||
KP | \(K_P\) | Potential circuit gain coeff. | 4 | NumParam | ||
KI | \(K_I\) | Potential circuit gain coeff. | 0.100 | NumParam | ||
VBMAX | \(V_{BMAX}\) | VB upper limit | 18 | p.u. | NumParam | |
KC | \(K_C\) | Rectifier loading factor proportional to commutating reactance | 0.100 | NumParam | ||
XL | \(X_L\) | Potential source reactance | 0.010 | NumParam | ||
VGMAX | \(V_{GMAX}\) | VG upper limit | 4 | p.u. | NumParam | |
THETAP | \(\theta_P\) | Rectifier firing angle | 0 | degree | NumParam | |
TM | \(K_C\) | Inner field regulator forward time constant | 0.100 | NumParam | ||
VMMAX | \(V_{MMAX}\) | Maximum VM limit | 1 | p.u. | NumParam | |
VMMIN | \(V_{RMIN}\) | Minimum VM limit | 0.100 | p.u. | NumParam | |
Sn | \(S_m\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_m\) | Rated voltage from generator | 0 | kV | ExtParam | |
bus | \(bus\) | Bus idx of the generators | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
LG_y | \(y_{LG}\) | \(V\) | State in lag transfer function | v_str | |
LL_x | \(x'_{LL}\) | \(y_{HG}\) | State in lead-lag | v_str | |
LAW1_y | \(y_{LAW1}\) | \(K_{A} y_{LL}\) | State in lag TF | v_str | |
LAW2_y | \(y_{LAW2}\) | \(K_{M} V_{RS}\) | State in lag TF | v_str | |
omega | \(\omega\) | Generator speed | |||
vout | \(v_{out}\) | \(v_{f0}\) | Exciter final output voltage | v_str | |
UEL | \(U_{EL}\) | \(0\) | Interface var for under exc. limiter | v_str | |
IN | \(I_{N}\) | \(\frac{K_{C} X_{ad}I_{fd}}{V_{E}}\) | Input to FEX | v_str | |
FEX_y | \(y_{FEX}\) | \(\begin{cases} 1 & \text{for}\: I_{N} \leq 0 \\1 - 0.577 I_{N} & \text{for}\: I_{N} \leq 0.433 \\\sqrt{0.75 - I_{N}^{2}} & \text{for}\: I_{N} \leq 0.75 \\1.732 - 1.732 I_{N} & \text{for}\: I_{N} \leq 1 \\0 & \text{otherwise} \end{cases}\) | Output of piecewise | v_str | |
VB_x | \(x_{VB}\) | \(V_{E} y_{FEX}\) | Gain output before limiter | v_str | |
VB_y | \(y_{VB}\) | \(VB_{lim zi} x_{VB} + VB_{lim zu} V_{BMAX}\) | Gain output after limiter | v_str | |
VG_x | \(x_{VG}\) | \(K_{G} v_{out}\) | Gain output before limiter | v_str | |
VG_y | \(y_{VG}\) | \(VG_{lim zi} x_{VG} + VG_{lim zu} V_{GMAX}\) | Gain output after limiter | v_str | |
vrs | \(V_{RS}\) | \(\frac{v_{f0}}{K_{M} y_{VB}}\) | VR subtract feedback VG | v_str | |
vref | \(V_{ref}\) | \(V + \frac{V_{RS} + y_{VG}}{K_{A}}\) | Reference voltage input | p.u. | v_str |
vi | \(V_{i}\) | \(- V + V_{ref}\) | Total input voltages | p.u. | v_str |
vil | \(V_{il}\) | \(V_{i} z_{i}^{HLI} + V_{IMAX} z_{u}^{HLI} + V_{IMIN} z_{l}^{HLI}\) | Input voltage after limit | v_str | |
HG_y | \(y_{HG}\) | \(HG_{sl s0} U_{EL} + HG_{sl s1} V_{il}\) | HVGate output | v_str | |
LL_y | \(y_{LL}\) | \(y_{HG}\) | Output of lead-lag | v_str | |
vf | \(v_{f}\) | Excitation field voltage to generator | |||
XadIfd | \(X_{ad}I_{fd}\) | Armature excitation current | |||
a | \(\theta\) | Bus voltage phase angle | |||
v | \(V\) | Bus voltage magnitude | |||
vd | \(V_{d}\) | d-axis machine voltage | |||
vq | \(V_{q}\) | q-axis machine voltage | |||
Id | \(I_{d}\) | d-axis machine current | |||
Iq | \(I_{q}\) | q-axis machine current |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
LG_y | \(y_{LG}\) | State | \(V - y_{LG}\) | \(T_R\) |
LL_x | \(x'_{LL}\) | State | \(- x'_{LL} + y_{HG}\) | \(T_B\) |
LAW1_y | \(y_{LAW1}\) | State | \(K_{A} y_{LL} - y_{LAW1}\) | \(T_A\) |
LAW2_y | \(y_{LAW2}\) | State | \(K_{M} V_{RS} - y_{LAW2}\) | \(K_C\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
vout | \(v_{out}\) | Algeb | \(- v_{out} + y_{LAW2} y_{VB}\) |
UEL | \(U_{EL}\) | Algeb | \(- U_{EL}\) |
IN | \(I_{N}\) | Algeb | \(- I_{N} + \frac{K_{C} X_{ad}I_{fd}}{V_{E}}\) |
FEX_y | \(y_{FEX}\) | Algeb | \(- y_{FEX} + \begin{cases} 1 & \text{for}\: I_{N} \leq 0 \\1 - 0.577 I_{N} & \text{for}\: I_{N} \leq 0.433 \\\sqrt{0.75 - I_{N}^{2}} & \text{for}\: I_{N} \leq 0.75 \\1.732 - 1.732 I_{N} & \text{for}\: I_{N} \leq 1 \\0 & \text{otherwise} \end{cases}\) |
VB_x | \(x_{VB}\) | Algeb | \(V_{E} y_{FEX} - x_{VB}\) |
VB_y | \(y_{VB}\) | Algeb | \(VB_{lim zi} x_{VB} + VB_{lim zu} V_{BMAX} - y_{VB}\) |
VG_x | \(x_{VG}\) | Algeb | \(K_{G} v_{out} - x_{VG}\) |
VG_y | \(y_{VG}\) | Algeb | \(VG_{lim zi} x_{VG} + VG_{lim zu} V_{GMAX} - y_{VG}\) |
vrs | \(V_{RS}\) | Algeb | \(- V_{RS} + y_{LAW1} - y_{VG}\) |
vref | \(V_{ref}\) | Algeb | \(V_{ref0} - V_{ref}\) |
vi | \(V_{i}\) | Algeb | \(- V_{i} + V_{ref} - y_{LG}\) |
vil | \(V_{il}\) | Algeb | \(V_{i} z_{i}^{HLI} + V_{IMAX} z_{u}^{HLI} + V_{IMIN} z_{l}^{HLI} - V_{il}\) |
HG_y | \(y_{HG}\) | Algeb | \(HG_{sl s0} U_{EL} + HG_{sl s1} V_{il} - y_{HG}\) |
LL_y | \(y_{LL}\) | Algeb | \(LL_{LT1 z1} LL_{LT2 z1} \left(- x'_{LL} + y_{LL}\right) + T_{B} x'_{LL} - T_{B} y_{LL} + T_{C} \left(- x'_{LL} + y_{HG}\right)\) |
vf | \(v_{f}\) | ExtAlgeb | \(u \left(- v_{f0} + v_{out}\right)\) |
XadIfd | \(X_{ad}I_{fd}\) | ExtAlgeb | \(0\) |
a | \(\theta\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
vd | \(V_{d}\) | ExtAlgeb | \(0\) |
vq | \(V_{q}\) | ExtAlgeb | \(0\) |
Id | \(I_{d}\) | ExtAlgeb | \(0\) |
Iq | \(I_{q}\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
KPC | \(K_{PC}\) | \(K_{P} e^{i \operatorname{radians}{\left(\theta_P \right)}}\) | ConstService |
VE | \(V_E\) | \(\left|{K_{PC} \left(V_{d} + i V_{q}\right) + i \left(I_{d} + i I_{q}\right) \left(K_{I} + K_{PC} X_{L}\right)}\right|\) | VarService |
vref0 | \(V_{ref0}\) | \(V_{ref}\) | PostInitService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
VB_lim | \(lim_{VB}\) | HardLimiter | |
VG_lim | \(lim_{VG}\) | HardLimiter | |
HG_sl | \(None_{HG}\) | Selector | HVGate Selector |
LL_LT1 | \(LT_{LL}\) | LessThan | |
LL_LT2 | \(LT_{LL}\) | LessThan | |
LAW1_lim | \(lim_{LAW1}\) | AntiWindup | Limiter in Lag |
HLI | \(HLI\) | HardLimiter | Input limiter |
LAW2_lim | \(lim_{LAW2}\) | AntiWindup | Limiter in Lag |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
LG | \(LG\) | Lag | Voltage transducer |
FEX | \(FEX\) | Piecewise | Piecewise function FEX |
VB | \(VB\) | GainLimiter | VB with limiter |
VG | \(VG\) | GainLimiter | Feedback gain with HL |
HG | \(HG\) | HVGate | HVGate for under excitation |
LL | \(LL\) | LeadLag | Regulator |
LAW1 | \(LAW1\) | LagAntiWindup | Lag AW on VR |
LAW2 | \(LAW2\) | LagAntiWindup | Lag AW on VM |
SEXS¶
Group Exciter
Simplified Excitation System Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory | |||
TATB | \(T_A/T_B\) | Time constant TA/TB | 0.400 | NumParam | ||
TB | \(T_B\) | Time constant TB in LL | 5 | NumParam | ||
K | \(K\) | Gain | 20 | NumParam | non_zero | |
TE | \(T_E\) | AW Lag time constant | 1 | NumParam | ||
EMIN | \(E_{MIN}\) | lower limit | -99 | NumParam | ||
EMAX | \(E_{MAX}\) | upper limit | 99 | NumParam | ||
Sn | \(S_m\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_m\) | Rated voltage from generator | 0 | kV | ExtParam | |
bus | \(bus\) | Bus idx of the generators | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
LL_x | \(x'_{LL}\) | \(V_{i}\) | State in lead-lag | v_str | |
LAW_y | \(y_{LAW}\) | \(K y_{LL}\) | State in lag TF | v_str | |
omega | \(\omega\) | Generator speed | |||
vout | \(v_{out}\) | \(v_{f0}\) | Exciter final output voltage | v_str | |
vref | \(V_{ref}\) | \(V_{ref0}\) | Reference voltage input | p.u. | v_str |
vi | \(V_{i}\) | \(- V + V_{ref0}\) | Total input voltages | p.u. | v_str |
LL_y | \(y_{LL}\) | \(V_{i}\) | Output of lead-lag | v_str | |
vf | \(v_{f}\) | Excitation field voltage to generator | |||
XadIfd | \(X_{ad}I_{fd}\) | Armature excitation current | |||
a | \(\theta\) | Bus voltage phase angle | |||
v | \(V\) | Bus voltage magnitude |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
LL_x | \(x'_{LL}\) | State | \(V_{i} - x'_{LL}\) | \(T_B\) |
LAW_y | \(y_{LAW}\) | State | \(K y_{LL} - y_{LAW}\) | \(T_E\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
vout | \(v_{out}\) | Algeb | \(- v_{out} + y_{LAW}\) |
vref | \(V_{ref}\) | Algeb | \(V_{ref0} - V_{ref}\) |
vi | \(V_{i}\) | Algeb | \(- V - V_{i} + V_{ref}\) |
LL_y | \(y_{LL}\) | Algeb | \(LL_{LT1 z1} LL_{LT2 z1} \left(- x'_{LL} + y_{LL}\right) + TA \left(V_{i} - x'_{LL}\right) + T_{B} x'_{LL} - T_{B} y_{LL}\) |
vf | \(v_{f}\) | ExtAlgeb | \(u \left(- v_{f0} + v_{out}\right)\) |
XadIfd | \(X_{ad}I_{fd}\) | ExtAlgeb | \(0\) |
a | \(\theta\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
TA | \(TA\) | \(T_{A/T B} T_{B}\) | ConstService |
vref0 | \(V_{ref0}\) | \(V + \frac{v_{f0}}{K}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
LL_LT1 | \(LT_{LL}\) | LessThan | |
LL_LT2 | \(LT_{LL}\) | LessThan | |
LAW_lim | \(lim_{LAW}\) | AntiWindup | Limiter in Lag |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
LL | \(LL\) | LeadLag | |
LAW | \(LAW\) | LagAntiWindup |
Experimental¶
Experimantal group
Common Parameters: u, name
Available models: PI2
PI2¶
Group Experimental
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
Kp | NumParam | |||||
Ki | NumParam | |||||
Wmax | NumParam | |||||
Wmin | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
uin | \(uin\) | \(0\) | v_str | ||
x | \(x\) | \(0.05\) | v_str | ||
y | \(y\) | \(0.05\) | v_str | ||
w | \(w\) | \(0.05\) | v_str |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
uin | \(uin\) | State | \(\begin{cases} 0 & \text{for}\: t_{dae} \leq 0 \\1 & \text{for}\: t_{dae} \leq 2 \\-1 & \text{for}\: t_{dae} < 6 \\1 & \text{otherwise} \end{cases}\) | |
x | \(x\) | State | \(Ki uin z_{i}^{HL}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
y | \(y\) | Algeb | \(Kp uin + x - y\) |
w | \(w\) | Algeb | \(Wmax z_{u}^{HL} + Wmin z_{l}^{HL} - w + y z_{i}^{HL}\) |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
HL | \(HL\) | HardLimiter |
FreqMeasurement¶
Frequency measurements.
Common Parameters: u, name
Common Variables: f
Available models: BusFreq, BusROCOF
BusFreq¶
Group FreqMeasurement
Bus frequency measurement.
Bus frequency output variable is f.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus | bus idx | IdxParam | mandatory | |||
Tf | \(T_f\) | input digital filter time const | 0.020 | sec | NumParam | |
Tw | \(T_w\) | washout time const | 0.020 | sec | NumParam | |
fn | \(f_n\) | nominal frequency | 60 | Hz | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
L_y | \(y_{L}\) | \(\theta - \theta_0\) | State in lag transfer function | v_str | |
WO_x | \(x'_{WO}\) | \(y_{L}\) | State in washout filter | v_str | |
WO_y | \(y_{WO}\) | \(0\) | Output of washout filter | v_str | |
f | \(f\) | \(1\) | frequency output | p.u. (Hz) | v_str |
a | \(\theta\) | ||||
v | \(V\) |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
L_y | \(y_{L}\) | State | \(\theta - \theta_0 - y_{L}\) | \(T_f\) |
WO_x | \(x'_{WO}\) | State | \(- x'_{WO} + y_{L}\) | \(T_w\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
WO_y | \(y_{WO}\) | Algeb | \(1/\omega_n \left(- x'_{WO} + y_{L}\right) - T_{w} y_{WO}\) |
f | \(f\) | Algeb | \(- f + y_{WO} + 1\) |
a | \(\theta\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
iwn | \(1/\omega_n\) | \(\frac{u}{2 \pi f_{n}}\) | ConstService |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
L | \(L\) | Lag | digital filter |
WO | \(WO\) | Washout | angle washout |
BusROCOF¶
Group FreqMeasurement
Bus frequency and ROCOF measurement.
The ROCOF output variable is
Wf_y
.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus | bus idx | IdxParam | mandatory | |||
Tf | \(T_f\) | input digital filter time const | 0.020 | sec | NumParam | |
Tw | \(T_w\) | washout time const | 0.020 | sec | NumParam | |
fn | \(f_n\) | nominal frequency | 60 | Hz | NumParam | |
Tr | \(T_r\) | frequency washout time constant | 0.100 | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
L_y | \(y_{L}\) | \(\theta - \theta_0\) | State in lag transfer function | v_str | |
WO_x | \(x'_{WO}\) | \(y_{L}\) | State in washout filter | v_str | |
Wf_x | \(x'_{Wf}\) | \(f\) | State in washout filter | v_str | |
WO_y | \(y_{WO}\) | \(0\) | Output of washout filter | v_str | |
f | \(f\) | \(1\) | frequency output | p.u. (Hz) | v_str |
Wf_y | \(y_{Wf}\) | \(0\) | Output of washout filter | v_str | |
a | \(\theta\) | ||||
v | \(V\) |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
L_y | \(y_{L}\) | State | \(\theta - \theta_0 - y_{L}\) | \(T_f\) |
WO_x | \(x'_{WO}\) | State | \(- x'_{WO} + y_{L}\) | \(T_w\) |
Wf_x | \(x'_{Wf}\) | State | \(f - x'_{Wf}\) | \(T_r\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
WO_y | \(y_{WO}\) | Algeb | \(1/\omega_n \left(- x'_{WO} + y_{L}\right) - T_{w} y_{WO}\) |
f | \(f\) | Algeb | \(- f + y_{WO} + 1\) |
Wf_y | \(y_{Wf}\) | Algeb | \(- T_{r} y_{Wf} + f - x'_{Wf}\) |
a | \(\theta\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
iwn | \(1/\omega_n\) | \(\frac{u}{2 \pi f_{n}}\) | ConstService |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
L | \(L\) | Lag | digital filter |
WO | \(WO\) | Washout | angle washout |
Wf | \(Wf\) | Washout | frequency washout yielding ROCOF |
PSS¶
Power system stabilizer group.
Common Parameters: u, name
Common Variables: vsout
Available models: IEEEST, ST2CUT
IEEEST¶
Group PSS
IEEEST stabilizer model. Automatically adds frequency measurement devices if not provided.
Input signals (MODE):
1 (s0) - Rotor speed deviation (p.u.), 2 (s1) - Bus frequency deviation (*) (p.u.), 3 (s2) - Generator P electrical in Gen MVABase (p.u.), 4 (s3) - Generator accelerating power (p.u.), 5 (s4) - Bus voltage (p.u.), 6 (s5) - Derivative of p.u. bus voltage.
(*) Due to the frequency measurement implementation difference, mode 2 is likely to yield different results across software.
Blocks are named F1, F2, LL1, LL2 and WO in sequence. Two limiters are named VLIM and OLIM in sequence.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
avr | Exciter idx | IdxParam | mandatory | |||
MODE | Input signal | NumParam | mandatory | |||
busr | Optional remote bus idx | IdxParam | ||||
busf | BusFreq idx for mode 2 | IdxParam | ||||
A1 | \(A_1\) | filter time const. (pole) | 1 | NumParam | ||
A2 | \(A_2\) | filter time const. (pole) | 1 | NumParam | ||
A3 | \(A_3\) | filter time const. (pole) | 1 | NumParam | ||
A4 | \(A_4\) | filter time const. (pole) | 1 | NumParam | ||
A5 | \(A_5\) | filter time const. (zero) | 1 | NumParam | ||
A6 | \(A_6\) | filter time const. (zero) | 1 | NumParam | ||
T1 | \(T_1\) | first leadlag time const. (zero) | 1 | NumParam | ||
T2 | \(T_2\) | first leadlag time const. (pole) | 1 | NumParam | ||
T3 | \(T_3\) | second leadlag time const. (pole) | 1 | NumParam | ||
T4 | \(T_4\) | second leadlag time const. (pole) | 1 | NumParam | ||
T5 | \(T_5\) | washout time const. (zero) | 1 | NumParam | ||
T6 | \(T_6\) | washout time const. (pole) | 1 | NumParam | ||
KS | \(K_S\) | Gain before washout | 1 | NumParam | ||
LSMAX | \(L_{SMAX}\) | Max. output limit | 0.300 | NumParam | ||
LSMIN | \(L_{SMIN}\) | Min. output limit | -0.300 | NumParam | ||
VCU | \(V_{CU}\) | Upper enabling bus voltage | 999 | p.u. | NumParam | |
VCL | \(V_{CL}\) | Upper enabling bus voltage | -999 | p.u. | NumParam | |
syn | Retrieved generator idx | 0 | ExtParam | |||
bus | Retrieved bus idx | ExtParam | ||||
Sn | \(S_n\) | Generator power base | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
F1_x | \(x'_{F1}\) | \(0\) | State in 2nd order LPF | v_str | |
F1_y | \(y_{F1}\) | \(S_{ig}\) | Output of 2nd order LPF | v_str | |
F2_x1 | \(x'_{F2}\) | \(0\) | State #1 in 2nd order lead-lag | v_str | |
F2_x2 | \(x''_{F2}\) | \(y_{F1}\) | State #2 in 2nd order lead-lag | v_str | |
LL1_x | \(x'_{LL1}\) | \(y_{F2}\) | State in lead-lag | v_str | |
LL2_x | \(x'_{LL2}\) | \(y_{LL1}\) | State in lead-lag | v_str | |
WO_x | \(x'_{WO}\) | \(y_{Vks}\) | State in washout filter | v_str | |
omega | \(\omega\) | Generator speed | p.u. | ||
vsout | \(v_{sout}\) | PSS output voltage to exciter | |||
sig | \(S_{ig}\) | \(V s_{4}^{SW} + s_{0}^{SW} \left(\omega - 1\right) + s_{3}^{SW} \left(\tau_m - \tau_{m0}\right) + \frac{\tau_{m0} s_{2}^{SW}}{(Sb/Sn)}\) | Input signal | v_str | |
F2_y | \(y_{F2}\) | \(y_{F1}\) | Output of 2nd order lead-lag | v_str | |
LL1_y | \(y_{LL1}\) | \(y_{F2}\) | Output of lead-lag | v_str | |
LL2_y | \(y_{LL2}\) | \(y_{LL1}\) | Output of lead-lag | v_str | |
Vks_y | \(y_{Vks}\) | \(K_{S} y_{LL2}\) | Gain output | v_str | |
WO_y | \(y_{WO}\) | \(WO_{LT z1} x'_{WO}\) | Output of washout filter | v_str | |
Vss | \(V_{ss}\) | Voltage output before output limiter | |||
tm | \(\tau_m\) | Generator mechanical input | |||
te | \(\tau_e\) | Generator electrical output | |||
v | \(V\) | Bus (or busr, if given) terminal voltage | |||
f | \(f\) | Bus frequency | |||
vi | \(v_{i}\) | Exciter input voltage |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
F1_x | \(x'_{F1}\) | State | \(- A_{1} x'_{F1} + S_{ig} - y_{F1}\) | \(A_2\) |
F1_y | \(y_{F1}\) | State | \(x'_{F1}\) | |
F2_x1 | \(x'_{F2}\) | State | \(- A_{3} x'_{F2} - x''_{F2} + y_{F1}\) | \(A_4\) |
F2_x2 | \(x''_{F2}\) | State | \(x'_{F2}\) | |
LL1_x | \(x'_{LL1}\) | State | \(- x'_{LL1} + y_{F2}\) | \(T_2\) |
LL2_x | \(x'_{LL2}\) | State | \(- x'_{LL2} + y_{LL1}\) | \(T_4\) |
WO_x | \(x'_{WO}\) | State | \(- x'_{WO} + y_{Vks}\) | \(T_6\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
vsout | \(v_{sout}\) | Algeb | \(V_{ss} z_{i}^{OLIM} - v_{sout}\) |
sig | \(S_{ig}\) | Algeb | \(- S_{ig} + V s_{4}^{SW} + V^{dv} s_{5}^{SW} + s_{0}^{SW} \left(\omega - 1\right) + s_{1}^{SW} \left(f - 1\right) + s_{3}^{SW} \left(\tau_m - \tau_{m0}\right) + \frac{\tau_e s_{2}^{SW}}{(Sb/Sn)}\) |
F2_y | \(y_{F2}\) | Algeb | \(A_{4} A_{5} x'_{F2} + A_{4} x''_{F2} - A_{4} y_{F2} + A_{6} \left(- A_{3} x'_{F2} - x''_{F2} + y_{F1}\right) + F_{2 LT1 z1} F_{2 LT2 z1} F_{2 LT3 z1} F_{2 LT4 z1} \left(- x''_{F2} + y_{F2}\right)\) |
LL1_y | \(y_{LL1}\) | Algeb | \(LL_{1 LT1 z1} LL_{1 LT2 z1} \left(- x'_{LL1} + y_{LL1}\right) + T_{1} \left(- x'_{LL1} + y_{F2}\right) + T_{2} x'_{LL1} - T_{2} y_{LL1}\) |
LL2_y | \(y_{LL2}\) | Algeb | \(LL_{2 LT1 z1} LL_{2 LT2 z1} \left(- x'_{LL2} + y_{LL2}\right) + T_{3} \left(- x'_{LL2} + y_{LL1}\right) + T_{4} x'_{LL2} - T_{4} y_{LL2}\) |
Vks_y | \(y_{Vks}\) | Algeb | \(K_{S} y_{LL2} - y_{Vks}\) |
WO_y | \(y_{WO}\) | Algeb | \(T_{5} WO_{LT z0} \left(- x'_{WO} + y_{Vks}\right) + T_{6} WO_{LT z1} x'_{WO} - T_{6} y_{WO}\) |
Vss | \(V_{ss}\) | Algeb | \(L_{SMAX} z_{u}^{VLIM} + L_{SMIN} z_{l}^{VLIM} - V_{ss} + y_{WO} z_{i}^{VLIM}\) |
tm | \(\tau_m\) | ExtAlgeb | \(0\) |
te | \(\tau_e\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
f | \(f\) | ExtAlgeb | \(0\) |
vi | \(v_{i}\) | ExtAlgeb | \(u v_{sout}\) |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
dv | \(dv\) | Derivative | |
SW | \(SW\) | Switcher | |
F2_LT1 | \(LT_{F2}\) | LessThan | |
F2_LT2 | \(LT_{F2}\) | LessThan | |
F2_LT3 | \(LT_{F2}\) | LessThan | |
F2_LT4 | \(LT_{F2}\) | LessThan | |
LL1_LT1 | \(LT_{LL1}\) | LessThan | |
LL1_LT2 | \(LT_{LL1}\) | LessThan | |
LL2_LT1 | \(LT_{LL2}\) | LessThan | |
LL2_LT2 | \(LT_{LL2}\) | LessThan | |
WO_LT | \(LT_{WO}\) | LessThan | |
VLIM | \(VLIM\) | Limiter | Vss limiter |
OLIM | \(OLIM\) | Limiter | output limiter |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
F1 | \(F1\) | Lag2ndOrd | |
F2 | \(F2\) | LeadLag2ndOrd | |
LL1 | \(LL1\) | LeadLag | |
LL2 | \(LL2\) | LeadLag | |
Vks | \(Vks\) | Gain | |
WO | \(WO\) | WashoutOrLag |
Config Fields in [IEEEST]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
freq_model | BusFreq | default freq. measurement model | ('BusFreq',) |
ST2CUT¶
Group PSS
ST2CUT stabilizer model. Automatically adds frequency measurement devices if not provided.
Input signals (MODE and MODE2):
0 - Disable input signal 1 (s1) - Rotor speed deviation (p.u.), 2 (s2) - Bus frequency deviation (*) (p.u.), 3 (s3) - Generator P electrical in Gen MVABase (p.u.), 4 (s4) - Generator accelerating power (p.u.), 5 (s5) - Bus voltage (p.u.), 6 (s6) - Derivative of p.u. bus voltage.
(*) Due to the frequency measurement implementation difference, mode 2 is likely to yield different results across software.
Blocks are named LL1, LL2, LL3, LL4 in sequence. Two limiters are named VSS_lim and OLIM in sequence.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
avr | Exciter idx | IdxParam | mandatory | |||
MODE | Input signal 1 | NumParam | mandatory | |||
busr | Remote bus 1 | NumParam | ||||
busf | BusFreq idx for signal 1 mode 2 | IdxParam | ||||
MODE2 | Input signal 2 | NumParam | ||||
busr2 | Remote bus 2 | NumParam | ||||
busf2 | BusFreq idx for signal 2 mode 2 | IdxParam | ||||
K1 | \(K_1\) | Transducer 1 gain | 1 | NumParam | ||
K2 | \(K_2\) | Transducer 2 gain | 1 | NumParam | ||
T1 | \(T_1\) | Transducer 1 time const. | 1 | NumParam | ||
T2 | \(T_2\) | Transducer 2 time const. | 1 | NumParam | ||
T3 | \(T_3\) | Washout int. time const. | 1 | NumParam | ||
T4 | \(T_4\) | Washout delay time const. | 0.200 | NumParam | ||
T5 | \(T_5\) | Leadlag 1 time const. (1) | 1 | NumParam | ||
T6 | \(T_6\) | Leadlag 1 time const. (2) | 0.500 | NumParam | ||
T7 | \(T_7\) | Leadlag 2 time const. (1) | 1 | NumParam | ||
T8 | \(T_8\) | Leadlag 2 time const. (2) | 1 | NumParam | ||
T9 | \(T_9\) | Leadlag 3 time const. (1) | 1 | NumParam | ||
T10 | \(T_{10}\) | Leadlag 3 time const. (2) | 0.200 | NumParam | ||
LSMAX | \(L_{SMAX}\) | Max. output limit | 0.300 | NumParam | ||
LSMIN | \(L_{SMIN}\) | Min. output limit | -0.300 | NumParam | ||
VCU | \(V_{CU}\) | Upper enabling bus voltage | 999 | p.u. | NumParam | |
VCL | \(V_{CL}\) | Upper enabling bus voltage | -999 | p.u. | NumParam | |
syn | Retrieved generator idx | 0 | ExtParam | |||
bus | Retrieved bus idx | ExtParam | ||||
Sn | \(S_n\) | Generator power base | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
L1_y | \(y_{L1}\) | \(K_{1} S_{ig}\) | State in lag transfer function | v_str | |
L2_y | \(y_{L2}\) | \(K_{2} S_{ig2}\) | State in lag transfer function | v_str | |
WO_x | \(x'_{WO}\) | \(I_{N}\) | State in washout filter | v_str | |
LL1_x | \(x'_{LL1}\) | \(y_{WO}\) | State in lead-lag | v_str | |
LL2_x | \(x'_{LL2}\) | \(y_{LL1}\) | State in lead-lag | v_str | |
LL3_x | \(x'_{LL3}\) | \(y_{LL2}\) | State in lead-lag | v_str | |
omega | \(\omega\) | Generator speed | p.u. | ||
vsout | \(v_{sout}\) | PSS output voltage to exciter | |||
sig | \(S_{ig}\) | \(V s_{5}^{SW} + s_{1}^{SW} \left(\omega - 1\right) + s_{4}^{SW} \left(\tau_m - \tau_{m0}\right) + \frac{\tau_{m0} s_{3}^{SW}}{(Sb/Sn)}\) | Input signal | v_str | |
sig2 | \(S_{ig2}\) | \(V s_{5}^{SW_{2}} + s_{1}^{SW_{2}} \left(\omega - 1\right) + s_{4}^{SW_{2}} \left(\tau_m - \tau_{m0}\right) + \frac{\tau_{m0} s_{3}^{SW_{2}}}{(Sb/Sn)}\) | Input signal 2 | v_str | |
IN | \(I_{N}\) | \(y_{L1} + y_{L2}\) | Sum of inputs | v_str | |
WO_y | \(y_{WO}\) | \(WO_{LT z1} x'_{WO}\) | Output of washout filter | v_str | |
LL1_y | \(y_{LL1}\) | \(y_{WO}\) | Output of lead-lag | v_str | |
LL2_y | \(y_{LL2}\) | \(y_{LL1}\) | Output of lead-lag | v_str | |
LL3_y | \(y_{LL3}\) | \(y_{LL2}\) | Output of lead-lag | v_str | |
VSS_x | \(x_{VSS}\) | \(y_{LL3}\) | Gain output before limiter | v_str | |
VSS_y | \(y_{VSS}\) | \(L_{SMAX} VSS_{lim zu} + L_{SMIN} VSS_{lim zl} + VSS_{lim zi} x_{VSS}\) | Gain output after limiter | v_str | |
tm | \(\tau_m\) | Generator mechanical input | |||
te | \(\tau_e\) | Generator electrical output | |||
v | \(V\) | Bus (or busr, if given) terminal voltage | |||
f | \(f\) | Bus frequency | |||
vi | \(v_{i}\) | Exciter input voltage | |||
v2 | \(V\) | Bus (or busr2, if given) terminal voltage | |||
f2 | \(f_{2}\) | Bus frequency 2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
L1_y | \(y_{L1}\) | State | \(K_{1} S_{ig} - y_{L1}\) | \(T_1\) |
L2_y | \(y_{L2}\) | State | \(K_{2} S_{ig2} - y_{L2}\) | \(T_2\) |
WO_x | \(x'_{WO}\) | State | \(I_{N} - x'_{WO}\) | \(T_4\) |
LL1_x | \(x'_{LL1}\) | State | \(- x'_{LL1} + y_{WO}\) | \(T_6\) |
LL2_x | \(x'_{LL2}\) | State | \(- x'_{LL2} + y_{LL1}\) | \(T_8\) |
LL3_x | \(x'_{LL3}\) | State | \(- x'_{LL3} + y_{LL2}\) | \(T_{10}\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
vsout | \(v_{sout}\) | Algeb | \(- v_{sout} + y_{VSS} z_{i}^{OLIM}\) |
sig | \(S_{ig}\) | Algeb | \(- S_{ig} + V s_{5}^{SW} + V^{dv} s_{6}^{SW} + s_{1}^{SW} \left(\omega - 1\right) + s_{2}^{SW} \left(f - 1\right) + s_{4}^{SW} \left(\tau_m - \tau_{m0}\right) + \frac{\tau_e s_{3}^{SW}}{(Sb/Sn)}\) |
sig2 | \(S_{ig2}\) | Algeb | \(- S_{ig2} + V s_{5}^{SW_{2}} + V^{dv_{2}} s_{6}^{SW_{2}} + s_{1}^{SW_{2}} \left(\omega - 1\right) + s_{2}^{SW_{2}} \left(f_{2} - 1\right) + s_{4}^{SW_{2}} \left(\tau_m - \tau_{m0}\right) + \frac{\tau_e s_{3}^{SW_{2}}}{(Sb/Sn)}\) |
IN | \(I_{N}\) | Algeb | \(- I_{N} + y_{L1} + y_{L2}\) |
WO_y | \(y_{WO}\) | Algeb | \(T_{3} WO_{LT z0} \left(I_{N} - x'_{WO}\right) + T_{4} WO_{LT z1} x'_{WO} - T_{4} y_{WO}\) |
LL1_y | \(y_{LL1}\) | Algeb | \(LL_{1 LT1 z1} LL_{1 LT2 z1} \left(- x'_{LL1} + y_{LL1}\right) + T_{5} \left(- x'_{LL1} + y_{WO}\right) + T_{6} x'_{LL1} - T_{6} y_{LL1}\) |
LL2_y | \(y_{LL2}\) | Algeb | \(LL_{2 LT1 z1} LL_{2 LT2 z1} \left(- x'_{LL2} + y_{LL2}\right) + T_{7} \left(- x'_{LL2} + y_{LL1}\right) + T_{8} x'_{LL2} - T_{8} y_{LL2}\) |
LL3_y | \(y_{LL3}\) | Algeb | \(LL_{3 LT1 z1} LL_{3 LT2 z1} \left(- x'_{LL3} + y_{LL3}\right) + T_{9} \left(- x'_{LL3} + y_{LL2}\right) + T_{10} x'_{LL3} - T_{10} y_{LL3}\) |
VSS_x | \(x_{VSS}\) | Algeb | \(- x_{VSS} + y_{LL3}\) |
VSS_y | \(y_{VSS}\) | Algeb | \(L_{SMAX} VSS_{lim zu} + L_{SMIN} VSS_{lim zl} + VSS_{lim zi} x_{VSS} - y_{VSS}\) |
tm | \(\tau_m\) | ExtAlgeb | \(0\) |
te | \(\tau_e\) | ExtAlgeb | \(0\) |
v | \(V\) | ExtAlgeb | \(0\) |
f | \(f\) | ExtAlgeb | \(0\) |
vi | \(v_{i}\) | ExtAlgeb | \(u v_{sout}\) |
v2 | \(V\) | ExtAlgeb | \(0\) |
f2 | \(f_{2}\) | ExtAlgeb | \(0\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
VOU | \(VOU\) | \(VCUr + V_{0}\) | ConstService |
VOL | \(VOL\) | \(VCLr + V_{0}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
dv | \(dv\) | Derivative | |
dv2 | \(dv2\) | Derivative | |
SW | \(SW\) | Switcher | |
SW2 | \(SW2\) | Switcher | |
WO_LT | \(LT_{WO}\) | LessThan | |
LL1_LT1 | \(LT_{LL1}\) | LessThan | |
LL1_LT2 | \(LT_{LL1}\) | LessThan | |
LL2_LT1 | \(LT_{LL2}\) | LessThan | |
LL2_LT2 | \(LT_{LL2}\) | LessThan | |
LL3_LT1 | \(LT_{LL3}\) | LessThan | |
LL3_LT2 | \(LT_{LL3}\) | LessThan | |
VSS_lim | \(lim_{VSS}\) | HardLimiter | |
OLIM | \(OLIM\) | Limiter | output limiter |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
L1 | \(L1\) | Lag | Transducer 1 |
L2 | \(L2\) | Lag | Transducer 2 |
WO | \(WO\) | WashoutOrLag | |
LL1 | \(LL1\) | LeadLag | |
LL2 | \(LL2\) | LeadLag | |
LL3 | \(LL3\) | LeadLag | |
VSS | \(VSS\) | GainLimiter |
Config Fields in [ST2CUT]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
freq_model | BusFreq | default freq. measurement model | ('BusFreq',) |
StaticACDC¶
AC DC device for power flow
Common Parameters: u, name
Available models: VSCShunt
VSCShunt¶
Group StaticACDC
Data for VSC Shunt in power flow Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus | idx of connected bus | IdxParam | mandatory | |||
node1 | Node 1 index | IdxParam | mandatory | |||
node2 | Node 2 index | IdxParam | mandatory | |||
Vn | \(V_n\) | AC voltage rating | 110 | NumParam | non_zero | |
Vdcn1 | \(V_{dcn1}\) | DC voltage rating on node 1 | 100 | kV | NumParam | non_zero |
Vdcn2 | \(V_{dcn2}\) | DC voltage rating on node 2 | 100 | kV | NumParam | non_zero |
Idcn | \(I_{dcn}\) | DC current rating | 1 | kA | NumParam | non_zero |
rsh | \(r_{sh}\) | AC interface resistance | 0.003 | ohm | NumParam | z |
xsh | \(x_{sh}\) | AC interface reactance | 0.060 | ohm | NumParam | z |
control | Control method: 0-PQ, 1-PV, 2-vQ or 3-vV | NumParam | mandatory | |||
v0 | AC voltage setting (PV or vV) or initial guess (PQ or vQ) | 1 | NumParam | |||
p0 | AC active power setting | 0 | pu | NumParam | ||
q0 | AC reactive power setting | 0 | pu | NumParam | ||
vdc0 | \(v_{dc0}\) | DC voltage setting | 1 | pu | NumParam | |
k0 | Loss coefficient - constant | 0 | NumParam | |||
k1 | Loss coefficient - linear | 0 | NumParam | |||
k2 | Loss coefficient - quadratic | 0 | NumParam | |||
droop | Enable dc voltage droop control | 0 | boolean | NumParam | ||
K | Droop coefficient | 0 | NumParam | |||
vhigh | Upper voltage threshold in droop control | 9999 | pu | NumParam | ||
vlow | Lower voltage threshold in droop control | 0 | pu | NumParam | ||
vshmax | Maximum ac interface voltage | 1.100 | pu | NumParam | ||
vshmin | Minimum ac interface voltage | 0.900 | pu | NumParam | ||
Ishmax | Maximum ac current | 2 | pu | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
ash | \(\theta_{sh}\) | \(a\) | voltage phase behind the transformer | rad | v_str |
vsh | \(V_{sh}\) | \(v_{0}\) | voltage magnitude behind transformer | p.u. | v_str |
psh | \(P_{sh}\) | \(p_{0} \left(s_{0}^{mode} + s_{1}^{mode}\right)\) | active power injection into VSC | p.u. | v_str |
qsh | \(Q_{sh}\) | \(q_{0} \left(s_{0}^{mode} + s_{2}^{mode}\right)\) | reactive power injection into VSC | v_str | |
pdc | \(P_{dc}\) | \(0\) | DC power injection | v_str | |
a | \(a\) | AC bus voltage phase | |||
v | \(v\) | AC bus voltage magnitude | |||
v1 | \(v_{1}\) | DC node 1 voltage | |||
v2 | \(v_{2}\) | DC node 2 voltage |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
ash | \(\theta_{sh}\) | Algeb | \(- P_{sh} + u \left(V_{sh} b_{sh} v \sin{\left(\theta_{sh} - a \right)} - V_{sh} g_{sh} v \cos{\left(\theta_{sh} - a \right)} + g_{sh} v^{2}\right)\) |
vsh | \(V_{sh}\) | Algeb | \(- Q_{sh} + u \left(V_{sh} b_{sh} v \cos{\left(\theta_{sh} - a \right)} + V_{sh} g_{sh} v \sin{\left(\theta_{sh} - a \right)} - b_{sh} v^{2}\right)\) |
psh | \(P_{sh}\) | Algeb | \(u \left(- P_{sh} + p_{0}\right) \left(s_{0}^{mode} + s_{1}^{mode}\right) + u \left(s_{2}^{mode} + s_{3}^{mode}\right) \left(v_{1} - v_{2} - v_{dc0}\right)\) |
qsh | \(Q_{sh}\) | Algeb | \(u \left(- Q_{sh} + q_{0}\right) \left(s_{0}^{mode} + s_{2}^{mode}\right) + u \left(s_{1}^{mode} + s_{3}^{mode}\right) \left(- v + v_{0}\right)\) |
pdc | \(P_{dc}\) | Algeb | \(P_{dc} + u \left(V_{sh}^{2} g_{sh} - V_{sh} b_{sh} v \sin{\left(\theta_{sh} - a \right)} - V_{sh} g_{sh} v \cos{\left(\theta_{sh} - a \right)}\right)\) |
a | \(a\) | ExtAlgeb | \(- P_{sh}\) |
v | \(v\) | ExtAlgeb | \(- Q_{sh}\) |
v1 | \(v_{1}\) | ExtAlgeb | \(- \frac{P_{dc}}{v_{1} - v_{2}}\) |
v2 | \(v_{2}\) | ExtAlgeb | \(\frac{P_{dc}}{v_{1} - v_{2}}\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
gsh | \(g_{sh}\) | \(\frac{\operatorname{re}{\left(r_{sh}\right)} - \operatorname{im}{\left(x_{sh}\right)}}{\left(\operatorname{re}{\left(r_{sh}\right)} - \operatorname{im}{\left(x_{sh}\right)}\right)^{2} + \left(\operatorname{re}{\left(x_{sh}\right)} + \operatorname{im}{\left(r_{sh}\right)}\right)^{2}}\) | ConstService |
bsh | \(b_{sh}\) | \(\frac{- \operatorname{re}{\left(x_{sh}\right)} - \operatorname{im}{\left(r_{sh}\right)}}{\left(\operatorname{re}{\left(r_{sh}\right)} - \operatorname{im}{\left(x_{sh}\right)}\right)^{2} + \left(\operatorname{re}{\left(x_{sh}\right)} + \operatorname{im}{\left(r_{sh}\right)}\right)^{2}}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
mode | \(mode\) | Switcher |
StaticGen¶
Static generator group for power flow calculation
Common Parameters: u, name, Sn, Vn, p0, q0, ra, xs, subidx
Common Variables: p, q, a, v
PV¶
Group StaticGen
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
Sn | \(S_n\) | Power rating | 100 | NumParam | non_zero | |
Vn | \(V_n\) | AC voltage rating | 110 | NumParam | non_zero | |
subidx | index for generators on the same bus | DataParam | ||||
bus | idx of the installed bus | IdxParam | ||||
busr | bus idx for remote voltage control | IdxParam | ||||
p0 | \(p_0\) | active power set point in system base | 0 | p.u. | NumParam | |
q0 | \(q_0\) | reactive power set point in system base | 0 | p.u. | NumParam | |
pmax | \(p_{max}\) | maximum active power in system base | 999 | p.u. | NumParam | |
pmin | \(p_{min}\) | minimum active power in system base | -1 | p.u. | NumParam | |
qmax | \(q_{max}\) | maximim reactive power in system base | 999 | p.u. | NumParam | |
qmin | \(q_{min}\) | minimum reactive power in system base | -999 | p.u. | NumParam | |
v0 | \(v_0\) | voltage set point | 1 | NumParam | ||
vmax | \(v_{max}\) | maximum voltage voltage | 1.400 | NumParam | ||
vmin | \(v_{min}\) | minimum allowed voltage | 0.600 | NumParam | ||
ra | \(r_a\) | armature resistance | 0.010 | NumParam | ||
xs | \(x_s\) | armature reactance | 0.300 | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
p | \(p\) | \(p_{0}\) | actual active power generation | p.u. | v_str |
q | \(q\) | \(q_{0}\) | actual reactive power generation | p.u. | v_str |
a | \(\theta\) | ||||
v | \(V\) | \(v_{0}\) | v_str,v_setter |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
p | \(p\) | Algeb | \(u \left(- p + p_{0}\right)\) |
q | \(q\) | Algeb | \(u \left(z_{i}^{qlim} \left(- V + v_{0}\right) + z_{l}^{qlim} \left(- q + q_{min}\right) + z_{u}^{qlim} \left(- q + q_{max}\right)\right)\) |
a | \(\theta\) | ExtAlgeb | \(- p u\) |
v | \(V\) | ExtAlgeb | \(- q u\) |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
qlim | \(qlim\) | SortedLimiter |
Config Fields in [PV]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
pv2pq | \(z_{pv2pq}\) | 0 | convert PV to PQ in PFlow at Q limits | (0, 1) |
npv2pq | \(n_{pv2pq}\) | 1 | max. # of pv2pq conversion in each iteration | >=0 |
Slack¶
Group StaticGen
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
Sn | \(S_n\) | Power rating | 100 | NumParam | non_zero | |
Vn | \(V_n\) | AC voltage rating | 110 | NumParam | non_zero | |
subidx | index for generators on the same bus | DataParam | ||||
bus | idx of the installed bus | IdxParam | ||||
busr | bus idx for remote voltage control | IdxParam | ||||
p0 | \(p_0\) | active power set point in system base | 0 | p.u. | NumParam | |
q0 | \(q_0\) | reactive power set point in system base | 0 | p.u. | NumParam | |
pmax | \(p_{max}\) | maximum active power in system base | 999 | p.u. | NumParam | |
pmin | \(p_{min}\) | minimum active power in system base | -1 | p.u. | NumParam | |
qmax | \(q_{max}\) | maximim reactive power in system base | 999 | p.u. | NumParam | |
qmin | \(q_{min}\) | minimum reactive power in system base | -999 | p.u. | NumParam | |
v0 | \(v_0\) | voltage set point | 1 | NumParam | ||
vmax | \(v_{max}\) | maximum voltage voltage | 1.400 | NumParam | ||
vmin | \(v_{min}\) | minimum allowed voltage | 0.600 | NumParam | ||
ra | \(r_a\) | armature resistance | 0.010 | NumParam | ||
xs | \(x_s\) | armature reactance | 0.300 | NumParam | ||
a0 | \(\theta_0\) | reference angle set point | 0 | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
p | \(p\) | \(p_{0}\) | actual active power generation | p.u. | v_str |
q | \(q\) | \(q_{0}\) | actual reactive power generation | p.u. | v_str |
a | \(\theta\) | \(\theta_0\) | v_str,v_setter | ||
v | \(V\) | \(v_{0}\) | v_str,v_setter |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
p | \(p\) | Algeb | \(u \left(z_{i}^{plim} \left(- \theta + \theta_0\right) + z_{l}^{plim} \left(- p + p_{min}\right) + z_{u}^{plim} \left(- p + p_{max}\right)\right)\) |
q | \(q\) | Algeb | \(u \left(z_{i}^{qlim} \left(- V + v_{0}\right) + z_{l}^{qlim} \left(- q + q_{min}\right) + z_{u}^{qlim} \left(- q + q_{max}\right)\right)\) |
a | \(\theta\) | ExtAlgeb | \(- p u\) |
v | \(V\) | ExtAlgeb | \(- q u\) |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
qlim | \(qlim\) | SortedLimiter | |
plim | \(plim\) | SortedLimiter |
Config Fields in [Slack]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
pv2pq | \(z_{pv2pq}\) | 0 | convert PV to PQ in PFlow at Q limits | (0, 1) |
npv2pq | \(n_{pv2pq}\) | 1 | max. # of pv2pq conversion in each iteration | >=0 |
av2pv | \(z_{av2pv}\) | 0 | convert Slack to PV in PFlow at P limits | (0, 1) |
StaticLoad¶
Static load group.
Common Parameters: u, name
Available models: PQ
PQ¶
Group StaticLoad
PQ load model.
Implements an automatic pq2z conversion during power flow when the voltage is outside [vmin, vmax]. The conversion can be turned off by setting pq2z to 0 in the Config file.
Before time-domain simulation, PQ load will be converted to impedance, current source, and power source based on the weights in the Config file.
Weights (p2p, p2i, p2z) corresponds to the weights for constant power, constant current and constant impedance. p2p, p2i and p2z must be in decimal numbers and sum up exactly to 1. The same rule applies to (q2q, q2i, q2z).
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus | linked bus idx | IdxParam | mandatory | |||
Vn | \(V_n\) | AC voltage rating | 110 | kV | NumParam | non_zero |
p0 | \(p_0\) | active power load in system base | 0 | p.u. | NumParam | |
q0 | \(q_0\) | reactive power load in system base | 0 | p.u. | NumParam | |
vmax | \(v_{max}\) | max voltage before switching to impedance | 1.200 | NumParam | ||
vmin | \(v_{min}\) | min voltage before switching to impedance | 0.800 | NumParam | ||
owner | owner idx | IdxParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
a | \(\theta\) | ||||
v | \(V\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
a | \(\theta\) | ExtAlgeb | \(u \left(I_{peq} V \gamma_{p2i} + P_{pf} \gamma_{p2p} + R_{eq} V^{2} \gamma_{p2z}\right) \left(t_{dae} > 0\right) + u \left(R_{lb} V^{2} z_{l}^{vcmp} + R_{ub} V^{2} z_{u}^{vcmp} + p_{0} z_{i}^{vcmp}\right) \left(t_{dae} \leq 0\right)\) |
v | \(V\) | ExtAlgeb | \(u \left(I_{qeq} V \gamma_{q2i} + Q_{pf} \gamma_{q2q} + V^{2} X_{eq} \gamma_{q2z}\right) \left(t_{dae} > 0\right) + u \left(V^{2} X_{lb} z_{l}^{vcmp} + V^{2} X_{ub} z_{u}^{vcmp} + q_{0} z_{i}^{vcmp}\right) \left(t_{dae} \leq 0\right)\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
Rub | \(R_{ub}\) | \(\frac{p_{0}}{v_{max}^{2}}\) | ConstService |
Xub | \(X_{ub}\) | \(\frac{q_{0}}{v_{max}^{2}}\) | ConstService |
Rlb | \(R_{lb}\) | \(\frac{p_{0}}{v_{min}^{2}}\) | ConstService |
Xlb | \(X_{lb}\) | \(\frac{q_{0}}{v_{min}^{2}}\) | ConstService |
Ppf | \(P_{pf}\) | \(R_{lb} V_{0}^{2} z_{l}^{vcmp} + R_{ub} V_{0}^{2} z_{u}^{vcmp} + p_{0} z_{i}^{vcmp}\) | ConstService |
Qpf | \(Q_{pf}\) | \(V_{0}^{2} X_{lb} z_{l}^{vcmp} + V_{0}^{2} X_{ub} z_{u}^{vcmp} + q_{0} z_{i}^{vcmp}\) | ConstService |
Req | \(R_{eq}\) | \(\frac{P_{pf}}{V_{0}^{2}}\) | ConstService |
Xeq | \(X_{eq}\) | \(\frac{Q_{pf}}{V_{0}^{2}}\) | ConstService |
Ipeq | \(I_{peq}\) | \(\frac{P_{pf}}{V_{0}}\) | ConstService |
Iqeq | \(I_{qeq}\) | \(\frac{Q_{pf}}{V_{0}}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
vcmp | \(vcmp\) | Limiter |
Config Fields in [PQ]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
pq2z | \(z_{pq2z}\) | 1 | pq2z conversion if out of voltage limits | (0, 1) |
p2p | \(\gamma_{p2p}\) | 0 | P constant power percentage for TDS. Must have (p2p+p2i+p2z)=1 | float |
p2i | \(\gamma_{p2i}\) | 0 | P constant current percentage | float |
p2z | \(\gamma_{p2z}\) | 1 | P constant impedance percentage | float |
q2q | \(\gamma_{q2q}\) | 0 | Q constant power percentage for TDS. Must have (q2q+q2i+q2z)=1 | float |
q2i | \(\gamma_{q2i}\) | 0 | Q constant current percentage | float |
q2z | \(\gamma_{q2z}\) | 1 | Q constant impedance percentage | float |
StaticShunt¶
Static shunt compensator group.
Common Parameters: u, name
Available models: Shunt
Shunt¶
Group StaticShunt
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus | idx of connected bus | IdxParam | mandatory | |||
Sn | \(S_n\) | Power rating | 100 | NumParam | non_zero | |
Vn | \(V_n\) | AC voltage rating | 110 | NumParam | non_zero | |
g | \(g\) | shunt conductance (real part) | 0 | NumParam | y | |
b | \(b\) | shunt susceptance (positive as capatance) | 0 | NumParam | y | |
fn | \(f\) | rated frequency | 60 | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
a | \(\theta\) | ||||
v | \(V\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
a | \(\theta\) | ExtAlgeb | \(V^{2} g u\) |
v | \(V\) | ExtAlgeb | \(- V^{2} b u\) |
SynGen¶
Synchronous generator group.
Common Parameters: u, name, Sn, Vn, fn, bus, M, D
Common Variables: omega, delta, tm, te, vf, XadIfd, vd, vq, Id, Iq, a, v
Available models: GENCLS, GENROU
GENCLS¶
Group SynGen
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus | interface bus id | IdxParam | mandatory | |||
gen | static generator index | IdxParam | mandatory | |||
coi | center of inertia index | IdxParam | ||||
Sn | \(S_n\) | Power rating | 100 | NumParam | ||
Vn | \(V_n\) | AC voltage rating | 110 | NumParam | ||
fn | \(f\) | rated frequency | 60 | NumParam | ||
D | \(D\) | Damping coefficient | 0 | NumParam | power | |
M | \(M\) | machine start up time (2H) | 6 | NumParam | non_zero,power | |
ra | \(r_a\) | armature resistance | 0 | NumParam | z | |
xl | \(x_l\) | leakage reactance | 0 | NumParam | z | |
xd1 | \(x'_d\) | d-axis transient reactance | 0.302 | NumParam | z | |
kp | \(k_p\) | active power feedback gain | 0 | NumParam | ||
kw | \(k_w\) | speed feedback gain | 0 | NumParam | ||
S10 | \(S_{1.0}\) | first saturation factor | 0 | NumParam | ||
S12 | \(S_{1.2}\) | second saturation factor | 1 | NumParam | ||
subidx | Generator idx in plant; only used by PSS/E data | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
delta | \(\delta\) | \(\delta_0\) | rotor angle | rad | v_str |
omega | \(\omega\) | \(u\) | rotor speed | pu (Hz) | v_str |
Id | \(I_{d}\) | \(I_{d0}\) | d-axis current | v_str | |
Iq | \(I_{q}\) | \(I_{q0}\) | q-axis current | v_str | |
vd | \(V_{d}\) | \(V_{d0}\) | d-axis voltage | v_str | |
vq | \(V_{q}\) | \(V_{q0}\) | q-axis voltage | v_str | |
tm | \(\tau_m\) | \(\tau_{m0}\) | mechanical torque | v_str | |
te | \(\tau_e\) | \(P_{0}\) | electric torque | v_str | |
vf | \(v_{f}\) | \(v_{f0}\) | excitation voltage | pu | v_str |
XadIfd | \(X_{ad}I_{fd}\) | \(v_{f0}\) | d-axis armature excitation current | p.u (kV) | v_str |
psid | \(\psi_d\) | \(\psi_{d0}\) | d-axis flux | v_str | |
psiq | \(\psi_q\) | \(\psi_{q0}\) | q-axis flux | v_str | |
a | \(\theta\) | Bus voltage phase angle | |||
v | \(V\) | Bus voltage magnitude |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
delta | \(\delta\) | State | \(2 \pi f u \left(\omega - 1\right)\) | |
omega | \(\omega\) | State | \(\frac{u \left(- D \left(\omega - 1\right) - \tau_e + \tau_m\right)}{M}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Id | \(I_{d}\) | Algeb | \(I_{d} xq + \psi_d - v_{f}\) |
Iq | \(I_{q}\) | Algeb | \(I_{q} xq + \psi_q\) |
vd | \(V_{d}\) | Algeb | \(V \sin{\left(\delta - \theta \right)} - V_{d}\) |
vq | \(V_{q}\) | Algeb | \(V \cos{\left(\delta - \theta \right)} - V_{q}\) |
tm | \(\tau_m\) | Algeb | \(- \tau_m + \tau_{m0}\) |
te | \(\tau_e\) | Algeb | \(- I_{d} \psi_q + I_{q} \psi_d - \tau_e\) |
vf | \(v_{f}\) | Algeb | \(- v_{f} + v_{f0}\) |
XadIfd | \(X_{ad}I_{fd}\) | Algeb | \(- X_{ad}I_{fd} + v_{f0}\) |
psid | \(\psi_d\) | Algeb | \(- \psi_d + u \left(I_{q} r_{a} + V_{q}\right)\) |
psiq | \(\psi_q\) | Algeb | \(\psi_q + u \left(I_{d} r_{a} + V_{d}\right)\) |
a | \(\theta\) | ExtAlgeb | \(- u \left(I_{d} V_{d} + I_{q} V_{q}\right)\) |
v | \(V\) | ExtAlgeb | \(- u \left(I_{d} V_{q} - I_{q} V_{d}\right)\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
_V | \(V_c\) | \(V e^{i \theta}\) | ConstService |
_S | \(S\) | \(P_{0} - i Q_{0}\) | ConstService |
_I | \(I_c\) | \(\frac{S}{\operatorname{conj}{\left(V_{c} \right)}}\) | ConstService |
_E | \(E\) | \(I_{c} \left(r_{a} + i xq\right) + V_{c}\) | ConstService |
_deltac | \(\delta_c\) | \(\log{\left(\frac{E}{\operatorname{abs}{\left(E \right)}} \right)}\) | ConstService |
delta0 | \(\delta_0\) | \(u \operatorname{im}{\left(\delta_c\right)}\) | ConstService |
vdq | \(V_{dq}\) | \(V_{c} u e^{- \delta_c + 0.5 i \pi}\) | ConstService |
Idq | \(I_{dq}\) | \(I_{c} u e^{- \delta_c + 0.5 i \pi}\) | ConstService |
Id0 | \(I_{d0}\) | \(\operatorname{re}{\left(I_{dq}\right)}\) | ConstService |
Iq0 | \(I_{q0}\) | \(\operatorname{im}{\left(I_{dq}\right)}\) | ConstService |
vd0 | \(V_{d0}\) | \(\operatorname{re}{\left(V_{dq}\right)}\) | ConstService |
vq0 | \(V_{q0}\) | \(\operatorname{im}{\left(V_{dq}\right)}\) | ConstService |
tm0 | \(\tau_{m0}\) | \(u \left(I_{d0} \left(I_{d0} r_{a} + V_{d0}\right) + I_{q0} \left(I_{q0} r_{a} + V_{q0}\right)\right)\) | ConstService |
psid0 | \(\psi_{d0}\) | \(I_{q0} r_{a} u + V_{q0}\) | ConstService |
psiq0 | \(\psi_{q0}\) | \(- I_{d0} r_{a} u - V_{d0}\) | ConstService |
vf0 | \(v_{f0}\) | \(I_{d0} xq + I_{q0} r_{a} + V_{q0}\) | ConstService |
Config Fields in [GENCLS]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
vf_lower | 1 | lower limit for vf warning | ||
vf_upper | 5 | upper limit for vf warning |
GENROU¶
Group SynGen
Round rotor generator with quadratic saturation
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus | interface bus id | IdxParam | mandatory | |||
gen | static generator index | IdxParam | mandatory | |||
coi | center of inertia index | IdxParam | ||||
Sn | \(S_n\) | Power rating | 100 | NumParam | ||
Vn | \(V_n\) | AC voltage rating | 110 | NumParam | ||
fn | \(f\) | rated frequency | 60 | NumParam | ||
D | \(D\) | Damping coefficient | 0 | NumParam | power | |
M | \(M\) | machine start up time (2H) | 6 | NumParam | non_zero,power | |
ra | \(r_a\) | armature resistance | 0 | NumParam | z | |
xl | \(x_l\) | leakage reactance | 0 | NumParam | z | |
xd1 | \(x'_d\) | d-axis transient reactance | 0.302 | NumParam | z | |
kp | \(k_p\) | active power feedback gain | 0 | NumParam | ||
kw | \(k_w\) | speed feedback gain | 0 | NumParam | ||
S10 | \(S_{1.0}\) | first saturation factor | 0 | NumParam | ||
S12 | \(S_{1.2}\) | second saturation factor | 1 | NumParam | ||
xd | \(x_d\) | d-axis synchronous reactance | 1.900 | NumParam | z | |
xq | \(x_q\) | q-axis synchronous reactance | 1.700 | NumParam | z | |
xd2 | \(x''_d\) | d-axis sub-transient reactance | 0.204 | NumParam | z | |
xq1 | \(x'_q\) | q-axis transient reactance | 0.500 | NumParam | z | |
xq2 | \(x''_q\) | q-axis sub-transient reactance | 0.300 | NumParam | z | |
Td10 | \(T'_{d0}\) | d-axis transient time constant | 8 | NumParam | ||
Td20 | \(T''_{d0}\) | d-axis sub-transient time constant | 0.040 | NumParam | ||
Tq10 | \(T'_{q0}\) | q-axis transient time constant | 0.800 | NumParam | ||
Tq20 | \(T''_{q0}\) | q-axis sub-transient time constant | 0.020 | NumParam | ||
subidx | Generator idx in plant; only used by PSS/E data | 0 | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
delta | \(\delta\) | \(\delta_0\) | rotor angle | rad | v_str |
omega | \(\omega\) | \(u\) | rotor speed | pu (Hz) | v_str |
e1q | \(e'_{q}\) | \(e'_{q0}\) | q-axis transient voltage | v_str | |
e1d | \(e'_{d}\) | \(e'_{d0}\) | d-axis transient voltage | v_str | |
e2d | \(e''_{d}\) | \(e''_{d0}\) | d-axis sub-transient voltage | v_str | |
e2q | \(e''_{q}\) | \(e''_{q0}\) | q-axis sub-transient voltage | v_str | |
Id | \(I_{d}\) | \(I_{d0}\) | d-axis current | v_str | |
Iq | \(I_{q}\) | \(I_{q0}\) | q-axis current | v_str | |
vd | \(V_{d}\) | \(V_{d0}\) | d-axis voltage | v_str | |
vq | \(V_{q}\) | \(V_{q0}\) | q-axis voltage | v_str | |
tm | \(\tau_m\) | \(\tau_{m0}\) | mechanical torque | v_str | |
te | \(\tau_e\) | \(P_{0}\) | electric torque | v_str | |
vf | \(v_{f}\) | \(v_{f0}\) | excitation voltage | pu | v_str |
XadIfd | \(X_{ad}I_{fd}\) | \(v_{f0}\) | d-axis armature excitation current | p.u (kV) | v_str |
psid | \(\psi_d\) | \(\psi_{d0}\) | d-axis flux | v_str | |
psiq | \(\psi_q\) | \(\psi_{q0}\) | q-axis flux | v_str | |
psi2q | \(\psi_{aq}\) | \(\psi_{aq0}\) | q-axis air gap flux | v_str | |
psi2d | \(\psi_{ad}\) | \(\psi_{ad0}\) | d-axis air gap flux | v_str | |
psi2 | \(\psi_a\) | \(\operatorname{abs}{\left(\psi''_{0,dq} \right)}\) | air gap flux magnitude | v_str | |
Se | \(S_e(|\psi_{a}|)\) | \(S_{e0}\) | saturation output | v_str | |
XaqI1q | \(X_{aq}I_{1q}\) | \(0\) | q-axis reaction | p.u (kV) | v_str |
a | \(\theta\) | Bus voltage phase angle | |||
v | \(V\) | Bus voltage magnitude |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
delta | \(\delta\) | State | \(2 \pi f u \left(\omega - 1\right)\) | |
omega | \(\omega\) | State | \(\frac{u \left(- D \left(\omega - 1\right) - \tau_e + \tau_m\right)}{M}\) | |
e1q | \(e'_{q}\) | State | \(\frac{- X_{ad}I_{fd} + v_{f}}{T'_{d0}}\) | |
e1d | \(e'_{d}\) | State | \(- \frac{X_{aq}I_{1q}}{T'_{q0}}\) | |
e2d | \(e''_{d}\) | State | \(\frac{- I_{d} \left(x'_{d} - x_{l}\right) - e''_{d} + e'_{q}}{T''_{d0}}\) | |
e2q | \(e''_{q}\) | State | \(\frac{I_{q} \left(x'_{q} - x_{l}\right) - e''_{q} + e'_{d}}{T''_{q0}}\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
Id | \(I_{d}\) | Algeb | \(I_{d} x''_{d} + \psi_d - \psi_{ad}\) |
Iq | \(I_{q}\) | Algeb | \(I_{q} x''_{q} + \psi_q + \psi_{aq}\) |
vd | \(V_{d}\) | Algeb | \(V \sin{\left(\delta - \theta \right)} - V_{d}\) |
vq | \(V_{q}\) | Algeb | \(V \cos{\left(\delta - \theta \right)} - V_{q}\) |
tm | \(\tau_m\) | Algeb | \(- \tau_m + \tau_{m0}\) |
te | \(\tau_e\) | Algeb | \(- I_{d} \psi_q + I_{q} \psi_d - \tau_e\) |
vf | \(v_{f}\) | Algeb | \(- v_{f} + v_{f0}\) |
XadIfd | \(X_{ad}I_{fd}\) | Algeb | \(S_e(|\psi_{a}|) \psi_{ad} - X_{ad}I_{fd} + e'_{q} + \left(- x'_{d} + x_{d}\right) \left(I_{d} \gamma_{d1} - \gamma_{d2} e''_{d} + \gamma_{d2} e'_{q}\right)\) |
psid | \(\psi_d\) | Algeb | \(- \psi_d + u \left(I_{q} r_{a} + V_{q}\right)\) |
psiq | \(\psi_q\) | Algeb | \(\psi_q + u \left(I_{d} r_{a} + V_{d}\right)\) |
psi2q | \(\psi_{aq}\) | Algeb | \(\gamma_{q1} e'_{d} - \psi_{aq} + e''_{q} \left(1 - \gamma_{q1}\right)\) |
psi2d | \(\psi_{ad}\) | Algeb | \(\gamma_{d1} e'_{q} + \gamma_{d2} e''_{d} \left(x'_{d} - x_{l}\right) - \psi_{ad}\) |
psi2 | \(\psi_a\) | Algeb | \(- \psi_a + \sqrt{\psi_{ad}^{2} + \psi_{aq}^{2}}\) |
Se | \(S_e(|\psi_{a}|)\) | Algeb | \(\frac{B^q_{S_{AT}} z_{0}^{SL} \left(- A^q_{S_{AT}} + \psi_a\right)^{2}}{\psi_a} - S_e(|\psi_{a}|)\) |
XaqI1q | \(X_{aq}I_{1q}\) | Algeb | \(S_e(|\psi_{a}|) \gamma_{qd} \psi_{aq} - X_{aq}I_{1q} + e'_{d} + \left(- x'_{q} + x_{q}\right) \left(- I_{q} \gamma_{q1} - \gamma_{q2} e''_{q} + \gamma_{q2} e'_{d}\right)\) |
a | \(\theta\) | ExtAlgeb | \(- u \left(I_{d} V_{d} + I_{q} V_{q}\right)\) |
v | \(V\) | ExtAlgeb | \(- u \left(I_{d} V_{q} - I_{q} V_{d}\right)\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
gd1 | \(\gamma_{d1}\) | \(\frac{x''_{d} - x_{l}}{x'_{d} - x_{l}}\) | ConstService |
gq1 | \(\gamma_{q1}\) | \(\frac{x''_{q} - x_{l}}{x'_{q} - x_{l}}\) | ConstService |
gd2 | \(\gamma_{d2}\) | \(\frac{- x''_{d} + x'_{d}}{\left(x'_{d} - x_{l}\right)^{2}}\) | ConstService |
gq2 | \(\gamma_{q2}\) | \(\frac{- x''_{q} + x'_{q}}{\left(x'_{q} - x_{l}\right)^{2}}\) | ConstService |
gqd | \(\gamma_{qd}\) | \(\frac{- x_{l} + x_{q}}{x_{d} - x_{l}}\) | ConstService |
_S12 | \(S_{1.2}\) | \(S_{1.2} - _fS12 + 1\) | ConstService |
SAT_E1 | \(E^{1c}_{S_{AT}}\) | \(1.0\) | ConstService |
SAT_E2 | \(E^{2c}_{S_{AT}}\) | \(1.2\) | ConstService |
SAT_SE1 | \(SE^{1c}_{S_{AT}}\) | \(S_{1.0}\) | ConstService |
SAT_SE2 | \(SE^{2c}_{S_{AT}}\) | \(S_{1.2} - 2 z^{SE2}_{S_{AT}} + 2\) | ConstService |
SAT_a | \(a_{S_{AT}}\) | \(\sqrt{\frac{E^{1c}_{S_{AT}} SE^{1c}_{S_{AT}}}{E^{2c}_{S_{AT}} SE^{2c}_{S_{AT}}}} \left(\left(SE^{2c}_{S_{AT}} > 0\right) + \left(SE^{2c}_{S_{AT}} < 0\right)\right)\) | ConstService |
SAT_A | \(A^q_{S_{AT}}\) | \(E^{2c}_{S_{AT}} - \frac{E^{1c}_{S_{AT}} - E^{2c}_{S_{AT}}}{a_{S_{AT}} - 1}\) | ConstService |
SAT_B | \(B^q_{S_{AT}}\) | \(\frac{E^{2c}_{S_{AT}} SE^{2c}_{S_{AT}} \left(a_{S_{AT}} - 1\right)^{2} \left(\left(a_{S_{AT}} > 0\right) + \left(a_{S_{AT}} < 0\right)\right)}{\left(E^{1c}_{S_{AT}} - E^{2c}_{S_{AT}}\right)^{2}}\) | ConstService |
_V | \(V_c\) | \(V e^{i \theta}\) | ConstService |
_S | \(S\) | \(P_{0} - i Q_{0}\) | ConstService |
_Zs | \(Z_s\) | \(r_{a} + i x''_{d}\) | ConstService |
_It | \(I_t\) | \(\frac{S}{\operatorname{conj}{\left(V_{c} \right)}}\) | ConstService |
_Is | \(I_s\) | \(I_{t} + \frac{V_{c}}{Z_{s}}\) | ConstService |
psi20 | \(\psi''_0\) | \(I_{s} Z_{s}\) | ConstService |
psi20_arg | \(\theta_{\psi''0}\) | \(\arg{\left(\psi''_0 \right)}\) | ConstService |
psi20_abs | \(|\psi''_0|\) | \(\operatorname{abs}{\left(\psi''_0 \right)}\) | ConstService |
_It_arg | \(\theta_{It0}\) | \(\arg{\left(I_{t} \right)}\) | ConstService |
_psi20_It_arg | \(\theta_{\psi a It}\) | \(- \theta_{It0} + \theta_{\psi''0}\) | ConstService |
Se0 | \(S_{e0}\) | \(\frac{B^q_{S_{AT}} \left(- A^q_{S_{AT}} + |\psi''_0|\right)^{2} \left(|\psi''_0| \geq A^q_{S_{AT}}\right)}{|\psi''_0|}\) | ConstService |
_a | \(a\) | \(|\psi''_0| \left(S_{e0} \gamma_{qd} + 1\right)\) | ConstService |
_b | \(b\) | \(\left(x''_{q} - x_{q}\right) \operatorname{abs}{\left(I_{t} \right)}\) | ConstService |
delta0 | \(\delta_0\) | \(\theta_{\psi''0} + \operatorname{atan}{\left(\frac{b \cos{\left(\theta_{\psi a It} \right)}}{- \theta + b \sin{\left(\theta_{\psi a It} \right)}} \right)}\) | ConstService |
_Tdq | \(T_{dq}\) | \(- i \sin{\left(\delta_0 \right)} + \cos{\left(\delta_0 \right)}\) | ConstService |
psi20_dq | \(\psi''_{0,dq}\) | \(T_{dq} \psi''_0\) | ConstService |
It_dq | \(I_{t,dq}\) | \(\operatorname{conj}{\left(I_{t} T_{dq} \right)}\) | ConstService |
psi2d0 | \(\psi_{ad0}\) | \(\operatorname{re}{\left(\psi''_{0,dq}\right)}\) | ConstService |
psi2q0 | \(\psi_{aq0}\) | \(- \operatorname{im}{\left(\psi''_{0,dq}\right)}\) | ConstService |
Id0 | \(I_{d0}\) | \(\operatorname{im}{\left(I_{t,dq}\right)}\) | ConstService |
Iq0 | \(I_{q0}\) | \(\operatorname{re}{\left(I_{t,dq}\right)}\) | ConstService |
vd0 | \(V_{d0}\) | \(- I_{d0} r_{a} + I_{q0} x''_{q} + \psi_{aq0}\) | ConstService |
vq0 | \(V_{q0}\) | \(- I_{d0} x''_{d} - I_{q0} r_{a} + \psi_{ad0}\) | ConstService |
tm0 | \(\tau_{m0}\) | \(u \left(I_{d0} \left(I_{d0} r_{a} + V_{d0}\right) + I_{q0} \left(I_{q0} r_{a} + V_{q0}\right)\right)\) | ConstService |
vf0 | \(v_{f0}\) | \(I_{d0} \left(- x''_{d} + x_{d}\right) + \psi_{ad0} \left(S_{e0} + 1\right)\) | ConstService |
psid0 | \(\psi_{d0}\) | \(I_{q0} r_{a} u + V_{q0}\) | ConstService |
psiq0 | \(\psi_{q0}\) | \(- I_{d0} r_{a} u - V_{d0}\) | ConstService |
e1q0 | \(e'_{q0}\) | \(I_{d0} \left(x'_{d} - x_{d}\right) - S_{e0} \psi_{ad0} + v_{f0}\) | ConstService |
e1d0 | \(e'_{d0}\) | \(I_{q0} \left(- x'_{q} + x_{q}\right) - S_{e0} \gamma_{qd} \psi_{aq0}\) | ConstService |
e2d0 | \(e''_{d0}\) | \(I_{d0} \left(- x_{d} + x_{l}\right) - S_{e0} \psi_{ad0} + v_{f0}\) | ConstService |
e2q0 | \(e''_{q0}\) | \(- I_{q0} \left(x_{l} - x_{q}\right) - S_{e0} \gamma_{qd} \psi_{aq0}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
SL | \(SL\) | LessThan |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
SAT | \(S_{AT}\) | ExcQuadSat |
Config Fields in [GENROU]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
vf_lower | 1 | lower limit for vf warning | ||
vf_upper | 5 | upper limit for vf warning |
TimedEvent¶
Timed event group
Common Parameters: u, name
Available models: Toggler, Fault
Toggler¶
Group TimedEvent
Time-based connectivity status toggler.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
model | Model or Group of the device to control | DataParam | mandatory | |||
dev | idx of the device to control | IdxParam | mandatory | |||
t | switch time for connection status | -1 | TimerParam | mandatory |
Fault¶
Group TimedEvent
Three-phase to ground fault.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
bus | linked bus idx | IdxParam | mandatory | |||
tf | Bus fault start time | -1 | second | TimerParam | mandatory | |
tc | Bus fault end time | -1 | second | TimerParam | ||
xf | \(x_f\) | Fault to ground impedance (positive) | 0.000 | p.u.(sys) | NumParam | |
rf | \(x_f\) | Fault to ground resistance (positive) | 0 | p.u.(sys) | NumParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
a | \(\theta\) | Bus voltage angle | p.u.(kV) | ||
v | \(V\) | Bus voltage magnitude | p.u.(kV) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
a | \(\theta\) | ExtAlgeb | \(V^{2} g_{f} u u_{f}\) |
v | \(V\) | ExtAlgeb | \(- V^{2} b_{f} u u_{f}\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
gf | \(g_{f}\) | \(\frac{\operatorname{re}{\left(x_{f}\right)} - \operatorname{im}{\left(x_{f}\right)}}{\left(\operatorname{re}{\left(x_{f}\right)} - \operatorname{im}{\left(x_{f}\right)}\right)^{2} + \left(\operatorname{re}{\left(x_{f}\right)} + \operatorname{im}{\left(x_{f}\right)}\right)^{2}}\) | ConstService |
bf | \(b_{f}\) | \(\frac{- \operatorname{re}{\left(x_{f}\right)} - \operatorname{im}{\left(x_{f}\right)}}{\left(\operatorname{re}{\left(x_{f}\right)} - \operatorname{im}{\left(x_{f}\right)}\right)^{2} + \left(\operatorname{re}{\left(x_{f}\right)} + \operatorname{im}{\left(x_{f}\right)}\right)^{2}}\) | ConstService |
uf | \(u_f\) | \(0\) | ConstService |
TurbineGov¶
Turbine governor group for synchronous generator.
Common Parameters: u, name
Common Variables: pout
Available models: TG2, TGOV1, IEEEG1
TG2¶
Group TurbineGov
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory,unique | |||
Tn | \(T_n\) | Turbine power rating. Equal to Sn if not provided. | MVA | NumParam | ||
wref0 | \(\omega_{ref0}\) | Base speed reference | 1 | p.u. | NumParam | |
R | \(R\) | Speed regulation gain (mach. base default) | 0.050 | p.u. | NumParam | ipower |
pmax | \(p_{max}\) | Maximum power output | 999 | p.u. | NumParam | power |
pmin | \(p_{min}\) | Minimum power output | 0 | p.u. | NumParam | power |
dbl | \(L_{db}\) | Deadband lower limit | -0.000 | p.u. | NumParam | |
dbu | \(U_{db}\) | Deadband upper limit | 0.000 | p.u. | NumParam | |
dbc | \(C_{db}\) | Deadband neutral value | 0 | p.u. | NumParam | |
T1 | \(T_1\) | Transient gain time | 0.200 | NumParam | ||
T2 | \(T_2\) | Governor time constant | 10 | NumParam | ||
Sg | \(S_n\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_n\) | Rated voltage from generator | 0 | kV | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
ll_x | \(x'_{ll}\) | \(\omega_{dmG}\) | State in lead-lag | v_str | |
omega | \(\omega\) | Generator speed | p.u. | ||
paux | \(P_{aux}\) | \(P_{aux0}\) | Auxiliary power input | v_str | |
pout | \(P_{out}\) | \(\tau_{m0} u\) | Turbine final output power | v_str | |
wref | \(\omega_{ref}\) | \(\omega_{ref0}\) | Speed reference variable | v_str | |
w_d | \(\omega_{dev}\) | \(0\) | Generator speed deviation before dead band (positive for under speed) | v_str | |
w_dm | \(\omega_{dm}\) | \(0\) | Measured speed deviation after dead band | v_str | |
w_dmg | \(\omega_{dmG}\) | \(0\) | Speed deviation after dead band after gain | v_str | |
ll_y | \(y_{ll}\) | \(\omega_{dmG}\) | Output of lead-lag | v_str | |
pnl | \(P_{nl}\) | \(\tau_{m0}\) | Power output before hard limiter | v_str | |
tm | \(\tau_m\) | Mechanical power interface to SynGen |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
ll_x | \(x'_{ll}\) | State | \(\omega_{dmG} - x'_{ll}\) | \(T_2\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
paux | \(P_{aux}\) | Algeb | \(P_{aux0} - P_{aux}\) |
pout | \(P_{out}\) | Algeb | \(P_{nl} z_{i}^{plim} - P_{out} + p_{max} z_{u}^{plim} + p_{min} z_{l}^{plim}\) |
wref | \(\omega_{ref}\) | Algeb | \(\omega_{ref0} - \omega_{ref}\) |
w_d | \(\omega_{dev}\) | Algeb | \(- \omega_{dev} + u \left(- \omega + \omega_{ref}\right)\) |
w_dm | \(\omega_{dm}\) | Algeb | \(L_{db} z_{lr}^{w_{db}} + U_{db} z_{ur}^{w_{db}} + \omega_{dev} \left(1 - z_{i}^{w_{db}}\right) - \omega_{dm}\) |
w_dmg | \(\omega_{dmG}\) | Algeb | \(G \omega_{dm} - \omega_{dmG}\) |
ll_y | \(y_{ll}\) | Algeb | \(T_{1} \left(\omega_{dmG} - x'_{ll}\right) + T_{2} x'_{ll} - T_{2} y_{ll} + ll_{LT1 z1} ll_{LT2 z1} \left(- x'_{ll} + y_{ll}\right)\) |
pnl | \(P_{nl}\) | Algeb | \(- P_{nl} + \tau_{m0} + y_{ll}\) |
tm | \(\tau_m\) | ExtAlgeb | \(u \left(P_{out} - \tau_{m0}\right)\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
paux0 | \(P_{aux0}\) | \(0\) | ConstService |
gain | \(G\) | \(\frac{u}{R}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
w_db | \(w_db\) | DeadBand | |
ll_LT1 | \(LT_{ll}\) | LessThan | |
ll_LT2 | \(LT_{ll}\) | LessThan | |
plim | \(plim\) | HardLimiter |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
ll | \(ll\) | LeadLag |
Config Fields in [TG2]
Option | Symbol | Value | Info | Accepted values |
---|---|---|---|---|
deadband | \(z_{deadband}\) | 0 | enable input dead band | (0, 1) |
hardlimit | \(z_{hardlimit}\) | 1 | enable output hard limit | (0, 1) |
TGOV1¶
Group TurbineGov
TGOV1 model.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory,unique | |||
Tn | \(T_n\) | Turbine power rating. Equal to Sn if not provided. | MVA | NumParam | ||
wref0 | \(\omega_{ref0}\) | Base speed reference | 1 | p.u. | NumParam | |
R | \(R\) | Speed regulation gain (mach. base default) | 0.050 | p.u. | NumParam | ipower |
VMAX | \(V_{max}\) | Maximum valve position | 1.200 | p.u. | NumParam | power |
VMIN | \(V_{min}\) | Minimum valve position | 0 | p.u. | NumParam | power |
T1 | \(T_1\) | Valve time constant | 0.100 | NumParam | ||
T2 | \(T_2\) | Lead-lag lead time constant | 0.200 | NumParam | ||
T3 | \(T_3\) | Lead-lag lag time constant | 10 | NumParam | ||
Dt | \(D_t\) | Turbine damping coefficient | 0 | NumParam | power | |
Sg | \(S_n\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_n\) | Rated voltage from generator | 0 | kV | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
LAG_y | \(y_{LAG}\) | \(P_{d}\) | State in lag TF | v_str | |
LL_x | \(x'_{LL}\) | \(y_{LAG}\) | State in lead-lag | v_str | |
omega | \(\omega\) | Generator speed | p.u. | ||
paux | \(P_{aux}\) | \(P_{aux0}\) | Auxiliary power input | v_str | |
pout | \(P_{out}\) | \(\tau_{m0} u\) | Turbine final output power | v_str | |
wref | \(\omega_{ref}\) | \(\omega_{ref0}\) | Speed reference variable | v_str | |
pref | \(P_{ref}\) | \(R \tau_{m0}\) | Reference power input | v_str | |
wd | \(\omega_{dev}\) | \(0\) | Generator under speed | p.u. | v_str |
pd | \(P_{d}\) | \(\tau_{m0} u\) | Pref plus under speed times gain | p.u. | v_str |
LL_y | \(y_{LL}\) | \(y_{LAG}\) | Output of lead-lag | v_str | |
tm | \(\tau_m\) | Mechanical power interface to SynGen |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
LAG_y | \(y_{LAG}\) | State | \(P_{d} - y_{LAG}\) | \(T_1\) |
LL_x | \(x'_{LL}\) | State | \(- x'_{LL} + y_{LAG}\) | \(T_3\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
paux | \(P_{aux}\) | Algeb | \(P_{aux0} - P_{aux}\) |
pout | \(P_{out}\) | Algeb | \(D_{t} \omega_{dev} - P_{out} + y_{LL}\) |
wref | \(\omega_{ref}\) | Algeb | \(\omega_{ref0} - \omega_{ref}\) |
pref | \(P_{ref}\) | Algeb | \(- P_{ref} + R \tau_{m0}\) |
wd | \(\omega_{dev}\) | Algeb | \(- \omega - \omega_{dev} + \omega_{ref}\) |
pd | \(P_{d}\) | Algeb | \(G u \left(P_{aux} + P_{ref} + \omega_{dev}\right) - P_{d}\) |
LL_y | \(y_{LL}\) | Algeb | \(LL_{LT1 z1} LL_{LT2 z1} \left(- x'_{LL} + y_{LL}\right) + T_{2} \left(- x'_{LL} + y_{LAG}\right) + T_{3} x'_{LL} - T_{3} y_{LL}\) |
tm | \(\tau_m\) | ExtAlgeb | \(u \left(P_{out} - \tau_{m0}\right)\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
paux0 | \(P_{aux0}\) | \(0\) | ConstService |
gain | \(G\) | \(\frac{u}{R}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
LAG_lim | \(lim_{LAG}\) | AntiWindup | Limiter in Lag |
LL_LT1 | \(LT_{LL}\) | LessThan | |
LL_LT2 | \(LT_{LL}\) | LessThan |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
LAG | \(LAG\) | LagAntiWindup | |
LL | \(LL\) | LeadLag |
IEEEG1¶
Group TurbineGov
IEEE Type 1 Speed-Governing Model.
If only one generator is connected, its idx must be given to syn, and syn2 must be left blank. Each generator must provide data in its Sn base.
syn is connected to the high-pressure output (PHP) and the optional syn2 is connected to the low- pressure output (PLP).
The speed deviation of generator 1 (syn) is measured. If the turbine rating Tn is not specified, the sum of Sn of all connected generators will be used.
Normally, K1 + K2 + ... + K8 = 1.0. If the second generator is not connected, K1 + K3 + K5 + K7 = 1, and K2 + K4 + K6 + K8 = 0.
Parameters
Name | Symbol | Description | Default | Unit | Type | Properties |
---|---|---|---|---|---|---|
idx | unique device idx | DataParam | ||||
u | \(u\) | connection status | 1 | bool | NumParam | |
name | device name | DataParam | ||||
syn | Synchronous generator idx | IdxParam | mandatory,unique | |||
Tn | \(T_n\) | Turbine power rating. Equal to Sn if not provided. | MVA | NumParam | ||
wref0 | \(\omega_{ref0}\) | Base speed reference | 1 | p.u. | NumParam | |
syn2 | Optional SynGen idx | IdxParam | ||||
K | \(K\) | Gain (1/R) in mach. base | 20 | p.u. (power) | NumParam | power |
T1 | \(T_1\) | Gov. lag time const. | 1 | NumParam | ||
T2 | \(T_2\) | Gov. lead time const. | 1 | NumParam | ||
T3 | \(T_3\) | Valve controller time const. | 0.100 | NumParam | ||
UO | \(U_o\) | Max. valve opening rate | 0.100 | p.u./sec | NumParam | |
UC | \(U_c\) | Max. valve closing rate | -0.100 | p.u./sec | NumParam | |
PMAX | \(P_{MAX}\) | Max. turbine power | 5 | NumParam | power | |
PMIN | \(P_{MIN}\) | Min. turbine power | 0 | NumParam | power | |
T4 | \(T_4\) | Inlet piping/steam bowl time constant | 0.400 | NumParam | ||
K1 | \(K_1\) | Fraction of power from HP | 0.500 | NumParam | ||
K2 | \(K_2\) | Fraction of power from LP | 0 | NumParam | ||
T5 | \(T_5\) | Time constant of 2nd boiler pass | 8 | NumParam | ||
K3 | \(K_3\) | Fraction of HP shaft power after 2nd boiler pass | 0.500 | NumParam | ||
K4 | \(K_4\) | Fraction of LP shaft power after 2nd boiler pass | 0 | NumParam | ||
T6 | \(T_6\) | Time constant of 3rd boiler pass | 0.500 | NumParam | ||
K5 | \(K_5\) | Fraction of HP shaft power after 3rd boiler pass | 0 | NumParam | ||
K6 | \(K_6\) | Fraction of LP shaft power after 3rd boiler pass | 0 | NumParam | ||
T7 | \(T_7\) | Time constant of 4th boiler pass | 0.050 | NumParam | ||
K7 | \(K_7\) | Fraction of HP shaft power after 4th boiler pass | 0 | NumParam | ||
K8 | \(K_8\) | Fraction of LP shaft power after 4th boiler pass | 0 | NumParam | ||
Sg | \(S_n\) | Rated power from generator | 0 | MVA | ExtParam | |
Vn | \(V_n\) | Rated voltage from generator | 0 | kV | ExtParam | |
Sg2 | \(S_{n2}\) | Rated power of Syn2 | 0 | MVA | ExtParam |
Variables
Name | Symbol | Initial Value | Description | Unit | Properties |
---|---|---|---|---|---|
LL_x | \(x'_{LL}\) | \(\omega_{dev}\) | State in lead-lag | v_str | |
IAW_y | \(y_{IAW}\) | \(tm_{012}\) | AW Integrator output | v_str | |
L4_y | \(y_{L4}\) | \(y_{IAW}\) | State in lag transfer function | v_str | |
L5_y | \(y_{L5}\) | \(y_{L4}\) | State in lag transfer function | v_str | |
L6_y | \(y_{L6}\) | \(y_{L5}\) | State in lag transfer function | v_str | |
L7_y | \(y_{L7}\) | \(y_{L6}\) | State in lag transfer function | v_str | |
omega | \(\omega\) | Generator speed | p.u. | ||
paux | \(P_{aux}\) | \(P_{aux0}\) | Auxiliary power input | v_str | |
pout | \(P_{out}\) | \(\tau_{m0} u\) | Turbine final output power | v_str | |
wref | \(\omega_{ref}\) | \(\omega_{ref0}\) | Speed reference variable | v_str | |
wd | \(\omega_{dev}\) | \(0\) | Generator under speed | p.u. | v_str |
LL_y | \(y_{LL}\) | \(\omega_{dev}\) | Output of lead-lag | v_str | |
vs | \(V_{s}\) | \(0\) | Valve speed | v_str | |
vsl | \(V_{sl}\) | \(U_{c} z_{l}^{HL} + U_{o} z_{u}^{HL} + V_{s} z_{i}^{HL}\) | Valve move speed after limiter | v_str | |
PHP | \(P_{HP}\) | \(K_{1} y_{L4} + K_{3} y_{L5} + K_{5} y_{L6} + K_{7} y_{L7}\) | HP output | v_str | |
PLP | \(P_{LP}\) | \(K_{2} y_{L4} + K_{4} y_{L5} + K_{6} y_{L6} + K_{8} y_{L7}\) | LP output | v_str | |
tm | \(\tau_m\) | Mechanical power interface to SynGen | |||
tm2 | \(\tau_{m2}\) | Mechanical power to syn2 |
Differential Equations
Name | Symbol | Type | RHS of Equation "T x' = f(x, y)" | T (LHS) |
---|---|---|---|---|
LL_x | \(x'_{LL}\) | State | \(\omega_{dev} - x'_{LL}\) | \(T_1\) |
IAW_y | \(y_{IAW}\) | State | \(V_{sl}\) | \(1\) |
L4_y | \(y_{L4}\) | State | \(y_{IAW} - y_{L4}\) | \(T_4\) |
L5_y | \(y_{L5}\) | State | \(y_{L4} - y_{L5}\) | \(T_5\) |
L6_y | \(y_{L6}\) | State | \(y_{L5} - y_{L6}\) | \(T_6\) |
L7_y | \(y_{L7}\) | State | \(y_{L6} - y_{L7}\) | \(T_7\) |
omega | \(\omega\) | ExtState | \(0\) |
Algebraic Equations
Name | Symbol | Type | RHS of Equation "0 = g(x, y)" |
---|---|---|---|
paux | \(P_{aux}\) | Algeb | \(P_{aux0} - P_{aux}\) |
pout | \(P_{out}\) | Algeb | \(P_{HP} - P_{out}\) |
wref | \(\omega_{ref}\) | Algeb | \(\omega_{ref0} - \omega_{ref}\) |
wd | \(\omega_{dev}\) | Algeb | \(- \omega - \omega_{dev} + \omega_{ref}\) |
LL_y | \(y_{LL}\) | Algeb | \(K T_{1} x'_{LL} + K T_{2} \left(\omega_{dev} - x'_{LL}\right) + LL_{LT1 z1} LL_{LT2 z1} \left(- K x'_{LL} + y_{LL}\right) - T_{1} y_{LL}\) |
vs | \(V_{s}\) | Algeb | \(- V_{s} + \frac{P_{aux} + tm_{012} - y_{IAW} + y_{LL}}{T_{3}}\) |
vsl | \(V_{sl}\) | Algeb | \(U_{c} z_{l}^{HL} + U_{o} z_{u}^{HL} + V_{s} z_{i}^{HL} - V_{sl}\) |
PHP | \(P_{HP}\) | Algeb | \(K_{1} y_{L4} + K_{3} y_{L5} + K_{5} y_{L6} + K_{7} y_{L7} - P_{HP}\) |
PLP | \(P_{LP}\) | Algeb | \(K_{2} y_{L4} + K_{4} y_{L5} + K_{6} y_{L6} + K_{8} y_{L7} - P_{LP}\) |
tm | \(\tau_m\) | ExtAlgeb | \(u \left(P_{out} - \tau_{m0}\right)\) |
tm2 | \(\tau_{m2}\) | ExtAlgeb | \(u z_{syn2} \left(P_{LP} - \tau_{m02}\right)\) |
Services
Name | Symbol | Equation | Type |
---|---|---|---|
paux0 | \(P_{aux0}\) | \(0\) | ConstService |
_sumK18 | \(\sum_{i=1}^8 K_i\) | \(K_{1} + K_{2} + K_{3} + K_{4} + K_{5} + K_{6} + K_{7} + K_{8}\) | ConstService |
_tm0K2 | \(_tm0K2\) | \(\tau_{m0} z_{syn2} \left(K_{2} + K_{4} + K_{6} + K_{8}\right)\) | PostInitService |
_tm02K1 | \(_tm02K1\) | \(\tau_{m02} \left(K_{1} + K_{3} + K_{5} + K_{7}\right)\) | PostInitService |
tm012 | \(tm012\) | \(\tau_{m02} + \tau_{m0}\) | ConstService |
Discrete
Name | Symbol | Type | Info |
---|---|---|---|
LL_LT1 | \(LT_{LL}\) | LessThan | |
LL_LT2 | \(LT_{LL}\) | LessThan | |
HL | \(HL\) | HardLimiter | Limiter on valve acceleration |
IAW_lim | \(lim_{IAW}\) | AntiWindup | Limiter in integrator |
Blocks
Name | Symbol | Type | Info |
---|---|---|---|
LL | \(LL\) | LeadLag | Signal conditioning for wd |
IAW | \(IAW\) | IntegratorAntiWindup | Valve position integrator |
L4 | \(L4\) | Lag | first process |
L5 | \(L5\) | Lag | second (reheat) process |
L6 | \(L6\) | Lag | third process |
L7 | \(L7\) | Lag | fourth (second reheat) process |
Undefined¶
Common Parameters: u, name
Config References¶
System¶
Option | Value | Info | Accepted values |
---|---|---|---|
freq | 60 | base frequency [Hz] | float |
mva | 100 | system base MVA | float |
store_z | 0 | store limiter status in TDS output | (0, 1) |
ipadd | 1 | Use spmatrix.ipadd if available | (0, 1) |
warn_limits | 1 | warn variables initialized at limits | (0, 1) |
warn_abnormal | 1 | warn initialization out of normal values | (0, 1) |
PFlow¶
Option | Value | Info | Accepted values |
---|---|---|---|
sparselib | klu | linear sparse solver name | ('klu', 'umfpack', 'spsolve', 'cupy') |
linsolve | 0 | solve symbolic factorization each step (enable when KLU segfaults) | (0, 1) |
tol | 0.000 | convergence tolerance | float |
max_iter | 25 | max. number of iterations | >=10 |
method | NR | calculation method | ('NR', 'dishonest') |
n_factorize | 4 | first N iterations to factorize Jacobian in dishonest method | >0 |
report | 1 | write output report | (0, 1) |
degree | 0 | use degree in report | (0, 1) |
init_tds | 0 | initialize TDS after PFlow | (0, 1) |
TDS¶
Option | Value | Info | Accepted values |
---|---|---|---|
sparselib | klu | linear sparse solver name | ('klu', 'umfpack', 'spsolve', 'cupy') |
linsolve | 0 | solve symbolic factorization each step (enable when KLU segfaults) | (0, 1) |
tol | 0.000 | convergence tolerance | float |
t0 | 0 | simulation starting time | >=0 |
tf | 20 | simulation ending time | >t0 |
fixt | 1 | use fixed step size (1) or variable (0) | (0, 1) |
shrinkt | 1 | shrink step size for fixed method if not converged | (0, 1) |
tstep | 0.033 | the initial step step size | float |
max_iter | 15 | maximum number of iterations | >=10 |
EIG¶
Option | Value | Info | Accepted values |
---|---|---|---|
sparselib | klu | linear sparse solver name | ('klu', 'umfpack', 'spsolve', 'cupy') |
linsolve | 0 | solve symbolic factorization each step (enable when KLU segfaults) | (0, 1) |
plot | 0 | show plot after computation | (0, 1) |
Miscellaneous¶
Per Unit System¶
The bases for AC system are
- \(S_b^{ac}\): three-phase power in MVA. By default, \(S_b^{ac}=100 MVA\) (in
System.config.mva
). - \(V_b^{ac}\): phase-to-phase voltage in kV.
- \(I_b^{ac}\): current base \(I_b^{ac} = \frac{S_b^{ac}} {\sqrt{3} V_b^{ac}}\)
The bases for DC system are
- \(S_b^{dc}\): power in MVA. It is assumed to be the same as \(S_b^{ac}\).
- \(V_b^{dc}\): voltage in kV.
Profiling Import¶
To speed up the command-line program, import profiling is used to breakdown the program loading time.
With tool profimp
, andes
can be profiled with profimp "import andes" --html > andes_import.htm
. The
report can be viewed in any web browser.
Release Notes¶
The APIs before v3.0.0 are in beta and may change without prior notice.
v1.0.0 (2020-05-25)¶
This release is going to be tagged as v0.9.5 and later tagged as v1.0.0.
- Added verification results using IEEE 14-bus, NPCC, and WECC systems under folder examples.
- Patches GENROU and EXDC2 models.
- Updated test cases for WECC, NPCC IEEE 14-bus.
- Documentation improvements.
- Various tweaks.
v0.9.4 (2020-05-20)¶
- Added exciter models EXST1, ESST3A, ESDC2A, SEXS, and IEEEX1, turbine governor model IEEEG1 (dual-machine support), and stabilizer model ST2CUT.
- Added blocks HVGate and LVGate with a work-around for sympy.maximum/ minimum.
- Added services PostInitService (for storing initialized values), and VarService (variable services that get updated) after limiters and before equations).
- Added service InitChecker for checking initialization values against typical values. Warnings will be issued when out of bound or equality/ inequality conditions are not met.
- Allow internal variables to be associated with a discrete component which will be updated before initialization (through BaseVar.discrete).
- Allow turbine governors to specify an optional Tn (turbine rating). If not provided, turbine rating will fall back to Sn (generator rating).
- Renamed OptionalSelect to DataSelect; Added NumSelect, the array-based version of DataSelect.
- Allow to regenerate code for updated models through
andes prepare -qi
. - Various patches to allow zeroing out time constants in transfer functions.
v0.9.3 (2020-05-05)¶
This version contains bug fixes and performance tweaks.
- Fixed an AntiWindup issue that causes variables to stuck at limits.
- Allow
TDS.run()
to resume from a stopped simulation and run to the new end time inTDS.config.tf
. - Improved TDS data dump speed by not constructing DataFrame by default.
- Added tests for kundur_full.xlsx and kundur_aw.xlsx to ensure results are the same as known values.
- Other bug fixes.
v0.9.1 (2020-05-02)¶
This version accelerates computations by about 35%.
- Models with flag
collate=False
, which is the new default, will slice DAE arrays for all internal vars to reduce copying back and forth. - The change above greatly reduced computation time.
For
kundur_ieeest.xlsx
, simulation time is down from 2.50 sec to 1.64 sec. - The side-effects include a change in variable ordering in output lst file. It also eliminated the feasibility of evaluating model equations in parallel, which has not been implemented and does not seem promising in Python.
- Separated symbolic processor and documentation generator from Model into
SymProcessor
andDocumenter
classes. andes prepare
now shows progress in the console.- Store exit code in
System.exit_code
and returns to system when called from CLI. - Refactored the solver interface.
- Patched Config.check for routines.
- SciPy Newton-Krylov power flow solver is no longer supported.
- Patched a bug in v0.9.0 related to dae.Tf.
v0.8.8 (2020-04-28)¶
This update contains a quick but significant fix to boost the simulation speed by avoiding calls to empty user-defined numerical calls.
- In Model.flags and Block.flags, added f_num, g_num and j_num to indicate if user-defined numerical calls exist.
- In Model.f_update, Model.g_update and Model.j_update, check the above flags to avoid unnecessary calls to empty numeric functions.
- For the kundur_ieeest.xlsx case, simulation time was reduced from 3.5s to 2.7s.
v0.8.7 (2020-04-28)¶
- Changed RefParam to a service type called BackRef.
- Added DeviceFinder, a service type to find device idx when not provided. DeviceFinder will also automatically add devices if not found.
- Added OptionalSelect, a service type to select optional parameters if provided and select fallback ones otherwise.
- Added discrete types Derivative, Delay, and Average,
- Implemented full IEEEST stabilizer.
- Implemented COI for generator speed and angle measurement.
v0.8.6 (2020-04-21)¶
This release contains important documentation fixes and two new blocks.
- Fixed documentations in andes doc to address a misplacement of symbols and equations.
- Converted all blocks to the division-free formulation (with dae.zf renamed to dae.Tf).
- Fixed equation errors in the block documentation.
- Implemented two new blocks: Lag2ndOrd and LeadLag2ndOrd.
- Added a prototype for IEEEST stabilizer with some fixes needed.
v0.8.5 (2020-04-17)¶
- Converted the differential equations to the form of
T \dot{x} = f(x, y)
, where T is supplied tot_const
ofState/ExtState
. - Added the support for Config fields in documentation (in
andes doc
and on readthedocs). - Added Config consistency checking.
- Converted Model.idx from a list to DataParam.
- Renamed the API of routines (summary, init, run, report).
- Automatically generated indices now start at 1 (i.e., "GENCLS_1" is the first GENCLS device).
- Added test cases for WECC system. The model with classical generators is verified against TSAT.
- Minor features: andes -v 1 for debug output with levels and line numbers.
v0.8.4 (2020-04-07)¶
- Added support for JSON case files. Convert existing case file to JSON with
--convert json
. - Added support for PSS/E dyr files, loadable with
-addfile ADDFILE
. - Added
andes plot --xargs
for searching variable name and plotting. See example 6. - Various bug fixes: Fault power injection fix;
v0.8.3 (2020-03-25)¶
- Improved storage for Jacobian triplets (see
andes.core.triplet.JacTriplet
). - On-the-fly parameter alteration for power flow calculations (
Model.alter
method). - Exported frequently used functions to the root package
(
andes.config_logger
,andes.run
,andes.prepare
andandes.load
). - Return a list of System objects when multiprocessing in an interactive environment.
- Exported classes to andes.core.
- Various bug fixes and documentation improvements.
v0.8.0 (2020-02-12)¶
- First release of the hybrid symbolic-numeric framework in ANDES.
- A new framework is used to describe DAE models, generate equation documentation, and generate code for numerical simulation.
- Models are written in the new framework. Supported models include GENCLS, GENROU, EXDC2, TGOV1, TG2
- PSS/E raw parser, MATPOWER parser, and ANDES xlsx parser.
- Newton-Raphson power flow, trapezoidal rule for numerical integration, and full eigenvalue analysis.
v0.6.9 (2020-02-12)¶
- Version 0.6.9 is the last version for the numeric-only modeling framework.
- This version will not be updated any more. But, models, routines and functions will be ported to the new version.
License¶
GNU Public License v3¶
ANDES is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
ANDES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Subpackages¶
andes.core package¶
Submodules¶
andes.core.block module¶
-
class
andes.core.block.
Block
(name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None)[source]¶ Bases:
object
Base class for control blocks.
Blocks are meant to be instantiated as Model attributes to provide pre-defined equation sets. Subclasses must overload the __init__ method to take custom inputs. Subclasses of Block must overload the define method to provide initialization and equation strings. Exported variables, services and blocks must be constructed into a dictionary
self.vars
at the end of the constructor.Blocks can be nested. A block can have blocks but itself as attributes and therefore reuse equations. When a block has sub-blocks, the outer block must be constructed with a``name``.
Nested block works in the following way: the parent block modifies the sub-block's
name
attribute by prepending the parent block's name at the construction phase. The parent block then exports the sub-block as a whole. When the parent Model class picks up the block, it will recursively import the variables in the block and the sub-blocks correctly. See the example section for details.Parameters: - name : str, optional
Block name
- tex_name : str, optional
Block LaTeX name
- info : str, optional
Block description.
Warning
It is a good practice to avoid more than one level of nesting, to avoid multi-underscore variable names.
Examples
Example for two-level nested blocks. Suppose we have the following hierarchy
SomeModel instance M | LeadLag A exports (x, y) | Lag B exports (x, y)
SomeModel instance M contains an instance of LeadLag block named A, which contains an instance of a Lag block named B. Both A and B exports two variables
x
andy
.In the code of Model, the following code is used to instantiate LeadLag
class SomeModel: def __init__(...) ... self.A = LeadLag(name='A', u=self.foo1, T1=self.foo2, T2=self.foo3)
To use Lag in the LeadLag code, the following lines are found in the constructor of LeadLag
class LeadLag: def __init__(name, ...) ... self.B = Lag(u=self.y, K=self.K, T=self.T) self.vars = {..., 'A': self.A}
The
__setattr__
magic of LeadLag takes over the construction and assignsA_B
to B.name, given A's name provided at run time. self.A is exported with the internal nameA
at the end.Again, the LeadLag instance name (A in this example) MUST be provided in SomeModel's constructor for the name prepending to work correctly. If there is more than one level of nesting, other than the leaf-level block, all parent blocks' names must be provided at instantiation.
When A is picked up by SomeModel.__setattr__, B is captured from A's exports. Recursively, B's variables are exported, Recall that B.name is now
A_B
, following the naming rule (parent block's name + variable name), B's internal variables becomeA_B_x
andA_B_y
.In this way, B's
define()
needs no modification since the naming rule is the same. For example, B's internal y is always{self.name}_y
, although B has gotten a new nameA_B
.-
class_name
¶ Return the class name.
-
define
(self)[source]¶ Function for setting the initialization and equation strings for internal variables. This method must be implemented by subclasses.
The equations should be written with the "final" variable names. Let's say the block instance is named blk (kept at
self.name
of the block), and an internal variable v is defined. The internal variable will be captured asblk_v
by the parent model. Therefore, all equations should use{self.name}_v
to represent variablev
, where{self.name}
is the name of the block at run time.On the other hand, the names of externally provided parameters or variables are obtained by directly accessing the
name
attribute. For example, ifself.T
is a parameter provided through the block constructor,{self.T.name}
should be used in the equation.See also
PIController.define
- Equations for the PI Controller block
Examples
An internal variable
v
has a trivial equationT = v
, where T is a parameter provided to the block constructor.In the model, one has
class SomeModel(): def __init__(...) self.input = Algeb() self.T = Param() self.blk = ExampleBlock(u=self.input, T=self.T)
In the ExampleBlock function, the internal variable is defined in the constructor as
class ExampleBlock(): def __init__(...): self.v = Algeb() self.vars = {'v', self.v}
In the
define
, the equation is provided asdef define(self): self.v.v_str = '{self.T.name}' self.v.e_str = '{self.T.name} - {self.name}_v'
In the parent model,
v
from the block will be captured asblk_v
, and the equation will evaluate intoself.blk_v.v_str = 'T' self.blk_v.e_str = 'T - blk_v'
-
export
(self)[source]¶ Method for exporting instances defined in this class in a dictionary. This method calls the
define
method first and returnsself.vars
.Returns: - dict
Keys are the (last section of the) variable name, and the values are the attribute instance.
-
f_numeric
(self, **kwargs)[source]¶ Function call to update differential equation values.
This function should modify the
e
value of blockState
andExtState
in place.
-
g_numeric
(self, **kwargs)[source]¶ Function call to update algebraic equation values.
This function should modify the
e
value of blockAlgeb
andExtAlgeb
in place.
-
j_numeric
(self)[source]¶ This function stores the constant and variable jacobian information in corresponding lists.
Constant jacobians are stored by indices and values in, for example, ifxc, jfxc and vfxc. Value scalars or arrays are stored in vfxc.
Variable jacobians are stored by indices and functions. The function shall return the value of the corresponding jacobian elements.
-
class
andes.core.block.
Gain
(u, K, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Gain block.
┌───┐ u -> │ K │ -> y └───┘
Exports an algebraic output y.
-
class
andes.core.block.
GainLimiter
(u, K, upper, lower, no_upper=False, no_lower=False, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Gain followed by a limiter.
Exports the limited output y, unlimited output x, and HardLimiter lim.
┌─────┐ upper │ │ /¯¯¯¯¯ u -> │ K │ -> x / -> y │ │ _____/ └─────┘ lower
Parameters: - u : str, BaseVar
Input variable, or an equation string for constructing an anonymous variable
-
class
andes.core.block.
HVGate
(u1, u2, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
High Value Gate. Outputs the maximum of two inputs.
┌─────────┐ u1 -> │ HV Gate │ │ │ -> y u2 -> │ (MAX) │ └─────────┘
-
define
(self)[source]¶ Implemented equations and initial conditions
\[0 = s_0^{sl} u_1 + s_1^{sl} u_2 - y y_0 = maximum(u_1, u_2)\]Notes
In the implementation, one should not use
self.y.v_str = f'maximum({self.u1.name}, {self.u2.name})',
because SymPy processes this equation to {self.u1.name}. Not sure if this is a bug or intended.
-
-
class
andes.core.block.
Integrator
(u, T, K, y0, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Integrator block.
┌──────┐ u -> │ K/sT │ -> y └──────┘
Exports a differential variable y. The initial output is specified by y0 and default to zero.
-
class
andes.core.block.
IntegratorAntiWindup
(u, T, K, y0, lower, upper, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Integrator block with anti-windup limiter.
upper /¯¯¯¯¯ ┌──────┐ u -> │ K/sT │ -> y └──────┘ _____/ lower
Exports a differential variable y and an AntiWindup lim. The initial output must be specified through y0.
-
class
andes.core.block.
LVGate
(u1, u2, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Low Value Gate. Outputs the minimum of the two inputs.
┌─────────┐ u1 -> │ LV Gate | │ | -> y u2 -> │ (MIN) | └─────────┘
-
class
andes.core.block.
Lag
(u, T, K, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Lag (low pass filter) transfer function.
┌────────┐ │ K │ u -> │ ────── │ -> y │ 1 + sT │ └────────┘
Exports one state variable y as the output.
Parameters: - K
Gain
- T
Time constant
- u
Input variable
-
class
andes.core.block.
Lag2ndOrd
(u, K, T1, T2, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Second order lag transfer function (low-pass filter)
┌──────────────────┐ │ K │ u -> │ ──────────────── │ -> y │ 1 + sT1 + s^2 T2 │ └──────────────────┘
Exports one two state variables (x, y), where y is the output.
Parameters: - u
Input
- K
Gain
- T1
First order time constant
- T2
Second order time constant
-
class
andes.core.block.
LagAntiWindup
(u, T, K, lower, upper, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Lag (low pass filter) transfer function block with an anti-windup limiter.
upper /¯¯¯¯¯¯ ┌────────┐ │ K │ u -> │ ────── │ -> y │ 1 + sT │ └────────┘ ______/ lower
Exports one state variable y as the output and one AntiWindup instance lim.
Parameters: - K
Gain
- T
Time constant
- u
Input variable
-
class
andes.core.block.
LeadLag
(u, T1, T2, K=1, zero_out=True, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Lead-Lag transfer function block in series implementation
┌───────────┐ │ 1 + sT1 │ u -> │ K ─────── │ -> y │ 1 + sT2 │ └───────────┘
Exports two variables: internal state x and output algebraic variable y.
Parameters: - T1 : BaseParam
Time constant 1
- T2 : BaseParam
Time constant 2
- zero_out : bool
True to allow zeroing out lead-lag as a pass through (when T1=T2=0)
Notes
To allow zeroing out lead-lag as a pure gain, set
zero_out
to True.-
define
(self)[source]¶ Notes
Implemented equations and initial values
\[\begin{split}T_2 \dot{x'} &= (u - x') \\ T_2 y &= K T_1 (u - x') + K T_2 x' + E_2 \, , \text{where} \\ E_2 = & \left\{\begin{matrix} (y - K x') &\text{ if } T_1 = T_2 = 0 \& zero\_out=True \\ 0& \text{ otherwise } \end{matrix}\right. \\ x'^{(0)} & = u\\ y^{(0)} & = Ku\\\end{split}\]
-
class
andes.core.block.
LeadLag2ndOrd
(u, T1, T2, T3, T4, zero_out=False, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Second-order lead-lag transfer function block
┌──────────────────┐ │ 1 + sT3 + s^2 T4 │ u -> │ ──────────────── │ -> y │ 1 + sT1 + s^2 T2 │ └──────────────────┘
Exports two internal states (x1 and x2) and output algebraic variable y.
# TODO: instead of implementing zero_out using LessThan and an additional term, consider correcting all parameters to 1 if all are 0.
-
define
(self)[source]¶ Notes
Implemented equations and initial values are
\[\begin{split}T_2 \dot{x}_1 &= u - x_2 - T_1 x_1 \\ \dot{x}_2 &= x_1 \\ T_2 y &= T_2 x_2 + T_2 T_3 x_1 + T_4 (u - x_2 - T_1 x_1) + E_2 \, , \text{ where} \\ E_2 = & \left\{\begin{matrix} (y - x_2) &\text{ if } T_1 = T_2 = T_3 = T_4 = 0 \& zero\_out=True \\ 0& \text{ otherwise } \end{matrix}\right. \\ x_1^{(0)} &= 0 \\ x_2^{(0)} &= y^{(0)} = u\end{split}\]
-
-
class
andes.core.block.
LeadLagLimit
(u, T1, T2, lower, upper, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Lead-Lag transfer function block with hard limiter (series implementation)
┌─────────┐ upper │ 1 + sT1 │ /¯¯¯¯¯ u -> │ ─────── │ -> ynl / -> y │ 1 + sT2 │ _____/ └─────────┘ lower
Exports four variables: state x, output before hard limiter ynl, output y, and AntiWindup lim.
-
class
andes.core.block.
PIController
(u, ref, kp, ki, name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Proportional Integral Controller with the reference from an external variable
Parameters: - u : BaseVar
The input variable instance
- ref : Union[BaseVar, BaseParam]
The reference instance
- kp : BaseParam
The proportional gain parameter instance
- ki : [type]
The integral gain parameter instance
-
class
andes.core.block.
PIControllerNumeric
(u, ref, kp, ki, name=None, info=None)[source]¶ Bases:
andes.core.block.Block
A PI Controller implemented with numerical function calls
-
f_numeric
(self, **kwargs)[source]¶ Function call to update differential equation values.
This function should modify the
e
value of blockState
andExtState
in place.
-
g_numeric
(self, **kwargs)[source]¶ Function call to update algebraic equation values.
This function should modify the
e
value of blockAlgeb
andExtAlgeb
in place.
-
j_numeric
(self)[source]¶ This function stores the constant and variable jacobian information in corresponding lists.
Constant jacobians are stored by indices and values in, for example, ifxc, jfxc and vfxc. Value scalars or arrays are stored in vfxc.
Variable jacobians are stored by indices and functions. The function shall return the value of the corresponding jacobian elements.
-
-
class
andes.core.block.
Piecewise
(u, points: Union[List[T], Tuple], funs: Union[List[T], Tuple], name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Piecewise block. Outputs an algebraic variable y.
This block takes a list of N points, [x0, x1, ...x_{n-1}] to define N+1 ranges, namely (-inf, x0), (x0, x1), ..., (x_{n-1}, +inf). and a list of N+1 functions [fun0, ..., fun_n].
Inputs that fall within each range applies the corresponding function. The first range (-inf, x0) applies fun_0, and the last range (x_{n-1}, +inf) applies the last function fun_n.
Parameters: - points : list, tuple
A list of piecewise points. Need to be provided in the constructor function.
- funs : list, tuple
A list of strings for the piecewise functions. Need to be provided in the overloaded define function.
-
class
andes.core.block.
Washout
(u, T, K, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Block
Washout filter (high pass) block.
┌────────┐ │ sK │ u -> │ ────── │ -> y │ 1 + sT │ └────────┘
Exports state x (symbol x') and output algebraic variable y.
-
class
andes.core.block.
WashoutOrLag
(u, T, K, name=None, zero_out=True, tex_name=None, info=None)[source]¶ Bases:
andes.core.block.Washout
Washout with the capability to convert to Lag when K = 0.
Can be enabled with zero_out. Need to provide name to construct.
Exports state x (symbol x'), output algebraic variable y, and a LessThan block LT.
Parameters: - zero_out : bool, optional
If True,
sT
will become 1, and the washout will become a low-pass filter. If False, functions as a regular Washout.
andes.core.discrete module¶
-
class
andes.core.discrete.
AntiWindup
(u, lower, upper, enable=True, name=None, tex_name=None, info=None, state=None)[source]¶ Bases:
andes.core.discrete.Limiter
Anti-windup limiter.
Anti-windup limiter prevents the wind-up effect of a differential variable. The derivative of the differential variable is reset if it continues to increase in the same direction after exceeding the limits. During the derivative return, the limiter will be inactive
if x > xmax and x dot > 0: x = xmax and x dot = 0 if x < xmin and x dot < 0: x = xmin and x dot = 0
This class takes one more optional parameter for specifying the equation.
Parameters: - state : State, ExtState
A State (or ExtState) whose equation value will be checked and, when condition satisfies, will be reset by the anti-windup-limiter.
-
class
andes.core.discrete.
Average
(u, mode='step', delay=0, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.discrete.Delay
Compute the average of a BaseVar over a period of time or a number of samples.
-
class
andes.core.discrete.
DeadBand
(u, center, lower, upper, enable=True)[source]¶ Bases:
andes.core.discrete.Limiter
Dead band with the direction of return.
Parameters: - u : NumParam
The pre-deadband input variable
- center : NumParam
Neutral value of the output
- lower : NumParam
Lower bound
- upper : NumParam
Upper bpund
- enable : bool
Enabled if True; Disabled and works as a pass-through if False.
Notes
Input changes within a deadband will incur no output changes. This component computes and exports five flags.
- Three flags computed from the current input:
- zl: True if the input is below the lower threshold
- zi: True if the input is within the deadband
- zu: True if is above the lower threshold
- Two flags indicating the direction of return:
- zur: True if the input is/has been within the deadband and was returned from the upper threshold
- zlr: True if the input is/has been within the deadband and was returned from the lower threshold
Initial condition:
All five flags are initialized to zero. All flags are updated during check_var when enabled. If the deadband component is not enabled, all of them will remain zero.
Examples
Exported deadband flags need to be used in the algebraic equation corresponding to the post-deadband variable. Assume the pre-deadband input variable is var_in and the post-deadband variable is var_out. First, define a deadband instance db in the model using
self.db = DeadBand(u=self.var_in, center=self.dbc, lower=self.dbl, upper=self.dbu)
To implement a no-memory deadband whose output returns to center when the input is within the band, the equation for var can be written as
var_out.e_str = 'var_in * (1 - db_zi) + \ (dbc * db_zi) - var_out'
To implement a deadband whose output is pegged at the nearest deadband bounds, the equation for var can be provided as
var_out.e_str = 'var_in * (1 - db_zi) + \ dbl * db_zlr + \ dbu * db_zur - var_out'
-
check_var
(self, *args, **kwargs)[source]¶ Notes
Updates five flags: zi, zu, zl; zur, and zlr based on the following rules:
- zu:
- 1 if u > upper; 0 otherwise.
- zl:
- 1 if u < lower; 0 otherwise.
- zi:
- not(zu or zl);
- zur:
- set to 1 when (previous zu + present zi == 2)
- hold when (previous zi == zi)
- clear otherwise
- zlr:
- set to 1 when (previous zl + present zi == 2)
- hold when (previous zi == zi)
- clear otherwise
-
class
andes.core.discrete.
Delay
(u, mode='step', delay=0, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.discrete.Discrete
Delay class to memorize past variable values.
TODO: Add documentation.
-
class
andes.core.discrete.
Derivative
(u, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.discrete.Delay
Compute the derivative of an algebraic variable using numerical differentiation.
-
class
andes.core.discrete.
Discrete
(name=None, tex_name=None, info=None)[source]¶ Bases:
object
Base discrete class.
Discrete classes export flag arrays (usually boolean) .
-
check_eq
(self)[source]¶ This function is called in
l_check_eq
after updating equations.It should update internal flags only.
-
check_var
(self, *args, **kwargs)[source]¶ This function is called in
l_update_var
before evaluating equations.It should update internal flags only.
-
class_name
¶
-
get_tex_names
(self)[source]¶ Return tex_names of exported flags.
TODO: Fix the bug described in the warning below.
Returns: - list
A list of tex_names for all exported flags.
Warning
If underscore _ appears in both flag tex_name and self.tex_name (for example, when this discrete is within a block), the exported tex_name will become invalid for SymPy. Variable name substitution will fail.
-
-
class
andes.core.discrete.
HardLimiter
(u, lower, upper, enable=True, name=None, tex_name=None, info=None, no_upper=False, no_lower=False)[source]¶ Bases:
andes.core.discrete.Limiter
Hard limiter for algebraic or differential variable. This class is an alias of Limiter.
-
class
andes.core.discrete.
LessThan
(u, bound, equal=False, enable=True, name=None, tex_name=None, cache=False, z0=0, z1=1)[source]¶ Bases:
andes.core.discrete.Discrete
Less than (<) comparison function.
Exports two flags: z1 and z0. For elements satisfying the less-than condition, the corresponding z1 = 1. z0 is the element-wise negation of z1.
Notes
The default z0 and z1, if not enabled, can be set through the constructor.
-
class
andes.core.discrete.
Limiter
(u, lower, upper, enable=True, name=None, tex_name=None, info=None, no_upper=False, no_lower=False)[source]¶ Bases:
andes.core.discrete.Discrete
Base limiter class.
This class compares values and sets limit values. Exported flags are zi, zl and zu.
Parameters: - u : BaseVar
Input Variable instance
- lower : BaseParam
Parameter instance for the lower limit
- upper : BaseParam
Parameter instance for the upper limit
- no_lower : bool
True to only use the upper limit
- no_upper : bool
True to only use the lower limit
Notes
If not enabled, the default flags are
zu = zl = 0
,zi = 1
.Attributes: - zl : array-like
Flags of elements violating the lower limit; A array of zeros and/or ones.
- zi : array-like
Flags for within the limits
- zu : array-like
Flags for violating the upper limit
-
class
andes.core.discrete.
Selector
(*args, fun, tex_name=None, info=None)[source]¶ Bases:
andes.core.discrete.Discrete
Selection between two variables using the provided reduce function.
The reduce function should take the given number of arguments. An example function is np.maximum.reduce which can be used to select the maximum.
Names are in s0, s1.
Warning
A potential bug when more than two inputs are provided, and values in different inputs are equal. Only two inputs are allowed.
See also
numpy.ufunc.reduce
- NumPy reduce function
andes.core.block.HVGate
andes.core.block.LVGate
Notes
A common pitfall is the 0-based indexing in the Selector flags. Note that exported flags start from 0. Namely, s0 corresponds to the first variable provided for the Selector constructor.
Examples
Example 1: select the largest value between v0 and v1 and put it into vmax.
After the definitions of v0 and v1, define the algebraic variable vmax for the largest value, and a selector vs
self.vmax = Algeb(v_str='maximum(v0, v1)', tex_name='v_{max}', e_str='vs_s0 * v0 + vs_s1 * v1 - vmax') self.vs = Selector(self.v0, self.v1, fun=np.maximum.reduce)
The initial value of vmax is calculated by
maximum(v0, v1)
, which is the element-wise maximum in SymPy and will be generated intonp.maximum(v0, v1)
. The equation of vmax is to select the values based on vs_s0 and vs_s1.
-
class
andes.core.discrete.
SortedLimiter
(u, lower, upper, enable=True, n_select: Optional[int] = None, name=None, tex_name=None)[source]¶ Bases:
andes.core.discrete.Limiter
A comparer with the top value selection.
-
class
andes.core.discrete.
Switcher
(u, options: Union[list, Tuple], name: str = None, tex_name: str = None, cache=True)[source]¶ Bases:
andes.core.discrete.Discrete
Switcher based on an input parameter.
The switch class takes one v-provider, compares the input with each value in the option list, and exports one flag array for each option. The flags are 0-indexed.
Exported flags are named with _s0, _s1, ..., with a total number of len(options). See the examples section.
Notes
Switches needs to be distinguished from Selector.
Switcher is for generating flags indicating option selection based on an input parameter. Selector is for generating flags at run time based on variable values and a selection function.
Examples
The IEEEST model takes an input for selecting the signal. Options are 1 through 6. One can construct
self.IC = NumParam(info='input code 1-6') # input code self.SW = Switcher(u=self.IC, options=[1, 2, 3, 4, 5, 6])
If the IC values from the data file ends up being
self.IC.v = np.array([1, 2, 2, 4, 6])
Then, the exported flag arrays will be
{'IC_s0': np.array([1, 0, 0, 0, 0]), 'IC_s1': np.array([0, 1, 1, 0, 0]), 'IC_s2': np.array([0, 0, 0, 0, 0]), 'IC_s3': np.array([0, 0, 0, 1, 0]), 'IC_s4': np.array([0, 0, 0, 0, 0]), 'IC_s5': np.array([0, 0, 0, 0, 1]) }
andes.core.model module¶
Base class for building ANDES models.
-
class
andes.core.model.
Cache
[source]¶ Bases:
object
Class for caching the return value of callback functions.
-
class
andes.core.model.
Documenter
(parent)[source]¶ Bases:
object
Helper class for documenting models.
Parameters: - parent : Model
The Model instance to document
-
get
(self, max_width=78, export='plain')[source]¶ Return the model documentation in table-formatted string.
Parameters: - max_width : int
Maximum table width. Automatically et to 0 if format is
rest
.- export : str, ('plain', 'rest')
Export format. Use fancy table if is
rest
.
Returns: - str
A string with the documentations.
-
class
andes.core.model.
Model
(system=None, config=None)[source]¶ Bases:
object
Base class for power system DAE models.
After subclassing ModelData, subclass Model` to complete a DAE model. Subclasses of Model defines DAE variables, services, and other types of parameters, in the constructor
__init__
.Examples
Take the static PQ as an example, the subclass of Model, PQ, should looks like
class PQ(PQData, Model): def __init__(self, system, config): PQData.__init__(self) Model.__init__(self, system, config)
Since PQ is calling the base class constructors, it is meant to be the final class and not further derived. It inherits from PQData and Model and must call constructors in the order of PQData and Model. If the derived class of Model needs to be further derived, it should only derive from Model and use a name ending with Base. See
andes.models.synchronous.GENBASE
.Next, in PQ.__init__, set proper flags to indicate the routines in which the model will be used
self.flags.update({'pflow': True})
Currently, flags pflow and tds are supported. Both are False by default, meaning the model is neither used in power flow nor time-domain simulation. A very common pitfall is forgetting to set the flag.
Next, the group name can be provided. A group is a collection of models with common parameters and variables. Devices idx of all models in the same group must be unique. To provide a group name, use
self.group = 'StaticLoad'
The group name must be an existing class name in
andes.models.group
. The model will be added to the specified group and subject to the variable and parameter policy of the group. If not provided with a group class name, the model will be placed in the Undefined group.Next, additional configuration flags can be added. Configuration flags for models are load-time variables specifying the behavior of a model. It can be exported to an andes.rc file and automatically loaded when creating the System. Configuration flags can be used in equation strings, as long as they are numerical values. To add config flags, use
self.config.add(OrderedDict((('pq2z', 1), )))
It is recommended to use OrderedDict instead of dict, although the syntax is verbose. Note that booleans should be provided as integers (1, or 0), since True or False is interpreted as a string when loaded from the rc file and will cause an error.
Next, it's time for variables and equations! The PQ class does not have internal variables itself. It uses its bus parameter to fetch the corresponding a and v variables of buses. Equation wise, it imposes an active power and a reactive power load equation.
To define external variables from Bus, use
self.a = ExtAlgeb(model='Bus', src='a', indexer=self.bus, tex_name=r'\theta') self.v = ExtAlgeb(model='Bus', src='v', indexer=self.bus, tex_name=r'V')
Refer to the subsection Variables for more details.
The simplest PQ model will impose constant P and Q, coded as
self.a.e_str = "u * p" self.v.e_str = "u * q"
where the e_str attribute is the equation string attribute. u is the connectivity status. Any parameter, config, service or variables can be used in equation strings. An addition variable dae_t for the current simulation time can be used if the model has flag tds.
The above example is overly simplified. Our PQ model wants a feature to switch itself to a constant impedance if the voltage is out of the range (vmin, vmax). To implement this, we need to introduce a discrete component called Limiter, which yields three arrays of binary flags, zi, zl, and zu indicating in range, below lower limit, and above upper limit, respectively.
First, create an attribute vcmp as a Limiter instance
self.vcmp = Limiter(u=self.v, lower=self.vmin, upper=self.vmax, enable=self.config.pq2z)
where self.config.pq2z is a flag to turn this feature on or off. After this line, we can use vcmp_zi, vcmp_zl, and vcmp_zu in other equation strings.
self.a.e_str = "u * (p0 * vcmp_zi + " \ "p0 * vcmp_zl * (v ** 2 / vmin ** 2) + " \ "p0 * vcmp_zu * (v ** 2 / vmax ** 2))" self.v.e_str = "u * (q0 * vcmp_zi + " \ "q0 * vcmp_zl * (v ** 2 / vmin ** 2) + "\ "q0 * vcmp_zu * (v ** 2 / vmax ** 2))"
Note that PQ.a.e_str can use the three variables from vcmp even before defining PQ.vcmp, as long as PQ.vcmp is defined, because vcmp_zi is just a string literal in e_str.
The two equations above implements a piecewise power injection equation. It selects the original power demand if within range, and uses the calculated power when out of range.
Finally, to let ANDES pick up the model, the model name needs to be added to models/__init__.py. Follow the examples in the OrderedDict, where the key is the file name, and the value is the class name.
Attributes: - num_params : OrderedDict
{name: instance} of numerical parameters, including internal and external ones
-
alter
(self, src, idx, value)[source]¶ Alter input parameter value.
This function converts the new parameter to per unit.
-
class_name
¶ Return the class name
-
f_update
(self)[source]¶ Evaluate differential equations.
Notes
In-place equations: added to the corresponding DAE array. Non-inplace equations: in-place set to internal array to overwrite old values (and avoid clearing).
-
get
(self, src: str, idx, attr: str = 'v', allow_none=False, default=0.0)[source]¶ Get the value of an attribute of a model property.
The return value is
self.<src>.<attr>[idx]
Parameters: - src : str
Name of the model property
- idx : str, int, float, array-like
Indices of the devices
- attr : str, optional, default='v'
The attribute of the property to get.
v
for values,a
for address, ande
for equation value.- allow_none : bool
True to allow None values in the indexer
- default : float
If allow_none is true, the default value to use for None indexer.
Returns: - array-like
self.<src>.<attr>[idx]
-
get_inputs
(self, refresh=False)[source]¶ Get an OrderedDict of the inputs to the numerical function calls.
Parameters: - refresh : bool
Refresh the values in the dictionary. This is only used when the memory address of arrays changed. After initialization, all array assignments are inplace. To avoid overhead, refresh should not be used after initialization.
Returns: - OrderedDict
The input name and value array pairs in an OrderedDict
Notes
dae.t is now a numpy.ndarray which has stable memory. There is no need to refresh dat_t in this version.
-
get_times
(self)[source]¶ Get event switch_times from TimerParam.
Returns: - list
A list containing all switching times defined in TimerParams
-
idx2uid
(self, idx)[source]¶ Convert idx to the 0-indexed unique index.
Parameters: - idx : array-like, numbers, or str
idx of devices
Returns: - list
A list containing the unique indices of the devices
-
init
(self)[source]¶ Numerical initialization of a model.
Initialization sequence: 1. Sequential initialization based on the order of definition 2. Use Newton-Krylov method for iterative initialization 3. Custom init
-
j_numeric
(self, **kwargs)[source]¶ Custom numeric update functions.
This function should append indices to _ifx, _jfx, and append anonymous functions to _vfx. It is only called once by store_sparse_pattern.
-
j_update
(self)[source]¶ Update Jacobians and store the Jacobian values to
self.v<JName>
, where<JName>
is the Jacobian name.Returns: - None
-
l_check_eq
(self)[source]¶ Call the
check_eq
method of discrete components to update equation-dependent flags.This function should be called after equation updates.
Returns: - None
-
l_set_eq
(self)[source]¶ Call the
set_eq
method of discrete components.This function is only used by AntiWindup to append the pegged states to the
x_set
list.Returns: - None
-
l_update_var
(self, dae_t)[source]¶ Call the
check_var
method of discrete components to update the internal status flags.The function is variable-dependent and should be called before updating equations.
Returns: - None
-
list2array
(self)[source]¶ Convert all the value attributes
v
to NumPy arrays.Value attribute arrays should remain in the same address afterwards. Namely, all assignments to value array should be operated in place (e.g., with [:]).
-
refresh_inputs
(self)[source]¶ This is the helper function to refresh inputs.
The functions collects objects into OrderedDict and store to self._input and self._input_z.
Returns: - None
-
s_numeric_var
(self, **kwargs)[source]¶ Custom variable service value functions. Modify
VarService.v
directly.This custom numerical function is evaluated at each step/iteration before equation update.
-
s_update
(self)[source]¶ Update service equation values.
This function is only evaluated at initialization. Service values are updated sequentially. The
v
attribute of services will be assigned at a new memory.
-
set
(self, src, idx, attr, value)[source]¶ Set the value of an attribute of a model property.
Performs
self.<src>.<attr>[idx] = value
Parameters: - src : str
Name of the model property
- idx : str, int, float, array-like
Indices of the devices
- attr : str, optional, default='v'
The attribute of the property to get.
v
for values,a
for address, ande
for equation value.- value : array-like
Values to be set
Returns: - None
-
set_in_use
(self)[source]¶ Set the in_use attribute. Called at the end of
System.collect_ref
.This function is overloaded by models with BackRef to disable calls when no model is referencing. Models with no back references will have internal variable addresses assigned but external addresses being empty.
For internal equations that has external variables, the row indices will be non-zeros, while the col indices will be empty, which causes an error when updating Jacobians.
Setting self.in_use to False when len(back_ref_instance.v) == 0 avoids this error. See COI.
-
store_sparse_pattern
(self)[source]¶ Store rows and columns of the non-zeros in the Jacobians for building the sparsity pattern.
This function converts the internal 0-indexed equation/variable address to the numerical addresses for the loaded system.
Calling sequence: For each Jacobian name, fx, fy, gx and gy, store by a) generated constant and variable Jacobians c) user-provided constant and variable Jacobians, d) user-provided block constant and variable Jacobians
Notes
If self.n == 0, skipping this function will avoid appending empty lists/arrays and non-empty values, which, as a combination, is not accepted by cvxopt.spmatrix.
-
class
andes.core.model.
ModelCall
[source]¶ Bases:
object
Class for storing generated function calls and Jacobians.
-
class
andes.core.model.
ModelData
(*args, **kwargs)[source]¶ Bases:
object
Class for holding parameter data for a model.
This class is designed to hold the parameter data separately from model equations. Models should inherit this class to define the parameters from input files.
Inherit this class to create the specific class for holding input parameters for a new model. The recommended name for the derived class is the model name with
Data
. For example, data for GENCLS should be named GENCLSData.Parameters should be defined in the
__init__
function of the derived class.Refer to
andes.core.param
for available parameter types.Notes
Two default parameters, u (connection status of type
andes.core.param.NumParam
), andname
(device name of typeandes.core.param.DataParam
) are pre-defined inModelData
, and will be inherited by all models.Examples
If we want to build a class
PQData
(for static PQ load) with three parameters, Vn, p0 and q0, we can use the followingfrom andes.core.model import ModelData, Model from andes.core.param import IdxParam, NumParam class PQData(ModelData): super().__init__() self.Vn = NumParam(default=110, info="AC voltage rating", unit='kV', non_zero=True, tex_name=r'V_n') self.p0 = NumParam(default=0, info='active power load in system base', tex_name=r'p_0', unit='p.u.') self.q0 = NumParam(default=0, info='reactive power load in system base', tex_name=r'q_0', unit='p.u.')
In this example, all the three parameters are defined as
andes.core.param.NumParam
. In the full PQData class, other types of parameters also exist. For example, to store the idx of owner, PQData usesself.owner = IdxParam(model='Owner', info="owner idx")
Attributes: - cache
A cache instance for different views of the internal data.
- flags : dict
Flags to control the routine and functions that get called. If the model is using user-defined numerical calls, set f_num, g_num and j_num properly.
-
add
(self, **kwargs)[source]¶ Add a device (an instance) to this model.
Parameters: - kwargs
model parameters are collected into the kwargs dictionary
Warning
This function is not intended to be used directly. Use the
add
method from System so that the index can be registered correctly.
-
as_df
(self)[source]¶ Export all parameters as a pandas.DataFrame object. This function utilizes as_dict for preparing data.
Returns: - DataFrame
A dataframe containing all model data. An uid column is added.
-
as_df_in
(self)[source]¶ Export all parameters from original input (
vin
) as a pandas.DataFrame. This function utilizes as_dict for preparing data.Returns: - DataFrame
A
pandas.DataFrame
containing all model data. An uid column is prepended.
-
as_dict
(self, vin=False)[source]¶ Export all parameters as a dict.
Returns: - dict
a dict with the keys being the ModelData parameter names and the values being an array-like of data in the order of adding. An additional uid key is added with the value default to range(n).
-
find_idx
(self, keys, values, allow_none=False, default=False)[source]¶ Find idx of devices whose values match the given pattern.
Parameters: - keys : str, array-like, Sized
A string or an array-like of strings containing the names of parameters for the search criteria
- values : array, array of arrays, Sized
Values for the corresponding key to search for. If keys is a str, values should be an array of elements. If keys is a list, values should be an array of arrays, each corresponds to the key.
- allow_none : bool, Sized
Allow key, value to be not found. Used by groups.
- default : bool
Default idx to return if not found (missing)
Returns: - list
indices of devices
-
class
andes.core.model.
SymProcessor
(parent)[source]¶ Bases:
object
A helper class for symbolic processing and code generation.
Parameters: - parent : Model
The Model instance to document
Attributes: - xy : sympy.Matrix
variables pretty print in the order of State, ExtState, Algeb, ExtAlgeb
- f : sympy.Matrix
differential equations pretty print
- g : sympy.Matrix
algebraic equations pretty print
- df : sympy.SparseMatrix
df /d (xy) pretty print
- dg : sympy.SparseMatrix
dg /d (xy) pretty print
- inputs_dict : OrderedDict
All possible symbols in equations, including variables, parameters, discrete flags, and config flags. It has the same variables as what
get_inputs()
returns.- vars_dict : OrderedDict
variable-only symbols, which are useful when getting the Jacobian matrices.
- non_vars_dict : OrderedDict
symbols in
input_syms
but not invar_syms
.
-
generate_jacobians
(self)[source]¶ Generate Jacobians and store to corresponding triplets.
The internal indices of equations and variables are stored, alongside the lambda functions.
For example, dg/dy is a sparse matrix whose elements are
(row, col, val)
, whererow
andcol
are the internal indices, andval
is the numerical lambda function. They will be stored torow -> self.calls._igy col -> self.calls._jgy val -> self.calls._vgy
-
generate_py_files
(self)[source]¶ Create output source code file for generated code. NOT WORKING NOW.
-
generate_symbols
(self)[source]¶ Generate symbols for symbolic equation generations.
This function should run before other generate equations.
Attributes: - inputs_dict : OrderedDict
name-symbol pair of all parameters, variables and configs
- vars_dict : OrderedDict
name-symbol pair of all variables, in the order of (states_and_ext + algebs_and_ext)
- non_vars_dict : OrderedDict
name-symbol pair of all non-variables, namely, (inputs_dict - vars_dict)
andes.core.param module¶
-
class
andes.core.param.
BaseParam
(default: Union[float, str, int, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, mandatory: bool = False, export: bool = True)[source]¶ Bases:
object
The base parameter class.
This class provides the basic data structure and interfaces for all types of parameters. Parameters are from input files and in general constant once initialized.
Subclasses should overload the n() method for the total count of elements in the value array.
Parameters: - default : str or float, optional
The default value of this parameter if None is provided
- name : str, optional
Parameter name. If not provided, it will be automatically set to the attribute name defined in the owner model.
- tex_name : str, optional
LaTeX-formatted parameter name. If not provided, tex_name will be assigned the same as name.
- info : str, optional
Descriptive information of parameter
- mandatory : bool
True if this parameter is mandatory
- export : bool
True if the parameter will be exported when dumping data into files. True for most parameters. False for
BackRef
.
Warning
The most distinct feature of BaseParam, DataParam and IdxParam is that values are stored in a list without conversion to array. BaseParam, DataParam or IdxParam are not allowed in equations.
Attributes: - v : list
A list holding all the values. The
BaseParam
class does not convert thev
attribute into NumPy arrays.- property : dict
A dict containing the truth values of the model properties.
-
add
(self, value=None)[source]¶ Add a new parameter value (from a new device of the owner model) to the
v
list.Parameters: - value : str or float, optional
Parameter value of the new element. If None, the default will be used.
Notes
If the value is
math.nan
, it will set toNone
.
-
class_name
¶ Return the class name.
-
get_names
(self)[source]¶ Return
self.name
in a list.This is a helper function to provide the same API as blocks or discrete components.
Returns: - list
A list only containing the name of the parameter
-
get_property
(self, property_name: str)[source]¶ Check the boolean value of the given property. If the property does not exist in the dictionary,
False
will be returned.Parameters: - property_name : str
Property name
Returns: - The truth value of the property.
-
n
¶ Return the count of elements in the value array.
-
class
andes.core.param.
DataParam
(default: Union[float, str, int, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, mandatory: bool = False, export: bool = True)[source]¶ Bases:
andes.core.param.BaseParam
An alias of the BaseParam class.
This class is used for string parameters or non-computational numerical parameters. This class does not provide a to_array method. All input values will be stored in v as a list.
See also
andes.core.param.BaseParam
- Base parameter class
-
class
andes.core.param.
ExtParam
(model: str, src: str, indexer=None, dtype=<class 'float'>, allow_none=False, default=0.0, **kwargs)[source]¶ Bases:
andes.core.param.NumParam
A parameter whose values are retrieved from an external model or group.
Parameters: - model : str
Name of the model or group providing the original parameter
- src : str
The source parameter name
- indexer : BaseParam
A parameter defined in the model defining this ExtParam instance. indexer.v should contain indices into model.src.v. If is None, the source parameter values will be fully copied. If model is a group name, the indexer cannot be None.
Attributes: - parent_model : Model
The parent model providing the original parameter.
-
class
andes.core.param.
IdxParam
(default: Union[float, str, int, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, mandatory: bool = False, unique: bool = False, export: bool = True, model: Optional[str] = None)[source]¶ Bases:
andes.core.param.BaseParam
An alias of BaseParam with an additional storage of the owner model name
This class is intended for storing idx into other models. It can be used in the future for data consistency check.
Notes
This will be useful when, for example, one connects two TGs to one SynGen.
Examples
A PQ model connected to Bus model will have the following code
class PQModel(...): def __init__(...): ... self.bus = IdxParam(model='Bus')
-
class
andes.core.param.
NumParam
(default: Union[float, str, Callable, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, vrange: Union[List[T], Tuple, None] = None, Sn: str = 'Sn', Vn: str = 'Vn', non_zero: bool = False, positive: bool = False, mandatory: bool = False, power: bool = False, ipower: bool = False, voltage: bool = False, current: bool = False, z: bool = False, y: bool = False, r: bool = False, g: bool = False, dc_voltage: bool = False, dc_current: bool = False, export: bool = True)[source]¶ Bases:
andes.core.param.BaseParam
A computational numerical parameter.
Parameters defined using this class will have their v field converted to a NumPy array after adding. The original input values will be copied to vin, and the system-base per-unit conversion coefficients (through multiplication) will be stored in pu_coeff.
Parameters: - default : str or float, optional
The default value of this parameter if no value is provided
- name : str, optional
Name of this parameter. If not provided, name will be set to the attribute name of the owner model.
- tex_name : str, optional
LaTeX-formatted parameter name. If not provided, tex_name will be assigned the same as name.
- info : str, optional
A description of this parameter
- mandatory : bool
True if this parameter is mandatory
- unit : str, optional
Unit of the parameter
- vrange : list, tuple, optional
Typical value range
Other Parameters: - Sn : str
Name of the parameter for the device base power.
- Vn : str
Name of the parameter for the device base voltage.
- non_zero : bool
True if this parameter must be non-zero
- positive: bool
True if this parameter must be positive
- mandatory : bool
True if this parameter must not be None
- power : bool
True if this parameter is a power per-unit quantity under the device base
- ipower : bool
True if this parameter is an inverse-power per-unit quantity under the device base
- voltage : bool
True if the parameter is a voltage pu quantity under the device base
- current : bool
True if the parameter is a current pu quantity under the device base
- z : bool
True if the parameter is an AC impedance pu quantity under the device base
- y : bool
True if the parameter is an AC admittance pu quantity under the device base
- r : bool
True if the parameter is a DC resistance pu quantity under the device base
- g : bool
True if the parameter is a DC conductance pu quantity under the device base
- dc_current : bool
True if the parameter is a DC current pu quantity under device base
- dc_voltage : bool
True if the parameter is a DC voltage pu quantity under device base
-
add
(self, value=None)[source]¶ Add a value to the parameter value list.
In addition to
BaseParam.add
, this method checks for non-zero property and reset to default if is zero.See also
BaseParam.add
- the add method of BaseParam
-
restore
(self)[source]¶ Restore parameter to the original input by copying
self.vin
toself.v
.pu_coeff will not be overwritten.
-
class
andes.core.param.
TimerParam
(callback: Optional[Callable] = None, default: Union[float, str, Callable, None] = None, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, non_zero: bool = False, mandatory: bool = False, export: bool = True)[source]¶ Bases:
andes.core.param.NumParam
A parameter whose values are event occurrence times during the simulation.
The constructor takes an additional Callable self.callback for the action of the event. TimerParam has a default value of -1, meaning deactivated.
Examples
A connectivity status toggler class Toggler takes a parameter t for the toggle time. Inside
Toggler.__init__
, one would haveself.t = TimerParam()
The Toggler class also needs to define a method for togging the connectivity status
def _u_switch(self, is_time: np.ndarray): action = False for i in range(self.n): if is_time[i] and (self.u.v[i] == 1): instance = self.system.__dict__[self.model.v[i]] # get the original status and flip the value u0 = instance.get(src='u', attr='v', idx=self.dev.v[i]) instance.set(src='u', attr='v', idx=self.dev.v[i], value=1-u0) action = True return action
Finally, in
Toggler.__init__
, assign the function as the callback for self.tself.t.callback = self._u_switch
-
is_time
(self, dae_t)[source]¶ Element-wise check if the DAE time is the same as the parameter value. The current implementation uses np.isclose
Parameters: - dae_t : float
Current simulation time
Returns: - np.ndarray
The array containing the truth value of if the DAE time is close to the parameter value.
See also
numpy.isclose
- See NumPy.isclose for the warning on absolute tolerance
-
andes.core.service module¶
-
class
andes.core.service.
BackRef
(**kwargs)[source]¶ Bases:
andes.core.service.BaseService
A special type of reference collector.
BackRef is used for collecting device indices of other models referencing the parent model of the BackRef. The v``field will be a list of lists, each containing the `idx of other models referencing each device of the parent model.
BackRef can be passed as indexer for params and vars, or shape for NumReduce and NumRepeat. See examples for illustration.
See also
andes.core.service.NumReduce
- A more complete example using BackRef to build the COI model
Examples
A Bus device has an IdxParam of area, storing the idx of area to which the bus device belongs. In
Bus.__init__()
, one hasself.area = IdxParam(model='Area')
Suppose Bus has the following data
idx area Vn 1 1 110 2 2 220 3 1 345 4 1 500 The Area model wants to collect the indices of Bus devices which points to the corresponding Area device. In
Area.__init__
, one definesself.Bus = BackRef()
where the member attribute name Bus needs to match exactly model name that Area wants to collect idx for. Similarly, one can define
self.ACTopology = BackRef()
to collect devices in the ACTopology group that references Area.The collection of idx happens in
andes.system.System._collect_ref_param()
. It has to be noted that the specific Area entry must exist to collect model idx-dx referencing it. For example, if Area has the following dataidx 1
Then, only Bus 1, 3, and 4 will be collected into self.Bus.v, namely,
self.Bus.v == [ [1, 3, 4] ]
.If Area has data
idx 1 2
Then, self.Bus.v will end up with
[ [1, 3, 4], [2] ]
.
-
class
andes.core.service.
BaseService
(name: str = None, tex_name: str = None, info: str = None, vtype: Type[CT_co] = None)[source]¶ Bases:
object
Base class for Service.
Service is a v-provider type for holding internal and temporary values. Subclasses need to implement
v
as a member attribute or using a property decorator.Parameters: - name : str
Instance name
Attributes: - owner : Model
The hosting/owner model instance
-
class_name
¶ Return the class name
-
get_names
(self)[source]¶ Return name in a list
Returns: - list
A list only containing the name of the service variable
-
n
¶ Return the count of values in
self.v
.Needs to be overloaded if
v
of subclasses is not a 1-dimensional array.Returns: - int
The count of elements in this variable
-
class
andes.core.service.
ConstService
(v_str: Optional[str] = None, v_numeric: Optional[Callable] = None, name: Optional[str] = None, tex_name=None, info=None)[source]¶ Bases:
andes.core.service.BaseService
A type of Service that stays constant once initialized.
ConstService are usually constants calculated from parameters. They are only evaluated once in the initialization phase before variables are initialized. Therefore, uninitialized variables must not be used in v_str`.
Parameters: - name : str
Name of the ConstService
- v_str : str
An equation string to calculate the variable value.
- v_numeric : Callable, optional
A callable which returns the value of the ConstService
Attributes: - v : array-like or a scalar
ConstService value
-
class
andes.core.service.
DataSelect
(optional, fallback, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None)[source]¶ Bases:
andes.core.service.BaseService
Class for selecting values for optional DataParam or NumParam.
This service is a v-provider that uses optional DataParam if available with a fallback.
DataParam will be tested for None, and NumParam will be tested with np.isnan().
Notes
An use case of DataSelect is remote bus. One can do
self.buss = DataSelect(option=self.busr, fallback=self.bus)
Then, pass
self.buss
instead ofself.bus
as indexer to retrieve voltages.Another use case is to allow an optional turbine rating. One can do
self.Tn = NumParam(default=None) self.Sg = ExtParam(...) self.Sn = DataSelect(Tn, Sg)
-
v
¶
-
-
class
andes.core.service.
DeviceFinder
(u, link, idx_name, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.service.BaseService
Service for finding indices of optionally linked devices.
If not provided, DeviceFinder will add devices at the beginning of System.setup.
Examples
IEEEST stabilizer takes an optional busf (IdxParam) for specifying the connected BusFreq, which is needed for mode 6. To avoid reimplementing BusFreq within IEEEST, one can do
self.busfreq = DeviceFinder(self.busf, link=self.buss, idx_name='bus')
where self.busf is the optional input, self.buss is the bus indices that busf should measure, and idx_name is the name of a BusFreq parameter through which the measured bus indices are specified. For each None values in self.busf, a BusFreq is created to measure the corresponding bus in self.buss.
That is,
BusFreq.[idx_name].v = [link]
. DeviceFinder will find / create BusFreq devices so that the returned list of BusFreq indices are connected to self.buss, respectively.-
v
¶
-
-
class
andes.core.service.
ExtService
(model: str, src: str, indexer: andes.core.param.BaseParam, attr='v', allow_none=False, default=0, name: str = None, tex_name: str = None, info=None)[source]¶ Bases:
andes.core.service.BaseService
Service constants whose value is from an external model or group.
Parameters: - src : str
Variable or parameter name in the source model or group
- model : str
A model name or a group name
- indexer : IdxParam or BaseParam
An "Indexer" instance whose
v
field contains theidx
of devices in the model or group.
Examples
A synchronous generator needs to retrieve the
p
andq
values from static generators for initialization.ExtService
is used for this purpose.In a synchronous generator, one can define the following to retrieve
StaticGen.p
asp0
:class GENCLSModel(Model): def __init__(...): ... self.p0 = ExtService(src='p', model='StaticGen', indexer=self.gen, tex_name='P_0')
-
class
andes.core.service.
FlagNotNone
(indexer, to_flag=None, name=None, tex_name=None, info=None, cache=True)[source]¶ Bases:
andes.core.service.BaseService
Class for flagging non-None indices as 1 and None indices as 0 in a numpy array.
Warning
FlagNotNone can only be applied to BaseParam with cache=True. Applying to Service will fail until cache is False (at a performance cost).
-
v
¶
-
-
class
andes.core.service.
IdxRepeat
(u, ref, **kwargs)[source]¶ Bases:
andes.core.service.OperationService
Helper class to repeat IdxParam.
This class has the same functionality as
andes.core.service.NumRepeat
but only operates on IdxParam, DataParam or NumParam.-
v
¶ Return values stored in self._v. May be overloaded by subclasses.
-
-
class
andes.core.service.
InitChecker
(u, lower=None, upper=None, equal=None, not_equal=None, enable=True, error_out=False, **kwargs)[source]¶ Bases:
andes.core.service.OperationService
Class for checking init values against known typical values.
Instances will be stored in Model.services_post and Model.services_icheck, which will be checked in Model.post_init_check() after initialization.
Parameters: - u
v-provider to be checked
- lower : float, BaseParam, BaseVar, BaseService
lower bound
- upper : float, BaseParam, BaseVar, BaseService
upper bound
- equal : float, BaseParam, BaseVar, BaseService
values that the value from v_str should equal
- not_equal : float, BaseParam, BaseVar, BaseService
values that should not equal
- enable : bool
True to enable checking
Examples
Let's say generator excitation voltages are known to be in the range of 1.6 - 3.0 per unit. One can add the following instance to GENBase
self._vfc = InitChecker(u=self.vf, info='vf range', lower=1.8, upper=3.0, )
lower and upper can also take v-providers instead of float values.
One can also pass float values from Config to make it adjustable as in our implementation of
GENBase._vfc
.
-
class
andes.core.service.
NumReduce
(u, ref: andes.core.service.BackRef, fun: Callable, name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.service.OperationService
A helper Service type which reduces a linearly stored 2-D ExtParam into 1-D Service.
NumReduce works with ExtParam whose v field is a list of lists. A reduce function which takes an array-like and returns a scalar need to be supplied. NumReduce calls the reduce function on each of the lists and return all the scalars in an array.
Parameters: - u : ExtParam
Input ExtParam whose
v
contains linearly stored 2-dimensional values- ref : BackRef
The BackRef whose 2-dimensional shapes are used for indexing
- fun : Callable
The callable for converting a 1-D array-like to a scalar
Examples
Suppose one wants to calculate the mean value of the
Vn
in one Area. In theArea
class, one definesclass AreaModel(...): def __init__(...): ... # backward reference from `Bus` self.Bus = BackRef() # collect the Vn in an 1-D array self.Vn = ExtParam(model='Bus', src='Vn', indexer=self.Bus) self.Vn_mean = NumReduce(u=self.Vn, fun=np.mean, ref=self.Bus)
Suppose we define two areas, 1 and 2, the Bus data looks like
idx area Vn 1 1 110 2 2 220 3 1 345 4 1 500 Then, self.Bus.v is a list of two lists
[ [1, 3, 4], [2] ]
. self.Vn.v will be retrieved and linearly stored as[110, 345, 500, 220]
. Based on the shape from self.Bus,numpy.mean()
will be called on[110, 345, 500]
and[220]
respectively. Thus, self.Vn_mean.v will become[318.33, 220]
.-
v
¶ Return the reduced values from the reduction function in an array
Returns: - The array
self._v
storing the reduced values
- The array
-
class
andes.core.service.
NumRepeat
(u, ref, **kwargs)[source]¶ Bases:
andes.core.service.OperationService
A helper Service type which repeats a v-provider's value based on the shape from a BackRef
Examples
NumRepeat was originally designed for computing the inertia-weighted average rotor speed (center of inertia speed). COI speed is computed with
\[\omega_{COI} = \frac{ \sum{M_i * \omega_i} } {\sum{M_i}}\]The numerator can be calculated with a mix of BackRef, ExtParam and ExtState. The denominator needs to be calculated with NumReduce and Service Repeat. That is, use NumReduce to calculate the sum, and use NumRepeat to repeat the summed value for each device.
In the COI class, one would have
class COIModel(...): def __init__(...): ... self.SynGen = BackRef() self.SynGenIdx = RefFlatten(ref=self.SynGen) self.M = ExtParam(model='SynGen', src='M', indexer=self.SynGenIdx) self.wgen = ExtState(model='SynGen', src='omega', indexer=self.SynGenIdx) self.Mt = NumReduce(u=self.M, fun=np.sum, ref=self.SynGen) self.Mtr = NumRepeat(u=self.Mt, ref=self.SynGen) self.pidx = IdxRepeat(u=self.idx,ref=self.SynGen)
Finally, one would define the center of inertia speed as
self.wcoi = Algeb(v_str='1', e_str='-wcoi') self.wcoi_sub = ExtAlgeb(model='COI', src='wcoi', e_str='M * wgen / Mtr', v_str='M / Mtr', indexer=self.pidx, )
It is very worth noting that the implementation uses a trick to separate the average weighted sum into n sub-equations, each calculating the \((M_i * \omega_i) / (\sum{M_i})\). Since all the variables are preserved in the sub-equation, the derivatives can be calculated correctly.
-
v
¶ Return the values of the repeated values in a sequential 1-D array
Returns: - The array,
self._v
storing the repeated values
- The array,
-
-
class
andes.core.service.
NumSelect
(optional, fallback, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None)[source]¶ Bases:
andes.core.service.OperationService
Class for selecting values for optional NumParam.
Notes
One use case is to allow an optional turbine rating. One can do
self.Tn = NumParam(default=None) self.Sg = ExtParam(...) self.Sn = DataSelect(Tn, Sg)
-
v
¶ Return values stored in self._v. May be overloaded by subclasses.
-
-
class
andes.core.service.
OperationService
(name=None, tex_name=None, info=None)[source]¶ Bases:
andes.core.service.BaseService
Base class for a type of Service which performs specific operations
This class cannot be used by itself.
See also
-
v
¶ Return values stored in self._v. May be overloaded by subclasses.
-
-
class
andes.core.service.
ParamCalc
(param1, param2, func, name=None, tex_name=None, info=None, cache=True)[source]¶ Bases:
andes.core.service.BaseService
Parameter calculation service.
Useful to create parameters calculated instantly from existing ones.
-
v
¶
-
-
class
andes.core.service.
PostInitService
(v_str: Optional[str] = None, v_numeric: Optional[Callable] = None, name: Optional[str] = None, tex_name=None, info=None)[source]¶ Bases:
andes.core.service.ConstService
Constant service that gets stored once after init.
This service is useful when one need to store initialization values stored in variables.
Examples
In ESST3A model, the vf variable is initialized followed by other variables. One can store the initial vf into vf0 so that equation
vf - vf0 = 0
will hold.self.vref0 = PostInitService(info='Initial reference voltage input', tex_name='V_{ref0}', v_str='vref', )
Since all ConstService are evaluated before equation evaluation, without using PostInitService, one will need to create lots of ConstService to store values in the initialization path towards vf0, in order to correctly initialize vf.
-
class
andes.core.service.
RandomService
(func=<built-in method rand of numpy.random.mtrand.RandomState object>, **kwargs)[source]¶ Bases:
andes.core.service.BaseService
A service type for generating random numbers.
Parameters: - name : str
Name
- func : Callable
A callable for generating the random variable.
Warning
The value will be randomized every time it is accessed. Do not use it if the value needs to be stable for each simulation step.
-
v
¶ This class has v wrapped by a property decorator.
Returns: - array-like
Randomly generated service variables
-
class
andes.core.service.
RefFlatten
(ref, **kwargs)[source]¶ Bases:
andes.core.service.OperationService
A service type for flattening
andes.core.service.BackRef
into a 1-D list.Examples
This class is used when one wants to pass BackRef values as indexer.
andes.models.coi.COI
collects referencingandes.models.group.SynGen
withself.SynGen = BackRef(info='SynGen idx lists', export=False)
After collecting BackRefs, self.SynGen.v will become a two-level list of indices, where the first level correspond to each COI and the second level correspond to generators of the COI.
Convert self.SynGen into 1-d as self.SynGenIdx, which can be passed as indexer for retrieving other parameters and variables
self.SynGenIdx = RefFlatten(ref=self.SynGen) self.M = ExtParam(model='SynGen', src='M', indexer=self.SynGenIdx, export=False, )
-
v
¶ Return values stored in self._v. May be overloaded by subclasses.
-
-
class
andes.core.service.
Replace
(old_val, flt, new_val, name=None, tex_name=None, info=None, cache=True)[source]¶ Bases:
andes.core.service.BaseService
Replace parameters with new values if the function returns True
-
v
¶
-
-
class
andes.core.service.
VarService
(v_str: Optional[str] = None, v_numeric: Optional[Callable] = None, name: Optional[str] = None, tex_name=None, info=None)[source]¶ Bases:
andes.core.service.ConstService
Variable service that gets updated in each step/loop as variables change.
This class is useful when one has non-differentiable algebraic equations, which make use of abs(), re and im. Instead of creating Algeb, one can put the equation in VarService, which will be updated before solving algebraic equations.
Warning
VarService is not solved with other algebraic equations, meaning that there is one step "delay" between the algebraic variables and VarService. Use an algebraic variable whenever possible.
Examples
In ESST3A model, the voltage and current sensors (vd + jvq), (Id + jIq) estimate the sensed VE using equation
\[VE = | K_{PC}*(v_d + 1j v_q) + 1j (K_I + K_{PC}*X_L)*(I_d + 1j I_q)|\]One can use VarService to implement this equation
self.VE = VarService(tex_name='V_E', info='VE', v_str='Abs(KPC*(vd + 1j*vq) + 1j*(KI + KPC*XL)*(Id + 1j*Iq))', )
andes.core.solver module¶
-
class
andes.core.solver.
CuPySolver
[source]¶ Bases:
andes.core.solver.SciPySolver
CuPy lsqr solver (GPU-based).
-
class
andes.core.solver.
KLUSolver
[source]¶ Bases:
andes.core.solver.SuiteSparseSolver
KLU solver.
Requires package
cvxoptklu
.-
linsolve
(self, A, b)[source]¶ Solve linear equation set
Ax = b
and returns the solutions in a 1-D array.This function performs both symbolic and numeric factorizations every time, and can be slower than
Solver.solve
.Parameters: - A
Sparse matrix
- b
RHS of the equation
Returns: - The solution in a 1-D np array.
-
-
class
andes.core.solver.
SciPySolver
[source]¶ Bases:
object
Base class for scipy family solvers.
-
class
andes.core.solver.
Solver
(sparselib='umfpack')[source]¶ Bases:
object
Sparse matrix solver class.
This class wraps UMFPACK, KLU, SciPy and CuPy solvers to provide an unified interface for solving sparse linear equations
Ax = b
.Provides methods
solve
,linsolve
andclear
.
-
class
andes.core.solver.
SpSolve
[source]¶ Bases:
andes.core.solver.SciPySolver
scipy.sparse.linalg.spsolve Solver.
-
class
andes.core.solver.
SuiteSparseSolver
[source]¶ Bases:
object
Base SuiteSparse solver interface.
Need to be derived by specific solvers such as UMFPACK or KLU.
-
linsolve
(self, A, b)[source]¶ Solve linear equation set
Ax = b
and returns the solutions in a 1-D array.This function performs both symbolic and numeric factorizations every time, and can be slower than
Solver.solve
.Parameters: - A
Sparse matrix
- b
RHS of the equation
Returns: - The solution in a 1-D np array.
-
solve
(self, A, b)[source]¶ Solve linear system
Ax = b
using numeric factorizationN
and symbolic factorizationF
. Store the solution inb
.This function caches the symbolic factorization in
self.F
and is faster in general. Will attemptSolver.linsolve
if the cached symbolic factorization is invalid.Parameters: - A
Sparse matrix for the equation set coefficients.
- F
The symbolic factorization of A or a matrix with the same non-zero shape as
A
.- N
Numeric factorization of A.
- b
RHS of the equation.
Returns: - numpy.ndarray
The solution in a 1-D ndarray
-
-
class
andes.core.solver.
UMFPACKSolver
[source]¶ Bases:
andes.core.solver.SuiteSparseSolver
UMFPACK solver.
Utilizes
cvxopt.umfpack
for factorization.-
linsolve
(self, A, b)[source]¶ Solve linear equation set
Ax = b
and returns the solutions in a 1-D array.This function performs both symbolic and numeric factorizations every time, and can be slower than
Solver.solve
.Parameters: - A
Sparse matrix
- b
RHS of the equation
Returns: - The solution in a 1-D np array.
-
andes.core.common module¶
-
class
andes.core.common.
Config
(name, dct=None, **kwargs)[source]¶ Bases:
object
A class for storing system, model and routine configurations.
-
add
(self, dct=None, **kwargs)[source]¶ Add config fields from a dictionary or keyword args.
Existing configs will NOT be overwritten.
-
as_dict
(self, refresh=False)[source]¶ Return the config fields and values in an
OrderedDict
.Values are cached in self._dict unless refreshed.
-
tex_names
¶
-
-
class
andes.core.common.
DummyValue
(value)[source]¶ Bases:
object
Class for converting a scalar value to a dummy parameter with name and tex_name fields.
A DummyValue object can be passed to Block, which utilizes the name field to dynamically generate equations.
Notes
Pass a numerical value to the constructor for most use cases, especially when passing as a v-provider.
-
class
andes.core.common.
JacTriplet
[source]¶ Bases:
object
Storage class for Jacobian triplet lists.
-
append_ijv
(self, j_full_name, ii, jj, vv)[source]¶ Append triplets to the given sparse matrix triplets.
Parameters: - j_full_name : str
Full name of the sparse Jacobian. If is a constant Jacobian, append 'c' to the Jacobian name.
- ii : array-like
Row indices
- jj : array-like
Column indices
- vv : array-like
Value indices
-
-
class
andes.core.common.
ModelFlags
(collate=False, pflow=False, tds=False, series=False, nr_iter=False, f_num=False, g_num=False, j_num=False, s_num=False, sv_num=False)[source]¶ Bases:
object
Model flags.
Parameters: - collate : bool
True: collate variables by device; False: by variable. Non-collate (continuous memory) has faster computation speed.
- pflow : bool
True: called during power flow
- tds : bool
True if called during tds; if is False,
dae_t
cannot be used- series : bool
True if is series device
- nr_iter : bool
True if is series device
- f_num : bool
True if the model defines f_numeric
- g_num : bool
True if the model defines g_numeric
- j_num : bool
True if the model defines j_numeric
- s_num : bool
True if the model defines s_numeric
- sv_num : bool
True if the model defines s_numeric_var
andes.core.var module¶
-
class
andes.core.var.
Algeb
(name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, discrete: Optional[andes.core.discrete.Discrete] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source]¶ Bases:
andes.core.var.BaseVar
Algebraic variable class, an alias of the BaseVar.
Attributes: - e_code : str
Equation code string, equals string literal
g
- v_code : str
Variable code string, equals string literal
y
-
e_code
= 'g'¶
-
v_code
= 'y'¶
-
class
andes.core.var.
BaseVar
(name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, discrete: Optional[andes.core.discrete.Discrete] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source]¶ Bases:
object
Base variable class.
Derived classes State and Algeb should be used to build model variables.
Parameters: - name : str, optional
Variable name
- info : str, optional
Descriptive information
- unit : str, optional
Unit
- tex_name : str
LaTeX-formatted variable name. If is None, use name instead.
- discrete : Discrete
Associated discrete component. Will call check_var on the discrete component.
Attributes: - a : array-like
variable address
- v : array-like
local-storage of the variable value
- e : array-like
local-storage of the corresponding equation value
- e_str : str
the string/symbolic representation of the equation
-
class_name
¶
-
class
andes.core.var.
ExtAlgeb
(model: str, src: str, indexer: Union[List[T], numpy.ndarray, andes.core.param.BaseParam, andes.core.service.BaseService, None] = None, allow_none: Optional[bool] = False, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source]¶ Bases:
andes.core.var.ExtVar
External algebraic variable type.
-
e_code
= 'g'¶
-
v_code
= 'y'¶
-
-
class
andes.core.var.
ExtState
(model: str, src: str, indexer: Union[List[T], numpy.ndarray, andes.core.param.BaseParam, andes.core.service.BaseService, None] = None, allow_none: Optional[bool] = False, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source]¶ Bases:
andes.core.var.ExtVar
External state variable type.
Warning
ExtState
is not allowed to sett_const
, as it will conflict with the sourceState
variable. In fact, one should not sete_str
forExtState
.-
e_code
= 'f'¶
-
t_const
= None¶
-
v_code
= 'x'¶
-
-
class
andes.core.var.
ExtVar
(model: str, src: str, indexer: Union[List[T], numpy.ndarray, andes.core.param.BaseParam, andes.core.service.BaseService, None] = None, allow_none: Optional[bool] = False, name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source]¶ Bases:
andes.core.var.BaseVar
Externally defined algebraic variable
This class is used to retrieve the addresses of externally- defined variable. The e value of the ExtVar will be added to the corresponding address in the DAE equation.
Parameters: - model : str
Name of the source model
- src : str
Source variable name
- indexer : BaseParam, BaseService
A parameter of the hosting model, used as indices into the source model and variable. If is None, the source variable address will be fully copied.
- allow_none : bool
True to allow None in indexer
Attributes: - parent_model : Model
The parent model providing the original parameter.
- uid : array-like
An array containing the absolute indices into the parent_instance values.
- e_code : str
Equation code string; copied from the parent instance.
- v_code : str
Variable code string; copied from the parent instance.
-
link_external
(self, ext_model)[source]¶ Update variable addresses provided by external models
This method sets attributes including parent_model, parent_instance, uid, a, n, e_code and v_code. It initializes the e and v to zero.
Parameters: - ext_model : Model
Instance of the parent model
Returns: - None
Warning
link_external does not check if the ExtVar type is the same as the original variable to reduce performance overhead. It will be a silent error (a dimension too small error from dae.build_pattern) if a model uses ExtAlgeb to access a State, or vice versa.
-
class
andes.core.var.
State
(name: Optional[str] = None, tex_name: Optional[str] = None, info: Optional[str] = None, unit: Optional[str] = None, v_str: Union[str, float, None] = None, v_iter: Optional[str] = None, e_str: Optional[str] = None, discrete: Optional[andes.core.discrete.Discrete] = None, t_const: Union[andes.core.param.BaseParam, andes.core.common.DummyValue, None] = None, v_setter: Optional[bool] = False, e_setter: Optional[bool] = False, addressable: Optional[bool] = True, export: Optional[bool] = True, diag_eps: Optional[float] = 0.0)[source]¶ Bases:
andes.core.var.BaseVar
Differential variable class, an alias of the BaseVar.
Parameters: - t_const : BaseParam, DummyValue
Left-hand time constant for the differential equation. Time constants will not be evaluated as part of the differential equation. They will be collected to array dae.Tf to multiply to the right-hand side dae.f.
Attributes: - e_code : str
Equation code string, equals string literal
f
- v_code : str
Variable code string, equals string literal
x
-
e_code
= 'f'¶
-
v_code
= 'x'¶
Module contents¶
Import subpackage classes
andes.io package¶
Submodules¶
andes.io.matpower module¶
Simple MATPOWER format parser
andes.io.psse module¶
PSS/E file parser.
Include a RAW parser and a DYR parser.
-
andes.io.psse.
read_add
(system, file)[source]¶ Read an addition PSS/E dyr file.
Parameters: - system : System
System instance to which data will be loaded
- file : str
Path to the additional dyr file
Returns: - bool
data parsing status
andes.io.txt module¶
andes.io.xlsx module¶
Excel reader and writer for ANDES power system parameters
This module utilizes xlsxwriter and pandas.Frame. While I like the simplicity of the dome format, spreadsheet data is easier to read and edit.
-
andes.io.xlsx.
read
(system, infile)[source]¶ Read an xlsx file with ANDES model data into an empty system
Parameters: - system : System
Empty System instance
- infile : str
Path to the input file
Returns: - System
System instance after succeeded
-
andes.io.xlsx.
write
(system, outfile, skip_empty=True, overwrite=None, add_book=None, **kwargs)[source]¶ Write loaded ANDES system data into an xlsx file
Parameters: - system : System
A loaded system with parameters
- outfile : str
Path to the output file
- skip_empty : bool
Skip output of empty models (n = 0)
- overwrite : bool, optional
None to prompt for overwrite selection; True to overwrite; False to not overwrite
- add_book : str, optional
An optional model to be added to the output spreadsheet
Returns: - bool
True if file written; False otherwise
Module contents¶
-
andes.io.
dump
(system, output_format, full_path=None, overwrite=False, **kwargs)[source]¶ Dump the System data into the requested output format.
Parameters: - system
System object
- output_format : str
Output format name. 'xlsx' will be used if is not an instance of str.
Returns: - bool
True if successful; False otherwise.
andes.models package¶
Submodules¶
andes.models.area module¶
-
class
andes.models.area.
AreaData
[source]¶ Bases:
andes.core.model.ModelData
andes.models.bus module¶
-
class
andes.models.bus.
Bus
(system=None, config=None)[source]¶ Bases:
andes.core.model.Model
,andes.models.bus.BusData
AC Bus model.
Power balance equation have the form of
load - injection = 0
. Namely, load is positively summed, while injections are negative.
-
class
andes.models.bus.
BusData
[source]¶ Bases:
andes.core.model.ModelData
Class for Bus data
andes.models.governor module¶
-
class
andes.models.governor.
IEEEG1
(system, config)[source]¶ Bases:
andes.models.governor.IEEEG1Data
,andes.models.governor.IEEEG1Model
IEEE Type 1 Speed-Governing Model.
If only one generator is connected, its idx must be given to syn, and syn2 must be left blank. Each generator must provide data in its Sn base.
syn is connected to the high-pressure output (PHP) and the optional syn2 is connected to the low- pressure output (PLP).
The speed deviation of generator 1 (syn) is measured. If the turbine rating Tn is not specified, the sum of Sn of all connected generators will be used.
Normally, K1 + K2 + ... + K8 = 1.0. If the second generator is not connected, K1 + K3 + K5 + K7 = 1, and K2 + K4 + K6 + K8 = 0.
-
class
andes.models.governor.
IEEEG1Model
(system, config)[source]¶ Bases:
andes.models.governor.TGBase
-
class
andes.models.governor.
TG2
(system, config)[source]¶ Bases:
andes.models.governor.TG2Data
,andes.models.governor.TGBase
-
class
andes.models.governor.
TGBase
(system, config, add_sn=True, add_tm0=True)[source]¶ Bases:
andes.core.model.Model
Base Turbine Governor model.
Parameters: - add_sn : bool
True to add NumSelect Sn; False to add later in custom models. This is useful when the governor connects to two generators.
-
class
andes.models.governor.
TGBaseData
[source]¶ Bases:
andes.core.model.ModelData
-
class
andes.models.governor.
TGOV1
(system, config)[source]¶ Bases:
andes.models.governor.TGOV1Data
,andes.models.governor.TGOV1Model
TGOV1 model.
-
class
andes.models.governor.
TGOV1Model
(system, config)[source]¶ Bases:
andes.models.governor.TGBase
-
class
andes.models.governor.
TGOV1ModelAlt
(system, config)[source]¶ Bases:
andes.models.governor.TGBase
andes.models.group module¶
-
class
andes.models.group.
ACLine
[source]¶ Bases:
andes.models.group.GroupBase
-
class
andes.models.group.
ACTopology
[source]¶ Bases:
andes.models.group.GroupBase
-
class
andes.models.group.
Calculation
[source]¶ Bases:
andes.models.group.GroupBase
Group of classes that calculates based on other models.
-
class
andes.models.group.
Collection
[source]¶ Bases:
andes.models.group.GroupBase
Collection of topology models
-
class
andes.models.group.
DCLink
[source]¶ Bases:
andes.models.group.GroupBase
Basic DC links
-
class
andes.models.group.
DCTopology
[source]¶ Bases:
andes.models.group.GroupBase
-
class
andes.models.group.
Exciter
[source]¶ Bases:
andes.models.group.GroupBase
Exciter group for synchronous generators.
-
class
andes.models.group.
Experimental
[source]¶ Bases:
andes.models.group.GroupBase
Experimantal group
-
class
andes.models.group.
FreqMeasurement
[source]¶ Bases:
andes.models.group.GroupBase
Frequency measurements.
-
class
andes.models.group.
GroupBase
[source]¶ Bases:
object
Base class for groups
-
add
(self, idx, model)[source]¶ Register an idx from model_name to the group
Parameters: - idx: Union[str, float, int]
Register an element to a model
- model: Model
instance of the model
-
class_name
¶
-
find_idx
(self, keys, values, allow_none=False, default=None)[source]¶ Find indices of devices that satisfy the given key=value condition.
This method iterates over all models in this group.
-
get
(self, src: str, idx, attr: str = 'v', allow_none=False, default=0.0)[source]¶ Based on the indexer, get the attr field of the src parameter or variable.
Parameters: - src : str
param or var name
- idx : array-like
device idx
- attr
The attribute of the param or var to retrieve
- allow_none : bool
True to allow None values in the indexer
- default : float
If allow_none is true, the default value to use for None indexer.
Returns: - The requested param or variable attribute
-
get_next_idx
(self, idx=None, model_name=None)[source]¶ Return the auto-generated next idx
Parameters: - idx
- model_name
-
idx2model
(self, idx, allow_none=False)[source]¶ Find model name for the given idx.
If allow_none is True, will return None at the corr. position.
-
n
¶ Total number of devices
-
-
class
andes.models.group.
PSS
[source]¶ Bases:
andes.models.group.GroupBase
Power system stabilizer group.
-
class
andes.models.group.
StaticACDC
[source]¶ Bases:
andes.models.group.GroupBase
AC DC device for power flow
-
class
andes.models.group.
StaticGen
[source]¶ Bases:
andes.models.group.GroupBase
Static generator group for power flow calculation
-
class
andes.models.group.
StaticLoad
[source]¶ Bases:
andes.models.group.GroupBase
Static load group.
-
class
andes.models.group.
StaticShunt
[source]¶ Bases:
andes.models.group.GroupBase
Static shunt compensator group.
-
class
andes.models.group.
SynGen
[source]¶ Bases:
andes.models.group.GroupBase
Synchronous generator group.
-
class
andes.models.group.
TimedEvent
[source]¶ Bases:
andes.models.group.GroupBase
Timed event group
-
class
andes.models.group.
TurbineGov
[source]¶ Bases:
andes.models.group.GroupBase
Turbine governor group for synchronous generator.
-
class
andes.models.group.
Undefined
[source]¶ Bases:
andes.models.group.GroupBase
andes.models.jit module¶
andes.models.line module¶
-
class
andes.models.line.
LineData
[source]¶ Bases:
andes.core.model.ModelData
andes.models.pq module¶
-
class
andes.models.pq.
PQ
(system=None, config=None)[source]¶ Bases:
andes.models.pq.PQData
,andes.core.model.Model
PQ load model.
Implements an automatic pq2z conversion during power flow when the voltage is outside [vmin, vmax]. The conversion can be turned off by setting pq2z to 0 in the Config file.
Before time-domain simulation, PQ load will be converted to impedance, current source, and power source based on the weights in the Config file.
Weights (p2p, p2i, p2z) corresponds to the weights for constant power, constant current and constant impedance. p2p, p2i and p2z must be in decimal numbers and sum up exactly to 1. The same rule applies to (q2q, q2i, q2z).
-
class
andes.models.pq.
PQData
[source]¶ Bases:
andes.core.model.ModelData
andes.models.pv module¶
-
class
andes.models.pv.
PVData
[source]¶ Bases:
andes.core.model.ModelData
-
class
andes.models.pv.
PVModel
(system=None, config=None)[source]¶ Bases:
andes.core.model.Model
PV generator model (power flow) with q limit and PV-PQ conversion.
-
class
andes.models.pv.
SlackData
[source]¶ Bases:
andes.models.pv.PVData
andes.models.shunt module¶
-
class
andes.models.shunt.
ShuntData
(system=None, name=None)[source]¶ Bases:
andes.core.model.ModelData
andes.models.synchronous module¶
Synchronous generator classes
-
class
andes.models.synchronous.
Flux0
[source]¶ Bases:
object
Flux model without electro-magnetic transients and ignore speed deviation
-
class
andes.models.synchronous.
Flux1
[source]¶ Bases:
object
Flux model without electro-magnetic transients but considers speed deviation.
-
class
andes.models.synchronous.
Flux2
[source]¶ Bases:
object
Flux model with electro-magnetic transients.
-
class
andes.models.synchronous.
GENBase
(system, config)[source]¶ Bases:
andes.core.model.Model
-
class
andes.models.synchronous.
GENBaseData
[source]¶ Bases:
andes.core.model.ModelData
-
class
andes.models.synchronous.
GENCLS
(system, config)[source]¶ Bases:
andes.models.synchronous.GENBaseData
,andes.models.synchronous.GENBase
,andes.models.synchronous.GENCLSModel
,andes.models.synchronous.Flux0
-
class
andes.models.synchronous.
GENROU
(system, config)[source]¶ Bases:
andes.models.synchronous.GENROUData
,andes.models.synchronous.GENBase
,andes.models.synchronous.GENROUModel
,andes.models.synchronous.Flux0
Round rotor generator with quadratic saturation
andes.models.timer module¶
-
class
andes.models.timer.
Fault
(system, config)[source]¶ Bases:
andes.core.model.ModelData
,andes.core.model.Model
Three-phase to ground fault.
-
class
andes.models.timer.
Toggler
(system, config)[source]¶ Bases:
andes.models.timer.TogglerData
,andes.core.model.Model
Time-based connectivity status toggler.
-
class
andes.models.timer.
TogglerData
[source]¶ Bases:
andes.core.model.ModelData
Module contents¶
andes.routines package¶
Submodules¶
andes.routines.base module¶
andes.routines.eig module¶
-
class
andes.routines.eig.
EIG
(system, config)[source]¶ Bases:
andes.routines.base.BaseRoutine
Eigenvalue analysis routine
-
calc_state_matrix
(self)[source]¶ Return state matrix and store to
self.As
.Returns: - cvxopt.matrix
state matrix
Notes
For systems with the form
\[\begin{split}T \dot{x} = f(x, y) \\ 0 = g(x, y)\end{split}\]The state matrix is calculated from
\[A_s = T^{-1} (f_x - f_y * g_y^{-1} * g_x)\]
-
export_state_matrix
(self)[source]¶ Export state matrix to a
<CaseName>_As.mat
file with the variable nameAs
, where<CaseName>
is the test case name.State variable names are stored in variables
x_name
andx_tex_name
.Returns: - bool
True if successful
-
andes.routines.pflow module¶
-
class
andes.routines.pflow.
PFlow
(system=None, config=None)[source]¶ Bases:
andes.routines.base.BaseRoutine
Power flow calculation routine.
-
newton_krylov
(self, verbose=False)[source]¶ Full Newton-Krylov method
Parameters: - verbose
Warning
The result might be wrong if discrete are in use!
-
andes.routines.tds module¶
-
class
andes.routines.tds.
TDS
(system=None, config=None)[source]¶ Bases:
andes.routines.base.BaseRoutine
Time-domain simulation routine.
-
calc_h
(self)[source]¶ Calculate the time step size during the TDS.
Returns: - float
computed time step size stored in
self.h
Notes
A heuristic function is used for variable time step size
min(0.50 * h, hmin), if niter >= 15 h = max(1.10 * h, hmax), if niter <= 6 min(0.95 * h, hmin), otherwise
-
init
(self)[source]¶ Initialize the status, storage and values for TDS.
Returns: - array-like
The initial values of xy.
-
is_switch_time
(self)[source]¶ Return if the current time is a switching time for time domain simulation.
Time is approximated with a tolerance of 1e-8.
Returns: - bool
True
if is a switching time;False
otherwise.
-
run
(self, no_pbar=False, no_summary=False, **kwargs)[source]¶ Run the implicit numerical integration for TDS.
Parameters: - no_pbar : bool
True to disable progress bar
- no_summary : bool, optional
True to disable the display of summary
-
Module contents¶
andes.utils package¶
Submodules¶
andes.utils.cached module¶
-
class
andes.utils.cached.
cached
(func, name=None, doc=None)[source]¶ Bases:
object
A decorator that converts a function into a lazy property. The function wrapped is called the first time to retrieve the result and then that calculated result is used the next time you access the value:
class Foo(object): @cached_property def foo(self): # calculate something important here return 42
The class has to have a __dict__ in order for this property to work. See for details: http://stackoverflow.com/questions/17486104/python-lazy-loading-of-class-attributes
andes.utils.paths module¶
Utility functions for loading andes stock test cases
-
class
andes.utils.paths.
DisplayablePath
(path, parent_path, is_last)[source]¶ Bases:
object
-
display_filename_prefix_last
= '└──'¶
-
display_filename_prefix_middle
= '├──'¶
-
display_parent_prefix_last
= '│ '¶
-
display_parent_prefix_middle
= ' '¶
-
displayname
¶
-
-
andes.utils.paths.
get_config_path
(file_name='andes.rc')[source]¶ Return the path of the config file to be loaded.
Search Priority: 1. current directory; 2. home directory.
Parameters: - file_name : str, optional
Config file name with the default as
andes.rc
.
Returns: - Config path in string if found; None otherwise.
-
andes.utils.paths.
get_log_dir
()[source]¶ Get the directory for log file.
On Linux or macOS,
/tmp/andes
is the default. On Windows,%APPDATA%/andes
is the default.Returns: - str
The path to the temporary logging directory
-
andes.utils.paths.
get_pkl_path
()[source]¶ Get the path to the picked/dilled function calls.
Returns: - str
Path to the calls.pkl file
andes.utils.func module¶
-
andes.utils.func.
interp_n2
(t, x, y)[source]¶ Interpolation function for N * 2 value arrays.
Parameters: - t : float
Point for which the interpolation is calculated
- x : 1-d array with two values
x-axis values
- y : 2-d array with size N-by-2
Values corresponding to x
Returns: - N-by-1 array
interpolated values at t
andes.utils.misc module¶
andes.utils.tab module¶
-
class
andes.utils.tab.
Tab
(title=None, header=None, descr=None, data=None, export='plain', max_width=78)[source]¶ Bases:
andes.utils.texttable.Texttable
Use package
texttable
to create well-formatted tables for setting helps and device helps.Parameters: - export : ('plain', 'rest')
Export format in plain text or restructuredText.
- max_width : int
Maximum table width. If there are equations in cells, set to 0 to disable wrapping.
Module contents¶
andes.variables package¶
Submodules¶
andes.variables.dae module¶
-
class
andes.variables.dae.
DAE
(system)[source]¶ Bases:
object
Class for storing numerical values of the DAE system, including variables, equations and first order derivatives (Jacobian matrices).
Variable values and equation values are stored as
numpy.ndarray
, while Jacobians are stored ascvxopt.spmatrix
. The defined arrays and descriptions are as follows:DAE Array Description x Array for state variable values y Array for algebraic variable values z Array for 0/1 limiter states (if enabled) f Array for differential equation derivatives Tf Left-hand side time constant array for f g Array for algebraic equation mismatches The defined scalar member attributes to store array sizes are
Scalar Description m The number of algebraic variables/equations n The number of algebraic variables/equations o The number of limiter state flags The derivatives of f and g with respect to x and y are stored in four
cvxopt.spmatrix
sparse matrices: fx, fy, gx, and gy, where the first letter is the equation name, and the second letter is the variable name.Notes
DAE in ANDES is defined in the form of
\[\begin{split}T \dot{x} = f(x, y) \\ 0 = g(x, y)\end{split}\]DAE does not keep track of the association of variable and address. Only a variable instance keeps track of its addresses.
-
build_pattern
(self, name)[source]¶ Build sparse matrices with stored patterns.
Call to store_row_col_idx should be made before this function.
Parameters: - name : name
jac name
-
fg
¶ Return a concatenated array of [f, g].
-
get_size
(self, name)[source]¶ Get the size of an array or sparse matrix based on name.
Parameters: - name : str (f, g, fx, gy, etc.)
array/sparse name
Returns: - tuple
sizes of each element in a tuple
-
resize_arrays
(self)[source]¶ Resize arrays to the new sizes m and n, and o.
If
m > len(self.y)
orn > len(self.x
, arrays will be extended. Otherwise, new empty arrays will be sliced, starting from 0 to the given size.
-
store_sparse_ijv
(self, name, row, col, val)[source]¶ Store the sparse pattern triplets.
This function is to be called by System after building the complete sparsity pattern for each Jacobian matrix.
Parameters: - name : str
sparse Jacobian matrix name
- row : np.ndarray
all row indices
- col : np.ndarray
all col indices
- val : np.ndarray
all values
-
write_npy
(self, npy_path)[source]¶ Write TDS data into NumPy output files.
TODO: Compress when the matrix is larger than 25 MB.
-
xy
¶ Return a concatenated array of [x, y].
-
xy_name
¶ Return a concatenated list of all variable names without format.
-
xy_tex_name
¶ Return a concatenated list of all variable names in LaTeX format.
-
xyz
¶ Return a concatenated array of [x, y].
-
xyz_name
¶ Return a concatenated list of all variable names without format.
-
xyz_tex_name
¶ Return a concatenated list of all variable names in LaTeX format.
-
-
class
andes.variables.dae.
DAETimeSeries
(dae=None)[source]¶ Bases:
object
DAE time series data
-
store_txyz
(self, t, xy, z=None)[source]¶ Store t, xy, and z in internal storage, respectively.
Parameters: - t : float
simulation time
- xy : array-like
array data for states and algebraic variables
- z : array-like or None
discrete flags data
-
txyz
¶ Return the values of [t, x, y, z] in an array.
-
unpack
(self, df=False)[source]¶ Unpack stored data in _xy and _z into arrays t, xy, and z.
Parameters: - df : bool
True to construct DataFrames self.df and self.df_z (time-consuming).
-
x
¶
-
y
¶
-
andes.variables.fileman module¶
andes.variables.report module¶
Module contents¶
Submodules¶
andes.cli module¶
andes.main module¶
-
andes.main.
config_logger
(stream=True, file=True, stream_level=20, log_file='andes.log', log_path=None, file_level=10)[source]¶ Configure a logger for the andes package with options for a FileHandler and a StreamHandler. This function is called at the beginning of
andes.main.main()
.Parameters: - stream : bool, optional
Create a StreamHandler for stdout if
True
. IfFalse
, the handler will not be created.- file : bool, optionsl
True if logging to
log_file
.- log_file : str, optional
Logg file name for FileHandler,
'andes.log'
by default. IfNone
, the FileHandler will not be created.- log_path : str, optional
Path to store the log file. By default, the path is generated by get_log_dir() in utils.misc.
- stream_level : {10, 20, 30, 40, 50}, optional
StreamHandler verbosity level.
- file_level : {10, 20, 30, 40, 50}, optional
FileHandler verbosity level.
- Returns
- -------
- None
-
andes.main.
doc
(attribute=None, list_supported=False, init_seq=False, config=False, **kwargs)[source]¶ Quick documentation from command-line.
-
andes.main.
edit_conf
(edit_config: Union[str, bool, NoneType] = '')[source]¶ Edit the Andes config file which occurs first in the search path.
Parameters: - edit_config : bool
If
True
, try to open up an editor and edit the config file. Otherwise returns.
Returns: - bool
True
is a config file is found and an editor is opened.False
ifedit_config
is False.
-
andes.main.
load
(case, codegen=False, setup=True, **kwargs)[source]¶ Load a case and set up without running. Return a system
Parameters: - case: str
Path to the test case
- codegen : bool, optional
Call full System.prepare on the returned system. Set to True if one need to inspect pretty-print equations and run simulations.
- setup : bool, optional
Call System.setup after loading
- Warnings
- -------
- If one need to add devices beside these from the case
- file, do ``setup=False`` and manually invoke ``setup()``
- after adding all devices.
-
andes.main.
misc
(edit_config='', save_config='', show_license=False, clean=True, recursive=False, overwrite=None, cli=False, **kwargs)[source]¶ Misc functions.
-
andes.main.
prepare
(quick=False, incremental=False, cli=False, **kwargs)[source]¶ Run code generation.
Returns: - System object
-
andes.main.
remove_output
(recursive=False)[source]¶ Remove the outputs generated by Andes, including power flow reports
_out.txt
, time-domain list_out.lst
and data_out.dat
, eigenvalue analysis report_eig.txt
.Parameters: - recursive : bool
Recursively clean all subfolders
Returns: - bool
True
is the function body executes with success.False
otherwise.
-
andes.main.
run
(filename, input_path='', verbose=20, mp_verbose=30, ncpu=2, pool=False, cli=False, codegen=False, shell=False, **kwargs)[source]¶ Entry point to run ANDES routines.
Parameters: - filename : str
file name (or pattern)
- input_path : str, optional
input search path
- verbose : int, 10 (DEBUG), 20 (INFO), 30 (WARNING), 40 (ERROR), 50 (CRITICAL)
Verbosity level
- mp_verbose : int
Verbosity level for multiprocessing tasks
- ncpu : int, optional
Number of cpu cores to use in parallel
- pool: bool, optional
Use Pool for multiprocessing to return a list of created Systems.
- kwargs
Other supported keyword arguments
- cli : bool, optional
If is running from command-line. If True, returns exit code instead of System
- return_code : bool, optional
Return exit code instead of system instances
- codegen : bool, optional
Run full code generation for System before loading case. Only used for single test case.
Returns: - System
An instance
-
andes.main.
run_case
(case, routine='pflow', profile=False, convert='', convert_all='', add_book=None, codegen=False, remove_pycapsule=False, **kwargs)[source]¶ Run a single simulation case.
-
andes.main.
save_conf
(config_path=None, overwrite=None)[source]¶ Save the Andes config to a file at the path specified by
save_config
. The save action will not run ifsave_config = ''
.Parameters: - config_path : None or str, optional, ('' by default)
Path to the file to save the config file. If the path is an emtpy string, the save action will not run. Save to ~/.andes/andes.conf if
None
.
Returns: - bool
True
is the save action is run.False
otherwise.
andes.plot module¶
The Andes plotting tool.
-
class
andes.plot.
TDSData
(full_name=None, mode='file', dae=None, path=None)[source]¶ Bases:
object
A data container for loading and plotting results from Andes time-domain simulation.
-
bqplot_data
(self, xdata, ydata, xheader=None, yheader=None, xlabel=None, ylabel=None, left=None, right=None, ymin=None, ymax=None, legend=True, grid=False, fig=None, latex=True, dpi=150, line_width=1.0, greyscale=False, savefig=None, save_format=None, show=True, **kwargs)[source]¶ Plot with
bqplot
. Experimental and imcomplete.
-
export_csv
(self, path=None, idx=None, header=None, formatted=False, sort_idx=True, fmt='%.18e')[source]¶ Export to a csv file.
Parameters: - path : str
path of the csv file to save
- idx : None or array-like, optional
the indices of the variables to export. Export all by default
- header : None or array-like, optional
customized header if not None. Use the names from the lst file by default
- formatted : bool, optional
Use LaTeX-formatted header. Does not apply when using customized header
- sort_idx : bool, optional
Sort by idx or not, # TODO: implement sort
- fmt : str
cell formatter
-
find
(self, query, exclude=None, formatted=False, idx_only=False)[source]¶ Return variable names and indices matching query.
Parameters: - query : str
The string for querying variables. Multiple conditions can be separated by comma without space.
- exclude : str, optional
A string pattern to be excluded
- formatted : bool, optional
True to return formatted names, False otherwise
- idx_only : bool, optional
True if only return indices
Returns: - (list, list)
(List of found indices, list of found names)
-
get_header
(self, idx, formatted=False)[source]¶ Return a list of the variable names at the given indices.
Parameters: - idx : list or int
The indices of the variables to retrieve
- formatted : bool
True to retrieve latex-formatted names, False for unformatted names
Returns: - list
A list of variable names (headers)
-
get_values
(self, idx)[source]¶ Return the variable values at the given indices.
Parameters: - idx : list
The indicex of the variables to retrieve. idx=0 is for Time. Variable indices start at 1.
Returns: - np.ndarray
Variable data
-
guess_event_time
(self)[source]¶ Guess the event starting time from the input data by checking when the values start to change
-
load_lst
(self)[source]¶ Load the lst file into internal data structures _idx, _fname, _uname, and counts the number of variables to nvars.
Returns: - None
-
load_npy_or_csv
(self, delimiter=', ')[source]¶ Load the npy or csv file into internal data structures self._xy.
Parameters: - delimiter : str, optional
The delimiter for the case file. Default to comma.
Returns: - None
-
plot
(self, yidx, xidx=(0, ), a=None, ycalc=None, left=None, right=None, ymin=None, ymax=None, ytimes=None, xlabel=None, ylabel=None, legend=None, grid=False, greyscale=False, latex=True, dpi=150, line_width=1.0, font_size=12, savefig=None, save_format=None, show=True, title=None, use_bqplot=False, **kwargs)[source]¶ Entery function for plot scripting. This function retrieves the x and y values based on the xidx and yidx inputs and then calls plot_data() to do the actual plotting.
Note that ytimes and ycalc are applied sequentially if apply.
Refer to plot_data() for the definition of arguments.
Parameters: - xidx : list or int
The index for the x-axis variable
- yidx : list or int
The indices for the y-axis variables
Returns: - (fig, ax)
Figure and axis handles
-
plot_data
(self, xdata, ydata, xheader=None, yheader=None, xlabel=None, ylabel=None, line_styles=None, left=None, right=None, ymin=None, ymax=None, legend=None, grid=False, fig=None, ax=None, latex=True, dpi=150, line_width=1.0, font_size=12, greyscale=False, savefig=None, save_format=None, show=True, title=None, **kwargs)[source]¶ Plot lines for the supplied data and options. This functions takes xdata and ydata values. If you provide variable indices instead of values, use plot().
Parameters: - xdata : array-like
An array-like object containing the values for the x-axis variable
- ydata : array
An array containing the values of each variables for the y-axis variable. The row of ydata must match the row of xdata. Each column correspondings to a variable.
- xheader : list
A list containing the variable names for the x-axis variable
- yheader : list
A list containing the variable names for the y-axis variable
- xlabel : str
Text label for the x axis
- ylabel : str
Text label for the y axis
- left : float
The starting value of the x axis
- right : float
The ending value of the x axis
- ymin : float
The minimum value of the y axis
- ymax : float
The maximum value of the y axis
- legend : bool
True to show legend and False otherwise
- grid : bool
True to show grid and False otherwise
- fig
Matplotlib fig object to draw the axis on
- ax
Matplotlib axis object to draw the lines on
- latex : bool
True to enable latex and False to disable
- greyscale : bool
True to use greyscale, False otherwise
- savefig : bool
True to save to png figure file
- save_format : str
File extension string (pdf, png or jpg) for the savefig format
- dpi : int
Dots per inch for screen print or save. savefig uses a minimum of 200 dpi
- line_width : float
Plot line width
- font_size : float
Text font size (labels and legends)
- show : bool
True to show the image
- kwargs
Optional kwargs
Returns: - (fig, ax)
The figure and axis handles
-
-
andes.plot.
add_plot
(x, y, xl, yl, fig, ax, LATEX=False, linestyle=None, **kwargs)[source]¶ Add plots to an existing plot
-
andes.plot.
check_init
(yval, yl)[source]¶ " Check initialization by comparing t=0 and t=end values for a flat run.
Warning
This function is deprecated as the initialization check feature is built into TDS. See
TDS.test_initialization()
.
-
andes.plot.
label_latexify
(label)[source]¶ Convert a label to latex format by appending surrounding $ and escaping spaces
Parameters: - label : str
The label string to be converted to latex expression
Returns: - str
A string with $ surrounding
-
andes.plot.
parse_y
(y, upper, lower=0)[source]¶ Parse command-line input for Y indices and return a list of indices
Parameters: - y : Union[List, Set, Tuple]
- Input for Y indices. Could be single item (with or without colon), or
multiple items
- upper : int
Upper limit. In the return list y, y[i] <= uppwer.
- lower : int
Lower limit. In the return list y, y[i] >= lower.
-
andes.plot.
scale_func
(k)[source]¶ Return a lambda function that scales its input by k
Parameters: - k : float
The scaling factor of the returned lambda function
- Returns
- -------
- Lambda function
-
andes.plot.
set_latex
(enable=True)[source]¶ Enables LaTeX for matplotlib based on the with_latex option and dvipng availability.
Parameters: - enable : bool, optional
True for latex on and False for off
Returns: - bool
True for LaTeX on, False for off
-
andes.plot.
tdsplot
(filename, y, x=(0, ), tocsv=False, find=None, xargs=None, exclude=None, **kwargs)[source]¶ TDS plot main function based on the new TDSData class
Parameters: - filename : str
Path to the ANDES TDS output data file. Works without extension.
- x : list or int, optional
The index for the x-axis variable. x=0 by default for time
- y : list or int
The indices for the y-axis variable
- tocsv : bool
True if need to export to a csv file
- find : str, optional
if not none, specify the variable name to find
- xargs : str, optional
similar to find, but return the result indices with file name, x idx name for xargs
- exclude : str, optional
variable name pattern to exclude
Returns: - TDSData object
andes.system module¶
System class for power system data and methods
-
class
andes.system.
System
(case: Optional[str] = None, name: Optional[str] = None, config_path: Optional[str] = None, options: Optional[Dict[KT, VT]] = None, **kwargs)[source]¶ Bases:
object
System contains models and routines for modeling and simulation.
System contains a several special OrderedDict member attributes for housekeeping. These attributes include models, groups, routines and calls for loaded models, groups, analysis routines, and generated numerical function calls, respectively.
Notes
System stores model and routine instances as attributes. Model and routine attribute names are the same as their class names. For example, Bus is stored at
system.Bus
, the power flow calculation routine is atsystem.PFlow
, and the numerical DAE instance is atsystem.dae
. See attributes for the list of attributes.Attributes: - dae : andes.variables.dae.DAE
Numerical DAE storage
- files : andes.variables.fileman.FileMan
File path storage
- config : andes.core.Config
System config storage
- models : OrderedDict
model name and instance pairs
- groups : OrderedDict
group name and instance pairs
- routines : OrderedDict
routine name and instance pairs
-
add
(self, model, param_dict=None, **kwargs)[source]¶ Add a device instance for an existing model.
This methods calls the
add
method of model and registers the device idx to group.
-
calc_pu_coeff
(self)[source]¶ Perform per unit value conversion.
This function calculates the per unit conversion factors, stores input parameters to vin, and perform the conversion.
-
call_models
(self, method: str, models: collections.OrderedDict, *args, **kwargs)[source]¶ Call methods on the given models.
Parameters: - method : str
Name of the model method to be called
- models : OrderedDict, list, str
Models on which the method will be called
- args
Positional arguments to be passed to the model method
- kwargs
Keyword arguments to be passed to the model method
Returns: - The return value of the models in an OrderedDict
-
dill
(self)[source]¶ Serialize generated numerical functions in System.calls with package dill.
The serialized file will be stored to
~/andes/calls.pkl
, where ~ is the home directory path.Notes
This function sets dill.settings['recurse'] = True to serialize the function calls recursively.
-
e_clear
(self, models: collections.OrderedDict)[source]¶ Clear equation arrays in DAE and model variables.
This step must be called before calling f_update or g_update to flush existing values.
-
f_update
(self, models: Union[str, List, collections.OrderedDict, NoneType] = None)[source]¶ Call the differential equation update method for models in sequence.
Notes
Updated equation values remain in models and have not been collected into DAE at the end of this step.
-
fg_to_dae
(self)[source]¶ Collect equation values into the DAE arrays.
Additionally, the function resets the differential equations associated with variables pegged by anti-windup limiters.
-
find_models
(self, flag: Union[str, Tuple, NoneType], skip_zero: bool = True)[source]¶ Find models with at least one of the flags as True.
Parameters: - flag : list, str
Flags to find
- skip_zero : bool
Skip models with zero devices
Returns: - OrderedDict
model name : model instance
Warning
Checking the number of devices has been centralized into this function.
models
passed to most System calls must be retrieved from here.
-
g_update
(self, models: Union[str, List, collections.OrderedDict, NoneType] = None)[source]¶ Call the algebraic equation update method for models in sequence.
Notes
Like f_update, updated values have not collected into DAE at the end of the step.
-
get_config
(self)[source]¶ Collect config data from models.
Returns: - dict
a dict containing the config from devices; class names are keys and configs in a dict are values.
-
get_z
(self, models: Union[str, List, collections.OrderedDict, NoneType] = None)[source]¶ Get all discrete status flags in a numpy array.
Returns: - numpy.array
-
import_groups
(self)[source]¶ Import all groups classes defined in
devices/group.py
.Groups will be stored as instances with the name as class names. All groups will be stored to dictionary
System.groups
.
-
import_models
(self)[source]¶ Import and instantiate models as System member attributes.
Models defined in
models/__init__.py
will be instantiated sequentially as attributes with the same name as the class name. In addition, all models will be stored in dictionarySystem.models
with model names as keys and the corresponding instances as values.Examples
system.Bus
stores the Bus object, andsystem.GENCLS
stores the classical generator object,system.models['Bus']
points the same instance assystem.Bus
.
-
import_routines
(self)[source]¶ Import routines as defined in
routines/__init__.py
.Routines will be stored as instances with the name as class names. All groups will be stored to dictionary
System.groups
.Examples
System.PFlow
is the power flow routine instance, andSystem.TDS
andSystem.EIG
are time-domain analysis and eigenvalue analysis routines, respectively.
-
init
(self, models: collections.OrderedDict)[source]¶ Initialize the variables for each of the specified models.
For each model, the initialization procedure is:
- Get values for all ExtService.
- Call the model init() method, which initializes internal variables.
- Copy variables to DAE and then back to the model.
-
j_update
(self, models: collections.OrderedDict)[source]¶ Call the Jacobian update method for models in sequence.
The procedure is - Restore the sparsity pattern with
andes.variables.dae.DAE.restore_sparse()
- For each sparse matrix in (fx, fy, gx, gy), evaluate the Jacobian function calls and add values.Notes
Updated Jacobians are immediately reflected in the DAE sparse matrices (fx, fy, gx, gy).
-
l_update_eq
(self, models: collections.OrderedDict)[source]¶ First, update equation-dependent limiter discrete components by calling
l_check_eq
of models. Second, force set equations after evaluating equations by callingl_set_eq
of models.This function is must be called after differential equation updates.
-
l_update_var
(self, models: collections.OrderedDict)[source]¶ Update variable-based limiter discrete states by calling
l_update_var
of models.This function is must be called before any equation evaluation.
-
static
load_config
(conf_path=None)[source]¶ Load config from an rc-formatted file.
Parameters: - conf_path : None or str
Path to the config file. If is None, the function body will not run.
Returns: - configparse.ConfigParser
-
prepare
(self, quick=False, incremental=False)[source]¶ Generate numerical functions from symbolically defined models.
All procedures in this function must be independent of test case.
Parameters: - quick : bool, optional
True to skip pretty-print generation to reduce code generation time.
- incremental : bool, optional
True to generate only for modified models, incrementally.
Warning
Generated lambda functions will be serialized to file, but pretty prints (SymPy objects) can only exist in the System instance on which prepare is called.
Notes
Option
incremental
compares the md5 checksum of all var and service strings, and only regenerate for updated models.Examples
If one needs to print out LaTeX-formatted equations in a Jupyter Notebook, one need to generate such equations with
import andes sys = andes.prepare()
Alternatively, one can explicitly create a System and generate the code
import andes sys = andes.System() sys.prepare()
-
reset
(self)[source]¶ Reset to the state after reading data and setup (before power flow).
Warning
If TDS is initialized, reset will lead to unpredictable state.
-
s_update_post
(self, models: collections.OrderedDict)[source]¶ Update variable services by calling
s_update_post
of models.This function is called at the end of System.init().
-
s_update_var
(self, models: collections.OrderedDict)[source]¶ Update variable services by calling
s_update_var
of models.This function is must be called before any equation evaluation after limiter update function l_update_var.
-
save_config
(self, file_path=None, overwrite=False)[source]¶ Save all system, model, and routine configurations to an rc-formatted file.
Parameters: - file_path : str, optional
path to the configuration file default to ~/andes/andes.rc.
- overwrite : bool, optional
If file exists, True to overwrite without confirmation. Otherwise prompt for confirmation.
Warning
Saved config is loaded back and populated at system instance creation time. Configs from the config file takes precedence over default config values.
-
set_config
(self, config=None)[source]¶ Set configuration for the System object.
Config for models are routines are passed directly to their constructors.
-
set_dae_names
(self, models)[source]¶ Set variable names for differential and algebraic variables, and discrete flags.
-
setup
(self)[source]¶ Set up system for studies.
This function is to be called after adding all device data.
-
store_adder_setter
(self, models)[source]¶ Store non-inplace adders and setters for variables and equations.
-
store_existing
(self)[source]¶ Store existing models in System.existing.
TODO: Models with TimerParam will need to be stored anyway. This will allow adding switches on the fly.
-
store_sparse_pattern
(self, models: collections.OrderedDict)[source]¶ Collect and store the sparsity pattern of Jacobian matrices.
This is a runtime function specific to cases.
Notes
For gy matrix, always make sure the diagonal is reserved. It is a safeguard if the modeling user omitted the diagonal term in the equations.
-
store_switch_times
(self, models)[source]¶ Store event switching time in a sorted Numpy array at
System.switch_times
.Returns: - array-like
self.switch_times
-
supported_models
(self, export='plain')[source]¶ Return the support group names and model names in a table.
Returns: - str
A table-formatted string for the groups and models
-
undill
(self)[source]¶ Deserialize the function calls from
~/andes.calls.pkl
with dill.If no change is made to models, future calls to
prepare()
can be replaced withundill()
for acceleration.