From 1c6900081d178465420870926d43f05ce9b73db8 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 10:48:38 -0700 Subject: [PATCH 01/12] fully deprecate contingency attribute --- ORBIT/manager.py | 21 ++++++++------------- tests/test_project_manager.py | 2 +- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/ORBIT/manager.py b/ORBIT/manager.py index a88b4466..2dbbe041 100644 --- a/ORBIT/manager.py +++ b/ORBIT/manager.py @@ -17,7 +17,6 @@ from math import ceil from numbers import Number from pathlib import Path -from warnings import warn from itertools import product warnings.filterwarnings("default") @@ -196,19 +195,15 @@ def run(self, **kwargs): def _print_warnings(self): if "contingency" in self.project_params: - warn( - "The 'contingency' project parameter will be deprecated" - " and replaced with two separate parameters:" - " 'installation_contingency' and 'procurement_contingency'." - " Specify the 'installation_contingency' and " - " 'procurement_contingency' in $/kW, or alternatively, use" - " 'procurement_contingency_factor' in '%' of the turbine " - " + system + project capex, and" - " 'installation_contingency_factor' in '%' of the" - " installation capex", - DeprecationWarning, - stacklevel=2, + msg = ( + "The 'contingency' project parameter was replaced with" + " separate 'installation_contingency' and" + " 'procurement_contingency' in ($/kW). Alternatively, use" + " the 'procurement_contingency_factor' (% of turbine, system," + " and project CapEx) or 'installation_contingency_factor'" + " (% of installation capex)." ) + raise AttributeError(msg) try: df = pd.DataFrame(self.logs) diff --git a/tests/test_project_manager.py b/tests/test_project_manager.py index 0a57220c..9fcdcf46 100644 --- a/tests/test_project_manager.py +++ b/tests/test_project_manager.py @@ -1023,7 +1023,7 @@ def test_construction_financing_factor_exception(): def test_deprecated_warnings(): config = deepcopy(complete_project) - config["project_parameters"] = {"contingency": 88} + config["project_parameters"] = {"procurement_contingency": 88} with pytest.deprecated_call(): project = ProjectManager(config) project.run() From e48352617bd06fe5690a1cd785cc8289f3684c56 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 10:49:26 -0700 Subject: [PATCH 02/12] fully deprecate top-level landfall dictionary for design --- ORBIT/phases/design/electrical_export.py | 16 ++++++---------- ORBIT/phases/design/export_system_design.py | 16 ++++++---------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/ORBIT/phases/design/electrical_export.py b/ORBIT/phases/design/electrical_export.py index bc3d03f7..e03fa2bd 100644 --- a/ORBIT/phases/design/electrical_export.py +++ b/ORBIT/phases/design/electrical_export.py @@ -5,7 +5,6 @@ __maintainer__ = "" __email__ = [] -from warnings import warn import numpy as np @@ -120,17 +119,14 @@ def __init__(self, config, **kwargs): self._design = self.config["export_system_design"] - _landfall = self.config.get("landfall", {}) - if _landfall: - warn( - "landfall dictionary will be deprecated and moved" - " into [export_system_design][landfall].", - DeprecationWarning, - stacklevel=2, + if self.config.get("landfall", None) is not None: + msg = ( + "The top-level 'landfall' dictionary is deprecated and" + " should be nested in the 'export_system_design' dictionary." ) + raise KeyError(msg) - else: - _landfall = self._design.get("landfall", {}) + _landfall = self._design.get("landfall", {}) self._distance_to_interconnection = _landfall.get( "interconnection_distance", 3 diff --git a/ORBIT/phases/design/export_system_design.py b/ORBIT/phases/design/export_system_design.py index ce9d487a..a16b328b 100644 --- a/ORBIT/phases/design/export_system_design.py +++ b/ORBIT/phases/design/export_system_design.py @@ -5,7 +5,6 @@ __maintainer__ = "Rob Hammond" __email__ = "rob.hammond@nlr.gov" -from warnings import warn import numpy as np @@ -86,17 +85,14 @@ def __init__(self, config, **kwargs): self._distance_to_landfall = config["site"]["distance_to_landfall"] self._get_touchdown_distance() - _landfall = self.config.get("landfall", {}) - if _landfall: - warn( - "landfall dictionary will be deprecated and moved" - " into [export_system_design][landfall].", - DeprecationWarning, - stacklevel=2, + if self.config.get("landfall", None) is not None: + msg = ( + "The top-level 'landfall' dictionary is deprecated and" + " should be nested in the 'export_system_design' dictionary." ) + raise KeyError(msg) - else: - _landfall = self.config["export_system_design"].get("landfall", {}) + _landfall = self._design.get("landfall", {}) self._distance_to_interconnection = _landfall.get( "interconnection_distance", 3 From 290424b7d06609361121bbe6aa02cecdf232f0a5 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 10:56:00 -0700 Subject: [PATCH 03/12] fully deprecate export install landfall and interconnection distance --- ORBIT/phases/install/cable_install/export.py | 33 ++++++++----------- .../cable_install/test_export_install.py | 20 +---------- 2 files changed, 15 insertions(+), 38 deletions(-) diff --git a/ORBIT/phases/install/cable_install/export.py b/ORBIT/phases/install/cable_install/export.py index 86a3076b..c5e2b56a 100644 --- a/ORBIT/phases/install/cable_install/export.py +++ b/ORBIT/phases/install/cable_install/export.py @@ -8,7 +8,6 @@ from copy import deepcopy from math import ceil -from warnings import warn from marmot import process @@ -138,16 +137,13 @@ def extract_distances(self): site = self.config["site"]["distance"] - _landfall = self.config.get("landfall", {}) - if _landfall: - warn( - "landfall dictionary will be deprecated and moved" - " into [export_system][landfall].", - DeprecationWarning, - stacklevel=2, + if self.config.get("landfall", None) is not None: + msg = ( + "The top-level 'landfall' dictionary is deprecated and" + " should be nested in the 'export_system' dictionary." ) - else: - _landfall = self.config["export_system"].get("landfall", {}) + raise KeyError(msg) + _landfall = self.config["export_system"].get("landfall", {}) trench = _landfall.get("trench_length", 1) @@ -203,16 +199,15 @@ def calculate_onshore_transmission_cost(self, **kwargs): # capacity = self.config["plant"]["capacity"] system = self.config["export_system"] voltage = system.get("interconnection_voltage", 345) - distance = system.get("interconnection_distance", None) - - if distance: - warn( - "[export_system][interconnection_distance] will be deprecated" - " and moved to" - " [export_system][landfall][interconnection_distance].", - DeprecationWarning, - stacklevel=2, + + if system.get("interconnection_distance", None) is not None: + msg = ( + "The `export_system`-level 'interconnection_distance' is" + "deprecated and should be placed in the 'export_system'" + "'landfall' dictionary" + "(e.g., export_system.landfall.interconnection_distance)." ) + raise KeyError(msg) landfall = system.get("landfall", {}) distance = landfall.get("interconnection_distance", 3) diff --git a/tests/phases/install/cable_install/test_export_install.py b/tests/phases/install/cable_install/test_export_install.py index 9c2bbd02..42b734ba 100644 --- a/tests/phases/install/cable_install/test_export_install.py +++ b/tests/phases/install/cable_install/test_export_install.py @@ -265,25 +265,7 @@ def test_deprecated_values(): deprecated["export_system"] = new_export_system - with pytest.deprecated_call(): - - # sim = ExportCableInstallation(base) - # sim.run() + with pytest.raises(KeyError): sim = ExportCableInstallation(deprecated) sim.run() - - # assert len(w) == 2 - # assert issubclass(w[0].category, DeprecationWarning) - # assert ( - # str(w[0].message) - # == "landfall dictionary will be deprecated and moved \ - # into [export_system][landfall]." - # ) - - # assert issubclass(w[1].category, DeprecationWarning) - # assert ( - # str(w[1].message) - # == "[export_system][interconnection] will be deprecated and \ - # moved into [export_system][landfall][interconnection]." - # ) From 653b959cd7f2157eff0b3f96a1ac736cae27bac5 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 12:35:13 -0700 Subject: [PATCH 04/12] deprecate and --- .../quayside_assembly_tow/gravity_base.py | 26 +++++++------------ .../install/quayside_assembly_tow/moored.py | 24 +++++++---------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/ORBIT/phases/install/quayside_assembly_tow/gravity_base.py b/ORBIT/phases/install/quayside_assembly_tow/gravity_base.py index f7d3384b..2e73c38e 100644 --- a/ORBIT/phases/install/quayside_assembly_tow/gravity_base.py +++ b/ORBIT/phases/install/quayside_assembly_tow/gravity_base.py @@ -5,7 +5,6 @@ __maintainer__ = "Jake Nunemaker" __email__ = "jake.nunemaker@nlr.gov" -from warnings import warn import simpy from marmot import le, process @@ -235,16 +234,12 @@ def initialize_support_vessel(self, **kwargs): Initializes Multi-Purpose Support Vessel to perform installation processes at site. """ - - specs = self.config.get("support_vessel", None) - - if specs is not None: - warn( - "support_vessel will be deprecated and replaced with" - " towing_vessels and ahts_vessel in the towing groups.\n", - DeprecationWarning, - stacklevel=2, + if self.config.get("support_vessel") is not None: + msg = ( + "`support_vessel` has been replaced with the separate" + " `towing_vessels`, `towing_groups`, and `ahts_vessel`." ) + raise KeyError(msg) specs = self.config["ahts_vessel"] vessel = self.initialize_vessel("Multi-Purpose AHTS Vessel", specs) @@ -258,13 +253,12 @@ def initialize_support_vessel(self, **kwargs): ) if station_keeping_vessels is not None: - warn( - "['towing_vessl_groups]['station_keeping_vessels']" - " will be deprecated and replaced with" - " ['towing_vessl_groups]['ahts_vessels'].\n", - DeprecationWarning, - stacklevel=2, + msg = ( + "`towing_vessl_groups.station_keeping_vessels` has been" + " replaced with the separate `towing_vessels`," + " `towing_groups`, and `ahts_vessel`." ) + raise KeyError(msg) station_keeping_vessels = self.config["towing_vessel_groups"].get( "ahts_vessels", 1 diff --git a/ORBIT/phases/install/quayside_assembly_tow/moored.py b/ORBIT/phases/install/quayside_assembly_tow/moored.py index ed1b03f8..7cb68c6b 100644 --- a/ORBIT/phases/install/quayside_assembly_tow/moored.py +++ b/ORBIT/phases/install/quayside_assembly_tow/moored.py @@ -245,15 +245,12 @@ def initialize_support_vessel(self): processes at site. """ - specs = self.config.get("support_vessel", None) - - if specs is not None: - warn( - "support_vessel will be deprecated and replaced with" - " towing_vessels and ahts_vessel in the towing groups.\n", - DeprecationWarning, - stacklevel=2, + if self.config.get("support_vessel") is not None: + msg = ( + "`support_vessel` has been replaced with the separate" + " `towing_vessels`, `towing_groups`, and `ahts_vessel`." ) + raise KeyError(msg) # vessel = self.initialize_vessel("Multi-Purpose Support Vessel", # specs) @@ -267,13 +264,12 @@ def initialize_support_vessel(self): ) if station_keeping_vessels is not None: - warn( - "['towing_vessl_groups]['station_keeping_vessels']" - " will be deprecated and replaced with" - " ['towing_vessl_groups]['ahts_vessels'].\n", - DeprecationWarning, - stacklevel=2, + msg = ( + "`towing_vessl_groups.station_keeping_vessels` has been" + " replaced with the separate `towing_vessels`," + " `towing_groups`, and `ahts_vessel`." ) + raise KeyError(msg) # install_moored_substructures( # self.support_vessel, From f96a31298ca946486ef9509096a6f483c28911e0 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 12:52:41 -0700 Subject: [PATCH 05/12] make contingency error consistent with other deprecations --- ORBIT/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ORBIT/manager.py b/ORBIT/manager.py index 2dbbe041..83d8bc36 100644 --- a/ORBIT/manager.py +++ b/ORBIT/manager.py @@ -203,7 +203,7 @@ def _print_warnings(self): " and project CapEx) or 'installation_contingency_factor'" " (% of installation capex)." ) - raise AttributeError(msg) + raise KeyError(msg) try: df = pd.DataFrame(self.logs) From 5ca8e31dbdd30c3bb4a935d99a216fdf640fcd83 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:16:23 -0700 Subject: [PATCH 06/12] update tests for deprecations --- .../config/complete_floating_project.yaml | 2 -- .../project/config/complete_project.yaml | 6 +++--- .../project/config/moored_install.yaml | 2 -- .../config/moored_install_no_supply.yaml | 2 -- tests/phases/design/test_electrical_design.py | 3 +-- .../design/test_export_system_design.py | 2 +- .../test_gravity_based.py | 4 ++-- .../quayside_assembly_tow/test_moored.py | 4 ++-- tests/test_project_manager.py | 20 ++++++++++--------- 9 files changed, 20 insertions(+), 25 deletions(-) diff --git a/tests/data/library/project/config/complete_floating_project.yaml b/tests/data/library/project/config/complete_floating_project.yaml index dff5b427..47019495 100644 --- a/tests/data/library/project/config/complete_floating_project.yaml +++ b/tests/data/library/project/config/complete_floating_project.yaml @@ -41,11 +41,9 @@ site: distance_to_landfall: 100 substructure: takt_time: 168 -support_vessel: test_support_vessel ahts_vessel: test_ahts_vessel towing_vessel: test_towing_vessel towing_vessel_groups: - station_keeping_vessels: 2 towing_vessels: 3 turbine: 12MW_generic wtiv: test_floating_heavy_lift_vessel diff --git a/tests/data/library/project/config/complete_project.yaml b/tests/data/library/project/config/complete_project.yaml index 5a29b68a..df77d0b4 100644 --- a/tests/data/library/project/config/complete_project.yaml +++ b/tests/data/library/project/config/complete_project.yaml @@ -19,6 +19,9 @@ export_cable_install_vessel: example_cable_lay_vessel export_system_design: cables: XLPE_500mm_132kV percent_added_length: 0.0 + landfall: + interconnection_distance: 3 + trench_length: 2 install_phases: ArrayCableInstallation: 0 ExportCableInstallation: 2000 @@ -30,9 +33,6 @@ install_phases: TurbineInstallation: !!python/tuple - MonopileInstallation - 0.1 -landfall: - interconnection_distance: 3 - trench_length: 2 oss_install_vessel: example_heavy_lift_vessel plant: layout: grid diff --git a/tests/data/library/project/config/moored_install.yaml b/tests/data/library/project/config/moored_install.yaml index 242bb802..631f0e44 100644 --- a/tests/data/library/project/config/moored_install.yaml +++ b/tests/data/library/project/config/moored_install.yaml @@ -13,11 +13,9 @@ substructure: towing_speed: 6 unit_cost: 12e6 ahts_vessel: test_ahts_vessel -support_vessel: test_support_vessel towing_vessel: test_towing_vessel towing_vessel_groups: num_groups: 1 ahts_vessels: 1 - station_keeping_vessels: 3 towing_vessels: 1 turbine: 12MW_generic diff --git a/tests/data/library/project/config/moored_install_no_supply.yaml b/tests/data/library/project/config/moored_install_no_supply.yaml index a91dd2ba..57d48179 100644 --- a/tests/data/library/project/config/moored_install_no_supply.yaml +++ b/tests/data/library/project/config/moored_install_no_supply.yaml @@ -11,11 +11,9 @@ substructure: towing_speed: 6 unit_cost: 12e6 ahts_vessel: test_ahts_vessel -support_vessel: test_support_vessel towing_vessel: test_towing_vessel towing_vessel_groups: num_groups: 1 - station_keeping_vessels: 3 ahts_vessels: 1 towing_vessels: 1 turbine: 12MW_generic diff --git a/tests/phases/design/test_electrical_design.py b/tests/phases/design/test_electrical_design.py index 454d13cc..b9d3b864 100644 --- a/tests/phases/design/test_electrical_design.py +++ b/tests/phases/design/test_electrical_design.py @@ -19,7 +19,6 @@ "site": {"distance_to_landfall": 50, "depth": 30}, "plant": {"capacity": 500}, "export_system_design": {"cables": "XLPE_630mm_220kV"}, - "landfall": {}, "substation_design": { "oss_pile_cost_rate": 1200, # need to set this for kwarg tests }, @@ -537,6 +536,6 @@ def test_deprecated_landfall(): deprecated = deepcopy(base) deprecated["landfall"] = {"interconnection_distance": 4} - with pytest.deprecated_call(): + with pytest.raises(KeyError): sim = ElectricalDesign(deprecated) sim.run() diff --git a/tests/phases/design/test_export_system_design.py b/tests/phases/design/test_export_system_design.py index b8ef86b7..8433ea3a 100644 --- a/tests/phases/design/test_export_system_design.py +++ b/tests/phases/design/test_export_system_design.py @@ -141,6 +141,6 @@ def test_deprecated_landfall(): deprecated = deepcopy(base) deprecated["landfall"] = {"interconnection_distance": 4} - with pytest.deprecated_call(): + with pytest.raises(KeyError): sim = ExportSystemDesign(deprecated) sim.run() diff --git a/tests/phases/install/quayside_assembly_tow/test_gravity_based.py b/tests/phases/install/quayside_assembly_tow/test_gravity_based.py index 2e31444b..80ab16e6 100644 --- a/tests/phases/install/quayside_assembly_tow/test_gravity_based.py +++ b/tests/phases/install/quayside_assembly_tow/test_gravity_based.py @@ -66,13 +66,13 @@ def test_deprecated_vessel(): deprecated = deepcopy(config) deprecated["support_vessel"] = "test_support_vessel" - with pytest.deprecated_call(): + with pytest.raises(KeyError): sim = GravityBasedInstallation(deprecated) sim.run() deprecated2 = deepcopy(config) deprecated2["towing_vessel_groups"]["station_keeping_vessels"] = 2 - with pytest.deprecated_call(): + with pytest.raises(KeyError): sim = GravityBasedInstallation(deprecated2) sim.run() diff --git a/tests/phases/install/quayside_assembly_tow/test_moored.py b/tests/phases/install/quayside_assembly_tow/test_moored.py index 59e67292..497488a5 100644 --- a/tests/phases/install/quayside_assembly_tow/test_moored.py +++ b/tests/phases/install/quayside_assembly_tow/test_moored.py @@ -98,13 +98,13 @@ def test_deprecated_vessel(): deprecated = deepcopy(config) deprecated["support_vessel"] = "test_support_vessel" - with pytest.deprecated_call(): + with pytest.raises(KeyError): sim = MooredSubInstallation(deprecated) sim.run() deprecated2 = deepcopy(config) deprecated2["towing_vessel_groups"]["station_keeping_vessels"] = 2 - with pytest.deprecated_call(): + with pytest.raises(KeyError): sim = MooredSubInstallation(deprecated2) sim.run() diff --git a/tests/test_project_manager.py b/tests/test_project_manager.py index 9fcdcf46..87403f2e 100644 --- a/tests/test_project_manager.py +++ b/tests/test_project_manager.py @@ -988,22 +988,24 @@ def test_capex_categories(): ) -def test_total_capex(): +def test_total_capex(subtests): """Test total capex for baseline fixed and floating project.""" fix_project = ProjectManager(complete_project) fix_project.run() - assert fix_project.total_capex == pytest.approx( - 1843929494.9506452, abs=1e-1 - ) + with subtests.test("Fixed-bottom project CapEx"): + assert fix_project.total_capex == pytest.approx( + 1843901331.93502, abs=1e-1 + ) flt_project = ProjectManager(complete_floating_project) flt_project.run() - assert flt_project.total_capex == pytest.approx( - 4448212431.513601, abs=1e-1 - ) + with subtests.test("Floating project CapEx"): + assert flt_project.total_capex == pytest.approx( + 4448212431.513601, abs=1e-1 + ) def test_construction_financing_factor_exception(): @@ -1023,7 +1025,7 @@ def test_construction_financing_factor_exception(): def test_deprecated_warnings(): config = deepcopy(complete_project) - config["project_parameters"] = {"procurement_contingency": 88} - with pytest.deprecated_call(): + config["project_parameters"] = {"contingency": 88} + with pytest.raises(KeyError): project = ProjectManager(config) project.run() From 23903bc05bd85836f5476db7facd11012a49370f Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:14:47 -0700 Subject: [PATCH 07/12] update example configurations for deprecation compliance --- examples/configs/example_floating_project.yaml | 3 +-- .../configs/example_gravity_based_project.yaml | 17 ++++++++--------- ...xample_separate_monopile_turbine_vessel.yaml | 16 ++++++++-------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/examples/configs/example_floating_project.yaml b/examples/configs/example_floating_project.yaml index 423a4c49..3f7050af 100644 --- a/examples/configs/example_floating_project.yaml +++ b/examples/configs/example_floating_project.yaml @@ -18,11 +18,10 @@ array_cable_install_vessel: example_cable_lay_vessel export_cable_install_vessel: example_cable_lay_vessel mooring_install_vessel: example_support_vessel oss_install_vessel: floating_heavy_lift_vessel -support_vessel: example_support_vessel ahts_vessel: example_ahts_vessel towing_vessel: example_towing_vessel towing_vessel_groups: - station_keeping_vessels: 2 + ahts_vessel: 1 towing_vessels: 3 wtiv: floating_heavy_lift_vessel # Module Specific diff --git a/examples/configs/example_gravity_based_project.yaml b/examples/configs/example_gravity_based_project.yaml index b75c8625..2e65a507 100644 --- a/examples/configs/example_gravity_based_project.yaml +++ b/examples/configs/example_gravity_based_project.yaml @@ -12,17 +12,16 @@ plant: turbine_spacing: 7 turbine: 15MW_generic # Vessels -support_vessel: example_support_vessel +ahts_vessel: example_ahts_vessel towing_vessel: example_towing_vessel towing_vessel_groups: - towing_vessels: 3 - ahts_vessels: 2 + towing_vessels: 3 + ahts_vessels: 2 array_cable_install_vessel: example_cable_lay_vessel export_cable_install_vessel: example_cable_lay_vessel export_cable_bury_vessel: example_cable_lay_vessel oss_install_vessel: example_heavy_lift_vessel spi_vessel: example_scour_protection_vessel -ahts_vessel: example_ahts_vessel # wtiv: example_wtiv # GBF installation without WTIV # Substructure substructure: @@ -30,11 +29,11 @@ substructure: takt_time: 0 # towing_speed: 6.5, considered on towing vessel file. port: - monthly_rate: 520700 # This is the turbine assembly crane monthly rate. The port rental costs are put in as line items in the LCOE calc (where CapEx breakdown is updated) to include the summed port & quayside cost assumed at 8 months. This 8 months includeds 6 months takt time and 2 months storage (why takt is set to 0). - sub_assembly_lines: 2 # how many you can produce in parallel - turbine_assembly_cranes: 2 - sub_storage: 1 - assembly_storage: 1 + monthly_rate: 520700 # This is the turbine assembly crane monthly rate. The port rental costs are put in as line items in the LCOE calc (where CapEx breakdown is updated) to include the summed port & quayside cost assumed at 8 months. This 8 months includeds 6 months takt time and 2 months storage (why takt is set to 0). + sub_assembly_lines: 2 # how many you can produce in parallel + turbine_assembly_cranes: 2 + sub_storage: 1 + assembly_storage: 1 # Module Specific OffshoreSubstationInstallation: feeder: example_heavy_feeder diff --git a/examples/configs/example_separate_monopile_turbine_vessel.yaml b/examples/configs/example_separate_monopile_turbine_vessel.yaml index 0abd1fab..68281495 100644 --- a/examples/configs/example_separate_monopile_turbine_vessel.yaml +++ b/examples/configs/example_separate_monopile_turbine_vessel.yaml @@ -13,11 +13,11 @@ plant: turbine: 15MW_generic # Vessels wtiv: example_wtiv -support_vessel: example_support_vessel +ahts_vessel: example_ahts_vessel towing_vessel: example_towing_vessel towing_vessel_groups: - towing_vessels: 3 - ahts_vessels: 2 + towing_vessels: 3 + ahts_vessels: 2 array_cable_install_vessel: example_cable_lay_vessel export_cable_install_vessel: example_cable_lay_vessel export_cable_bury_vessel: example_cable_lay_vessel @@ -29,11 +29,11 @@ substructure: takt_time: 0 # towing_speed: 6.5, considered on towing vessel file. port: - monthly_rate: 520700 # This is the turbine assembly crane monthly rate. The port rental costs are put in as line items in the LCOE calc (where CapEx breakdown is updated) to include the summed port & quayside cost assumed at 8 months. This 8 months includeds 6 months takt time and 2 months storage (why takt is set to 0). - sub_assembly_lines: 2 # how many you can produce in parallel - turbine_assembly_cranes: 2 - sub_storage: 1 - assembly_storage: 1 + monthly_rate: 520700 # This is the turbine assembly crane monthly rate. The port rental costs are put in as line items in the LCOE calc (where CapEx breakdown is updated) to include the summed port & quayside cost assumed at 8 months. This 8 months includeds 6 months takt time and 2 months storage (why takt is set to 0). + sub_assembly_lines: 2 # how many you can produce in parallel + turbine_assembly_cranes: 2 + sub_storage: 1 + assembly_storage: 1 # Module Specific scour_protection_design: cost_per_tonne: 40 From 76b7eec209d89c1ccc108004486e37f356ef6ca3 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:14:58 -0700 Subject: [PATCH 08/12] update changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b709aab..1bcae3fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,15 @@ tools. - Modernize and streamline the installation instructions. +### Deprecations + +- Project parameter `contingency` is fully deprecated in favor of `installation_contingency` and + `procurement_contingency` and will raise a `KeyError` when detected by the `ProjectManager`. +- Top-level `landfall` dictionary is no longer suppored and is fully deprecated in favor of nesting + it in the `export_system_design` and `export_system` dictionary, for design and installation phases. +- The `export_system`-level `interconnection_distance` variable is deprecated and should now be + placed in the `export_system.landfall` dictionary. + ## 1.2.6 - Implements `create_layout_df` for the `CustomArraySystemDesign` model to ensure From 6c00a0edf971dff1978e2b7066292b6a3f92193b Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:53:55 -0700 Subject: [PATCH 09/12] update odd pandas formatting --- docs/tutorials/available_outputs.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/available_outputs.md b/docs/tutorials/available_outputs.md index 02ae515f..e89df3bf 100644 --- a/docs/tutorials/available_outputs.md +++ b/docs/tutorials/available_outputs.md @@ -34,6 +34,9 @@ import matplotlib.pyplot as plt from ORBIT import ProjectManager, load_config +# Apply thousands separators and no decimals to floats +pd.options.display.float_format = '{:,.0f}'.format + # Ensure the correct examples directory is used when running this in docs or in examples here = Path(".").resolve() example_dir = here.parents[1] / "examples" if here.stem == "tutorials" else here @@ -388,8 +391,6 @@ mp_vessel_summary = ( mp_install[["agent", "action", "duration", "cost"]] .groupby(["agent", "action"]) .sum() - .style - .format("{:,.2f}") ) mp_vessel_summary ``` @@ -425,5 +426,5 @@ pd.concat( pd.DataFrame(project.cash_flow.values(), columns=["cash_flow"]), ], axis=1 -).head(12).style.format("{:,.2f}") +).head(12) ``` From 796d01e74885583ab6963a719e6f76906cafe879 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:57:46 -0700 Subject: [PATCH 10/12] update lingering references to station keeping and support vessels --- ORBIT/phases/install/quayside_assembly_tow/gravity_base.py | 2 -- ORBIT/phases/install/quayside_assembly_tow/moored.py | 2 -- docs/methods/install/MooredSubInstallation.md | 2 -- 3 files changed, 6 deletions(-) diff --git a/ORBIT/phases/install/quayside_assembly_tow/gravity_base.py b/ORBIT/phases/install/quayside_assembly_tow/gravity_base.py index 2e73c38e..0a79325a 100644 --- a/ORBIT/phases/install/quayside_assembly_tow/gravity_base.py +++ b/ORBIT/phases/install/quayside_assembly_tow/gravity_base.py @@ -26,13 +26,11 @@ class GravityBasedInstallation(InstallPhase): #: expected_config = { - "support_vessel": "str, (optional)", "wtiv": "str, (optional)", "ahts_vessel": "str", "towing_vessel": "str", "towing_vessel_groups": { "towing_vessels": "int", - "station_keeping_vessels": "int (optional)", "ahts_vessels": "int (optional, default: 1)", "num_groups": "int (optional)", }, diff --git a/ORBIT/phases/install/quayside_assembly_tow/moored.py b/ORBIT/phases/install/quayside_assembly_tow/moored.py index 7cb68c6b..29acb06e 100644 --- a/ORBIT/phases/install/quayside_assembly_tow/moored.py +++ b/ORBIT/phases/install/quayside_assembly_tow/moored.py @@ -28,12 +28,10 @@ class MooredSubInstallation(InstallPhase): #: expected_config = { - "support_vessel": "str, (optional)", "ahts_vessel": "str", "towing_vessel": "str", "towing_vessel_groups": { "towing_vessels": "int", - "station_keeping_vessels": "int (optional)", "ahts_vessels": "int (optional, default: 1)", "num_groups": "int (optional)", }, diff --git a/docs/methods/install/MooredSubInstallation.md b/docs/methods/install/MooredSubInstallation.md index 598dab7c..06b8d6e9 100644 --- a/docs/methods/install/MooredSubInstallation.md +++ b/docs/methods/install/MooredSubInstallation.md @@ -24,12 +24,10 @@ config = { ... - "support_vessel": "example_support_vessel", # Will perform onsite installation procedures. "ahts_vessel": "example_ahts_vessel", # Anchor handling tug supply vessel associated with each tow group. "towing_vessel": "example_towing_vessel", # Towing groups will contain multiple of this vessel. "towing_groups": { "towing_vessel": 1, # Vessels used to tow the substructure to site. - "station_keeping_vessels": 3, # Vessels used for station keeping during mooring line hookups. "num_groups": 1 # Number of independent groups. Optional, defualt: 1. }, From 6dd0a984562425ddc34bbac0bacb5e9b8d9ed4d7 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:40:45 -0700 Subject: [PATCH 11/12] put old test value back --- tests/data/library/project/config/complete_project.yaml | 4 ++++ tests/test_project_manager.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/data/library/project/config/complete_project.yaml b/tests/data/library/project/config/complete_project.yaml index df77d0b4..d9ff3e6f 100644 --- a/tests/data/library/project/config/complete_project.yaml +++ b/tests/data/library/project/config/complete_project.yaml @@ -22,6 +22,10 @@ export_system_design: landfall: interconnection_distance: 3 trench_length: 2 +export_system: + landfall: + interconnection_distance: 3 + trench_length: 2 install_phases: ArrayCableInstallation: 0 ExportCableInstallation: 2000 diff --git a/tests/test_project_manager.py b/tests/test_project_manager.py index 87403f2e..8f137429 100644 --- a/tests/test_project_manager.py +++ b/tests/test_project_manager.py @@ -996,7 +996,7 @@ def test_total_capex(subtests): with subtests.test("Fixed-bottom project CapEx"): assert fix_project.total_capex == pytest.approx( - 1843901331.93502, abs=1e-1 + 1843929494.9506452, abs=1e-1 ) flt_project = ProjectManager(complete_floating_project) From b8ddd39eebb7698e9a0d651080a3db791b3e4816 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Wed, 15 Apr 2026 15:55:38 -0700 Subject: [PATCH 12/12] update station keeping & ahts vessel info --- docs/methods/install/MooredSubInstallation.md | 1 + examples/configs/example_floating_project.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/methods/install/MooredSubInstallation.md b/docs/methods/install/MooredSubInstallation.md index 06b8d6e9..597128a6 100644 --- a/docs/methods/install/MooredSubInstallation.md +++ b/docs/methods/install/MooredSubInstallation.md @@ -28,6 +28,7 @@ config = { "towing_vessel": "example_towing_vessel", # Towing groups will contain multiple of this vessel. "towing_groups": { "towing_vessel": 1, # Vessels used to tow the substructure to site. + "ahts_vessels": 3, # Number of anchor handling/station keeping vessels "num_groups": 1 # Number of independent groups. Optional, defualt: 1. }, diff --git a/examples/configs/example_floating_project.yaml b/examples/configs/example_floating_project.yaml index 3f7050af..8ab201c7 100644 --- a/examples/configs/example_floating_project.yaml +++ b/examples/configs/example_floating_project.yaml @@ -21,7 +21,7 @@ oss_install_vessel: floating_heavy_lift_vessel ahts_vessel: example_ahts_vessel towing_vessel: example_towing_vessel towing_vessel_groups: - ahts_vessel: 1 + ahts_vessel: 2 towing_vessels: 3 wtiv: floating_heavy_lift_vessel # Module Specific