def test_fixed_phase_cost_passing():

    project = ProjectManager(fixed)
    project.run()

    assert_almost_equal(
        project.phases["MonopileDesign"].total_cost,
        project.phases["MonopileInstallation"].system_capex,
    )

    assert_almost_equal(
        project.phases["ScourProtectionDesign"].total_cost,
        project.phases["ScourProtectionInstallation"].system_capex,
    )

    assert_almost_equal(
        project.phases["ArraySystemDesign"].total_cost,
        project.phases["ArrayCableInstallation"].system_capex,
    )

    assert_almost_equal(
        project.phases["ExportSystemDesign"].total_cost,
        project.phases["ExportCableInstallation"].system_capex,
    )

    assert_almost_equal(
        project.phases["OffshoreSubstationDesign"].total_cost,
        project.phases["OffshoreSubstationInstallation"].system_capex,
    )
Exemplo n.º 2
0
def test_chained_dependencies():

    config_chained = deepcopy(config)
    config_chained["spi_vessel"] = "test_scour_protection_vessel"
    config_chained["scour_protection"] = {
        "tonnes_per_substructure": 200,
        "cost_per_tonne": 45,
    }
    config_chained["install_phases"] = {
        "ScourProtectionInstallation": 0,
        "MonopileInstallation": ("ScourProtectionInstallation", 0.1),
        "TurbineInstallation": ("MonopileInstallation", 0.5),
    }

    project = ProjectManager(config_chained)
    project.run()

    df = pd.DataFrame(project.actions)
    sp = list(df.loc[df["phase"] == "ScourProtectionInstallation"]["time"])
    mp = list(df.loc[df["phase"] == "MonopileInstallation"]["time"])
    tu = list(df.loc[df["phase"] == "TurbineInstallation"]["time"])

    assert min(sp) == 0
    assert min(mp) == (max(sp) - min(sp)) * 0.1
    assert min(tu) == (max(mp) - min(mp)) * 0.5 + min(mp)
Exemplo n.º 3
0
def test_duplicate_phase_definitions():
    config_with_duplicates = deepcopy(config)
    config_with_duplicates["MonopileInstallation_1"] = {
        "plant": {
            "num_turbines": 5
        }
    }

    config_with_duplicates["MonopileInstallation_2"] = {
        "plant": {
            "num_turbines": 5
        },
        "site": {
            "distance": 100
        },
    }

    config_with_duplicates["install_phases"] = {
        "MonopileInstallation_1": 0,
        "MonopileInstallation_2": 800,
        "TurbineInstallation": 1600,
    }

    project = ProjectManager(config_with_duplicates)
    project.run()

    df = (pd.DataFrame(project.actions).groupby(["phase",
                                                 "action"]).count()["time"])

    assert df.loc[("MonopileInstallation_1", "Drive Monopile")] == 5
    assert df.loc[("MonopileInstallation_2", "Drive Monopile")] == 5
    assert df.loc[("TurbineInstallation", "Attach Tower Section")] == 10
Exemplo n.º 4
0
def test_incomplete_config():

    incomplete_config = deepcopy(config)
    _ = incomplete_config["site"].pop("depth")

    with pytest.raises(MissingInputs):
        project = ProjectManager(incomplete_config)
        project.run()
Exemplo n.º 5
0
def test_wrong_phases():

    wrong_phases = deepcopy(config)
    wrong_phases["install_phases"].append("IncorrectPhaseName")

    with pytest.raises(PhaseNotFound):
        project = ProjectManager(wrong_phases)
        project.run()
Exemplo n.º 6
0
def test_complete_run(weather):

    project = ProjectManager(config, weather=weather)
    project.run()

    actions = pd.DataFrame(project.actions)

    phases = ["MonopileInstallation", "TurbineInstallation"]
    assert all(p in list(actions["phase"]) for p in phases)
Exemplo n.º 7
0
def test_for_equal_results():

    config = benedict(deepcopy(complete_project))
    config["site.distance"] = 20
    project = ProjectManager(config)
    project.run()

    parametric = ParametricManager(config, params, funcs)
    parametric.run()
    df = parametric.results.set_index("site.distance")
    assert df.loc[20]["bos_capex"] == project.bos_capex
Exemplo n.º 8
0
def test_bad_dates():

    bad_dates = deepcopy(config)
    bad_dates["install_phases"] = {
        "MonopileInstallation": "03/01/2015",
        "TurbineInstallation": "05/01/2015",
    }

    with pytest.raises(WeatherProfileError):
        project = ProjectManager(bad_dates, weather=weather_df)
        project.run()
Exemplo n.º 9
0
def test_no_defined_start():

    missing_start = deepcopy(config)
    missing_start["install_phases"] = {
        "MonopileInstallation": ("TurbineInstallation", 0.1),
        "TurbineInstallation": ("MonopileInstallation", 0.1),
    }

    with pytest.raises(ValueError):
        project = ProjectManager(missing_start)
        project.run()
