This example shows how to inspect the data of a loaded test system.
import andes
from andes.utils.paths import get_case
To show all the rows and columns, change the pandas configuration with
import pandas as pd
pd.options.display.max_columns = None
pd.options.display.max_rows = None
Let's load the Kundur's system.
The ANDES xlsx file is the best supported format. Other formats can be converted to the xlsx format.
See the link below for more about format conversion. https://github.com/cuihantao/andes/blob/master/README.md#format-converter
ss = andes.run(get_case('kundur/kundur_full.xlsx'))
Working directory: "/Users/hcui7/repos/andes/examples" Loaded config from file "/Users/hcui7/.andes/andes.rc" Parsing input file "/Users/hcui7/repos/andes/andes/cases/kundur/kundur_full.xlsx" Input file parsed in 0.0512 seconds. -> Power flow calculation Sparse Solver: KLU Method: NR method Power flow initialized. 0: |F(x)| = 14.9283 1: |F(x)| = 3.60858 2: |F(x)| = 0.17009 3: |F(x)| = 0.00203822 4: |F(x)| = 3.76399e-07 Converged in 5 iterations in 0.0086 seconds. Initialization was successful in 0.0196 seconds. Report saved to "kundur_full_out.txt" in 0.0026 seconds. -> Single process finished in 0.1531 seconds.
Alternatively, ANDES supports loading systems from PSS/E RAW and DYR files.
The PSS/E v32 raw format is best supported.
Note that this feature is experimental. We try out best to support this format, but the compatibility is not guaranteed.
raw_path = get_case('kundur/kundur.raw')
dyr_path = get_case('kundur/kundur_full.dyr')
The raw file is passed to the positional argument, whereas the dyr file is passed to addfile
.
ss = andes.run(raw_path, addfile=dyr_path)
Working directory: "/Users/hcui7/repos/andes/examples" Loaded config from file "/Users/hcui7/.andes/andes.rc" Parsing input file "/Users/hcui7/repos/andes/andes/cases/kundur/kundur.raw" MODIFIED KUNDUR'S TWO-AREA TEST SYSTEM, DISTRIBUTED WITH ANDES SEE THE BOOK "POWER SYSTEM STABILITY AND CONTROL" FOR ORIGINAL DATA Input file parsed in 0.0041 seconds. Parsing additional file "/Users/hcui7/repos/andes/andes/cases/kundur/kundur_full.dyr" Addfile parsed in 0.0627 seconds. -> Power flow calculation Sparse Solver: KLU Method: NR method Power flow initialized. 0: |F(x)| = 3.17585 1: |F(x)| = 3.17626e-06 2: |F(x)| = 3.33604e-10 Converged in 3 iterations in 0.0048 seconds. Initialization was successful in 0.0178 seconds. Report saved to "kundur_out.txt" in 0.0021 seconds. -> Single process finished in 0.1606 seconds.
Parameters are stored as attributes of the model. For example, ss.GENROU.M
, which is the machine starting time constant (2H
) is stored in ss.GENROU.M
.
ss.GENROU.M
<andes.core.param.NumParam at 0x7fd5aa2145c0>
It is an instance of NumParam
, which contains fields v
for the values after converting to system-base per unit values.
ss.GENROU.M.v
array([117. , 117. , 111.15, 111.15])
And field vin
is for the original input data.
ss.GENROU.M.vin
array([13. , 13. , 12.35, 12.35])
ANDES provides tabulated view of model parameters by using DataFrame. Each model object has an attribute called cache
for caching the parameter dataframes.
The original parameters from the input file are stored in cache.df_in
of the model object. For GENROU
, do
ss.GENROU.cache.df_in
idx | u | name | bus | gen | coi | Sn | Vn | fn | D | M | ra | xl | xd1 | kp | kw | S10 | S12 | xd | xq | xd2 | xq1 | xq2 | Td10 | Td20 | Tq10 | Tq20 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
uid | |||||||||||||||||||||||||||
0 | GENROU_1 | 1.0 | GENROU_1 | 1 | 1 | None | 900.0 | 20.0 | 60.0 | 0.0 | 13.00 | 0.0 | 0.06 | 0.3 | 0.0 | 0.0 | 0.0 | 0.0 | 1.8 | 1.7 | 0.25 | 0.55 | 0.25 | 8.0 | 0.03 | 0.4 | 0.05 |
1 | GENROU_2 | 1.0 | GENROU_2 | 2 | 2 | None | 900.0 | 20.0 | 60.0 | 0.0 | 13.00 | 0.0 | 0.06 | 0.3 | 0.0 | 0.0 | 0.0 | 0.0 | 1.8 | 1.7 | 0.25 | 0.55 | 0.25 | 8.0 | 0.03 | 0.4 | 0.05 |
2 | GENROU_3 | 1.0 | GENROU_3 | 3 | 3 | None | 900.0 | 20.0 | 60.0 | 0.0 | 12.35 | 0.0 | 0.06 | 0.3 | 0.0 | 0.0 | 0.0 | 0.0 | 1.8 | 1.7 | 0.25 | 0.55 | 0.25 | 8.0 | 0.03 | 0.4 | 0.05 |
3 | GENROU_4 | 1.0 | GENROU_4 | 4 | 4 | None | 900.0 | 20.0 | 60.0 | 0.0 | 12.35 | 0.0 | 0.06 | 0.3 | 0.0 | 0.0 | 0.0 | 0.0 | 1.8 | 1.7 | 0.25 | 0.55 | 0.25 | 8.0 | 0.03 | 0.4 | 0.05 |
Parameters will be converted to per-unit in the system base after loading. This process have been done if andes.run
is used for loading the data file.
To inspect the converted parameters, check the cache.df
parameter.
ss.GENROU.cache.df
idx | u | name | bus | gen | coi | Sn | Vn | fn | D | M | ra | xl | xd1 | kp | kw | S10 | S12 | xd | xq | xd2 | xq1 | xq2 | Td10 | Td20 | Tq10 | Tq20 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
uid | |||||||||||||||||||||||||||
0 | GENROU_1 | 1.0 | GENROU_1 | 1 | 1 | None | 900.0 | 20.0 | 60.0 | 0.0 | 117.00 | 0.0 | 0.006667 | 0.033333 | 0.0 | 0.0 | 0.0 | 0.0 | 0.2 | 0.188889 | 0.027778 | 0.061111 | 0.027778 | 8.0 | 0.03 | 0.4 | 0.05 |
1 | GENROU_2 | 1.0 | GENROU_2 | 2 | 2 | None | 900.0 | 20.0 | 60.0 | 0.0 | 117.00 | 0.0 | 0.006667 | 0.033333 | 0.0 | 0.0 | 0.0 | 0.0 | 0.2 | 0.188889 | 0.027778 | 0.061111 | 0.027778 | 8.0 | 0.03 | 0.4 | 0.05 |
2 | GENROU_3 | 1.0 | GENROU_3 | 3 | 3 | None | 900.0 | 20.0 | 60.0 | 0.0 | 111.15 | 0.0 | 0.006667 | 0.033333 | 0.0 | 0.0 | 0.0 | 0.0 | 0.2 | 0.188889 | 0.027778 | 0.061111 | 0.027778 | 8.0 | 0.03 | 0.4 | 0.05 |
3 | GENROU_4 | 1.0 | GENROU_4 | 4 | 4 | None | 900.0 | 20.0 | 60.0 | 0.0 | 111.15 | 0.0 | 0.006667 | 0.033333 | 0.0 | 0.0 | 0.0 | 0.0 | 0.2 | 0.188889 | 0.027778 | 0.061111 | 0.027778 | 8.0 | 0.03 | 0.4 | 0.05 |
One will notice the converted parameters such as M
, xl
, and all other impedances.
It is very important to notice that cache.df
and cache.df_in
are both views. Altering data in these views will NOT alter the underlying parameter values.
To alter values, see the example below.
Parameters can be altered by calling the alter
method on a model instance.
We first look up the original value through get
.
Either v
or vin
can be passed to argument attr
to retrieve the converted or the original data. Here we are retrieving the original input data. If attr
is not provided, get
returns the value after per-unit conversion, which is the value used for calculation, by default.
ss.GENROU.get("M", "GENROU_1", attr='vin')
13.0
To change the M
of GENROU_1
to 10
, do
ss.GENROU.alter("M", "GENROU_1", 10)
The value set through alter
is always the data before per-unit conversion - just like it should have been in an input file. ANDES will perform the conversion and set vin
and v
correctly.
As mentioned, cache.df
and cache.df_in
are cached views and will not be automatically updated for inspection.
This is generally not an issue if one performs the simulation after altering data. However, if one needs to inspect the data again, cache.refresh()
needs to be called manually.
ss.GENROU.cache.refresh()
ss.GENROU.cache.df_in
idx | u | name | bus | gen | coi | Sn | Vn | fn | D | M | ra | xl | xq | kp | kw | S10 | S12 | xd | xd1 | xd2 | xq1 | xq2 | Td10 | Td20 | Tq10 | Tq20 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
uid | |||||||||||||||||||||||||||
0 | GENROU_1 | 1.0 | GENROU_1 | 1 | 1 | None | 900.0 | 20.0 | 60.0 | 0.0 | 10.00 | 0.0 | 0.06 | 1.7 | 0.0 | 0.0 | 0.0 | 1.0 | 1.8 | 0.3 | 0.25 | 0.55 | 0.25 | 8.0 | 0.03 | 0.4 | 0.05 |
1 | GENROU_2 | 1.0 | GENROU_2 | 2 | 2 | None | 900.0 | 20.0 | 60.0 | 0.0 | 13.00 | 0.0 | 0.06 | 1.7 | 0.0 | 0.0 | 0.0 | 1.0 | 1.8 | 0.3 | 0.25 | 0.55 | 0.25 | 8.0 | 0.03 | 0.4 | 0.05 |
2 | GENROU_3 | 1.0 | GENROU_3 | 3 | 3 | None | 900.0 | 20.0 | 60.0 | 0.0 | 12.35 | 0.0 | 0.06 | 1.7 | 0.0 | 0.0 | 0.0 | 1.0 | 1.8 | 0.3 | 0.25 | 0.55 | 0.25 | 8.0 | 0.03 | 0.4 | 0.05 |
3 | GENROU_4 | 1.0 | GENROU_4 | 4 | 4 | None | 900.0 | 20.0 | 60.0 | 0.0 | 12.35 | 0.0 | 0.06 | 1.7 | 0.0 | 0.0 | 0.0 | 1.0 | 1.8 | 0.3 | 0.25 | 0.55 | 0.25 | 8.0 | 0.03 | 0.4 | 0.05 |
One might also want to check the variable values in a similar way to that for a parameter. Certainly, a variable has a v
attribute which stores values.
It is important to note that v
only holds the values at the last program state. Such program state could be the solution of power flow, the initialization of time-domain simulation, or the end of a simulation disturbances.
Since we have only ran power flow for ss
, ss.Bus.v.v
are the voltage magnitude solutions, where the first v
is for "voltage", and the second v
is the first v
's value attribute.
ss.Bus.v.v
array([1. , 1. , 1. , 1. , 0.98337472, 0.96908585, 0.9562181 , 0.95400018, 0.96856366, 0.98377143])
Variables hold more than values. They have an attribute a
for the addresses indexing into the corresponding type of array.
There are two system-level arrays, ss.dae.x
and ss.dae.y
for the right-hand-side of the differential and algebraic equations, respectively.
type(ss.Bus.v)
andes.core.var.Algeb
ss.Bus.v
is an algebraic variable, thus ss.Bus.v.a
holds the indices into ss.dae.g
.
ss.dae.y[ss.Bus.v.a]
array([1. , 1. , 1. , 1. , 0.98337472, 0.96908585, 0.9562181 , 0.95400018, 0.96856366, 0.98377143])
We can see that these two values are the same.
After a time-domain simulation, the time series of the variables can be retrieved through ss.dae.ts
. Let's first run a simulation.
ss.TDS.run()
-> Time Domain Simulation Summary: Sparse Solver: KLU Simulation time: 0.0-20.0 sec. Fixed step size: h=33.33 msec., shrink if not converged
<Toggler Toggler_1>: Line.Line_8 status changed to 0 at t=2.0 sec. 100%|████████████████████████████████| 100/100 [00:01<00:00, 68.97%/s]
Simulation completed in 1.4504 seconds. TDS outputs saved in 0.0290 seconds.
True
ss.dae.ts
<andes.variables.dae.DAETimeSeries at 0x7fd5a9625160>
ss.dae.ts
has four commonly used attributes: t
for time stamps, xy
for variables (differential and then algebraic), z
for discontinuous states, and df
for the dataframe of all.
ss.dae.ts.t
correspond to a row in ss.dae.ts.xy
.ss.dae.ts.xy
correspond to a variable, whose name can be located in ss.dae.xy_name
, for all timestamps.z
is not stored by default unless one enables it before simulation by setting ss.TDS.config.store_z = 1
.df
is not built by default but can be manually triggered after simulation by calling ss.dae.ts.unpack(df=True)
The following are some statistics of the shapes of arrays:
ss.dae.ts.t.shape
(602,)
ss.dae.ts.xy.shape
(602, 192)
len(ss.dae.xy_name)
192
!andes misc -C
_ _ | Version 0.8.8.post41.dev0+g56198e1 /_\ _ _ __| |___ ___ | Python 3.7.3 on Linux, 05/02/2020 12:52:41 PM / _ \| ' \/ _` / -_|_-< | /_/ \_\_||_\__,_\___/__/ | This program comes with ABSOLUTELY NO WARRANTY. <kundur_full_out.txt> removed.