{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Problem Set 2\n", "\n", "1. Add market power considerations to the basic mixed integer program that we discussed in class, following BMS (2008). For now, ignore forward contracts. Given that the model has only technologies (and no firms), pretend that each technology is a firm.\n", "\n", " a) What are the level of markups compared to the competitive equilibrium?\n", "\n", "2. Introduce the notion of forward contracts to the model. Given that these are unobserved, you can make different assumptions to calibrate them. It is often easy to interpret them as a percent of their equilibrium quantity, even if then they are not quite \"sunk\" (e.g., see Puller, 2007; Reguant, 2014). This parameter can also be intepreted as a \"conduct\" parameter.\n", "\n", " a) Write a function that solves the equilibrium for different values of the conduct parameter and plot markups as a function of those.\n", "\n", "3. Introduce competitive investment to the model. Allow investment for three technologies (New Gas, Wind, Solar). The fixed costs are provided in the tech file, which I annualized to be representative of annual costs.\n", "\n", " a) What is the baseline level of investment? We will use the zero profit condition in which the marginal technology just breaks even. You will need to add new variables for the capacity of new gas, wind, and solar, which are now set to zero as a parameter. You will need to expand the use of binary variables to include a new binary variable that equals 1 if investment in a technology is positive.\n", " -> Hint: As of now, u1 and u2 multiply the capacity of power plants. Use the M formulation to go around this multiplication for the techs with endogenoous investment.\n", " \n", " b) Does optimal investment change if you allow technologies to exercise market power as in part 2?" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n", "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.8/Project.toml`\n", "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.8/Manifest.toml`\n" ] }, { "data": { "text/plain": [ "\"/Users/marreguant/Dropbox/TEACHING/GRAD/Econ_498_2023/pset1/\"" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## LIBRARY AND PATH PREP\n", "begin\n", "\n", " using Pkg\n", " Pkg.add([\"DataFrames\", \"CSV\", \"JuMP\", \"HiGHS\", \"Plots\", \"Printf\", \"StatsBase\"])\n", "\n", " using DataFrames\n", " using CSV\n", " using JuMP\n", " using HiGHS\n", " using Plots\n", " using Printf\n", " using StatsBase\n", "\n", " dirpath = \"/Users/marreguant/Dropbox/TEACHING/GRAD/Econ_498_2023/pset1/\"\n", "\n", "end" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Data" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "

7 rows × 15 columns (omitted printing of 7 columns)

