{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Code-to-Code Comparison: IEA Task 26\n", "\n", "### National Renewable Energy Laboratory\n", "\n", "#### Rob Hammond\n", "\n", "##### 27 May 2021" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2021-05-28T03:27:56.588900Z", "iopub.status.busy": "2021-05-28T03:27:56.588067Z", "iopub.status.idle": "2021-05-28T03:27:58.524145Z", "shell.execute_reply": "2021-05-28T03:27:58.524591Z" } }, "outputs": [], "source": [ "import os\n", "import pickle\n", "from copy import deepcopy\n", "from time import perf_counter\n", "from pprint import pprint\n", "\n", "import numpy as np\n", "import pandas as pd\n", "import networkx as nx\n", "import matplotlib.pyplot as plt\n", "\n", "from wombat.core import Simulation\n", "from wombat.core.library import IEA_26, load_yaml\n", "pd.set_option(\"display.max_rows\", 1000)\n", "pd.set_option(\"display.max_columns\", 1000)\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2021-05-28T03:27:58.530498Z", "iopub.status.busy": "2021-05-28T03:27:58.529663Z", "iopub.status.idle": "2021-05-28T03:27:58.533695Z", "shell.execute_reply": "2021-05-28T03:27:58.534216Z" } }, "outputs": [ { "data": { "text/plain": [ "7.5" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tech_salary_annual = 100000\n", "techs = 30\n", "capacity = 400 * 1000 # 400MW -> kW\n", "tech_salary_annual * techs / capacity" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2021-05-28T03:27:58.540386Z", "iopub.status.busy": "2021-05-28T03:27:58.539645Z", "iopub.status.idle": "2021-05-28T03:27:58.541696Z", "shell.execute_reply": "2021-05-28T03:27:58.542210Z" } }, "outputs": [], "source": [ "configs = [\n", " \"one_mobilization\",\n", " \"one_mobilization_100pct_reduction\",\n", " \"two_mobilizations\",\n", " \"two_mobilizations_100pct_reduction\",\n", " \"three_mobilizations\",\n", " \"three_mobilizations_100pct_reduction\",\n", "]\n", "columns = deepcopy(configs)\n", "results = {\n", " \"availability - time based\": [],\n", " \"availability - production based\": [],\n", " \"capacity factor - net\": [],\n", " \"capacity factor - gross\": [],\n", " \"power production\": [],\n", " \"task completion rate\": [],\n", " \"total annual costs\": [],\n", " \"technicians\": [],\n", " \"materials\": [],\n", " \"vessels\": [],\n", " \"ctv cost\": [],\n", " \"hlv cost\": [],\n", " \"dsv cost\": [],\n", " \"cab cost\": [],\n", " \"manual reset\": [],\n", " \"minor repair\": [],\n", " \"major repair\": [],\n", " \"major replacement\": [],\n", " \"remote reset\": [],\n", " \"annual service\": [],\n", " \"bos\": [], # substructure inspection + scour repair + substation inspection + small/large transformer repairs\n", " \"total downtime\": [],\n", " \"ctv utilization\": [],\n", " \"hlv utilization\": [],\n", " \"dsv utilization\": [],\n", " \"cab utilization\": [],\n", "}" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2021-05-28T03:27:58.561457Z", "iopub.status.busy": "2021-05-28T03:27:58.560582Z", "iopub.status.idle": "2021-05-28T04:43:28.460163Z", "shell.execute_reply": "2021-05-28T04:43:28.461354Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " iea_26_one_mobilization | 8.23 m\n", " iea_26_one_mobilization_100pct_reduction | 11.13 m\n", " iea_26_two_mobilizations | 8.89 m\n", " iea_26_two_mobilizations_100pct_reduction | 10.59 m\n", " iea_26_three_mobilizations | 9.75 m\n", " iea_26_three_mobilizations_100pct_reduction | 12.67 m\n" ] } ], "source": [ "for config in configs:\n", " # Run the simulation\n", " start = perf_counter()\n", " config = load_yaml(os.path.join(str(IEA_26), \"config\"), f\"{config}.yaml\")\n", " sim = Simulation.from_inputs(**config)\n", " sim.run()\n", " end = perf_counter()\n", " print(f\"{config['name'].rjust(45)} | {(end - start) / 60:.2f} m\")\n", " \n", " # Gather the results of interest\n", " years = sim.metrics.events.year.unique().shape[0]\n", " mil = 1000000\n", " \n", " availability = sim.metrics.time_based_availability(frequency=\"project\", by=\"windfarm\")\n", " availability_production = sim.metrics.production_based_availability(frequency=\"project\", by=\"windfarm\")\n", " cf_net = sim.metrics.capacity_factor(which=\"net\", frequency=\"project\", by=\"windfarm\")\n", " cf_gross = sim.metrics.capacity_factor(which=\"gross\", frequency=\"project\", by=\"windfarm\")\n", " power_production = sim.metrics.power_production(frequency=\"project\", by_turbine=False).values[0][0]\n", " completion_rate = sim.metrics.task_completion_rate(which=\"both\", frequency=\"project\")\n", " parts = sim.metrics.events[[\"materials_cost\"]].sum().sum()\n", " techs = sim.metrics.project_fixed_costs(frequency=\"project\", resolution=\"medium\").labor[0]\n", " total = sim.metrics.events[[\"total_cost\"]].sum().sum()\n", "\n", " equipment = sim.metrics.equipment_costs(frequency=\"project\", by_equipment=True)\n", " equipment_sum = equipment.sum().sum()\n", " ctv = equipment[[el for el in equipment.columns if \"Crew Transfer Vessel\" in el]].sum().sum()\n", " hlv = equipment[[el for el in equipment.columns if \"Jack-up Vessel\" in el]].sum().sum()\n", " dsv = equipment[[el for el in equipment.columns if \"Diving Support Vessel\" in el]].sum().sum()\n", " cab = equipment[[el for el in equipment.columns if \"Cable Laying Vessel\" in el]].sum().sum()\n", "\n", " times = sim.metrics.process_times()\n", " times = times / years / 24 / 100 # events per turbine and year\n", " \n", " utilization = sim.metrics.service_equipment_utilization(frequency=\"project\")\n", " ctv_ur = utilization[[el for el in utilization.columns if \"Crew Transfer Vessel\" in el]].mean().mean()\n", " hlv_ur = utilization[[el for el in utilization.columns if \"Jack-up Vessel\" in el]].mean().mean()\n", " dsv_ur = utilization[[el for el in utilization.columns if \"Diving Support Vessel\" in el]].mean().mean()\n", " cab_ur = utilization[[el for el in utilization.columns if \"Cable Laying Vessel\" in el]].mean().mean()\n", "\n", " # Log the results of interest\n", " results[\"availability - time based\"].append(availability)\n", " results[\"availability - production based\"].append(availability_production)\n", " results[\"capacity factor - net\"].append(cf_net)\n", " results[\"capacity factor - gross\"].append(cf_gross)\n", " results[\"power production\"].append(power_production)\n", " results[\"task completion rate\"].append(completion_rate)\n", " results[\"total annual costs\"].append((total + techs) / mil / years)\n", " results[\"technicians\"].append(techs / mil / years)\n", " results[\"materials\"].append(parts / mil / years)\n", " results[\"vessels\"].append(equipment_sum / mil / years)\n", " results[\"ctv cost\"].append(ctv / mil / years)\n", " results[\"hlv cost\"].append(hlv / mil / years)\n", " results[\"dsv cost\"].append(dsv / mil / years)\n", " results[\"cab cost\"].append(cab / mil / years)\n", " results[\"manual reset\"].append(times.loc[times.index.intersection([\"manual reset\"]), \"downtime\"].sum())\n", " results[\"minor repair\"].append(times.loc[times.index.intersection([\"minor repair\", ]), \"downtime\"].sum())\n", " results[\"major repair\"].append(times.loc[times.index.intersection([\"major repair\"]), \"downtime\"].sum())\n", " results[\"major replacement\"].append(times.loc[times.index.intersection([\"major replacement\"]), \"downtime\"].sum())\n", " results[\"remote reset\"].append(times.loc[times.index.intersection([\"remote reset\"]), \"downtime\"].sum())\n", " results[\"annual service\"].append(times.loc[times.index.intersection([\"annual service\"]), \"downtime\"].sum())\n", " ix = [\n", " \"substructure inspection\", \"substation inspection\",\n", " \"small foundation/scour repair\", \"cable replacement\",\n", " \"small transformer repair\", \"large transformer repair\"\n", " ]\n", " results[\"bos\"].append(times.loc[times.index.intersection(ix), \"downtime\"].sum())\n", " results[\"total downtime\"].append(times.loc[:, \"downtime\"].sum())\n", " results[\"ctv utilization\"].append(ctv_ur)\n", " results[\"hlv utilization\"].append(hlv_ur)\n", " results[\"dsv utilization\"].append(dsv_ur)\n", " results[\"cab utilization\"].append(cab_ur)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2021-05-28T04:43:28.479423Z", "iopub.status.busy": "2021-05-28T04:43:28.478572Z", "iopub.status.idle": "2021-05-28T04:43:28.490463Z", "shell.execute_reply": "2021-05-28T04:43:28.490971Z" } }, "outputs": [], "source": [ "# Save the results\n", "# pickled dictionary format\n", "with open(os.path.join(str(IEA_26), \"outputs\", \"results_dict.pkl\"), \"wb\") as f:\n", " pickle.dump(results, f)\n", "\n", "# dataframe/csv format\n", "results_df = pd.DataFrame(results.values(), columns=columns, index=results.keys()).fillna(0)\n", "results_df.to_csv(os.path.join(str(IEA_26), \"outputs\", \"results_data.csv\"), index_label=\"result\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true, "execution": { "iopub.execute_input": "2021-05-28T04:43:28.496174Z", "iopub.status.busy": "2021-05-28T04:43:28.495454Z", "iopub.status.idle": "2021-05-28T04:43:28.520392Z", "shell.execute_reply": "2021-05-28T04:43:28.520876Z" }, "jupyter": { "outputs_hidden": true } }, "outputs": [ { "data": { "text/html": [ "
| \n", " | one_mobilization | \n", "one_mobilization_100pct_reduction | \n", "two_mobilizations | \n", "two_mobilizations_100pct_reduction | \n", "three_mobilizations | \n", "three_mobilizations_100pct_reduction | \n", "
|---|---|---|---|---|---|---|
| availability - time based | \n", "0.66 | \n", "0.74 | \n", "0.84 | \n", "0.82 | \n", "0.95 | \n", "0.91 | \n", "
| availability - production based | \n", "0.66 | \n", "0.74 | \n", "0.84 | \n", "0.82 | \n", "0.95 | \n", "0.91 | \n", "
| capacity factor - net | \n", "0.39 | \n", "0.44 | \n", "0.49 | \n", "0.48 | \n", "0.56 | \n", "0.54 | \n", "
| capacity factor - gross | \n", "0.59 | \n", "0.59 | \n", "0.59 | \n", "0.59 | \n", "0.59 | \n", "0.59 | \n", "
| power production | \n", "27,389,328,921.00 | \n", "30,735,833,503.50 | \n", "34,598,056,055.00 | \n", "33,863,780,889.50 | \n", "39,287,511,766.00 | \n", "37,670,119,797.00 | \n", "
| task completion rate | \n", "1.00 | \n", "1.00 | \n", "1.00 | \n", "1.00 | \n", "1.00 | \n", "1.00 | \n", "
| total annual costs | \n", "15.27 | \n", "15.22 | \n", "20.99 | \n", "20.83 | \n", "24.78 | \n", "24.46 | \n", "
| technicians | \n", "3.00 | \n", "3.00 | \n", "3.00 | \n", "3.00 | \n", "3.00 | \n", "3.00 | \n", "
| materials | \n", "4.08 | \n", "4.03 | \n", "6.13 | \n", "5.98 | \n", "6.90 | \n", "6.55 | \n", "
| vessels | \n", "8.19 | \n", "8.19 | \n", "11.86 | \n", "11.85 | \n", "14.88 | \n", "14.91 | \n", "
| ctv cost | \n", "2.56 | \n", "2.56 | \n", "2.56 | \n", "2.56 | \n", "2.56 | \n", "2.56 | \n", "
| hlv cost | \n", "3.56 | \n", "3.56 | \n", "7.23 | \n", "7.22 | \n", "10.25 | \n", "10.28 | \n", "
| dsv cost | \n", "0.53 | \n", "0.53 | \n", "0.53 | \n", "0.53 | \n", "0.53 | \n", "0.53 | \n", "
| cab cost | \n", "1.55 | \n", "1.55 | \n", "1.55 | \n", "1.55 | \n", "1.55 | \n", "1.55 | \n", "
| manual reset | \n", "0.42 | \n", "4.43 | \n", "0.54 | \n", "5.44 | \n", "0.66 | \n", "7.80 | \n", "
| minor repair | \n", "0.94 | \n", "2.17 | \n", "1.21 | \n", "2.65 | \n", "1.48 | \n", "3.01 | \n", "
| major repair | \n", "0.57 | \n", "0.67 | \n", "0.70 | \n", "0.83 | \n", "0.78 | \n", "0.90 | \n", "
| major replacement | \n", "78.54 | \n", "59.59 | \n", "49.31 | \n", "44.78 | \n", "10.96 | \n", "9.25 | \n", "
| remote reset | \n", "0.02 | \n", "2.36 | \n", "0.04 | \n", "2.57 | \n", "0.06 | \n", "2.85 | \n", "
| annual service | \n", "1.98 | \n", "0.00 | \n", "1.63 | \n", "0.00 | \n", "1.84 | \n", "0.00 | \n", "
| bos | \n", "0.02 | \n", "3.54 | \n", "0.02 | \n", "3.09 | \n", "0.02 | \n", "3.86 | \n", "
| total downtime | \n", "82.70 | \n", "72.84 | \n", "53.68 | \n", "59.47 | \n", "16.09 | \n", "27.81 | \n", "
| ctv utilization | \n", "0.68 | \n", "0.35 | \n", "0.74 | \n", "0.40 | \n", "0.88 | \n", "0.46 | \n", "
| hlv utilization | \n", "1.00 | \n", "0.98 | \n", "1.00 | \n", "0.98 | \n", "0.73 | \n", "0.71 | \n", "
| dsv utilization | \n", "0.20 | \n", "0.23 | \n", "0.21 | \n", "0.23 | \n", "0.29 | \n", "0.23 | \n", "
| cab utilization | \n", "0.01 | \n", "0.01 | \n", "0.00 | \n", "0.01 | \n", "0.01 | \n", "0.03 | \n", "