Exemplo n.º 10
0
def test_ProjectProgress_with_incomplete_project():

    project = ProjectManager(config)
    project.run()

    _ = project.progress.parse_logs("Substructure")
    _ = project.progress.parse_logs("Turbine")

    with pytest.raises(ValueError):
        project.progress.complete_export_system

    with pytest.raises(ValueError):
        project.progress.complete_array_strings
Exemplo n.º 11
0
def test_circular_dependencies():

    circular_deps = deepcopy(config)
    circular_deps["spi_vessel"] = "test_scour_protection_vessel"
    circular_deps["scour_protection"] = {"tons_per_substructure": 200}
    circular_deps["install_phases"] = {
        "ScourProtectionInstallation": 0,
        "MonopileInstallation": ("TurbineInstallation", 0.1),
        "TurbineInstallation": ("MonopileInstallation", 0.1),
    }

    with pytest.raises(PhaseDependenciesInvalid):
        project = ProjectManager(circular_deps)
        project.run_project()
Exemplo n.º 12
0
    def compute(self, inputs, outputs, discrete_inputs, discrete_outputs):

        config = self.compile_orbit_config_file(inputs, outputs,
                                                discrete_inputs,
                                                discrete_outputs)

        project = ProjectManager(config)
        project.run()

        outputs["bos_capex"] = project.bos_capex
        outputs["total_capex"] = project.total_capex
        outputs["total_capex_kW"] = project.total_capex_per_kw
        outputs["installation_time"] = project.installation_time
        outputs["installation_capex"] = project.installation_capex
Exemplo n.º 13
0
def test_dependent_phase_ordering():

    wrong_order = deepcopy(config)
    wrong_order["spi_vessel"] = "test_scour_protection_vessel"
    wrong_order["scour_protection"] = {"tons_per_substructure": 200}
    wrong_order["install_phases"] = {
        "ScourProtectionInstallation": ("TurbineInstallation", 0.1),
        "TurbineInstallation": ("MonopileInstallation", 0.1),
        "MonopileInstallation": 0,
    }

    project = ProjectManager(wrong_order)
    project.run_project()

    assert len(project.phase_times) == 3
Exemplo n.º 14
0
def test_phase_specific_file_extraction():

    project = ProjectManager(config)
    turbine_config = project.create_config_for_phase("TurbineInstallation")
    monopile_config = project.create_config_for_phase("MonopileInstallation")

    assert isinstance(turbine_config["wtiv"], dict)
    assert isinstance(monopile_config["wtiv"], dict)

    bad_config = deepcopy(config)
    _ = bad_config.pop("TurbineInstallation")
    bad_config["wtiv"] = "example_wtiv"
    bad_config["MonopileInstallation"]["wtiv"] = "missing_vessel"

    with pytest.raises(LibraryItemNotFoundError):
        bad_project = ProjectManager(bad_config)
Exemplo n.º 15
0
def test_kwargs_in_ProjectManager():

    base = deepcopy(config_single)
    base["install_phases"] = ["OffshoreSubstationInstallation"]

    project = ProjectManager(base)
    project.run()
    baseline = project.phase_times["OffshoreSubstationInstallation"]

    keywords = [
        "mono_embed_len",
        "mono_drive_rate",
        "mono_fasten_time",
        "mono_release_time",
        "tp_bolt_time",
        "site_position_time",
        "crane_reequip_time",
        "rov_survey_time",
        "topside_fasten_time",
        "topside_release_time",
    ]

    failed = []

    for kw in keywords:

        default = pt[kw]

        if kw == "mono_drive_rate":
            _new = default - 2

            if _new <= 0:
                raise Exception(f"'{kw}' is less than 0.")

            processes = {kw: _new}

        else:
            processes = {kw: default + 2}

        new_config = deepcopy(base)
        new_config["processes"] = processes

        new_project = ProjectManager(new_config)
        new_project.run()
        new_time = new_project.phase_times["OffshoreSubstationInstallation"]

        if new_time > baseline:
            pass

        else:
            failed.append(kw)

    if failed:
        raise Exception(f"'{failed}' not affecting results.")

    else:
        assert True
Exemplo n.º 16
0
def test_start_dates_with_weather(m_start, t_start, expected):

    config_with_defined_starts = deepcopy(config)
    config_with_defined_starts["install_phases"] = {
        "MonopileInstallation": m_start,
        "TurbineInstallation": t_start,
    }

    project = ProjectManager(config_with_defined_starts, weather=weather_df)
    project.run()
    df = pd.DataFrame(project.actions)

    _m = df.loc[df["phase"] == "MonopileInstallation"].iloc[0]
    _t = df.loc[df["phase"] == "TurbineInstallation"].iloc[0]

    _diff = (_t["time"] - _t["duration"]) - (_m["time"] - _m["duration"])
    assert _diff == expected
