{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# setup needed Py packages:\n", "import numpy as np\n", "from scipy.optimize import differential_evolution as DE\n", "import win32com.client" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Instantiate the main OpenDSS Object:\n", "try:\n", " dssObj = win32com.client.Dispatch(\"OpenDSSengine.DSS\")\n", "except:\n", " print (\"Unable to start the OpenDSS Engine\")\n", " raise SystemExit" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Instantiate the other OpenDSS Object:\n", "dssText = dssObj.Text # Definiranje tekstualnog objekta\n", "dssCircuit = dssObj.ActiveCircuit # Definiranje objekta mreze\n", "dssSolution = dssCircuit.Solution # Definiranje objekta rjesenja\n", "dssElem = dssCircuit.ActiveCktElement # Definiranje objekta elementa mreze" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Compail the OpenDSS file\n", "dssText.Command = r\"Compile 'C:\\Users\\mimit1\\Documents\\OpenDSS\\Exercise3dss.dss'\"\n", "#dssText.Command = r\"Compile 'C:\\Users\\Barukcic\\Documents\\OpenDSS\\Exercise3dss.dss'\"" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('sour.1', 'sour.2', 'sour.3', 'b2.1', 'b2.2', 'b2.3', 'b3.1', 'b3.2', 'b3.3', 'b4.1', 'b4.2', 'b4.3', 'b5.1', 'b5.2', 'b5.3', 'b6.1', 'b6.2', 'b6.3', 'b7.1', 'b7.2', 'b7.3', 'b8.1', 'b8.2', 'b8.3', 'b9.1', 'b9.2', 'b9.3', 'b10.1', 'b10.2', 'b10.3', 'b11.1', 'b11.2', 'b11.3', 'b12.1', 'b12.2', 'b12.3', 'b13.1', 'b13.2', 'b13.3', 'b14.1', 'b14.2', 'b14.3', 'b15.1', 'b15.2', 'b15.3', 'b16.1', 'b16.2', 'b16.3', 'b17.1', 'b17.2', 'b17.3', 'b18.1', 'b18.2', 'b18.3', 'b19.1', 'b19.2', 'b19.3', 'b20.1', 'b20.2', 'b20.3', 'b21.1', 'b21.2', 'b21.3', 'b22.1', 'b22.2', 'b22.3', 'b23.1', 'b23.2', 'b23.3', 'b24.1', 'b24.2', 'b24.3', 'b25.1', 'b25.2', 'b25.3', 'b26.1', 'b26.2', 'b26.3', 'b27.1', 'b27.2', 'b27.3', 'b28.1', 'b28.2', 'b28.3', 'b29.1', 'b29.2', 'b29.3', 'b30.1', 'b30.2', 'b30.3', 'b31.1', 'b31.2', 'b31.3', 'b32.1', 'b32.2', 'b32.3', 'b33.1', 'b33.2', 'b33.3', 'b34.1', 'b34.2', 'b34.3')\n" ] } ], "source": [ "# Get node names:\n", "NodeN = dssCircuit.AllNodeNames\n", "# and print them:\n", "print (NodeN)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('sour', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b10', 'b11', 'b12', 'b13', 'b14', 'b15', 'b16', 'b17', 'b18', 'b19', 'b20', 'b21', 'b22', 'b23', 'b24', 'b25', 'b26', 'b27', 'b28', 'b29', 'b30', 'b31', 'b32', 'b33', 'b34')\n" ] } ], "source": [ "# Repeat for bus names:\n", "BusN = dssCircuit.AllBusNames\n", "print (BusN)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Nominal voltage of load L2 is: 11.0 kV \n", " Nominal active power of L2 is: 230.0 kW \n", " Nominal reactive power of L2 is: 142.5 kvar \n", " and complex power of L2 is: (230+142.5j) kVA\n" ] } ], "source": [ "# Get some properties of the load element:\n", "dssCircuit.Loads.Name = 'L2'\n", "VL2 = dssCircuit.Loads.kV\n", "PL2 = dssCircuit.Loads.kW\n", "QL2 = dssCircuit.Loads.kvar\n", "# and print them:\n", "print ('Nominal voltage of load L2 is: ', VL2, 'kV \\n',\n", " 'Nominal active power of L2 is: ', PL2, 'kW \\n',\n", " 'Nominal reactive power of L2 is: ', QL2, 'kvar \\n',\n", " 'and complex power of L2 is: ', complex(PL2, QL2), 'kVA')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# Let's make the objective function of the optimization problem of optimal allocation of DG in the distribution network in form of PY function:\n", "def FC(ind, *addtnP):\n", " # decoding DG allocation from DE individual\n", " LOCdg = int(round(ind[0])) # decode DG location from DE individual\n", " # print (type(LOCdg)) - control line\n", " Pdg = ind[1] # decode DG powers from DE individual\n", " Qdg = ind[2]\n", " \n", " # change DG location and power in OpenDSS script:\n", " dssText.Command = 'Edit generator.DG' + ' bus1=' + BusN[LOCdg] + ' kw=' + str(Pdg) + ' kvar=' + str(Qdg)\n", "\n", " # execute simulation with changed DG location and powers:\n", " dssSolution.Solve()\n", " \n", " # get nodal voltages, maximum and minimum voltages in [p.u]\n", " Vpu = dssCircuit.AllBusVmagPU\n", " Vmax = max(Vpu)\n", " Vmin = min(Vpu)\n", " \n", " # get network loosses\n", " NL = dssCircuit.Losses[0]/1000 # divide by 1000 to get numerical value in [kW]\n", " \n", " # check inequality constraints and penalize OF if they not satisfied (soft penalisation):\n", " if Vmax > Vu:\n", " NL = (1+Vmax-Vu)*NL\n", " if Vmin < Vl:\n", " NL = (1+Vl-Vmin)*NL\n", " \n", " # use network losses as objective function value\n", " return NL, Vmin, Vmax\n", "\n", "def OF(ind, *addtnP):\n", " FNC = FC(ind, *addtnP)\n", " return FNC[0]" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# set voltage limits in [p.u] (inequality constraints)\n", "Vl = 0.9\n", "Vu = 1.1\n", "\n", "# and forward them as additional parameters of objective function\n", "addtnP = (Vl, Vu)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Active network losses are: 175.67291438130664 [kW]\n", "Active network losses, min and max voltages are: (175.6749013589538, 0.9437485996516286, 0.9982302021996509) [kW, p.u., p.u.]\n" ] } ], "source": [ "# Control cell, check if objective function work well\n", "indp = [9.8, 500.0, 350.0]\n", "NLp = OF(indp, addtnP)\n", "NLpp = FC(indp, addtnP)\n", "\n", "# total network losses are:\n", "print ('Active network losses are: ', NLp, '[kW]')\n", "print ('Active network losses, min and max voltages are: ', NLpp, '[kW, p.u., p.u.]')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(0.0, 33.4), (0.0, 5000.0), (-2000.0, 2000.0)]\n" ] } ], "source": [ "# define optimization part: (tip: see the notebook you made in exercise 1)\n", "# Power limits of DG\n", "PDGmin = 0.0\n", "PDGmax = 5000.0\n", "QDGmin = -2000.0\n", "QDGmax = 2000.0\n", "\n", "# define box constraints (decision variable ranges (limits))\n", "BXC = [(0.0, len(BusN)-0.6),\n", " (PDGmin, PDGmax),\n", " (QDGmin, QDGmax)] # 0 - 1000 kW\n", "print (BXC)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "##################################################### \n", " fun: 46.92733182447343\n", " message: 'Optimization terminated successfully.'\n", " nfev: 12600\n", " nit: 20\n", " success: True\n", " x: array([ 20.2232962 , 2935.063716 , 1800.03192541]) \n", " ##################################################### \n", "\n", "\n", " Problem solution is: [ 20.2232962 2935.063716 1800.03192541] \n", " , and total network lossess are: 46.92733182447343 kW \n", " for optimal allocation: \n", " DG location in bus: b21 \n", " injecting active power of : 2935.0637160024808 kW \n", " and rective power of : 1800.03192541089 kvar\n", "\n", " Minimal and maximal nodal voltages are: 0.9822833324209491 and 0.9992635658187856\n" ] } ], "source": [ "# performe optimization by using DE\n", "solution = DE(OF, BXC, addtnP, maxiter=50, popsize=200, mutation=(0.5, 1), recombination=0.7, disp=False, polish=False, tol=0.001)\n", "print ('##################################################### \\n', solution, '\\n ##################################################### \\n')\n", "print ('\\n','Problem solution is: ', solution.x, '\\n', ', and total network lossess are: ', solution.fun, 'kW',\n", " '\\n for optimal allocation: ', \n", " '\\n DG location in bus: ', BusN[int(round(solution.x[0]))],\n", " '\\n injecting active power of : ', solution.x[1], 'kW',\n", " '\\n and rective power of : ', solution.x[2], 'kvar',)\n", "print ('\\n Minimal and maximal nodal voltages are: ', FC(solution.x, addtnP)[1], ' and ', FC(solution.x, addtnP)[2])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }