Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancing tests for design module's total cost #173

Merged
merged 6 commits into from
Aug 21, 2024
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
13 changes: 12 additions & 1 deletion ORBIT/phases/design/_cables.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,18 @@ def __init__(self, cable_specs, **kwargs):
raise ValueError(f"{needs_value} must be defined in cable_specs")

self.line_frequency = cable_specs.get("line_frequency", 60)
self.cable_type = cable_specs.get("cable_type", "HVAC")
cable_type = cable_specs.get("cable_type", "HVAC").split("-")
if len(cable_type) == 1:
self.cable_type = cable_type[0].upper()
elif len(cable_type) == 2:
self.cable_type = (
f"{cable_type[0].upper()}-{cable_type[1].lower()}"
)
else:
raise ValueError(
"`cable_type` should be of the form `type-subtype`,"
" e.g. 'HVDC-monopole'."
)

# Calc additional cable specs
if self.cable_type == "HVAC":
Expand Down
4 changes: 2 additions & 2 deletions ORBIT/phases/design/electrical_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def __init__(self, config, **kwargs):

self.substructure_type = self._oss_design.get(
"oss_substructure_type", "Monopile"
)
).title()

self._outputs = {}

Expand Down Expand Up @@ -539,7 +539,7 @@ def calc_substructure_mass_and_cost(self):

substructure_pile_mass = (
0
if "Floating" in self.substructure_type
if self.substructure_type == "Floating"
else 8 * substructure_mass**0.5574
)

Expand Down
16 changes: 10 additions & 6 deletions ORBIT/phases/design/mooring_system_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ def __init__(self, config, **kwargs):

self._design = self.config.get("mooring_system_design", {})
self.num_lines = self._design.get("num_lines", 4)
self.anchor_type = self._design.get("anchor_type", "Suction Pile")
self.mooring_type = self._design.get("mooring_type", "Catenary")
self.anchor_type = self._design.get(
"anchor_type", "Suction Pile"
).title()
self.mooring_type = self._design.get(
"mooring_type", "Catenary"
).title()

# Semi-Taut mooring system design parameters based on depth [2].
self._semitaut_params = {
Expand Down Expand Up @@ -169,7 +173,7 @@ def calculate_line_length_mass(self):

draft = self._design.get("draft_depth", 20)

if self.mooring_type == "SemiTaut":
if self.mooring_type == "Semitaut":

# Interpolation of rope and chain length at project depth
self.chain_length = interp1d(
Expand Down Expand Up @@ -209,7 +213,7 @@ def calculate_line_length_mass(self):
+ self.rope_length * rope_mass_per_m
) / 1e3 # tonnes

elif self.mooring_type == "TLP":
elif self.mooring_type == "Tlp":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see how this is now annoying because there are many forms of standardization this could take.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... Never a one size fits all, heh.


self.line_length = self.depth - draft

Expand All @@ -233,7 +237,7 @@ def calculate_anchor_mass_cost(self):
different anchors.
"""

if self.mooring_type == "SemiTaut":
if self.mooring_type == "Semitaut":

if self.anchor_type == "Drag Embedment":
self.anchor_mass = 20
Expand Down Expand Up @@ -267,7 +271,7 @@ def calculate_anchor_mass_cost(self):
def line_cost(self):
"""Returns cost of one line mooring line."""

if self.mooring_type == "SemiTaut":
if self.mooring_type == "Semitaut":
# Interpolation of line cost at project depth
line_cost = interp1d(
self._semitaut_params["depths"],
Expand Down
8 changes: 8 additions & 0 deletions tests/phases/design/test_array_system_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,11 @@ def test_floating_calculations():

with_cat_length = sim3.total_length
assert with_cat_length < no_cat_length


def test_total_cable_cost():

array = ArraySystemDesign(config_full_ring)
array.run()

assert array.total_cable_cost == pytest.approx(11969999, abs=1e0)
21 changes: 20 additions & 1 deletion tests/phases/design/test_electrical_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,23 @@ def test_new_old_hvac_substation():
assert new.shunt_reactor_cost != old.shunt_reactor_cost


def test_hvac_substation():
config = deepcopy(base)

hvac = ElectricalDesign(config)
hvac.run()

assert hvac.total_substation_cost == pytest.approx(134448256, abs=1e0)


def test_hvdc_substation():
config = deepcopy(base)
config["export_system_design"] = {"cables": "HVDC_2000mm_320kV"}
elect = ElectricalDesign(config)
elect.run()

assert elect.total_substation_cost == pytest.approx(451924714, abs=1e0)

assert elect.converter_cost != 0
assert elect.shunt_reactor_cost == 0
assert elect.dc_breaker_cost != 0
Expand All @@ -285,7 +297,14 @@ def test_hvdc_substation():
elect = ElectricalDesign(config)
elect.run()

# assert elect.num_converters == elect.num_cables # breaks
assert elect.total_substation_cost == pytest.approx(802924714, abs=1e0)

assert elect.converter_cost != 0
assert elect.shunt_reactor_cost == 0
assert elect.dc_breaker_cost != 0
assert elect.switchgear_cost == 0
assert elect.mpt_cost == 0
# assert elect.num_cables / elect.num_converters == 2 # breaks


def test_onshore_substation():
Expand Down
11 changes: 11 additions & 0 deletions tests/phases/design/test_monopile_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,14 @@ def test_transition_piece_kwargs():
results = m._outputs["transition_piece"]

assert results != base_results


def test_total_cost():
"""Simple unit test to track total cost of base configuration."""

mono = MonopileDesign(base)
mono.run()

print(mono.total_cost)

assert mono.total_cost == pytest.approx(68833066, abs=1e0)
6 changes: 6 additions & 0 deletions tests/phases/design/test_mooring_system_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def test_catenary_mooring_system_kwargs():

base_cost = moor.detailed_output["system_cost"]

assert base_cost == pytest.approx(76173891, abs=1e0)

for k, v in test_kwargs.items():
config = deepcopy(base)
config["mooring_system_design"] = {}
Expand Down Expand Up @@ -108,6 +110,8 @@ def test_semitaut_mooring_system_kwargs():

base_cost = moor.detailed_output["system_cost"]

assert base_cost == pytest.approx(102227311, abs=1e0)

for k, v in test_kwargs.items():
config = deepcopy(semi_base)
config["mooring_system_design"] = {}
Expand Down Expand Up @@ -136,6 +140,8 @@ def test_tlp_mooring_system_kwargs():

base_cost = moor.detailed_output["system_cost"]

assert base_cost == pytest.approx(57633231, abs=1e0)

for k, v in test_kwargs.items():
config = deepcopy(tlp_base)
config["mooring_system_design"] = {}
Expand Down
8 changes: 8 additions & 0 deletions tests/phases/design/test_oss_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,11 @@ def test_oss_kwargs():
cost = o.total_cost

assert cost != base_cost


def test_total_cost():

oss = OffshoreSubstationDesign(base)
oss.run()

assert oss.total_cost == pytest.approx(158022050, abs=1e0)
8 changes: 8 additions & 0 deletions tests/phases/design/test_semisubmersible_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,11 @@ def test_design_kwargs():
cost = s.total_cost

assert cost != base_cost


def test_total_cost():

semi = SemiSubmersibleDesign(base)
semi.run()

assert semi.total_cost == pytest.approx(630709636, abs=1e0)
8 changes: 8 additions & 0 deletions tests/phases/design/test_spar_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,11 @@ def test_design_kwargs():
cost = s.total_cost

assert cost != base_cost


def test_total_cost():

spar = SparDesign(base)
spar.run()

assert spar.total_cost == pytest.approx(698569358, abs=1e0)
17 changes: 17 additions & 0 deletions tests/test_project_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@

config = extract_library_specs("config", "project_manager")
complete_project = extract_library_specs("config", "complete_project")
complete_floating_project = extract_library_specs(
"config", "complete_floating_project"
)


# Top Level
Expand Down Expand Up @@ -921,3 +924,17 @@ def test_capex_categories():
new_breakdown["Export System Installation"]
> baseline["Export System Installation"]
)


def test_total_capex():
"""Test total capex for baseline fixed and floating project."""

fix_project = ProjectManager(complete_project)
fix_project.run()

assert fix_project.total_capex == pytest.approx(1207278397.56, abs=1e-1)

flt_project = ProjectManager(complete_floating_project)
flt_project.run()

assert flt_project.total_capex == pytest.approx(3284781912.73, abs=1e-1)
Loading