DCOPF Verification#

Prepared by Jinning Wang.

Conclusion#

For test cases, DCOPF results from AMS are identical to that from MATPOWER.

[1]:
import datetime

import numpy as np

import ams
import andes

import pypower.api as pyp
[2]:
print("Last run time:", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

print(f'ams: {ams.__version__}')
Last run time: 2024-04-21 17:30:41
ams: 0.9.6
[3]:
ams.config_logger(stream_level=30)

Generator Output#

Using built-in MATPOWER cases as inputs.

[4]:
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]
[5]:
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='ECOS')
    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']
<DCOPF> solved as optimal in 0.0080 seconds, converged in 13 iterations with ECOS.
<DCOPF> solved as optimal in 0.0097 seconds, converged in 17 iterations with ECOS.
<DCOPF> solved as optimal in 0.0194 seconds, converged in 15 iterations with ECOS.
<DCOPF> solved as optimal in 0.0200 seconds, converged in 17 iterations with ECOS.
<DCOPF> solved as optimal in 0.0211 seconds, converged in 17 iterations with ECOS.
<DCOPF> solved as optimal in 0.0321 seconds, converged in 17 iterations with ECOS.
[6]:
np.allclose(ams_obj, pyp_obj, atol=1e-6)
[6]:
True

LMP#

[7]:
sp2 = ams.load(ams.get_case('pglib/pglib_opf_case39_epri__api.m'),
               setup=True,
               no_output=True,
               default_config=True)
[8]:
sp2.DCOPF.run(solver='ECOS')
<DCOPF> solved as optimal in 0.0181 seconds, converged in 14 iterations with ECOS.
[8]:
True
[9]:
ppc2 = ams.io.pypower.system2ppc(sp2)
ppc2_sol = pyp.rundcopf(ppc2, ppopt)

Nodal price

[10]:
np.allclose(sp2.DCOPF.pi.v / sp2.config.mva,
            ppc2_sol['bus'][:, 13],
            atol=1e-6)
[10]:
True

Bus angle

[11]:
np.allclose(sp2.DCOPF.aBus.v * andes.shared.rad2deg,
            ppc2_sol['bus'][:, 8],
            atol=1e-6)
[11]:
True