{ "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": {}, "outputs": [], "source": [ "from copy import deepcopy\n", "from time import perf_counter\n", "from pprint import pprint\n", "\n", "import yaml\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": {}, "outputs": [ { "data": { "text/plain": [ "7.5" ] }, "execution_count": 2, "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": {}, "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": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " iea_26_one_mobilization | 5.58 m\n", " iea_26_one_mobilization_100pct_reduction | 5.86 m\n", " iea_26_two_mobilizations | 6.58 m\n", " iea_26_two_mobilizations_100pct_reduction | 6.78 m\n", " iea_26_three_mobilizations | 7.36 m\n", " iea_26_three_mobilizations_100pct_reduction | 7.31 m\n" ] } ], "source": [ "for config in configs:\n", " # Run the simulation\n", " start = perf_counter()\n", " sim = Simulation(IEA_26, f\"{config}.yaml\")\n", " sim.run()\n", " end = perf_counter()\n", " print(f\"{sim.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)\n", " sim.env.cleanup_log_files(log_only=True)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Save the results\n", "# pickled dictionary format\n", "with open(IEA_26/ \"outputs\" / \"results_dict_v0.4.yaml\", \"w\") as f:\n", " yaml.dump(results, f, default_flow_style=False, sort_keys=False)\n", "\n", "# dataframe/csv format\n", "results_df = pd.DataFrame(results.values(), columns=columns, index=results.keys()).fillna(0)\n", "results_df.to_csv(IEA_26 / \"outputs\" / \"results_data_v0.4.csv\", index_label=\"result\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "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.65 | \n", "0.90 | \n", "0.86 | \n", "0.96 | \n", "0.91 | \n", "
| availability - production based | \n", "0.67 | \n", "0.65 | \n", "0.91 | \n", "0.86 | \n", "0.96 | \n", "0.92 | \n", "
| capacity factor - net | \n", "0.39 | \n", "0.38 | \n", "0.53 | \n", "0.51 | \n", "0.57 | \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,533,472,037.00 | \n", "26,832,956,757.50 | \n", "37,498,176,059.00 | \n", "35,577,459,635.50 | \n", "39,785,891,398.50 | \n", "37,830,990,928.00 | \n", "
| task completion rate | \n", "0.99 | \n", "1.00 | \n", "0.99 | \n", "1.00 | \n", "0.99 | \n", "1.00 | \n", "
| total annual costs | \n", "15.35 | \n", "14.95 | \n", "21.34 | \n", "20.97 | \n", "24.84 | \n", "24.42 | \n", "
| technicians | \n", "3.00 | \n", "3.00 | \n", "3.00 | \n", "3.00 | \n", "3.00 | \n", "3.00 | \n", "
| materials | \n", "4.14 | \n", "3.76 | \n", "6.16 | \n", "5.83 | \n", "6.61 | \n", "6.38 | \n", "
| vessels | \n", "8.22 | \n", "8.19 | \n", "12.18 | \n", "12.14 | \n", "15.23 | \n", "15.03 | \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.59 | \n", "3.56 | \n", "7.54 | \n", "7.51 | \n", "10.60 | \n", "10.40 | \n", "
| dsv cost | \n", "0.53 | \n", "0.53 | \n", "0.54 | \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.27 | \n", "4.62 | \n", "0.26 | \n", "9.19 | \n", "0.29 | \n", "8.99 | \n", "
| minor repair | \n", "0.48 | \n", "2.34 | \n", "0.55 | \n", "3.64 | \n", "0.55 | \n", "3.68 | \n", "
| major repair | \n", "0.54 | \n", "0.74 | \n", "0.65 | \n", "0.94 | \n", "0.69 | \n", "0.94 | \n", "
| major replacement | \n", "88.43 | \n", "81.64 | \n", "30.48 | \n", "27.51 | \n", "9.74 | \n", "8.23 | \n", "
| remote reset | \n", "0.20 | \n", "2.42 | \n", "0.23 | \n", "3.22 | \n", "0.24 | \n", "3.34 | \n", "
| annual service | \n", "1.68 | \n", "0.00 | \n", "1.52 | \n", "0.00 | \n", "1.39 | \n", "0.00 | \n", "
| bos | \n", "0.17 | \n", "2.28 | \n", "0.04 | \n", "3.71 | \n", "0.01 | \n", "2.97 | \n", "
| total downtime | \n", "91.87 | \n", "94.10 | \n", "33.84 | \n", "48.29 | \n", "13.00 | \n", "28.22 | \n", "
| ctv utilization | \n", "0.04 | \n", "0.03 | \n", "0.05 | \n", "0.00 | \n", "0.00 | \n", "0.04 | \n", "
| hlv utilization | \n", "0.02 | \n", "0.02 | \n", "0.02 | \n", "0.00 | \n", "0.00 | \n", "0.01 | \n", "
| dsv utilization | \n", "0.00 | \n", "0.00 | \n", "0.03 | \n", "0.00 | \n", "0.00 | \n", "0.01 | \n", "
| cab utilization | \n", "0.02 | \n", "0.01 | \n", "0.01 | \n", "0.00 | \n", "0.00 | \n", "0.01 | \n", "