{ "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", "\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", " \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", " \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", " \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", " \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", "
one_mobilizationone_mobilization_100pct_reductiontwo_mobilizationstwo_mobilizations_100pct_reductionthree_mobilizationsthree_mobilizations_100pct_reduction
availability - time based0.660.650.900.860.960.91
availability - production based0.670.650.910.860.960.92
capacity factor - net0.390.380.530.510.570.54
capacity factor - gross0.590.590.590.590.590.59
power production27,533,472,037.0026,832,956,757.5037,498,176,059.0035,577,459,635.5039,785,891,398.5037,830,990,928.00
task completion rate0.991.000.991.000.991.00
total annual costs15.3514.9521.3420.9724.8424.42
technicians3.003.003.003.003.003.00
materials4.143.766.165.836.616.38
vessels8.228.1912.1812.1415.2315.03
ctv cost2.562.562.562.562.562.56
hlv cost3.593.567.547.5110.6010.40
dsv cost0.530.530.540.530.530.53
cab cost1.551.551.551.551.551.55
manual reset0.274.620.269.190.298.99
minor repair0.482.340.553.640.553.68
major repair0.540.740.650.940.690.94
major replacement88.4381.6430.4827.519.748.23
remote reset0.202.420.233.220.243.34
annual service1.680.001.520.001.390.00
bos0.172.280.043.710.012.97
total downtime91.8794.1033.8448.2913.0028.22
ctv utilization0.040.030.050.000.000.04
hlv utilization0.020.020.020.000.000.01
dsv utilization0.000.000.030.000.000.01
cab utilization0.020.010.010.000.000.01
\n", "
" ], "text/plain": [ " one_mobilization \\\n", "availability - time based 0.66 \n", "availability - production based 0.67 \n", "capacity factor - net 0.39 \n", "capacity factor - gross 0.59 \n", "power production 27,533,472,037.00 \n", "task completion rate 0.99 \n", "total annual costs 15.35 \n", "technicians 3.00 \n", "materials 4.14 \n", "vessels 8.22 \n", "ctv cost 2.56 \n", "hlv cost 3.59 \n", "dsv cost 0.53 \n", "cab cost 1.55 \n", "manual reset 0.27 \n", "minor repair 0.48 \n", "major repair 0.54 \n", "major replacement 88.43 \n", "remote reset 0.20 \n", "annual service 1.68 \n", "bos 0.17 \n", "total downtime 91.87 \n", "ctv utilization 0.04 \n", "hlv utilization 0.02 \n", "dsv utilization 0.00 \n", "cab utilization 0.02 \n", "\n", " one_mobilization_100pct_reduction \\\n", "availability - time based 0.65 \n", "availability - production based 0.65 \n", "capacity factor - net 0.38 \n", "capacity factor - gross 0.59 \n", "power production 26,832,956,757.50 \n", "task completion rate 1.00 \n", "total annual costs 14.95 \n", "technicians 3.00 \n", "materials 3.76 \n", "vessels 8.19 \n", "ctv cost 2.56 \n", "hlv cost 3.56 \n", "dsv cost 0.53 \n", "cab cost 1.55 \n", "manual reset 4.62 \n", "minor repair 2.34 \n", "major repair 0.74 \n", "major replacement 81.64 \n", "remote reset 2.42 \n", "annual service 0.00 \n", "bos 2.28 \n", "total downtime 94.10 \n", "ctv utilization 0.03 \n", "hlv utilization 0.02 \n", "dsv utilization 0.00 \n", "cab utilization 0.01 \n", "\n", " two_mobilizations \\\n", "availability - time based 0.90 \n", "availability - production based 0.91 \n", "capacity factor - net 0.53 \n", "capacity factor - gross 0.59 \n", "power production 37,498,176,059.00 \n", "task completion rate 0.99 \n", "total annual costs 21.34 \n", "technicians 3.00 \n", "materials 6.16 \n", "vessels 12.18 \n", "ctv cost 2.56 \n", "hlv cost 7.54 \n", "dsv cost 0.54 \n", "cab cost 1.55 \n", "manual reset 0.26 \n", "minor repair 0.55 \n", "major repair 0.65 \n", "major replacement 30.48 \n", "remote reset 0.23 \n", "annual service 1.52 \n", "bos 0.04 \n", "total downtime 33.84 \n", "ctv utilization 0.05 \n", "hlv utilization 0.02 \n", "dsv utilization 0.03 \n", "cab utilization 0.01 \n", "\n", " two_mobilizations_100pct_reduction \\\n", "availability - time based 0.86 \n", "availability - production based 0.86 \n", "capacity factor - net 0.51 \n", "capacity factor - gross 0.59 \n", "power production 35,577,459,635.50 \n", "task completion rate 1.00 \n", "total annual costs 20.97 \n", "technicians 3.00 \n", "materials 5.83 \n", "vessels 12.14 \n", "ctv cost 2.56 \n", "hlv cost 7.51 \n", "dsv cost 0.53 \n", "cab cost 1.55 \n", "manual reset 9.19 \n", "minor repair 3.64 \n", "major repair 0.94 \n", "major replacement 27.51 \n", "remote reset 3.22 \n", "annual service 0.00 \n", "bos 3.71 \n", "total downtime 48.29 \n", "ctv utilization 0.00 \n", "hlv utilization 0.00 \n", "dsv utilization 0.00 \n", "cab utilization 0.00 \n", "\n", " three_mobilizations \\\n", "availability - time based 0.96 \n", "availability - production based 0.96 \n", "capacity factor - net 0.57 \n", "capacity factor - gross 0.59 \n", "power production 39,785,891,398.50 \n", "task completion rate 0.99 \n", "total annual costs 24.84 \n", "technicians 3.00 \n", "materials 6.61 \n", "vessels 15.23 \n", "ctv cost 2.56 \n", "hlv cost 10.60 \n", "dsv cost 0.53 \n", "cab cost 1.55 \n", "manual reset 0.29 \n", "minor repair 0.55 \n", "major repair 0.69 \n", "major replacement 9.74 \n", "remote reset 0.24 \n", "annual service 1.39 \n", "bos 0.01 \n", "total downtime 13.00 \n", "ctv utilization 0.00 \n", "hlv utilization 0.00 \n", "dsv utilization 0.00 \n", "cab utilization 0.00 \n", "\n", " three_mobilizations_100pct_reduction \n", "availability - time based 0.91 \n", "availability - production based 0.92 \n", "capacity factor - net 0.54 \n", "capacity factor - gross 0.59 \n", "power production 37,830,990,928.00 \n", "task completion rate 1.00 \n", "total annual costs 24.42 \n", "technicians 3.00 \n", "materials 6.38 \n", "vessels 15.03 \n", "ctv cost 2.56 \n", "hlv cost 10.40 \n", "dsv cost 0.53 \n", "cab cost 1.55 \n", "manual reset 8.99 \n", "minor repair 3.68 \n", "major repair 0.94 \n", "major replacement 8.23 \n", "remote reset 3.34 \n", "annual service 0.00 \n", "bos 2.97 \n", "total downtime 28.22 \n", "ctv utilization 0.04 \n", "hlv utilization 0.01 \n", "dsv utilization 0.01 \n", "cab utilization 0.01 " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.options.display.float_format = '{:,.2f}'.format\n", "\n", "results_df" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" } }, "nbformat": 4, "nbformat_minor": 4 }