{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Dispatch with Energy Storage" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case, we will show the usage of energy storage included dispatch.\n", "\n", "In AMS, ``ESD1`` is a dispatch model for energy storage, which has a corresponding\n", "dynamic model ``ESD1`` in ANDES." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "import ams" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "ams.config_logger(stream_level=20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A small-size PJM 5-bus case with ESD1 is used in this example." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Parsing input file \"/Users/jinningwang/work/ams/ams/cases/5bus/pjm5bus_demo.xlsx\"...\n", "Input file parsed in 0.0954 seconds.\n", "Zero Line parameters detected, adjusted to default values: rate_b, rate_c.\n", "Parameters c2, c1 are altered to 0 as they are associated with ESD1 for following GCost: GCost_5\n", "All bus type are PQ, adjusted given load and generator connection status.\n", "System set up in 0.0022 seconds.\n" ] } ], "source": [ "sp = ams.load(ams.get_case('5bus/pjm5bus_demo.xlsx'),\n", " setup=True,\n", " no_output=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The model parameters can be inspected as follow." ] }, { "cell_type": "code", "execution_count": 4, "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", "
idxunamebusgenSngammapgammaqSOCminSOCmax...EtaCEtaDcesdccesddtdctddtdc0tdd0ucd0udd0
uid
0ESD1_11.0ESD1_11PV_2100.01.01.00.10.9...1.01.00.20.10.00.00.00.00.00.0
\n", "

1 rows × 23 columns

\n", "
" ], "text/plain": [ " idx u name bus gen Sn gammap gammaq SOCmin SOCmax \\\n", "uid \n", "0 ESD1_1 1.0 ESD1_1 1 PV_2 100.0 1.0 1.0 0.1 0.9 \n", "\n", " ... EtaC EtaD cesdc cesdd tdc tdd tdc0 tdd0 ucd0 udd0 \n", "uid ... \n", "0 ... 1.0 1.0 0.2 0.1 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", "[1 rows x 23 columns]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.ESD1.as_df()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`RTEDES` extends RTED to include energy storage.\n", "\n", "Note that mixed integer linear programming (MILP) requires\n", "capable solvers such as Gurobi or CPLEX.\n", "They might require extra installation and have their own license.\n", "\n", "The example here only aims to show the usage of RTEDES.\n", "More details can be found at [CVXPY - Choosing a solver](https://www.cvxpy.org/tutorial/advanced/index.html#choosing-a-solver)." ] }, { "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", " initialized in 0.0179 seconds.\n", " solved as optimal in 0.0298 seconds, converged in -1 iteration with SCIP.\n" ] }, { "data": { "text/plain": [ "True" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.RTEDES.run(solver='SCIP')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that, in RTED, the time interval is 5/60 [H] by default, and the\n", "dispatch model has been adjusted accordingly." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0.59641411])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.RTEDES.SOC.v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Routine ``RTEDESP`` is the price run of RTED with ESD1 model, where the binary terms are substituted by their solutions from the ``RTEDES`` or ``RTEDES2``" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ ": ESD1 associated StaticGen.p0 has been setaccording to \n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " initialized in 0.0287 seconds.\n", " solved as optimal in 0.0346 seconds, converged in 11 iterations with CLARABEL.\n" ] }, { "data": { "text/plain": [ "True" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.RTEDESP.run(solver='CLARABEL')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After it, you can have the LMP:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0.01221973, 0.00833333, 0.025 , 0.01678462, 0.01302902])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.RTEDESP.pi.v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, multi-period dispatch ``EDES`` and ``UCES`` are also available.\n", "They have 1 [H] time interval by default." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.EDES.config.t" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " initialized in 0.0230 seconds.\n", " solved as optimal in 0.3200 seconds, converged in -1 iteration with SCIP.\n" ] }, { "data": { "text/plain": [ "True" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.EDES.run(solver='SCIP')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.61443053, 0.63070058, 0.64861129, 0.66726776, 0.68632196,\n", " 0.70507786, 0.72164621, 0.73562929, 0.74831972, 0.75986667,\n", " 0.76936667, 0.77646667, 0.78146667, 0.75546793, 0.71489114,\n", " 0.67328647, 0.63070864, 0.58813081, 0.54622671, 0.50662611,\n", " 0.46707564, 0.47347564, 0.48512202, 0.5 ]])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.EDES.SOC.v" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "All generators are online at initial, make initial guess for commitment.\n", "As initial commitment guess, turn off StaticGen: PV_1\n", "Parsing OModel for \n", "Evaluating OModel for \n", "Finalizing OModel for \n", " initialized in 0.0226 seconds.\n", " solved as optimal in 0.2469 seconds, converged in -1 iteration with SCIP.\n" ] }, { "data": { "text/plain": [ "True" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.UCES.run(solver='SCIP')" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.59882146, 0.59882146, 0.59882146, 0.59882146, 0.59882146,\n", " 0.59882146, 0.59882146, 0.59672403, 0.59197199, 0.59197199,\n", " 0.58252336, 0.57062432, 0.55658119, 0.54581983, 0.54581983,\n", " 0.54581983, 0.54571032, 0.54560081, 0.54560081, 0.52777997,\n", " 0.51261374, 0.5 , 0.5 , 0.5 ]])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sp.UCES.SOC.v" ] } ], "metadata": { "kernelspec": { "display_name": "ams", "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 }