Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 86 additions & 23 deletions ORBIT/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def _print_warnings(self):
phase = df.loc[idx, "phase"]
print(f"{phase}:\n\t {msg}")

except:
except: # noqa: E722
pass

@property
Expand Down Expand Up @@ -365,7 +365,7 @@ def compile_input_dict(cls, phases):
" commissioning_factor)"
),
"construction_insurance_factor": (
"float (optional, default: 0.0115)"
"float (optional, default: 0.0207)"
),
"construction_financing_factor": (
"$/kW (optional, default: value calculated using"
Expand All @@ -379,20 +379,20 @@ def compile_input_dict(cls, phases):
),
"tax_rate": "float (optional, default: 0.26",
"interest_during_construction": (
"float (optional, default: 0.044"
"float (optional, default: 0.065"
),
"procurement_contingency_factor": (
"float (optional, default: 0.0575)"
),
"installation_contingency_factor": (
"float (optional, default: 0.345)"
),
"decommissioning_factor": ("float (optional, default: 0.1725)"),
"decommissioning_factor": ("float (optional, default: 0.2)"),
"commissioning_factor": "float (optional, default: 0.0115)",
"site_auction_price": "$ (optional, default: 100e6)",
"site_assessment_cost": "$ (optional, default: 50e6)",
"construction_plan_cost": "$ (optional, default: 1e6)",
"installation_plan_cost": "$ (optional, default: 0.25e6)",
"site_auction_price": "$ (optional, default: 105e6)",
"site_assessment_cost": "$ (optional, default: 200e6)",
"construction_plan_cost": "$ (optional, default: 25e6)",
"installation_plan_cost": "$ (optional, default: 25e6)",
}

config["design_phases"] = [*design_phases.keys()]
Expand Down Expand Up @@ -670,7 +670,7 @@ def run_install_phase(self, name, start, **kwargs):

if phase.installation_capex:
self.installation_costs[name] = phase.installation_capex

return time, logs

def get_phase_class(self, phase):
Expand Down Expand Up @@ -747,6 +747,8 @@ def run_design_phase(self, name, **kwargs):
self.detailed_outputs, phase.detailed_output
)



