示例#1
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)
示例#2
0
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,
    )
示例#3
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()
示例#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()
示例#5
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)
示例#6
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
示例#7
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()
示例#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()
示例#9
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
示例#10
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
示例#11
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
示例#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
示例#13
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
示例#14
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"]
示例#15
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
示例#16
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
示例#17
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())
示例#18
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
示例#19
0
def test_circular_dependencies():

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

    with pytest.raises(PhaseDependenciesInvalid):
        project = ProjectManager(circular_deps)
        project.run()
示例#20
0
def test_phase_specific_definitions():
    """
    Tests that phase specific information makes it to phase_config.
    """

    project = ProjectManager(config)

    phase_config = project.create_config_for_phase("MonopileInstallation")

    assert phase_config["wtiv"]["name"] == "Phase Specific WTIV"
    assert phase_config["site"]["distance"] == 500

    phase_config = project.create_config_for_phase("TurbineInstallation")

    assert phase_config["wtiv"]["name"] == "Example WTIV"
    assert phase_config["site"]["distance"] == 50

    project.run()
示例#21
0
def test_dependent_phase_ordering():

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

    project = ProjectManager(wrong_order)
    project.run()

    assert len(project.phase_times) == 3
示例#22
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
示例#23
0
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,
    )
示例#24
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
示例#25
0
def test_design_phases():

    config_with_design = deepcopy(config)

    # Add MonopileDesign
    config_with_design["design_phases"] = ["MonopileDesign"]

    # Add required parameters
    config_with_design["site"]["mean_windspeed"] = 9
    config_with_design["turbine"]["rotor_diameter"] = 200
    config_with_design["turbine"]["rated_windspeed"] = 10
    config_with_design["monopile_design"] = {}

    # Remove monopile sub dictionary
    _ = config_with_design.pop("monopile")
    project = ProjectManager(config_with_design)
    project.run()

    assert isinstance(project.config["monopile"], dict)

    project = ProjectManager(config_with_design)
    project.run()
示例#26
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
示例#27
0
def test_kwargs_in_ProjectManager():

    base = deepcopy(config)
    base["install_phases"] = ["ScourProtectionInstallation"]

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

    keywords = ["drop_rocks_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["ScourProtectionInstallation"]

        if new_time > baseline:
            pass

        else:
            failed.append(kw)

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

    else:
        assert True
示例#28
0
def test_kwargs_in_ProjectManager(anchor, key):

    base = deepcopy(config)
    base["mooring_system"]["anchor_type"] = anchor
    base["install_phases"] = ["MooringSystemInstallation"]

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

    keywords = ["mooring_system_load_time", "mooring_site_survey_time", key]

    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["MooringSystemInstallation"]

        if new_time > baseline:
            pass

        else:
            failed.append(kw)

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

    else:
        assert True
示例#29
0
def test_ProjectProgress_with_complete_project():

    project = ProjectManager(complete_project)
    project.run()

    _ = project.progress.parse_logs("Substructure")
    _ = project.progress.parse_logs("Turbine")
    _ = project.progress.parse_logs("Array String")
    _ = project.progress.parse_logs("Export System")
    _ = project.progress.parse_logs("Offshore Substation")

    _ = project.progress.complete_export_system
    _ = project.progress.complete_array_strings

    _ = project.progress.energize_points

    new = deepcopy(complete_project)
    new["plant"]["num_turbines"] = 61

    # Uneven strings
    project = ProjectManager(new)
    project.run()

    _ = project.progress.energize_points
示例#30
0
def test_npv():

    project = ProjectManager(complete_project)
    project.run()
    baseline = project.npv

    config = deepcopy(complete_project)
    config["project_parameters"] = {"ncf": 0.35}
    project = ProjectManager(config)
    project.run()
    assert project.npv != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"offtake_price": 70}
    project = ProjectManager(config)
    project.run()
    assert project.npv != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"project_lifetime": 30}
    project = ProjectManager(config)
    project.run()
    assert project.npv != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"discount_rate": 0.03}
    project = ProjectManager(config)
    project.run()
    assert project.npv != baseline

    config = deepcopy(complete_project)
    config["project_parameters"] = {"opex_rate": 120}
    project = ProjectManager(config)
    project.run()
    assert project.npv != baseline