This example gives a "hello world" example to use AMS.
We first import the ams
library.
import ams
We can configure the verbosity level for logging (output messages) by passing a verbosity level (10-DEBUG, 20-INFO, 30-WARNING, 40-ERROR, 50-CRITICAL) to the stream_level
argument of ams.main.config_logger()
. Verbose level 10 is useful for getting debug output.
The logging level can be altered by calling config_logger
again with new stream_level
and file_level
.
ams.config_logger(stream_level=20)
Note that the above ams.config_logger()
is a shorthand to ams.main.config_logger()
.
If this step is omitted, the default INFO
level (stream_level=20
) will be used.
AMS supports multiple input file formats, including AMS .xlsx
file, MATPOWER .m
file, PYPOWER .py
file, and PSS/E .raw
file.
Here we use the AMS .xlsx
file as an example. The source file locates at $HOME/ams/ams/cases/ieee39/ieee39_uced.xlsx
.
sp = ams.load(ams.get_case('5bus/pjm5bus_uced.xlsx'),
setup=True,
no_output=True,)
Parsing input file "/Users/jinningwang/work/miniconda3/envs/amsre/lib/python3.12/site-packages/ams/cases/5bus/pjm5bus_uced.xlsx"... Input file parsed in 0.1254 seconds. Zero line rates detacted in rate_b, rate_c, adjusted to 999. System set up in 0.0016 seconds.
In AMS, model
refers to the device-level models, and they are registered to an OrderedDict models
.
sp.models
OrderedDict([('Summary', Summary (3 devices) at 0x1044cecf0), ('Bus', Bus (5 devices) at 0x103f4e840), ('PQ', PQ (3 devices) at 0x336e2ab10), ('Slack', Slack (1 device) at 0x336e2b620), ('PV', PV (3 devices) at 0x336e2bfe0), ('Shunt', Shunt (0 devices) at 0x336e54aa0), ('Line', Line (7 devices) at 0x336e54e90), ('Jumper', Jumper (0 devices) at 0x336e55a00), ('PVD1', PVD1 (0 devices) at 0x336e28890), ('ESD1', ESD1 (0 devices) at 0x336e56690), ('EV1', EV1 (0 devices) at 0x336e56ba0), ('EV2', EV2 (0 devices) at 0x336e571a0), ('REGCA1', REGCA1 (0 devices) at 0x336e575c0), ('REGCV1', REGCV1 (0 devices) at 0x336e57d10), ('REGCV2', REGCV2 (0 devices) at 0x336e883e0), ('Area', Area (3 devices) at 0x336e88950), ('Zone', Zone (2 devices) at 0x336c8bd40), ('SFR', SFR (2 devices) at 0x336e2ae40), ('SR', SR (2 devices) at 0x336e89b50), ('NSR', NSR (2 devices) at 0x336e89f40), ('VSGR', VSGR (0 devices) at 0x336e8a300), ('GCost', GCost (4 devices) at 0x336e8a6f0), ('SFRCost', SFRCost (4 devices) at 0x336e8b0b0), ('SRCost', SRCost (4 devices) at 0x336e8b620), ('NSRCost', NSRCost (4 devices) at 0x336e8b9e0), ('VSGCost', VSGCost (0 devices) at 0x336e8bdd0), ('DCost', DCost (3 devices) at 0x336ec00e0), ('TimeSlot', TimeSlot (0 devices) at 0x336e57710), ('EDTSlot', EDTSlot (24 devices) at 0x336ec0c50), ('UCTSlot', UCTSlot (24 devices) at 0x336ec1040)])
We can inspect the detailed model data in the form of DataFrame.
sp.PQ.as_df()
idx | u | name | bus | Vn | p0 | q0 | vmax | vmin | owner | ctrl | |
---|---|---|---|---|---|---|---|---|---|---|---|
uid | |||||||||||
0 | PQ_1 | 1.0 | PQ 1 | Bus_2 | 230.0 | 3.0 | 0.9861 | 1.1 | 0.9 | None | 1.0 |
1 | PQ_2 | 1.0 | PQ 2 | Bus_3 | 230.0 | 3.0 | 0.9861 | 1.1 | 0.9 | None | 1.0 |
2 | PQ_3 | 1.0 | PQ 3 | Bus_4 | 230.0 | 4.0 | 1.3147 | 1.1 | 0.9 | None | 1.0 |
In AMS, all supported routines are registered to an OrderedDict routines
.
sp.routines
OrderedDict([('DCPF', DCPF at 0x336e2a3f0), ('PFlow', PFlow at 0x3351be300), ('CPF', CPF at 0x336ed9c70), ('ACOPF', ACOPF at 0x336f7cb60), ('DCOPF', DCOPF at 0x336f7da00), ('DCOPF2', DCOPF2 at 0x336f7ef30), ('ED', ED at 0x336fcc320), ('EDDG', EDDG at 0x336fcfaa0), ('EDES', EDES at 0x337001760), ('RTED', RTED at 0x337003ec0), ('RTEDDG', RTEDDG at 0x3370454f0), ('RTEDES', RTEDES at 0x337046c30), ('RTEDVIS', RTEDVIS at 0x337084c50), ('UC', UC at 0x336eda0f0), ('UCDG', UCDG at 0x339c36540), ('UCES', UCES at 0x339d52ed0), ('DOPF', DOPF at 0x339d81a00), ('DOPFVIS', DOPFVIS at 0x339d83230), ('PFlow0', PFlow0 at 0x339d83f20), ('DCPF0', DCPF0 at 0x339dc0e00)])
Before solving a routine, we need to initialize it first. Here Real-time Economic Dispatch (RTED) is used as an example.
sp.RTED.init()
Building system matrices Parsing OModel for <RTED> Evaluating OModel for <RTED> Finalizing OModel for <RTED> <RTED> initialized in 0.0105 seconds.
True
Then, one can solve it by calling run()
.
Here, argument solver
can be passed to specify the solver to use, such as solver='ECOS'
.
Installed solvers can be listed by ams.shared.installed_solvers
,
and more detailes of solver can be found at CVXPY-Choosing a solver.
ams.shared.installed_solvers
['CLARABEL', 'ECOS', 'ECOS_BB', 'GUROBI', 'HIGHS', 'MOSEK', 'OSQP', 'PIQP', 'SCIP', 'SCIPY', 'SCS']
sp.RTED.run(solver='CLARABEL')
<RTED> solved as optimal in 0.0139 seconds, converged in 10 iterations with CLARABEL.
True
The solved results are stored in each variable itself.
For example, the solved power generation of ten generators
are stored in pg.v
.
sp.RTED.pg.v
array([2.1, 5.2, 0.7, 2. ])
Here, get_all_idxes()
can be used to get the index of a variable.
sp.RTED.pg.get_all_idxes()
['PV_1', 'PV_3', 'PV_5', 'Slack_4']
Part of the solved results can be accessed with given indices.
sp.RTED.get(src='pg', attr='v', idx=['PV_1', 'PV_3'])
array([2.1, 5.2])
All Vars are listed in an OrderedDict vars
.
sp.RTED.vars
OrderedDict([('pg', Var: StaticGen.pg), ('vBus', Var: Bus.vBus), ('aBus', Var: Bus.aBus), ('pru', Var: StaticGen.pru), ('prd', Var: StaticGen.prd)])
The Objective value can be accessed with obj.v
.
sp.RTED.obj.v
np.float64(0.19537500002212993)
Similarly, all Constrs are listed in an OrderedDict constrs
,
and the expression values can also be accessed.
sp.RTED.constrs
OrderedDict([('pb', Constraint: pb [ON]), ('sba', Constraint: sbus [ON]), ('pglb', Constraint: pglb [ON]), ('pgub', Constraint: pgub [ON]), ('plflb', Constraint: plflb [ON]), ('plfub', Constraint: plfub [ON]), ('alflb', Constraint: alflb [ON]), ('alfub', Constraint: alfub [ON]), ('rbu', Constraint: rbu [ON]), ('rbd', Constraint: rbd [ON]), ('rru', Constraint: rru [ON]), ('rrd', Constraint: rrd [ON]), ('rgu', Constraint: rgu [ON]), ('rgd', Constraint: rgd [ON])])
We can also inspect the Constraint
values.
sp.RTED.rgu.v
array([ -997.9 , -997.0349, -1002.9651, -997. ])