Skip to content

Commit

Permalink
Merge pull request #42 from NVE/nett
Browse files Browse the repository at this point in the history
support for flowbased with example
  • Loading branch information
cjuli1 authored Nov 6, 2024
2 parents 98dd788 + f66b3a5 commit b563719
Show file tree
Hide file tree
Showing 6 changed files with 404 additions and 2 deletions.
272 changes: 272 additions & 0 deletions demos/other/nettmodelering.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "429e1141",
"metadata": {},
"outputs": [],
"source": [
"include(dirname(dirname(pwd()))*\"\\\\src\\\\TuLiPa.jl\");\n",
"using .TuLiPa\n",
"using Dates, DataFrames, CSV, JSON, Plots, JuMP, HiGHS"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "61cf14fc",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"make_flowbased (generic function with 1 method)"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function make_connection(from, to) \n",
" flow_name = \"$(from)$(to)\"\n",
" arrow_name_from = \"arrow_from$(from)$(to)\"\n",
" arrow_name_to = \"arrow_to$(from)$(to)\"\n",
" balance_from = \"$(from)\"\n",
" balance_to = \"$(to)\"\n",
" cap_name = \"$(flow_name)_cap\"\n",
" elem = [\n",
" DataElement(\"Flow\", \"BaseFlow\", flow_name, Dict()), \n",
" DataElement(\"Arrow\", \"BaseArrow\", arrow_name_from, Dict(\"Balance\" => balance_from, \"Flow\" => flow_name, \"Conversion\" => 1.0, \"Direction\" => \"Out\")),\n",
" DataElement(\"Arrow\", \"BaseArrow\", arrow_name_to, Dict(\"Balance\" => balance_to, \"Flow\" => flow_name, \"Conversion\" => 1.0, \"Direction\" => \"In\")),\n",
" #DataElement(\"Capacity\", \"PositiveCapacity\", cap_name, Dict(\"Param\" => cap_name, \"WhichInstance\" => flow_name, \"WhichConcept\" => \"Flow\", \"Bound\" => \"Upper\")), \n",
" #DataElement(\"Param\", \"MWToGWhSeriesParam\", cap_name, Dict{Any, Any}(\"Level\" => BC_cap, \"Profile\" => 1.0)),\n",
" ] \n",
" return elem\n",
"end\n",
"\n",
"function make_flowbased(ptdfs)\n",
" elem = Array{DataElement}([])\n",
" for row in eachrow(ptdfs)\n",
" line = row[\"line\"] # Flow variable used for transfer, i.e AB \n",
" ptdfs_names = names(ptdfs)\n",
" ptdfs_val = Array(row) \n",
" ptdfs_val, ptdfs_names, max_cap = TuLiPa.get_values_from_ptdf_df(ptdfs_val, ptdfs_names) \n",
" e = DataElement(\"FlowBased\", \"BaseFlowBased\", line, Dict(\n",
" \"Flow\" => line,\n",
" \"ptdfs_names\" => ptdfs_names,\n",
" \"ptdfs\" => ptdfs_val,\n",
" \"max_cap\" => max_cap)\n",
" )\n",
" push!(elem, e)\n",
" end\n",
" return elem\n",
"end\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "673cea13",
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/latex": [
"$$ \\begin{aligned}\n",
"\\min\\quad & FlowPowerA_{1} + 10000 FlowPowerB_{1} + 100 FlowPowerC_{1}\\\\\n",
"\\text{Subject to} \\quad & -FlowBA_{1} - FlowPowerA_{1} + FlowAC_{1} + FlowAB_{1} - FlowCA_{1} = -0.24\\\\\n",
" & FlowBA_{1} + FlowBC_{1} - FlowAB_{1} - FlowCB_{1} - FlowPowerB_{1} = -2.4\\\\\n",
" & -FlowBC_{1} - FlowAC_{1} + FlowCB_{1} - FlowPowerC_{1} + FlowCA_{1} = -0.24\\\\\n",
" & FlowAB_{1} + FlowBC_{1} + FlowCB_{1} \\leq 100\\\\\n",
" & FlowBA_{1} \\leq 0\\\\\n",
" & FlowAB_{1} + FlowAC_{1} + FlowCA_{1} \\leq 100\\\\\n",
" & FlowBA_{1} \\geq 0\\\\\n",
" & FlowBC_{1} \\geq 0\\\\\n",
" & FlowPowerA_{1} \\geq 0\\\\\n",
" & FlowAC_{1} \\geq 0\\\\\n",
" & FlowAB_{1} \\geq 0\\\\\n",
" & FlowCB_{1} \\geq 0\\\\\n",
" & FlowPowerB_{1} \\geq 0\\\\\n",
" & FlowPowerC_{1} \\geq 0\\\\\n",
" & FlowCA_{1} \\geq 0\\\\\n",
" & FlowPowerA_{1} \\leq 240\\\\\n",
" & FlowPowerB_{1} \\leq 240\\\\\n",
" & FlowPowerC_{1} \\leq 240\\\\\n",
"\\end{aligned} $$"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"* Solver : HiGHS\n",
"\n",
"* Status\n",
" Result count : 1\n",
" Termination status : OPTIMAL\n",
" Message from the solver:\n",
" \"kHighsModelStatusOptimal\"\n",
"\n",
"* Candidate solution (result #1)\n",
" Primal status : FEASIBLE_POINT\n",
" Dual status : FEASIBLE_POINT\n",
" Objective value : 2.88000e+00\n",
" Objective bound : 0.00000e+00\n",
" Relative gap : Inf\n",
" Dual objective value : 2.88000e+00\n",
" Primal solution :\n",
" FlowAB[1] : 2.40000e+00\n",
" FlowAC[1] : 2.40000e-01\n",
" FlowBA[1] : 0.00000e+00\n",
" FlowBC[1] : 0.00000e+00\n",
" FlowCA[1] : 0.00000e+00\n",
" FlowCB[1] : 0.00000e+00\n",
" FlowPowerA[1] : 2.88000e+00\n",
" FlowPowerB[1] : 0.00000e+00\n",
" FlowPowerC[1] : 0.00000e+00\n",
" Dual solution :\n",
" BalanceA[1] : -1.00000e+00\n",
" BalanceB[1] : -1.00000e+00\n",
" BalanceC[1] : -1.00000e+00\n",
" FlowBasedAB[1] : 0.00000e+00\n",
" FlowBasedAC[1] : 0.00000e+00\n",
" FlowBasedBC[1] : 0.00000e+00\n",
"\n",
"* Work counters\n",
" Solve time (sec) : 8.20160e-05\n",
" Simplex iterations : 4\n",
" Barrier iterations : 0\n",
" Node count : -1\n",
"\u001b[1m3×8 DataFrame\u001b[0m\n",
"\u001b[1m Row \u001b[0m│\u001b[1m line \u001b[0m\u001b[1m max_cap \u001b[0m\u001b[1m AB \u001b[0m\u001b[1m AC \u001b[0m\u001b[1m BA \u001b[0m\u001b[1m BC \u001b[0m\u001b[1m CA \u001b[0m\u001b[1m CB \u001b[0m\n",
"\u001b[90m String \u001b[0m\u001b[90m Int64 \u001b[0m\u001b[90m Float64 \u001b[0m\u001b[90m Float64 \u001b[0m\u001b[90m Float64 \u001b[0m\u001b[90m Float64 \u001b[0m\u001b[90m Float64 \u001b[0m\u001b[90m Float64 \u001b[0m\n",
"─────┼───────────────────────────────────────────────────────────────────────\n",
" 1 │ AB 0 0.0 0.0 1.0 0.0 0.0 0.0\n",
" 2 │ AC 100 1.0 1.0 0.0 0.0 1.0 0.0\n",
" 3 │ BC 100 1.0 0.0 0.0 1.0 0.0 1.0\n",
"Used capacities over AB, AC, BC lines\n",
"[0.0][2.6399999999999997][2.4]\n"
]
}
],
"source": [
"PowerA = 1.0\n",
"PowerA_cap = 10000.0\n",
"DemandA = 10.0\n",
"PowerB_cap = 10000.0\n",
"PowerB = 10000.0\n",
"DemandB = 100.0\n",
"PowerC_cap = 10000.0\n",
"PowerC = 100.0\n",
"DemandC = 10.0\n",
"\n",
"#AB_cap = 1000.0\n",
"#AC_cap = 2000.0\n",
"#BC_cap = 3000.0\n",
"\n",
"elements = [\n",
" \n",
" DataElement(\"Balance\", \"BaseBalance\", \"A\", Dict{Any, Any}(\"Commodity\" => \"Power\")), \n",
" DataElement(\"Flow\", \"BaseFlow\", \"PowerA\", Dict{Any, Any}()),\n",
" DataElement(\"Arrow\", \"BaseArrow\", \"A\", Dict{Any, Any}(\"Balance\" => \"A\", \"Flow\" => \"PowerA\", \"Conversion\" => 1.0, \"Direction\" => \"In\")),\n",
" DataElement(\"Cost\", \"CostTerm\", \"PowerA_cost\", Dict{Any, Any}(\"Param\" => PowerA, \"WhichInstance\" => \"PowerA\", \"WhichConcept\" => \"Flow\", \"Direction\" => \"In\")),\n",
" DataElement(\"Capacity\", \"PositiveCapacity\", \"PowerA_cap\", Dict{Any, Any}(\"Param\" => \"PowerA_cap\", \"WhichInstance\" => \"PowerA\", \"WhichConcept\" => \"Flow\", \"Bound\" => \"Upper\")),\n",
" DataElement(\"Param\", \"MWToGWhSeriesParam\", \"PowerA_cap\", Dict{Any, Any}(\"Level\" => PowerA_cap, \"Profile\" => 1.0)),\n",
" DataElement(\"Param\", \"MWToGWhSeriesParam\", \"DemandA\", Dict(\"Level\" => DemandA , \"Profile\" => 1.0)),\n",
" DataElement(\"RHSTerm\", \"BaseRHSTerm\", \"DemandA\", Dict{Any, Any}(\"Balance\" => \"A\", \"Param\" => \"DemandA\", \"Direction\" => \"Out\")),\n",
"\n",
" DataElement(\"Balance\", \"BaseBalance\", \"B\", Dict{Any, Any}(\"Commodity\" => \"Power\")), \n",
" DataElement(\"Flow\", \"BaseFlow\", \"PowerB\", Dict{Any, Any}()),\n",
" DataElement(\"Arrow\", \"BaseArrow\", \"B\", Dict{Any, Any}(\"Balance\" => \"B\", \"Flow\" => \"PowerB\", \"Conversion\" => 1.0, \"Direction\" => \"In\")),\n",
" DataElement(\"Cost\", \"CostTerm\", \"PowerB_cost\", Dict{Any, Any}(\"Param\" => PowerB, \"WhichInstance\" => \"PowerB\", \"WhichConcept\" => \"Flow\", \"Direction\" => \"In\")),\n",
" DataElement(\"Capacity\", \"PositiveCapacity\", \"PowerB_cap\", Dict{Any, Any}(\"Param\" => \"PowerB_cap\", \"WhichInstance\" => \"PowerB\", \"WhichConcept\" => \"Flow\", \"Bound\" => \"Upper\")),\n",
" DataElement(\"Param\", \"MWToGWhSeriesParam\", \"PowerB_cap\", Dict{Any, Any}(\"Level\" => PowerB_cap, \"Profile\" => 1.0)),\n",
" DataElement(\"Param\", \"MWToGWhSeriesParam\", \"DemandB\", Dict(\"Level\" => DemandB , \"Profile\" => 1.0)),\n",
" DataElement(\"RHSTerm\", \"BaseRHSTerm\", \"DemandB\", Dict{Any, Any}(\"Balance\" => \"B\", \"Param\" => \"DemandB\", \"Direction\" => \"Out\")),\n",
"\n",
" DataElement(\"Balance\", \"BaseBalance\", \"C\", Dict{Any, Any}(\"Commodity\" => \"Power\")), \n",
" DataElement(\"Flow\", \"BaseFlow\", \"PowerC\", Dict{Any, Any}()),\n",
" DataElement(\"Arrow\", \"BaseArrow\", \"C\", Dict{Any, Any}(\"Balance\" => \"C\", \"Flow\" => \"PowerC\", \"Conversion\" => 1.0, \"Direction\" => \"In\")),\n",
" DataElement(\"Cost\", \"CostTerm\", \"PowerC_cost\", Dict{Any, Any}(\"Param\" => PowerC, \"WhichInstance\" => \"PowerC\", \"WhichConcept\" => \"Flow\", \"Direction\" => \"In\")),\n",
" DataElement(\"Capacity\", \"PositiveCapacity\", \"PowerC_cap\", Dict{Any, Any}(\"Param\" => \"PowerC_cap\", \"WhichInstance\" => \"PowerC\", \"WhichConcept\" => \"Flow\", \"Bound\" => \"Upper\")),\n",
" DataElement(\"Param\", \"MWToGWhSeriesParam\", \"PowerC_cap\", Dict{Any, Any}(\"Level\" => PowerC_cap, \"Profile\" => 1.0)),\n",
" DataElement(\"Param\", \"MWToGWhSeriesParam\", \"DemandC\", Dict(\"Level\" => DemandC , \"Profile\" => 1.0)),\n",
" DataElement(\"RHSTerm\", \"BaseRHSTerm\", \"DemandC\", Dict{Any, Any}(\"Balance\" => \"C\", \"Param\" => \"DemandC\", \"Direction\" => \"Out\"))\n",
"]\n",
" \n",
"elements = vcat(elements, make_connection(\"A\", \"B\"))\n",
"elements = vcat(elements, make_connection(\"B\", \"A\"))\n",
" \n",
"elements = vcat(elements, make_connection(\"A\", \"C\"))\n",
"elements = vcat(elements, make_connection(\"C\", \"A\")) \n",
" \n",
"elements = vcat(elements, make_connection(\"B\", \"C\"))\n",
"elements = vcat(elements, make_connection(\"C\", \"B\"))\n",
"\n",
"power_horizon = SequentialHorizon(1, Day(1))\n",
"push!(elements, getelement(COMMODITY_CONCEPT, \"BaseCommodity\", \"Power\", (HORIZON_CONCEPT, power_horizon)))\n",
"addscenariotimeperiod!(elements, \"ScenarioTimePeriod\", getisoyearstart(1981), getisoyearstart(1983));\n",
" \n",
"ptdfs = DataFrame(\n",
" line = [\"AB\", \"AC\", \"BC\"],\n",
" max_cap = [0, 100, 100],\n",
" AB = [0.0, 1.0, 1.0],\n",
" AC = [0.0, 1.0, 0.0],\n",
" BA = [1.0, 0.0, 0.0],\n",
" BC = [0.0, 0.0, 1.0],\n",
" CA = [0.0, 1.0, 0.0],\n",
" CB = [0.0, 0.0, 1.0]\n",
")\n",
"\n",
"elements = vcat(elements, make_flowbased(ptdfs))\n",
"\n",
" \n",
"modelobjects = getmodelobjects(elements)\n",
"mymodel = JuMP.Model(HiGHS.Optimizer)\n",
"prob = JuMP_Prob(modelobjects, mymodel)\n",
"datatime = getisoyearstart(2023)\n",
"scenariotime = getisoyearstart(1981)\n",
"prob_time = TwoTime(datatime, scenariotime)\n",
" \n",
"update!(prob, prob_time)\n",
"solve!(prob)\n",
"print(prob.model)\n",
"print(solution_summary(prob.model, verbose = true))\n",
"println(ptdfs)\n",
"println(\"Used capacities over AB, AC, BC lines\")\n",
"println(value.(prob.model[:FlowBasedAB]), value.(prob.model[:FlowBasedAC]), value.(prob.model[:FlowBasedBC]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0a5771d9",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.2",
"language": "julia",
"name": "julia-1.9"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
1 change: 1 addition & 0 deletions src/TuLiPa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ include("trait_arrow.jl")
include("trait_rhsterm.jl")
include("trait_commodity.jl")
include("trait_metadata.jl")
include("trait_flow_based_constraints.jl")

# Parameters for model objects and traits (Lowlevel)
include("parameters.jl")
Expand Down
10 changes: 9 additions & 1 deletion src/abstracttypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -561,4 +561,12 @@ abstract type Offset end
# getdemand(prob, demand, t)
# getreserveprice(prob, demand, t)

abstract type Demand end
abstract type Demand end

# ---- FlowBased -------------------
#
# TODO
#
# Interface:

abstract type FlowBased end
Loading

0 comments on commit b563719

Please sign in to comment.