{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# DCOPF Verification\n", "\n", "Prepared by [Jinning Wang](https://jinningwang.github.io)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conclusion\n", "\n", "For test cases, DCOPF results from AMS are identical to that from PYPOWER.\n", "\n", "NOTE: This verification works with PYPOWER ***v5.1.16***, where ***v5.1.17*** yields unexpected results." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import datetime\n", "\n", "import numpy as np\n", "import pandas as pd\n", "\n", "import ams\n", "import andes\n", "\n", "import pypower.api as pyp" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Last run time: 2024-11-24 21:03:09\n", "ams: 0.9.12\n" ] } ], "source": [ "print(\"Last run time:\", datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\"))\n", "\n", "print(f'ams: {ams.__version__}')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "ams.config_logger(stream_level=30)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generator Output" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using built-in MATPOWER cases as inputs." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "cases = [\n", " ams.get_case('matpower/case14.m'),\n", " ams.get_case('matpower/case39.m'),\n", " ams.get_case('matpower/case118.m'),\n", " ams.get_case('npcc/npcc.m'),\n", " ams.get_case('wecc/wecc.m'),\n", " ams.get_case('matpower/case300.m'),]\n", "\n", "case_names = [case.split('/')[-1].split('.')[0] for case in cases]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Building system matrices\n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " solved as optimal in 0.0065 seconds, converged in 11 iterations with CLARABEL.\n", "Building system matrices\n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " solved as optimal in 0.0077 seconds, converged in 8 iterations with CLARABEL.\n", "Building system matrices\n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " solved as optimal in 0.0144 seconds, converged in 11 iterations with CLARABEL.\n", "Building system matrices\n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " solved as optimal in 0.0164 seconds, converged in 12 iterations with CLARABEL.\n", "Building system matrices\n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " solved as optimal in 0.0160 seconds, converged in 12 iterations with CLARABEL.\n", "Building system matrices\n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " solved as optimal in 0.0226 seconds, converged in 13 iterations with CLARABEL.\n" ] } ], "source": [ "ams_obj = np.zeros(len(cases))\n", "pyp_obj = np.zeros(len(cases))\n", "\n", "for i, case in enumerate(cases):\n", " sp = ams.load(case, setup=True)\n", " sp.DCOPF.init()\n", " sp.DCOPF.run(solver='CLARABEL')\n", " ams_obj[i] = sp.DCOPF.obj.v\n", "\n", " ppc = ams.io.pypower.system2ppc(sp)\n", " ppopt = pyp.ppoption(VERBOSE=0, OUT_ALL=0, PF_ALG=1, OPF_ALG_DC=200)\n", " ppc_sol = pyp.rundcopf(ppc, ppopt)\n", " pyp_obj[i] = ppc_sol['f']" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.allclose(ams_obj, pyp_obj, atol=1e-6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## LMP" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "sp2 = ams.load(ams.get_case('pglib/pglib_opf_case39_epri__api.m'),\n", " setup=True,\n", " no_output=True,\n", " default_config=True)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Building system matrices\n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " solved as optimal in 0.0072 seconds, converged in 13 iterations with CLARABEL.\n" ] }, { "data": { "text/plain": [ "True" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp2.DCOPF.run(solver='CLARABEL')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "ppc2 = ams.io.pypower.system2ppc(sp2)\n", "ppc2_sol = pyp.rundcopf(ppc2, ppopt)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nodal price" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.allclose(sp2.DCOPF.pi.v / sp2.config.mva,\n", " ppc2_sol['bus'][:, 13],\n", " atol=1e-6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bus angle" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.allclose(sp2.DCOPF.aBus.v * andes.shared.rad2deg,\n", " ppc2_sol['bus'][:, 8],\n", " atol=1e-6)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ams_LMPpyp_LMPams_aBuspyp_aBus
029.998829.9988-25.6184-25.6184
134.214734.2147-26.8519-26.8519
235.601235.6012-30.4965-30.4965
338.154238.1542-28.8548-28.8548
420.131120.1311-24.4545-24.4545
520.982320.9823-22.9110-22.9110
621.091821.0918-26.4821-26.4821
721.146621.1466-27.2531-27.2531
824.870124.8701-24.5329-24.5329
924.804724.8047-21.2851-21.2851
1023.569423.5694-21.8833-21.8833
1124.804724.8047-22.4869-22.4869
1226.040026.0400-22.7386-22.7386
1334.307134.3071-26.2107-26.2107
1434.682234.6822-29.2227-29.2227
1534.844634.8446-27.6899-27.6899
1634.998534.9985-29.5901-29.5901
1735.228335.2283-30.6918-30.6918
1834.844634.8446-21.3650-21.3650
1934.844634.8446-23.3981-23.3981
2034.844634.8446-24.2513-24.2513
2134.844634.8446-17.0667-17.0667
2234.844634.8446-17.0905-17.0905
2334.844634.8446-27.0536-27.0536
2434.307134.3071-25.0737-25.0737
2534.654434.6544-28.2256-28.2256
2634.812534.8125-30.9591-30.9591
2734.654434.6544-24.1366-24.1366
2834.654434.6544-19.8996-19.8996
2934.214734.2147-26.7668-26.7668
3020.982320.98230.00000.0000
3124.804724.8047-11.0741-11.0741
3234.844634.8446-14.3249-14.3249
3334.844634.8446-14.2720-14.2720
3432.306532.3065-9.5084-9.5084
3518.157518.1575-3.0644-3.0644
3631.550231.5502-12.8112-12.8112
3734.654434.6544-9.0065-9.0065
3827.434427.4344-22.5664-22.5664
\n", "
" ], "text/plain": [ " ams_LMP pyp_LMP ams_aBus pyp_aBus\n", "0 29.9988 29.9988 -25.6184 -25.6184\n", "1 34.2147 34.2147 -26.8519 -26.8519\n", "2 35.6012 35.6012 -30.4965 -30.4965\n", "3 38.1542 38.1542 -28.8548 -28.8548\n", "4 20.1311 20.1311 -24.4545 -24.4545\n", "5 20.9823 20.9823 -22.9110 -22.9110\n", "6 21.0918 21.0918 -26.4821 -26.4821\n", "7 21.1466 21.1466 -27.2531 -27.2531\n", "8 24.8701 24.8701 -24.5329 -24.5329\n", "9 24.8047 24.8047 -21.2851 -21.2851\n", "10 23.5694 23.5694 -21.8833 -21.8833\n", "11 24.8047 24.8047 -22.4869 -22.4869\n", "12 26.0400 26.0400 -22.7386 -22.7386\n", "13 34.3071 34.3071 -26.2107 -26.2107\n", "14 34.6822 34.6822 -29.2227 -29.2227\n", "15 34.8446 34.8446 -27.6899 -27.6899\n", "16 34.9985 34.9985 -29.5901 -29.5901\n", "17 35.2283 35.2283 -30.6918 -30.6918\n", "18 34.8446 34.8446 -21.3650 -21.3650\n", "19 34.8446 34.8446 -23.3981 -23.3981\n", "20 34.8446 34.8446 -24.2513 -24.2513\n", "21 34.8446 34.8446 -17.0667 -17.0667\n", "22 34.8446 34.8446 -17.0905 -17.0905\n", "23 34.8446 34.8446 -27.0536 -27.0536\n", "24 34.3071 34.3071 -25.0737 -25.0737\n", "25 34.6544 34.6544 -28.2256 -28.2256\n", "26 34.8125 34.8125 -30.9591 -30.9591\n", "27 34.6544 34.6544 -24.1366 -24.1366\n", "28 34.6544 34.6544 -19.8996 -19.8996\n", "29 34.2147 34.2147 -26.7668 -26.7668\n", "30 20.9823 20.9823 0.0000 0.0000\n", "31 24.8047 24.8047 -11.0741 -11.0741\n", "32 34.8446 34.8446 -14.3249 -14.3249\n", "33 34.8446 34.8446 -14.2720 -14.2720\n", "34 32.3065 32.3065 -9.5084 -9.5084\n", "35 18.1575 18.1575 -3.0644 -3.0644\n", "36 31.5502 31.5502 -12.8112 -12.8112\n", "37 34.6544 34.6544 -9.0065 -9.0065\n", "38 27.4344 27.4344 -22.5664 -22.5664" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.DataFrame({'ams_LMP': sp2.DCOPF.pi.v / sp2.config.mva,\n", " 'pyp_LMP': ppc2_sol['bus'][:, 13],\n", " 'ams_aBus': sp2.DCOPF.aBus.v * andes.shared.rad2deg,\n", " 'pyp_aBus': ppc2_sol['bus'][:, 8]}).round(4)" ] } ], "metadata": { "kernelspec": { "display_name": "amsre", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.0" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }