{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Problem 5.4 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Integrated Energy Grids**\n", "\n", "**Problem 5.4**\n", "\n", "**Assume we have three buses (Denmark, Sweden, and Norway) with nominal voltage $V_{nom}$= 2000 V connected by three transmission lines. In each of the buses, there is a gas power generator whose variable cost is 50 EUR/MWh and installed capacity is 50 MW. In the Denmark bus, there is a wind generator whose variable cost is zero and whose installed capacity is 200 MW. The transmission lines have a unitary resistance $r$=0.01 and reactance $x$=0.1, and nominal capacity $S_{nom}=100$ VA. The demand is 50 MW for Denmark and Sweden and 30 MW for Norway. Using Python for Power System Analysis (PyPSA):**\n", "\n", "**a) Calculate the optimal dispatch that minimizes the total system cost, the energy produced by each generator, and the power flows along the transmission lines using AC power flow representation.**\n", "\n", "**b) Calculate the optimal dispatch that minimizes the total system cost, the energy produced by each generator, and the power flows along the transmission lines using a linearized approximation (also known as DC optimal power flow).**\n", "\n", "**c) Calculate the optimal dispatch that minimizes the total system cost, the energy produced by each generator, and the power flows along the transmission lines using the Net Transfer Capacity (NTC) approach for the transmission lines and discuss the results.**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ":::{note}\n", "If you have not yet set up Python on your computer, you can execute this tutorial in your browser via [Google Colab](https://colab.research.google.com/). Click on the rocket in the top right corner and launch \"Colab\". If that doesn't work download the `.ipynb` file and import it in [Google Colab](https://colab.research.google.com/).\n", "\n", "Then install the following packages by executing the following command in a Jupyter cell at the top of the notebook.\n", "\n", "```sh\n", "!pip install numpy pypsa\n", "```\n", ":::" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pypsa" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We start by creating the network object and adding the three buses corresponding to Denmark, Sweden, and Norway. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "network = pypsa.Network()" ] }, { "cell_type": "code", "execution_count": 3, "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", "
v_nomtypexycarrierunitv_mag_pu_setv_mag_pu_minv_mag_pu_maxcontrolgeneratorsub_network
Bus
bus Denmark2000.00.00.0AC1.00.0infPQ
bus Sweden2000.00.00.0AC1.00.0infPQ
bus Norway2000.00.00.0AC1.00.0infPQ
\n", "
" ], "text/plain": [ " v_nom type x y carrier unit v_mag_pu_set v_mag_pu_min \\\n", "Bus \n", "bus Denmark 2000.0 0.0 0.0 AC 1.0 0.0 \n", "bus Sweden 2000.0 0.0 0.0 AC 1.0 0.0 \n", "bus Norway 2000.0 0.0 0.0 AC 1.0 0.0 \n", "\n", " v_mag_pu_max control generator sub_network \n", "Bus \n", "bus Denmark inf PQ \n", "bus Sweden inf PQ \n", "bus Norway inf PQ " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for node in [\"Denmark\", \"Sweden\", \"Norway\"]:\n", " network.add(\"Bus\", \"bus {}\".format(node), v_nom=2000)\n", "\n", "network.buses" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We add the three lines connecting the buses" ] }, { "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
bus0bus1typexrgbs_noms_nom_mods_nom_extendable...v_ang_minv_ang_maxsub_networkx_pur_pug_pub_pux_pu_effr_pu_effs_nom_opt
Line
line DK-SWbus Denmarkbus Sweden0.10.010.00.0100.00.0False...-infinf0.00.00.00.00.00.00.0
line DK-NObus Denmarkbus Norway0.10.010.00.0100.00.0False...-infinf0.00.00.00.00.00.00.0
line SW-NObus Swedenbus Norway0.10.010.00.0100.00.0False...-infinf0.00.00.00.00.00.00.0
\n", "

3 rows × 31 columns

\n", "
" ], "text/plain": [ " bus0 bus1 type x r g b s_nom \\\n", "Line \n", "line DK-SW bus Denmark bus Sweden 0.1 0.01 0.0 0.0 100.0 \n", "line DK-NO bus Denmark bus Norway 0.1 0.01 0.0 0.0 100.0 \n", "line SW-NO bus Sweden bus Norway 0.1 0.01 0.0 0.0 100.0 \n", "\n", " s_nom_mod s_nom_extendable ... v_ang_min v_ang_max \\\n", "Line ... \n", "line DK-SW 0.0 False ... -inf inf \n", "line DK-NO 0.0 False ... -inf inf \n", "line SW-NO 0.0 False ... -inf inf \n", "\n", " sub_network x_pu r_pu g_pu b_pu x_pu_eff r_pu_eff s_nom_opt \n", "Line \n", "line DK-SW 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "line DK-NO 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "line SW-NO 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "\n", "[3 rows x 31 columns]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.add(\"Line\", \"line DK-SW\", bus0 = \"bus Denmark\", bus1 = \"bus Sweden\", s_nom = 100, x=0.1, r=0.01)\n", "network.add(\"Line\", \"line DK-NO\", bus0 = \"bus Denmark\", bus1 = \"bus Norway\", s_nom = 100, x=0.1, r=0.01)\n", "network.add(\"Line\", \"line SW-NO\", bus0 = \"bus Sweden\", bus1 = \"bus Norway\", s_nom = 100, x=0.1, r=0.01)\n", "\n", "network.lines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We add the generators" ] }, { "cell_type": "code", "execution_count": 5, "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", "
buscontroltypep_nomp_nom_modp_nom_extendablep_nom_minp_nom_maxp_min_pup_max_pu...min_up_timemin_down_timeup_time_beforedown_time_beforeramp_limit_upramp_limit_downramp_limit_start_upramp_limit_shut_downweightp_nom_opt
Generator
gas Denmarkbus DenmarkPQ50.00.0False0.0inf0.01.0...0010NaNNaN1.01.01.00.0
gas Swedenbus SwedenPQ50.00.0False0.0inf0.01.0...0010NaNNaN1.01.01.00.0
gas Norwaybus NorwayPQ50.00.0False0.0inf0.01.0...0010NaNNaN1.01.01.00.0
wind Denmarkbus DenmarkPQ200.00.0False0.0inf0.01.0...0010NaNNaN1.01.01.00.0
\n", "

4 rows × 37 columns

\n", "
" ], "text/plain": [ " bus control type p_nom p_nom_mod p_nom_extendable \\\n", "Generator \n", "gas Denmark bus Denmark PQ 50.0 0.0 False \n", "gas Sweden bus Sweden PQ 50.0 0.0 False \n", "gas Norway bus Norway PQ 50.0 0.0 False \n", "wind Denmark bus Denmark PQ 200.0 0.0 False \n", "\n", " p_nom_min p_nom_max p_min_pu p_max_pu ... min_up_time \\\n", "Generator ... \n", "gas Denmark 0.0 inf 0.0 1.0 ... 0 \n", "gas Sweden 0.0 inf 0.0 1.0 ... 0 \n", "gas Norway 0.0 inf 0.0 1.0 ... 0 \n", "wind Denmark 0.0 inf 0.0 1.0 ... 0 \n", "\n", " min_down_time up_time_before down_time_before ramp_limit_up \\\n", "Generator \n", "gas Denmark 0 1 0 NaN \n", "gas Sweden 0 1 0 NaN \n", "gas Norway 0 1 0 NaN \n", "wind Denmark 0 1 0 NaN \n", "\n", " ramp_limit_down ramp_limit_start_up ramp_limit_shut_down \\\n", "Generator \n", "gas Denmark NaN 1.0 1.0 \n", "gas Sweden NaN 1.0 1.0 \n", "gas Norway NaN 1.0 1.0 \n", "wind Denmark NaN 1.0 1.0 \n", "\n", " weight p_nom_opt \n", "Generator \n", "gas Denmark 1.0 0.0 \n", "gas Sweden 1.0 0.0 \n", "gas Norway 1.0 0.0 \n", "wind Denmark 1.0 0.0 \n", "\n", "[4 rows x 37 columns]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for node in [\"Denmark\", \"Sweden\", \"Norway\"]:\n", " network.add(\"Generator\", \"gas {}\".format(node), bus=\"bus {}\".format(node), \n", " p_nom=50, \n", " marginal_cost=50) #EUR/MWh_elec \n", "network.add(\"Generator\", \n", " \"wind Denmark\", \n", " bus=\"bus Denmark\", \n", " p_nom=200, \n", " marginal_cost=10)\n", "network.generators" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We add the loads." ] }, { "cell_type": "code", "execution_count": 6, "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", "
buscarriertypep_setq_setsignactive
Load
load Denmarkbus Denmark50.00.0-1.0True
load Swedenbus Sweden50.00.0-1.0True
load Norwaybus Norway30.00.0-1.0True
\n", "
" ], "text/plain": [ " bus carrier type p_set q_set sign active\n", "Load \n", "load Denmark bus Denmark 50.0 0.0 -1.0 True\n", "load Sweden bus Sweden 50.0 0.0 -1.0 True\n", "load Norway bus Norway 30.0 0.0 -1.0 True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for node in [\"Denmark\", \"Sweden\"]:\n", " network.add(\"Load\", \"load {}\".format(node), \n", " bus=\"bus {}\".format(node), \n", " p_set=50)\n", "network.add(\"Load\", \"load Norway\", \n", " bus=\"bus Norway\", \n", " p_set=30)\n", "network.loads" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We optimize searching for the minimum system cost." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:pypsa.consistency:The following lines have carriers which are not defined:\n", "Index(['line DK-SW', 'line DK-NO', 'line SW-NO'], dtype='object', name='Line')\n", "WARNING:pypsa.consistency:The following buses have carriers which are not defined:\n", "Index(['bus Denmark', 'bus Sweden', 'bus Norway'], dtype='object', name='Bus')\n", "WARNING:pypsa.consistency:The following lines have carriers which are not defined:\n", "Index(['line DK-SW', 'line DK-NO', 'line SW-NO'], dtype='object', name='Line')\n", "WARNING:pypsa.consistency:The following buses have carriers which are not defined:\n", "Index(['bus Denmark', 'bus Sweden', 'bus Norway'], dtype='object', name='Bus')\n", "INFO:linopy.model: Solve problem using Highs solver\n", "INFO:linopy.io: Writing time: 0.02s\n", "INFO:linopy.constants: Optimization successful: \n", "Status: ok\n", "Termination condition: optimal\n", "Solution: 7 primals, 18 duals\n", "Objective: 1.30e+03\n", "Solver model: available\n", "Solver message: optimal\n", "\n", "INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Line-fix-s-lower, Line-fix-s-upper, Kirchhoff-Voltage-Law were not assigned to the network.\n" ] }, { "data": { "text/plain": [ "('ok', 'optimal')" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.optimize()\n", "#network.optimize(solver='gurobi', assign_all_duals=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we can look at what is the optimal dispatch form every genenerator. As expected, the wind generator is producing power to supply the demand in every node." ] }, { "cell_type": "code", "execution_count": 8, "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", "
Generatorgas Denmarkgas Swedengas Norwaywind Denmark
snapshot
now-0.0-0.0-0.0130.0
\n", "
" ], "text/plain": [ "Generator gas Denmark gas Sweden gas Norway wind Denmark\n", "snapshot \n", "now -0.0 -0.0 -0.0 130.0" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.generators_t.p" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see the optimal dispatch in the generators and then solve the non-linear power flow using a Newton-Raphson method." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:pypsa.pf:Performing non-linear load-flow on AC sub-network for snapshots Index(['now'], dtype='object', name='snapshot')\n" ] }, { "data": { "text/plain": [ "{'n_iter': SubNetwork 0\n", " snapshot \n", " now 2,\n", " 'error': SubNetwork 0\n", " snapshot \n", " now 7.362638e-09,\n", " 'converged': SubNetwork 0\n", " snapshot \n", " now True}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.generators_t.p_set = network.generators_t.p\n", "network.pf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ok, the solution converge, we can check now the active power flow on the lines." ] }, { "cell_type": "code", "execution_count": 10, "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", "
line DK-SWline DK-NOline SW-NO
snapshot
now43.33333836.66667-6.666667
\n", "
" ], "text/plain": [ " line DK-SW line DK-NO line SW-NO\n", "snapshot \n", "now 43.333338 36.66667 -6.666667" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.lines_t.p0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also check the voltage angles on the buses" ] }, { "cell_type": "code", "execution_count": 11, "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", "
Busbus Denmarkbus Swedenbus Norway
snapshot
now0.0-0.000062-0.000053
\n", "
" ], "text/plain": [ "Bus bus Denmark bus Sweden bus Norway\n", "snapshot \n", "now 0.0 -0.000062 -0.000053" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.buses_t.v_ang * 180 / np.pi" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and their per-unit mangitudes" ] }, { "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", "
Busbus Denmarkbus Swedenbus Norway
snapshot
now1.01.01.0
\n", "
" ], "text/plain": [ "Bus bus Denmark bus Sweden bus Norway\n", "snapshot \n", "now 1.0 1.0 1.0" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.buses_t.v_mag_pu" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**b) Calculate the optimal dispatch that minimizes the total system cost, the energy produced by each generator, and the power flows along the transmission lines using a linearized approximation (also known as DC optimal power flow)**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case, since the voltage angles are very small, the linear power flow should be a good approximation. We can calculate the power flows in the line using the linear power flow (lpf) and check that we obtained a very similar result." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:pypsa.pf:Performing linear load-flow on AC sub-network for snapshot(s) Index(['now'], dtype='object', name='snapshot')\n" ] } ], "source": [ "network.lpf()" ] }, { "cell_type": "code", "execution_count": 14, "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", "
line DK-SWline DK-NOline SW-NO
snapshot
now43.33333336.666667-6.666667
\n", "
" ], "text/plain": [ " line DK-SW line DK-NO line SW-NO\n", "snapshot \n", "now 43.333333 36.666667 -6.666667" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.lines_t.p0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**c) Calculate the optimal dispatch that minimizes the total system cost, the energy produced by each generator, and the power flows along the transmission lines using Net Transfer Capacity (NTC) approach for the transmission lines and discuss the results.**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can create the problem again and this time use links to represent lines using only their Net Transfer Capacities. \n", "By selecting p_min_pu=-1 we make the link reversible." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:pypsa.consistency:The following links have carriers which are not defined:\n", "Index(['line DK-SW', 'line DK-NO', 'line SW-NO'], dtype='object', name='Link')\n", "WARNING:pypsa.consistency:The following buses have carriers which are not defined:\n", "Index(['bus Denmark', 'bus Sweden', 'bus Norway'], dtype='object', name='Bus')\n", "WARNING:pypsa.consistency:The following links have carriers which are not defined:\n", "Index(['line DK-SW', 'line DK-NO', 'line SW-NO'], dtype='object', name='Link')\n", "WARNING:pypsa.consistency:The following buses have carriers which are not defined:\n", "Index(['bus Denmark', 'bus Sweden', 'bus Norway'], dtype='object', name='Bus')\n", "INFO:linopy.model: Solve problem using Highs solver\n", "INFO:linopy.io: Writing time: 0.03s\n", "INFO:linopy.constants: Optimization successful: \n", "Status: ok\n", "Termination condition: optimal\n", "Solution: 7 primals, 17 duals\n", "Objective: 1.30e+03\n", "Solver model: available\n", "Solver message: optimal\n", "\n", "INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Link-fix-p-lower, Link-fix-p-upper were not assigned to the network.\n" ] }, { "data": { "text/plain": [ "('ok', 'optimal')" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network = pypsa.Network()\n", "for node in [\"Denmark\", \"Sweden\", \"Norway\"]:\n", " network.add(\"Bus\", \"bus {}\".format(node), v_nom=2000)\n", "\n", "network.add(\"Link\",\"line DK-SW\", bus0 = \"bus Denmark\", bus1 = \"bus Sweden\", p_nom = 100, p_min_pu=-1)\n", "network.add(\"Link\",\"line DK-NO\", bus0 = \"bus Denmark\", bus1 = \"bus Norway\", p_nom =100, p_min_pu=-1)\n", "network.add(\"Link\",\"line SW-NO\", bus0 = \"bus Sweden\", bus1 = \"bus Norway\", p_nom = 100, p_min_pu=-1)\n", "\n", "for node in [\"Denmark\", \"Sweden\"]:\n", " network.add(\"Load\", \"load {}\".format(node), \n", " bus=\"bus {}\".format(node), \n", " p_set=50)\n", "network.add(\"Load\", \"load Norway\", \n", " bus=\"bus Norway\", \n", " p_set=30)\n", "network.loads\n", "\n", "for node in [\"Denmark\", \"Sweden\", \"Norway\"]:\n", " network.add(\"Generator\", \"gas {}\".format(node), bus=\"bus {}\".format(node), \n", " p_nom=50, \n", " marginal_cost=50) #EUR/MWh_elec \n", "network.add(\"Generator\", \"wind Denmark\", bus=\"bus Denmark\", \n", " p_nom=200, \n", " marginal_cost=10)\n", "\n", "\n", "network.optimize()" ] }, { "cell_type": "code", "execution_count": 17, "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", "
Generatorgas Denmarkgas Swedengas Norwaywind Denmark
snapshot
now-0.0-0.0-0.0130.0
\n", "
" ], "text/plain": [ "Generator gas Denmark gas Sweden gas Norway wind Denmark\n", "snapshot \n", "now -0.0 -0.0 -0.0 130.0" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.generators_t.p" ] }, { "cell_type": "code", "execution_count": 18, "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", "
Linkline DK-SWline DK-NOline SW-NO
snapshot
now100.0-20.050.0
\n", "
" ], "text/plain": [ "Link line DK-SW line DK-NO line SW-NO\n", "snapshot \n", "now 100.0 -20.0 50.0" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "network.links_t.p0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case, the power flows are also compatible with the nodal balances, but they are significantly different from those obtained using AC power flow or linearized AC power flow to represent the power flowing through the different lines." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "@webio": { "lastCommId": null, "lastKernelId": null }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.8" } }, "nbformat": 4, "nbformat_minor": 4 }