Prepared by Jinning Wang.
For test cases, DCOPF results from AMS are identical to that from PYPOWER.
NOTE: This verification works with PYPOWER *v5.1.16, where v5.1.17* yields unexpected results.
import datetime
import numpy as np
import pandas as pd
import ams
import andes
import pypower.api as pyp
print("Last run time:", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
print(f'ams: {ams.__version__}')
Last run time: 2024-11-24 21:03:09 ams: 0.9.12
ams.config_logger(stream_level=30)
Using built-in MATPOWER cases as inputs.
cases = [
ams.get_case('matpower/case14.m'),
ams.get_case('matpower/case39.m'),
ams.get_case('matpower/case118.m'),
ams.get_case('npcc/npcc.m'),
ams.get_case('wecc/wecc.m'),
ams.get_case('matpower/case300.m'),]
case_names = [case.split('/')[-1].split('.')[0] for case in cases]
ams_obj = np.zeros(len(cases))
pyp_obj = np.zeros(len(cases))
for i, case in enumerate(cases):
sp = ams.load(case, setup=True)
sp.DCOPF.init()
sp.DCOPF.run(solver='CLARABEL')
ams_obj[i] = sp.DCOPF.obj.v
ppc = ams.io.pypower.system2ppc(sp)
ppopt = pyp.ppoption(VERBOSE=0, OUT_ALL=0, PF_ALG=1, OPF_ALG_DC=200)
ppc_sol = pyp.rundcopf(ppc, ppopt)
pyp_obj[i] = ppc_sol['f']
Building system matrices Parsing OModel for <DCOPF> Evaluating OModel for <DCOPF> Finalizing OModel for <DCOPF> <DCOPF> solved as optimal in 0.0065 seconds, converged in 11 iterations with CLARABEL. Building system matrices Parsing OModel for <DCOPF> Evaluating OModel for <DCOPF> Finalizing OModel for <DCOPF> <DCOPF> solved as optimal in 0.0077 seconds, converged in 8 iterations with CLARABEL. Building system matrices Parsing OModel for <DCOPF> Evaluating OModel for <DCOPF> Finalizing OModel for <DCOPF> <DCOPF> solved as optimal in 0.0144 seconds, converged in 11 iterations with CLARABEL. Building system matrices Parsing OModel for <DCOPF> Evaluating OModel for <DCOPF> Finalizing OModel for <DCOPF> <DCOPF> solved as optimal in 0.0164 seconds, converged in 12 iterations with CLARABEL. Building system matrices Parsing OModel for <DCOPF> Evaluating OModel for <DCOPF> Finalizing OModel for <DCOPF> <DCOPF> solved as optimal in 0.0160 seconds, converged in 12 iterations with CLARABEL. Building system matrices Parsing OModel for <DCOPF> Evaluating OModel for <DCOPF> Finalizing OModel for <DCOPF> <DCOPF> solved as optimal in 0.0226 seconds, converged in 13 iterations with CLARABEL.
np.allclose(ams_obj, pyp_obj, atol=1e-6)
True
sp2 = ams.load(ams.get_case('pglib/pglib_opf_case39_epri__api.m'),
setup=True,
no_output=True,
default_config=True)
sp2.DCOPF.run(solver='CLARABEL')
Building system matrices Parsing OModel for <DCOPF> Evaluating OModel for <DCOPF> Finalizing OModel for <DCOPF> <DCOPF> solved as optimal in 0.0072 seconds, converged in 13 iterations with CLARABEL.
True
ppc2 = ams.io.pypower.system2ppc(sp2)
ppc2_sol = pyp.rundcopf(ppc2, ppopt)
Nodal price
np.allclose(sp2.DCOPF.pi.v / sp2.config.mva,
ppc2_sol['bus'][:, 13],
atol=1e-6)
True
Bus angle
np.allclose(sp2.DCOPF.aBus.v * andes.shared.rad2deg,
ppc2_sol['bus'][:, 8],
atol=1e-6)
True
pd.DataFrame({'ams_LMP': sp2.DCOPF.pi.v / sp2.config.mva,
'pyp_LMP': ppc2_sol['bus'][:, 13],
'ams_aBus': sp2.DCOPF.aBus.v * andes.shared.rad2deg,
'pyp_aBus': ppc2_sol['bus'][:, 8]}).round(4)
ams_LMP | pyp_LMP | ams_aBus | pyp_aBus | |
---|---|---|---|---|
0 | 29.9988 | 29.9988 | -25.6184 | -25.6184 |
1 | 34.2147 | 34.2147 | -26.8519 | -26.8519 |
2 | 35.6012 | 35.6012 | -30.4965 | -30.4965 |
3 | 38.1542 | 38.1542 | -28.8548 | -28.8548 |
4 | 20.1311 | 20.1311 | -24.4545 | -24.4545 |
5 | 20.9823 | 20.9823 | -22.9110 | -22.9110 |
6 | 21.0918 | 21.0918 | -26.4821 | -26.4821 |
7 | 21.1466 | 21.1466 | -27.2531 | -27.2531 |
8 | 24.8701 | 24.8701 | -24.5329 | -24.5329 |
9 | 24.8047 | 24.8047 | -21.2851 | -21.2851 |
10 | 23.5694 | 23.5694 | -21.8833 | -21.8833 |
11 | 24.8047 | 24.8047 | -22.4869 | -22.4869 |
12 | 26.0400 | 26.0400 | -22.7386 | -22.7386 |
13 | 34.3071 | 34.3071 | -26.2107 | -26.2107 |
14 | 34.6822 | 34.6822 | -29.2227 | -29.2227 |
15 | 34.8446 | 34.8446 | -27.6899 | -27.6899 |
16 | 34.9985 | 34.9985 | -29.5901 | -29.5901 |
17 | 35.2283 | 35.2283 | -30.6918 | -30.6918 |
18 | 34.8446 | 34.8446 | -21.3650 | -21.3650 |
19 | 34.8446 | 34.8446 | -23.3981 | -23.3981 |
20 | 34.8446 | 34.8446 | -24.2513 | -24.2513 |
21 | 34.8446 | 34.8446 | -17.0667 | -17.0667 |
22 | 34.8446 | 34.8446 | -17.0905 | -17.0905 |
23 | 34.8446 | 34.8446 | -27.0536 | -27.0536 |
24 | 34.3071 | 34.3071 | -25.0737 | -25.0737 |
25 | 34.6544 | 34.6544 | -28.2256 | -28.2256 |
26 | 34.8125 | 34.8125 | -30.9591 | -30.9591 |
27 | 34.6544 | 34.6544 | -24.1366 | -24.1366 |
28 | 34.6544 | 34.6544 | -19.8996 | -19.8996 |
29 | 34.2147 | 34.2147 | -26.7668 | -26.7668 |
30 | 20.9823 | 20.9823 | 0.0000 | 0.0000 |
31 | 24.8047 | 24.8047 | -11.0741 | -11.0741 |
32 | 34.8446 | 34.8446 | -14.3249 | -14.3249 |
33 | 34.8446 | 34.8446 | -14.2720 | -14.2720 |
34 | 32.3065 | 32.3065 | -9.5084 | -9.5084 |
35 | 18.1575 | 18.1575 | -3.0644 | -3.0644 |
36 | 31.5502 | 31.5502 | -12.8112 | -12.8112 |
37 | 34.6544 | 34.6544 | -9.0065 | -9.0065 |
38 | 27.4344 | 27.4344 | -22.5664 | -22.5664 |