def run_multiple_phases_in_serial(self, phase_list, **kwargs):
"""
Runs multiple phases listed in self.config['install_phases'] in serial.
Expand Down Expand Up @@ -1052,6 +1054,10 @@ def outputs(self, include_logs=False, npv_detailed=False):
"total_capex": self.total_capex,
"total_capex_per_kw": self.total_capex_per_kw,
"npv": self.npv,
"supply_chain_capex": self.supply_chain_capex,
"supply_chain_capex_kw": self.supply_chain_capex_per_kw,
"onshore_substation_capex": self.onshore_substation_capex,
"onshore_substation_capex_kw": self.onshore_substation_capex_per_kw,
}

if include_logs:
Expand Down Expand Up @@ -1440,12 +1446,17 @@ def capex_breakdown(self):
else:
outputs[name] = cost

outputs["Onshore Substation"] = self.onshore_substation_capex

outputs["Turbine"] = self.turbine_capex

outputs["Soft"] = self.soft_capex

outputs["Project"] = self.project_capex

if self.supply_chain_capex > 0:
outputs["Supply Chain"] = self.supply_chain_capex

return outputs

@property
Expand Down Expand Up @@ -1486,7 +1497,7 @@ def capex_detailed_soft_capex_breakdown_per_kw(self):
def bos_capex(self):
"""Returns total balance of system CapEx."""

return self.system_capex + self.installation_capex
return self.system_capex + self.installation_capex + self.onshore_substation_capex

@property
def bos_capex_per_kw(self):
Expand Down Expand Up @@ -1526,6 +1537,58 @@ def turbine_capex_per_kw(self):
_capex = self.project_params.get("turbine_capex", 1300)
return _capex

@property
def supply_chain_capex(self):
"""Returns the supply chain CapEx. This parameter includes any
project-level investments in supply chain development, port upgrades,
community benefit agreements, fisheries mitigation funds, community or
research initiatives, and U.S.-built vessels.
"""

_capex = self.project_params.get("supply_chain_capex", 0)

try:
num_turbines = self.config["plant"]["num_turbines"]
rating = self.config["turbine"]["turbine_rating"]

except KeyError:
pass

return _capex * num_turbines * rating * 1000

@property
def supply_chain_capex_per_kw(self):
"""Returns the supply chain CapEx/kW. This parameter includes any
project-level investments in supply chain development, port upgrades,
community benefit agreements, fisheries mitigation funds, community or
research initiatives, and U.S.-built vessels.
"""

_capex = self.project_params.get("supply_chain_capex", 0)

return _capex

@property
def onshore_substation_capex(self):
"""Returns the onshore substation CapEx if available in 'ElectricalDesign', otherwise 0."""
if "ElectricalDesign" in self.phases:
try:
return self.phases["ElectricalDesign"].detailed_output["export_system"]["onshore_substation_costs"]
except KeyError:
return 0
return 0

@property
def onshore_substation_capex_per_kw(self):
"""Returns the onshore substation CapEx/kW.
"""
if "ElectricalDesign" in self.phases:
try:
return self.onshore_substation_capex / (self.capacity * 1000)
except KeyError:
return None
return None

@property
def overnight_capex(self):
"""Returns the overnight capital cost of the project."""
Expand Down Expand Up @@ -1580,7 +1643,7 @@ def construction_insurance_capex(self):
)

contruction_insurance_factor = self.project_params.get(
"construction_insurance_factor", 0.0115
"construction_insurance_factor", 0.0207
)

if construction_insurance_per_kW is not None:
Expand All @@ -1606,7 +1669,7 @@ def decommissioning_capex(self):
)

decommissioning_factor = self.project_params.get(
"decommissioning_factor", 0.175
"decommissioning_factor", 0.2
)

if decommissioning_per_kW is not None:
Expand All @@ -1624,18 +1687,14 @@ def commissioning_capex(self):
Energy Review.
"""

commissioning_per_kW = self.project_params.get(
"commissioning", None
)
commissioning_per_kW = self.project_params.get("commissioning", None)

commissioning_factor = self.project_params.get(
"commissioning_factor", 0.0115
)

if commissioning_per_kW is not None:
commissioning = (
commissioning_per_kW * self.capacity * 1000
)
commissioning = commissioning_per_kW * self.capacity * 1000

else:
commissioning = (
Expand Down Expand Up @@ -1715,7 +1774,7 @@ def construction_financing_factor(self):
)
tax_rate = self.project_params.get("tax_rate", 0.26)
interest_during_construction = self.project_params.get(
"interest_during_construction", 0.044
"interest_during_construction", 0.065
)

_check = 0
Expand Down Expand Up @@ -1764,6 +1823,7 @@ def construction_financing_capex(self):
+ self.installation_contingency_capex()
+ self.bos_capex
+ self.turbine_capex
+ self.supply_chain_capex
) * (construction_financing_factor - 1)

return construction_financing
Expand All @@ -1775,13 +1835,15 @@ def project_capex(self):
the keys below should be passed to the 'project_parameters' subdict.
"""

site_auction = self.project_params.get("site_auction_price", 122698898)
site_assessment = self.project_params.get("site_assessment_cost", 61349449)
site_auction = self.project_params.get("site_auction_price", 105000000)
site_assessment = self.project_params.get(
"site_assessment_cost", 200000000
)
construction_plan = self.project_params.get(
"construction_plan_cost", 1226989
"construction_plan_cost", 25000000
)
installation_plan = self.project_params.get(
"installation_plan_cost", 306747
"installation_plan_cost", 25000000
)

return sum(
Expand Down Expand Up @@ -1814,6 +1876,7 @@ def total_capex(self):
+ self.turbine_capex
+ self.soft_capex
+ self.project_capex
+ self.supply_chain_capex
)

@property
Expand Down
Loading