Exemplo n.º 17
0
def test_install_phase_start_parsing():

    config_mixed_starts = deepcopy(config)
    config_mixed_starts["install_phases"] = {
        "MonopileInstallation": 0,
        "TurbineInstallation": "10/22/2009",
        "ArrayCableInstallation": ("MonopileInstallation", 0.5),
    }

    project = ProjectManager(config_mixed_starts, weather=weather_df)
    defined, depends = project._parse_install_phase_values(
        config_mixed_starts["install_phases"])
    assert len(defined) == 2
    assert len(depends) == 1

    assert defined["MonopileInstallation"] == 0
    assert defined["TurbineInstallation"] == 1
Exemplo n.º 18
0
def test_soft_costs():

    project = ProjectManager(complete_project)
    baseline = project.soft_capex

    config = deepcopy(complete_project)
    config["project_parameters"] = {"construction_insurance": 50}
    project = ProjectManager(config)
    assert project.soft_capex != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"construction_financing": 190}
    project = ProjectManager(config)
    assert project.soft_capex != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"contingency": 320}
    project = ProjectManager(config)
    assert project.soft_capex != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"contingency": 320}
    project = ProjectManager(config)
    assert project.soft_capex != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"commissioning": 50}
    project = ProjectManager(config)
    assert project.soft_capex != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"decommissioning": 50}
    project = ProjectManager(config)
    assert project.soft_capex != baseline
def test_mono_and_tp_definition():

    test_config = deepcopy(config)

    project = ProjectManager(test_config)
    project.run_project()

    for key, value in config["monopile"].items():
        if key == "type":
            continue

        assert project.config["monopile"][key] == value

    for key, value in config["transition_piece"].items():
        if key == "type":
            continue

        assert project.config["transition_piece"][key] == value
Exemplo n.º 20
0
    def _run_config(self, run, **kwargs):
        """Run an individual config."""

        config = deepcopy(self.base)
        config.merge(run)

        if self.module is not None:
            project = self.module(config, weather=self.weather, **kwargs)
            project.run()

        else:
            project = ProjectManager(config, weather=self.weather, **kwargs)
            project.run()

        results = self.map_funcs(project, self.funcs)
        data = {**run, **results}

        return data
Exemplo n.º 21
0
def test_kwargs_for_array_install_in_ProjectManager():

    base = deepcopy(base_config)
    base["install_phases"] = ["ArrayCableInstallation"]

    project = ProjectManager(base)
    project.run()
    baseline = project.phase_times["ArrayCableInstallation"]

    keywords = [
        "cable_load_time",
        "site_position_time",
        "cable_prep_time",
        "cable_lower_time",
        "cable_pull_in_time",
        "cable_termination_time",
    ]

    failed = []

    for kw in keywords:

        default = pt[kw]

        if "speed" in kw:
            _new = default - 0.05

            if _new <= 0:
                raise Exception(f"'{kw}' is less than 0.")

            processes = {kw: _new}

        else:
            processes = {kw: default + 2}

        new_config = deepcopy(base)
        new_config["processes"] = processes

        new_project = ProjectManager(new_config)
        new_project.run()
        new_time = new_project.phase_times["ArrayCableInstallation"]

        if new_time > baseline:
            pass

        else:
            failed.append(kw)

    if failed:
        raise Exception(f"ExpInstall: '{failed}' not affecting results.")

    else:
        assert True
Exemplo n.º 22
0
def test_monthly_expenses():

    project = ProjectManager(complete_project)
    project.run()
    _ = project.monthly_expenses

    # Still report expenses for "incomplete" project
    config = deepcopy(complete_project)
    _ = config["install_phases"].pop("TurbineInstallation")

    project = ProjectManager(config)
    project.run()

    _ = project.monthly_expenses
Exemplo n.º 23
0
def test_index_starts(m_start, t_start):
    """
    Tests functionality related to passing index starts into 'install_phases' sub-dict.
    """
    _target_diff = t_start - m_start

    config_with_index_starts = deepcopy(config)
    config_with_index_starts["install_phases"] = {
        "MonopileInstallation": m_start,
        "TurbineInstallation": t_start,
    }

    project = ProjectManager(config_with_index_starts)
    project.run()

    df = pd.DataFrame(project.actions)

    _m = df.loc[df["phase"] == "MonopileInstallation"].iloc[0]
    _t = df.loc[df["phase"] == "TurbineInstallation"].iloc[0]

    _diff = (_t["time"] - _t["duration"]) - (_m["time"] - _m["duration"])
    assert _diff == _target_diff