technameheatrateheatrate2FcapLBcapUBnewrenewable
String15Float64Float64Float64Float64Float64Int64Int64
1Hydro/Nuclear10.00.00.01.01.000
2Existing 16.671990.09291230.011.511.500
3Existing 29.794120.2862470.014.514.500
4Existing 313.818120.53520.00.5780.57800
5New Gas6.60.078.47730.00.010
6Wind0.00.0100.3030.00.011
7Solar0.00.0100.3030.00.011
" ], "text/latex": [ "\\begin{tabular}{r|ccccccccc}\n", "\t& techname & heatrate & heatrate2 & F & capLB & capUB & new & renewable & \\\\\n", "\t\\hline\n", "\t& String15 & Float64 & Float64 & Float64 & Float64 & Float64 & Int64 & Int64 & \\\\\n", "\t\\hline\n", "\t1 & Hydro/Nuclear & 10.0 & 0.0 & 0.0 & 1.0 & 1.0 & 0 & 0 & $\\dots$ \\\\\n", "\t2 & Existing 1 & 6.67199 & 0.0929123 & 0.0 & 11.5 & 11.5 & 0 & 0 & $\\dots$ \\\\\n", "\t3 & Existing 2 & 9.79412 & 0.286247 & 0.0 & 14.5 & 14.5 & 0 & 0 & $\\dots$ \\\\\n", "\t4 & Existing 3 & 13.8181 & 20.5352 & 0.0 & 0.578 & 0.578 & 0 & 0 & $\\dots$ \\\\\n", "\t5 & New Gas & 6.6 & 0.0 & 78.4773 & 0.0 & 0.0 & 1 & 0 & $\\dots$ \\\\\n", "\t6 & Wind & 0.0 & 0.0 & 100.303 & 0.0 & 0.0 & 1 & 1 & $\\dots$ \\\\\n", "\t7 & Solar & 0.0 & 0.0 & 100.303 & 0.0 & 0.0 & 1 & 1 & $\\dots$ \\\\\n", "\\end{tabular}\n" ], "text/plain": [ "\u001b[1m7×15 DataFrame\u001b[0m\n", "\u001b[1m Row \u001b[0m│\u001b[1m techname \u001b[0m\u001b[1m heatrate \u001b[0m\u001b[1m heatrate2 \u001b[0m\u001b[1m F \u001b[0m\u001b[1m capLB \u001b[0m\u001b[1m capUB \u001b[0m\u001b[1m new \u001b[0m\u001b[1m\u001b[0m ⋯\n", "\u001b[1m \u001b[0m│\u001b[90m String15 \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 Int64 \u001b[0m\u001b[90m\u001b[0m ⋯\n", "─────┼──────────────────────────────────────────────────────────────────────────\n", " 1 │ Hydro/Nuclear 10.0 0.0 0.0 1.0 1.0 0 ⋯\n", " 2 │ Existing 1 6.67199 0.0929123 0.0 11.5 11.5 0\n", " 3 │ Existing 2 9.79412 0.286247 0.0 14.5 14.5 0\n", " 4 │ Existing 3 13.8181 20.5352 0.0 0.578 0.578 0\n", " 5 │ New Gas 6.6 0.0 78.4773 0.0 0.0 1 ⋯\n", " 6 │ Wind 0.0 0.0 100.303 0.0 0.0 1\n", " 7 │ Solar 0.0 0.0 100.303 0.0 0.0 1\n", "\u001b[36m 8 columns omitted\u001b[0m" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## DATA PREP\n", "begin\n", "\n", " dfclust = CSV.read(string(dirpath,\"data_jaere_clustered.csv\"), DataFrame);\n", "\n", " # Re-scaling -- note correction for 8.76\n", " dfclust.weights = 8.76 * dfclust.weights / sum(dfclust.weights);\n", "\n", " # Here only one demand type to make it easier\n", " dfclust.demand = dfclust.q_residential + dfclust.q_commercial + dfclust.q_industrial;\n", "\n", " # Calibrate demand based on elasticities (using 0.1 here as only one final demand)\n", " elas = [.1, .2, .5, .3];\n", " dfclust.b = elas[1] * dfclust.demand ./ dfclust.price; # slope\n", " dfclust.a = dfclust.demand + dfclust.b .* dfclust.price; # intercept\n", "\n", " # Calibrate imports (using elas 0.3)\n", " dfclust.bm = elas[4] * dfclust.imports ./ dfclust.price; # slope\n", " dfclust.am = dfclust.imports - dfclust.bm .* dfclust.price; # intercept\n", "\n", " dfclust[:, [:demand,:price,:a,:b,:am,:bm]]\n", "\n", " tech = CSV.read(string(dirpath,\"data_technology.csv\"), DataFrame);\n", " afactor = (1 - (1 / (1.05^20.0))) / 0.05;\n", " tech.F = tech.F ./afactor;\n", " tech.F2 = tech.F2 ./afactor;\n", " tech\n", "\n", "end" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Modifications to code" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "1. We add a parameter theta that allows for market power. When theta = 0, firms have no forward contracts and market power is maximized.\n", "\n", "2. To derive the markup formula, note that I account for the import supply curve, which disciplines firms ability to exercise market power. Note also that I use the competitive baseline to set the markup calculation, as in BBW (2002).\n", "\n", "3. Adding investment follows the code that you could see in class, introducing a new binary variable for whether to invest in a technology or not." ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "clear_market_foc (generic function with 1 method)" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## Clear market based on first-order conditions\n", "function clear_market_foc(data::DataFrame, tech::DataFrame; theta=1.0, solve_invest=false, import_slope=true)\n", "\n", " # We declare a model\n", " model = Model(\n", " optimizer_with_attributes(\n", " HiGHS.Optimizer)\n", " );\n", "\n", " set_silent(model)\n", "\n", " # Set useful indexes\n", " I = nrow(tech); # number of techs\n", " T = nrow(data); # number of periods\n", " M = 1e4;\n", " \n", " # Variables to solve for\n", " @variable(model, price[1:T]);\n", " @variable(model, demand[1:T]);\n", " @variable(model, imports[1:T]);\n", " @variable(model, quantity[1:T, 1:I] >= 0);\n", " @variable(model, shadow[1:T, 1:I] >= 0); # price wedge if at capacity\n", " @variable(model, 0 <= K[5:I] <= 50.0); # new capacity\n", " @variable(model, profit[5:I] <= 0.0); # tech annual profits, at most zero in equilibrium\n", " @variable(model, u1[1:T, 1:I], Bin); # if tech used\n", " @variable(model, u2[1:T, 1:I], Bin); # if tech at max\n", " @variable(model, u3[5:I], Bin); # if tech is built\n", "\n", " @objective(model, Min, sum(price[t] * data.weights[t] for t=1:T));\n", "\n", " # Market clearing\n", " @constraint(model, [t=1:T], \n", " demand[t] == data.a[t] - data.b[t] * price[t]);\n", " @constraint(model, [t=1:T], \n", " imports[t] == data.am[t] + data.bm[t] * price[t]);\n", " @constraint(model, [t=1:T], \n", " demand[t] == sum(quantity[t,i] for i=1:I) + imports[t]);\n", "\n", " # Capacity constraints\n", " @constraint(model, [t=1:T], \n", " quantity[t,1] <= u1[t,1] * data.hydronuc[t]); #we can only use the technology if u1 = 1\n", " @constraint(model, [t=1:T,i=2:4], \n", " quantity[t,i] <= u1[t,i] * tech[i,\"capUB\"]);\n", " @constraint(model, [t=1:T, i=5:I], \n", " quantity[t,i] <= u1[t,i] * M);\n", " @constraint(model, [t=1:T], \n", " quantity[t,5] <= K[5]);\n", " @constraint(model, [t=1:T], \n", " quantity[t,6] <= K[6] * data.wind_cap[t]);\n", " @constraint(model, [t=1:T], \n", " quantity[t,7] <= K[7] * data.solar_cap[t]);\n", "\n", " @constraint(model, [t=1:T], \n", " quantity[t,1] >= u2[t,1] * data.hydronuc[t]); #if u2 = u1 = 1, hydronuc <= q <= hydronuc\n", " @constraint(model, [t=1:T,i=2:4], \n", " quantity[t,i] >= u2[t,i] * tech[i,\"capUB\"]);\n", " @constraint(model, [t=1:T], \n", " quantity[t,5] >= K[5] - M * (1.0-u2[t,5]));\n", " @constraint(model, [t=1:T], \n", " quantity[t,6] >= K[6] * data.wind_cap[t] - M * (1.0-u2[t,6]));\n", " @constraint(model, [t=1:T], \n", " quantity[t,7] >= K[7] * data.solar_cap[t] - M * (1.0-u2[t,7]));\n", "\n", " @constraint(model, [t=1:T,i=1:I], u1[t,i] >= u2[t,i]);\n", "\n", " # Constraints on optimality \n", " if (import_slope==true)\n", " @constraint(model, [t=1:T,i=1:I],\n", " price[t] - tech.c[i] - tech.c2[i]*quantity[t,i] - (1.0-theta)/(data.b[t]+data.bm[t])*quantity[t,i] - shadow[t,i] \n", " >= -M * (1-u1[t,i]));\n", " @constraint(model, [t=1:T,i=1:I],\n", " price[t] - tech.c[i] - tech.c2[i]*quantity[t,i] - (1.0-theta)/(data.b[t]+data.bm[t])*quantity[t,i] - shadow[t,i] \n", " <= 0.0);\n", " else\n", " @constraint(model, [t=1:T,i=1:I],\n", " price[t] - tech.c[i] - tech.c2[i]*quantity[t,i] - (1.0-theta)/data.b[t]*quantity[t,i] - shadow[t,i] \n", " >= -M * (1-u1[t,i]));\n", " @constraint(model, [t=1:T,i=1:I],\n", " price[t] - tech.c[i] - tech.c2[i]*quantity[t,i] - (1.0-theta)/data.b[t]*quantity[t,i] - shadow[t,i] \n", " <= 0.0);\n", " end\n", " @constraint(model, [t=1:T,i=1:I], shadow[t,i] <= M*u2[t,i]);\n", "\n", " if (solve_invest==true)\n", " # Definition of profit\n", " @constraint(model, profit[5] == \n", " sum(data.weights[t]*shadow[t,5] for t=1:T) - tech.F[5] - 2 * tech.F2[5]*K[5]);\n", " @constraint(model, profit[6] == \n", " sum(data.weights[t]*shadow[t,6]*data.wind_cap[t] for t=1:T) - tech.F[6] - 2 * tech.F2[6]*K[6]);\n", " @constraint(model, profit[7] == \n", " sum(data.weights[t]*shadow[t,7]*data.solar_cap[t] for t=1:T) - tech.F[7] - 2 * tech.F2[7]*K[7]);\n", "\n", " # Constraints on investment \n", " @constraint(model, [i=5:I], profit[i] >= -M*(1.0-u3[i])); # zero profits if investing\n", " @constraint(model, [i=5:I], K[i] <= M*u3[i]); # capacity only positive if firms can make zero profit\n", " else\n", " @constraint(model, [i=5:I], K[i]==0.0)\n", " end\n", "\n", " # Solve model\n", " optimize!(model);\n", "\n", " status = @sprintf(\"%s\", JuMP.termination_status(model));\n", "\n", " if (status==\"OPTIMAL\")\n", " p = JuMP.value.(price);\n", " avg_price = mean(p, weights(data.weights));\t\t\n", " q = JuMP.value.(quantity);\n", " imp = JuMP.value.(imports);\n", " d = JuMP.value.(demand);\n", " cost = sum(data.weights[t] * (sum(tech.c[i] * q[t,i] \n", " + tech.c2[i] * q[t,i]^2 / 2 for i=1:I) \n", " + (imp[t] - data.am[t])^2/(2 * data.bm[t])) for t=1:T)/sum(data.weights);\n", " shadow = JuMP.value.(shadow);\n", " u1 = JuMP.value.(u1);\n", " u2 = JuMP.value.(u2);\n", " u3 = JuMP.value.(u3);\n", " K = JuMP.value.(K)[5:I];\n", " results = Dict(\"status\" => @sprintf(\"%s\",JuMP.termination_status(model)),\n", " \"avg_price\" => avg_price,\n", " \"price\" => p,\n", " \"quantity\" => q,\n", " \"imports\" => imp,\n", " \"demand\" => d,\n", " \"cost\" => cost,\n", " \"shadow\" => shadow,\n", " \"u1\" => u1,\n", " \"u2\" => u2,\n", " \"u3\" => u3,\n", " \"gas_gw\" => K[5],\n", " \"wind_gw\" => K[6],\n", " \"solar_gw\" => K[7]);\n", " return results\n", " else\n", " results = Dict(\"status\" => @sprintf(\"%s\",JuMP.termination_status(model)));\n", " return results\n", " end\n", "\n", "end" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Part 1\n", "Markups are around 46% with full market power." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.46143894298956983" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# baseline no market power or investment\n", "baseline = clear_market_foc(dfclust, tech)\n", "\n", "# with full market power\n", "mkt_power = clear_market_foc(dfclust, tech, theta=0.0)\n", "\n", "mean((mkt_power[\"price\"] .- baseline[\"price\"])./mkt_power[\"price\"], weights(dfclust.weights))" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Dict{String, Any} with 14 entries:\n", " \"avg_price\" => 85.336\n", " \"price\" => [116.648, 81.8344, 71.9601, 93.1855, 89.6374, 72.2146, 75.8245…\n", " \"gas_gw\" => 0.0\n", " \"status\" => \"OPTIMAL\"\n", " \"u1\" => [1.0 1.0 … 1.0 1.0; 1.0 1.0 … 1.0 1.0; … ; 1.0 1.0 … 1.0 1.0; …\n", " \"quantity\" => [7.54349 6.4507 … 0.0 0.0; 4.0713 4.56106 … 0.0 0.0; … ; 2.615…\n", " \"solar_gw\" => 0.0\n", " \"imports\" => [12.7279, 11.4027, 11.5082, 10.1038, 8.77071, 10.6208, 11.5722…\n", " \"demand\" => [32.7407, 23.9546, 23.9571, 25.0004, 19.0459, 21.9857, 22.6403…\n", " \"shadow\" => [0.0 0.0 … 116.648 116.648; 20.9557 0.0 … 81.8344 81.8344; … ;…\n", " \"u2\" => [0.0 0.0 … 1.0 1.0; 1.0 0.0 … 1.0 1.0; … ; 1.0 0.0 … 1.0 1.0; …\n", " \"u3\" => 1-dimensional DenseAxisArray{Float64,1,...} with index sets:…\n", " \"cost\" => 523.04\n", " \"wind_gw\" => 0.0" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mkt_power_no_import = clear_market_foc(dfclust, tech, import_slope=false, theta=0.0)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Part 2\n", "Markups are declining with forward contracts." ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "thetaMat = collect(0.0:0.1:1.0)\n", "df_noinvest = DataFrame(theta=Float64[],mkup=Float64[])\n", "for th in thetaMat\n", " res = clear_market_foc(dfclust, tech, theta=th)\n", " mkup = mean((res[\"price\"] .- baseline[\"price\"])./res[\"price\"], weights(dfclust.weights))\n", " push!(df_noinvest, [th, mkup])\n", "end\n", "\n", "plot(df_noinvest.theta, df_noinvest.mkup, xlabel=\"Forward contract position\", ylabel=\"% Markup\", legend=false)\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Part 3\n", "\n", "Investment disciplines market power but it also distorts it.\n", "\n", "Market power makes free entry of renewables more attractive." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "baseline = clear_market_foc(dfclust, tech, solve_invest=true)\n", "thetaMat = collect(0.0:0.1:1.0)\n", "df_invest = DataFrame(theta=Float64[],mkup=Float64[],gas_gw=Float64[],wind_gw=Float64[],solar_gw=Float64[])\n", "for th in thetaMat\n", " res = clear_market_foc(dfclust, tech, theta=th, solve_invest=true)\n", " mkup = mean((res[\"price\"] .- baseline[\"price\"])./res[\"price\"], weights(dfclust.weights))\n", " push!(df_invest, [th, mkup, res[\"gas_gw\"], res[\"wind_gw\"], res[\"solar_gw\"]])\n", "end" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot(df_invest.theta,df_invest.gas_gw, xlabel=\"Forward contract position\", ylabel=\"GW\", label=\"Gas\")\n", "plot!(df_invest.theta,df_invest.wind_gw, label=\"Wind\")\n", "plot!(df_invest.theta,df_invest.solar_gw, label=\"Solar\")" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plot(df_noinvest.theta, df_noinvest.mkup, xlabel=\"Forward contract position\", ylabel=\"% Markup\", label=\"No investment\")\n", "plot!(df_invest.theta, df_invest.mkup, label=\"Investment\")" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Dict{String, Any} with 14 entries:\n", " \"avg_price\" => 70.1757\n", " \"price\" => [99.8415, 68.6815, 63.3209, 76.5591, 68.6982, 60.4261, 59.4982…\n", " \"gas_gw\" => 2.84764\n", " \"status\" => \"OPTIMAL\"\n", " \"u1\" => [1.0 1.0 … 1.0 1.0; 1.0 1.0 … 1.0 1.0; … ; 1.0 1.0 … 1.0 1.0; …\n", " \"quantity\" => [6.35472 5.28865 … 1.57304 1.1219; 4.0713 3.53526 … 1.27152 0.…\n", " \"solar_gw\" => 1.7239\n", " \"imports\" => [11.835, 10.4808, 10.8335, 9.1362, 7.7309, 9.69145, 10.328, 9.…\n", " \"demand\" => [33.9294, 25.0071, 24.687, 26.4537, 20.2906, 23.1509, 23.9485,…\n", " \"shadow\" => [0.0 0.0 … 77.6023 83.9803; 7.8028 0.0 … 52.7914 68.5411; … ; …\n", " \"u2\" => [0.0 0.0 … 1.0 1.0; 1.0 0.0 … 1.0 1.0; … ; 1.0 0.0 … 1.0 1.0; …\n", " \"u3\" => 1-dimensional DenseAxisArray{Float64,1,...} with index sets:…\n", " \"cost\" => 435.585\n", " \"wind_gw\" => 4.95305" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Check without import slope\n", "mkt_power = clear_market_foc(dfclust, tech, solve_invest=true, import_slope=false, theta=0.0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.8.5", "language": "julia", "name": "julia-1.8" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.8.5" } }, "nbformat": 4, "nbformat_minor": 2 }