{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# BEE 4750 Homework 4: Linear Programming and Capacity Expansion\n", "\n", "**Name**:\n", "\n", "**ID**:\n", "\n", "> **Due Date**\n", ">\n", "> Thursday, 11/07/23, 9:00pm\n", "\n", "## Overview\n", "\n", "### Instructions\n", "\n", "- Problem 1 asks you to formulate and solve a resource allocation\n", " problem using linear programming.\n", "- Problem 2 asks you to formulate, solve, and analyze a standard\n", " generating capacity expansion problem.\n", "- Problem 3 (5750 only) asks you to add a CO2 constraint to\n", " the capacity expansion problem and identify changes in the resulting\n", " solution.\n", "\n", "### Load Environment\n", "\n", "The following code loads the environment and makes sure all needed\n", "packages are installed. This should be at the start of most Julia\n", "scripts." ], "id": "774a0f9d-7faa-437f-baf0-5f4011c63ced" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import Pkg\n", "Pkg.activate(@__DIR__)\n", "Pkg.instantiate()" ], "id": "2" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "using JuMP\n", "using HiGHS\n", "using DataFrames\n", "using Plots\n", "using Measures\n", "using CSV\n", "using MarkdownTables" ], "id": "4" }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Problems (Total: 50/60 Points)\n", "\n", "### Problem 1 (20 points)\n", "\n", "A farmer has access to a pesticide which can be used on corn, soybeans,\n", "and wheat fields, and costs \\$70/kg-yr to apply. The crop yields the\n", "farmer can obtain following crop yields by applying varying rates of\n", "pesticides to the field are shown in\n", "Table 1.\n", "\n", "| Application Rate (kg/ha) | Soybean (kg/ha) | Wheat (kg/ha) | Corn (kg/ha) |\n", "|:------------------------:|:---------------:|:-------------:|:------------:|\n", "| 0 | 2900 | 3500 | 5900 |\n", "| 1 | 3800 | 4100 | 6700 |\n", "| 2 | 4400 | 4200 | 7900 |\n", "\n", "Table 1: Crop yields from applying varying pesticide rates for Problem\n", "1.\n", "\n", "The costs of production, *excluding pesticides*, for each crop, and\n", "selling prices, are shown in\n", "Table 2.\n", "\n", "| Crop | Production Cost (\\$/ha-yr) | Selling Price (\\$/kg) |\n", "|:--------:|:--------------------------:|:---------------------:|\n", "| Soybeans | 350 | 0.36 |\n", "| Wheat | 280 | 0.27 |\n", "| Corn | 390 | 0.22 |\n", "\n", "Table 2: Costs of crop production, excluding pesticides, and selling\n", "prices for each crop.\n", "\n", "Recently, environmental authorities have declared that farms cannot have\n", "an *average* application rate on soybeans, wheat, and corn which exceeds\n", "0.8, 0.7, and 0.6 kg/ha, respectively. The farmer has asked you for\n", "advice on how they should plant crops and apply pesticides to maximize\n", "profits over 130 total ha while remaining in regulatory compliance if\n", "demand for each crop (which is the maximum the market would buy) this\n", "year is 250,000 kg?\n", "\n", "**In this problem**:\n", "\n", "- Formulate a linear program for this resource allocation problem,\n", " including clear definitions of decision variable(s) (including\n", " units), objective function(s), and constraint(s) (make sure to\n", " explain functions and constraints with any needed derivations and\n", " explanations). **Tip: Make sure that all of your constraints are\n", " linear**.\n", "- Implement the program in `JuMP.jl` and find the solution. How many\n", " ha should the farmer dedicate to each crop and with what pesticide\n", " application rate(s)? How much profit will the farmer expect to make?\n", "- The farmer has an opportunity to buy an extra 10 ha of land. How\n", " much extra profit would this land be worth to the farmer? Discuss\n", " why this value makes sense and whether you would recommend the\n", " farmer should make the purchase.\n", "\n", "### Problem 2 (30 points)\n", "\n", "For this problem, we will use hourly load (demand) data from 2013 in New\n", "York’s Zone C (which includes Ithaca). The load data is loaded and\n", "plotted below in Figure 1." ], "id": "2c31e833-1539-4a79-aa85-b75b04665964" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# load the data, pull Zone C, and reformat the DataFrame\n", "NY_demand = DataFrame(CSV.File(\"data/2013_hourly_load_NY.csv\"))\n", "rename!(NY_demand, :\"Time Stamp\" => :Date)\n", "demand = NY_demand[:, [:Date, :C]]\n", "rename!(demand, :C => :Demand)\n", "demand[:, :Hour] = 1:nrow(demand)\n", "\n", "# plot demand\n", "plot(demand.Hour, demand.Demand, xlabel=\"Hour of Year\", ylabel=\"Demand (MWh)\", label=:false)" ], "id": "cell-fig-demand" }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we load the generator data, shown in\n", "Table 3. This data\n", "includes fixed costs (\\$/MW installed), variable costs (\\$/MWh\n", "generated), and CO2 emissions intensity (tCO2/MWh\n", "generated)." ], "id": "3d762807-b122-4ff7-a546-a1ce575ba508" }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "gens = DataFrame(CSV.File(\"data/generators.csv\"))" ], "id": "04ba2c8b-fdd5-4251-ad81-74c6528e6cd7" }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we load the hourly solar and wind capacity factors, which are\n", "plotted in Figure 2. These\n", "tell us the fraction of installed capacity which is expected to be\n", "available in a given hour for generation (typically based on the average\n", "meteorology)." ], "id": "3698a58d-e3bd-41a1-989e-1125a8a5a289" }, { "cell_type": "code", "execution_count": 1, "metadata": { "layout-nrow": 2 }, "outputs": [], "source": [ "# load capacify factors into a DataFrame\n", "cap_factor = DataFrame(CSV.File(\"data/wind_solar_capacity_factors.csv\"))\n", "\n", "# plot January capacity factors\n", "p1 = plot(cap_factor.Wind[1:(24*31)], label=\"Wind\")\n", "plot!(cap_factor.Solar[1:(24*31)], label=\"Solar\")\n", "xaxis!(\"Hour of the Month\")\n", "yaxis!(\"Capacity Factor\")\n", "\n", "p2 = plot(cap_factor.Wind[4344:4344+(24*31)], label=\"Wind\")\n", "plot!(cap_factor.Solar[4344:4344+(24*31)], label=\"Solar\")\n", "xaxis!(\"Hour of the Month\")\n", "yaxis!(\"Capacity Factor\")\n", "\n", "display(p1)\n", "display(p2)" ], "id": "eda339b8-599e-45f3-b32e-45dbc4c4008a" }, { "cell_type": "markdown", "metadata": {}, "source": [ "You have been asked to develop a generating capacity expansion plan for\n", "the utility in Riley County, NY, which currently has no existing\n", "electrical generation infrastructure. The utility can build any of the\n", "following plant types: geothermal, coal, natural gas combined cycle gas\n", "turbine (CCGT), natural gas combustion turbine (CT), solar, and wind.\n", "\n", "While coal, CCGT, and CT plants can generate at their full installed\n", "capacity, geothermal plants operate at maximum 85% capacity, and solar\n", "and wind available capacities vary by the hour depend on the expected\n", "meteorology. The utility will also penalize any non-served demand at a\n", "rate of \\$10,000/MWh.\n", "\n", "**In this problem**:\n", "\n", "- Formulate a linear program for this capacity expansion problem,\n", " including clear definitions of decision variable(s) (including\n", " units), objective function(s), and constraint(s) (make sure to\n", " explain functions and constraints with any needed derivations and\n", " explanations).\n", "- Implement your linear program in `JuMP.jl`. Find the optimal\n", " solution. How much should the utility build of each type of\n", " generating plant? What will the total cost be? How much energy will\n", " be non-served?\n", "- What fraction of annual generation does each plant type produce? How\n", " does this compare to the breakdown of built capacity that you found\n", " in Problem 1.5? Do these results make sense given the generator\n", " data?\n", "- Make a plot of the electricity price in each hour. Discuss any\n", " trends that you see.\n", "\n", "> **Significant Digits**\n", ">\n", "> Use `round(x; digits=n)` to report values to the appropriate\n", "> precision! If your number is on a different order of magnitude and you\n", "> want to round to a certain number of significant digits, you can use\n", "> `round(x; sigdigits=n)`.\n", "\n", "> **Getting Variable Output Values**\n", ">\n", "> `value.(x)` will report the values of a `JuMP` variable `x`, but it\n", "> will return a special container which holds other information about\n", "> `x` that is useful for `JuMP`. This means that you can’t use this\n", "> output directly for further calculations. To just extract the values,\n", "> use `value.(x).data`.\n", "\n", "> **Suppressing Model Command Output**\n", ">\n", "> The output of specifying model components (variable or constraints)\n", "> can be quite large for this problem because of the number of time\n", "> periods. If you end a cell with an `@variable` or `@constraint`\n", "> command, I *highly* recommend suppressing output by adding a\n", "> semi-colon after the last command, or you might find that your\n", "> notebook crashes.\n", "\n", "### Problem 3 (10 points)\n", "\n", "**This problem is only required for students in BEE 5750**.\n", "\n", "The NY state legislature is considering enacting an annual\n", "CO2 limit, which for the utility would limit the emissions in\n", "its footprint to 1.5 MtCO2/yr.\n", "\n", "**In this problem**:\n", "\n", "- Reformulate your linear program from Problem 2 with any necessary\n", " changes to capture the CO2 limit.\n", "- Implement the new optimization problem and find the optimal\n", " solution. How much should the utility build of each type of\n", " generating plant? What is different from your plan from Problem 1?\n", " Do these changes make sense?\n", "- What would the value to the utility be of allowing it to emit an\n", " additional 1000 tCO2/yr? An additional 5000?" ], "id": "69f4182e-16ed-4890-96fd-493f789002ab" }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References\n", "\n", "List any external references consulted, including classmates." ], "id": "6dd10a11-f4ed-434e-b73f-cc63bc508b8e" } ], "nbformat": 4, "nbformat_minor": 5, "metadata": { "kernel_info": { "name": "julia" }, "kernelspec": { "name": "julia", "display_name": "Julia", "language": "julia" }, "language_info": { "name": "julia", "codemirror_mode": "julia", "version": "1.10.4" } } }