Exemplo n.º 24
0
def instantiate_orbit():
    ProjectManager.compile_input_dict(phases)
    path = os.path.join(os.getcwd(), "..\general_library")
    ORBIT_project = ProjectManager(config, weather=None, library_path=path)
    ORBIT_project.run_project()
    print('OSS',
          ORBIT_project._phases["OffshoreSubstationDesign"].design_result)
    return ORBIT_project
Exemplo n.º 25
0
def test_monthly_revenue():

    project = ProjectManager(complete_project)
    project.run()
    _ = project.monthly_revenue

    # Can't generate revenue with "incomplete" project
    config = deepcopy(complete_project)
    _ = config["install_phases"].pop("TurbineInstallation")

    project = ProjectManager(config)
    project.run()

    with pytest.raises(ValueError):
        _ = project.monthly_revenue
Exemplo n.º 26
0
def test_kwargs_in_ProjectManager():

    base = deepcopy(config_wtiv)
    base["install_phases"] = ["TurbineInstallation"]

    project = ProjectManager(base)
    project.run()
    baseline = project.phase_times["TurbineInstallation"]

    keywords = [
        "tower_section_fasten_time",
        "tower_section_release_time",
        "tower_section_attach_time",
        "nacelle_fasten_time",
        "nacelle_release_time",
        "nacelle_attach_time",
        "blade_fasten_time",
        "blade_release_time",
        "blade_attach_time",
        "site_position_time",
        "crane_reequip_time",
    ]

    failed = []

    for kw in keywords:

        default = pt[kw]
        processes = {kw: default + 2}

        new_config = deepcopy(base)
        new_config["processes"] = processes

        new_project = ProjectManager(new_config)
        new_project.run()
        new_time = new_project.phase_times["TurbineInstallation"]

        if new_time > baseline:
            pass

        else:
            failed.append(kw)

    if failed:
        raise Exception(f"'{failed}' not affecting results.")

    else:
        assert True
Exemplo n.º 27
0
def test_capex_categories():

    project = ProjectManager(complete_project)
    project.run()
    baseline = project.capex_breakdown
    _ = project.capex_breakdown_per_kw

    new_config = deepcopy(complete_project)
    new_config["install_phases"]["ExportCableInstallation_1"] = 0
    new_project = ProjectManager(new_config)
    new_project.run()
    new_breakdown = new_project.capex_breakdown

    assert new_breakdown["Export System"] > baseline["Export System"]
    assert (new_breakdown["Export System Installation"] >
            baseline["Export System Installation"])
Exemplo n.º 28
0
def test_cash_flow():

    project = ProjectManager(complete_project)
    project.run()
    _ = project.cash_flow

    # Can't generate revenue with "incomplete" project but cash flow will still
    # be reported
    config = deepcopy(complete_project)
    _ = config["install_phases"].pop("TurbineInstallation")

    project = ProjectManager(config)
    project.run()

    cash_flow = project.cash_flow
    assert all(v <= 0 for v in cash_flow.values())
Exemplo n.º 29
0
def test_project_costs():

    project = ProjectManager(complete_project)
    baseline = project.project_capex

    config = deepcopy(complete_project)
    config["project_parameters"] = {"site_auction_price": 50e6}
    project = ProjectManager(config)
    assert project.project_capex != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"site_assessment_cost": 25e6}
    project = ProjectManager(config)
    assert project.project_capex != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"construction_plan_cost": 25e6}
    project = ProjectManager(config)
    assert project.project_capex != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"installation_plan_cost": 25e6}
    project = ProjectManager(config)
    assert project.project_capex != baseline
def test_floating_phase_cost_passing():

    project = ProjectManager(floating)
    project.run()

    assert_almost_equal(
        project.phases["MooringSystemDesign"].total_cost,
        project.phases["MooringSystemInstallation"].system_capex,
    )

    assert_almost_equal(
        project.phases["SemiSubmersibleDesign"].total_cost,
        project.phases["MooredSubInstallation"].system_capex,
    )

    assert_almost_equal(
        project.phases["ArraySystemDesign"].total_cost,
        project.phases["ArrayCableInstallation"].system_capex,
    )

    assert_almost_equal(
        project.phases["ExportSystemDesign"].total_cost,
        project.phases["ExportCableInstallation"].system_capex,
    )

    assert_almost_equal(
        project.phases["OffshoreSubstationDesign"].total_cost,
        project.phases["OffshoreSubstationInstallation"].system_capex,
    )

    spar = deepcopy(floating)
    spar["design_phases"].remove("SemiSubmersibleDesign")
    spar["design_phases"].append("SparDesign")

    project = ProjectManager(spar)
    project.run()

    assert_almost_equal(
        project.phases["SparDesign"].total_cost,
        project.phases["MooredSubInstallation"].system_capex,
    )