import os
import pickle
from copy import deepcopy
from time import perf_counter
from pprint import pprint
from pathlib import Path
import numpy as np
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
from wombat.core import Simulation, Metrics
from wombat.core.library import DINWOODIE, load_yaml
pd.set_option("display.max_rows", 1000)
pd.set_option("display.max_columns", 1000)
pd.options.display.float_format = '{:,.2f}'.format
%matplotlib inline
# Converting Labor values to fixed cost input for the base case
tech_salary_annual = 80000
techs = 20
capacity = 240 * 1000 # 240 -> kW
f"{tech_salary_annual * techs / capacity:.4f}"
'6.6667'
configs = [
"base",
"more_ctvs",
"fewer_ctvs",
"more_techs",
"fewer_techs",
"failure_50",
"failure_200",
"no_hlvs",
"no_weather",
"historic_weather",
"manual_resets_only",
"minor_repairs_only",
"medium_repairs_only",
"major_repairs_only",
"major_replacements_only",
"annual_service_only",
]
columns = deepcopy(configs)
results = {
"availability - time based": [],
"availability - production based": [],
"capacity factor - net": [],
"capacity factor - gross": [],
"power production": [],
"task completion rate": [],
"annual direct O&M cost": [],
"annual vessel cost": [],
"ctv cost": [],
"fsv cost": [],
"hlv cost": [],
"annual repair cost": [],
"annual technician cost": [],
"ctv utilization": [],
"fsv utilization": [],
"hlv utilization": [],
}
for config in configs:
# Run the simulation
start = perf_counter()
sim = Simulation(library_path=DINWOODIE, config=f"{config}.yaml")
print(f"{sim.config.name.rjust(30)}", end=" | ")
sim.run(8760)
end = perf_counter()
print(f"{(end - start) / 60:.2f} min")
events_fname = Path(sim.env.events_log_fname)
fname = events_fname.name
fname = fname.replace("_events.log", "_metrics_inputs.yaml")
# Get the path and move it 1 level up to <data_dir>/outputs/
fpath = events_fname.parents[1]
metrics = Metrics.from_simulation_outputs(fpath, fname)
# Gather the results of interest
years = metrics.events.year.unique().shape[0]
mil = 1000000
availability_time = metrics.time_based_availability(frequency="project", by="windfarm")
availability_production = metrics.production_based_availability(frequency="project", by="windfarm")
cf_net = metrics.capacity_factor(which="net", frequency="project", by="windfarm")
cf_gross = metrics.capacity_factor(which="gross", frequency="project", by="windfarm")
power_production = metrics.power_production(frequency="project", by_turbine=False).values[0][0]
completion_rate = metrics.task_completion_rate(which="both", frequency="project")
parts = metrics.events[["materials_cost"]].sum().sum()
techs = metrics.project_fixed_costs(frequency="project", resolution="low").operations[0]
total = metrics.events[["total_cost"]].sum().sum()
equipment = metrics.equipment_costs(frequency="project", by_equipment=True)
equipment_sum = equipment.sum().sum()
hlv = equipment[[el for el in equipment.columns if "Heavy Lift Vessel" in el]].sum().sum()
fsv = equipment[[el for el in equipment.columns if "Field Support Vessel" in el]].sum().sum()
ctv = equipment[[el for el in equipment.columns if "Crew Transfer Vessel" in el]].sum().sum()
utilization = metrics.service_equipment_utilization(frequency="project")
hlv_ur = utilization[[el for el in utilization.columns if "Heavy Lift Vessel" in el]].mean().mean()
fsv_ur = utilization[[el for el in utilization.columns if "Field Support Vessel" in el]].mean().mean()
ctv_ur = utilization[[el for el in utilization.columns if "Crew Transfer Vessel" in el]].mean().mean()
# Log the results of interest
results["availability - time based"].append(availability_time)
results["availability - production based"].append(availability_production)
results["capacity factor - net"].append(cf_net)
results["capacity factor - gross"].append(cf_gross)
results["power production"].append(power_production)
results["task completion rate"].append(completion_rate)
results["annual direct O&M cost"].append((total + techs) / mil / years)
results["annual vessel cost"].append(equipment_sum / mil / years)
results["ctv cost"].append(ctv / mil / years)
results["fsv cost"].append(fsv / mil / years)
results["hlv cost"].append(hlv / mil / years)
results["annual repair cost"].append(parts / mil / years)
results["annual technician cost"].append(techs / mil / years)
results["ctv utilization"].append(ctv_ur)
results["fsv utilization"].append(fsv_ur)
results["hlv utilization"].append(hlv_ur)
break
dinwoodie_base | 0.48 min
# Save the results
# pickled dictionary format
# with open(os.path.join(str(DINWOODIE), "outputs", "results_dict.pkl"), "wb") as f:
# pickle.dump(results, f)
# dataframe/csv format
results_df = pd.DataFrame(results.values(), columns=[columns[0]], index=results.keys()).fillna(0)
# results_df.to_csv(os.path.join(str(DINWOODIE), "outputs", "results_data.csv"), index_label="result")
results_df
base | |
---|---|
availability - time based | 0.98 |
availability - production based | 0.97 |
capacity factor - net | 0.41 |
capacity factor - gross | 0.42 |
power production | 859,422,410.50 |
task completion rate | 0.99 |
annual direct O&M cost | 14.58 |
annual vessel cost | 10.43 |
ctv cost | 1.92 |
fsv cost | 0.27 |
hlv cost | 8.25 |
annual repair cost | 2.55 |
annual technician cost | 1.60 |
ctv utilization | 0.65 |
fsv utilization | 0.17 |
hlv utilization | 0.46 |
# start = perf_counter()
# sim = Simulation(library_path=DINWOODIE, config="base.yaml")
# print(f"{sim.config.name.rjust(30)}", end=" | ")
# sim.run()
# end = perf_counter()
# print(f"{(end - start) / 60:.2f} min")