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