From 44bbcd1b4d172baf483dca232b24ba26d9a924c4 Mon Sep 17 00:00:00 2001 From: elenya-grant <116225007+elenya-grant@users.noreply.github.com> Date: Wed, 26 Nov 2025 12:38:26 -0700 Subject: [PATCH 1/6] added wind turbine export tools --- h2integrate/core/utilities.py | 7 ++ h2integrate/preprocess/__init__.py | 0 h2integrate/preprocess/test/__init__.py | 0 h2integrate/preprocess/test/conftest.py | 20 ++++ .../test/test_wind_turbine_file_tools.py | 102 ++++++++++++++++++ .../preprocess/wind_turbine_file_tools.py | 100 +++++++++++++++++ pyproject.toml | 1 + 7 files changed, 230 insertions(+) create mode 100644 h2integrate/preprocess/__init__.py create mode 100644 h2integrate/preprocess/test/__init__.py create mode 100644 h2integrate/preprocess/test/conftest.py create mode 100644 h2integrate/preprocess/test/test_wind_turbine_file_tools.py create mode 100644 h2integrate/preprocess/wind_turbine_file_tools.py diff --git a/h2integrate/core/utilities.py b/h2integrate/core/utilities.py index bff78344b..87497d53e 100644 --- a/h2integrate/core/utilities.py +++ b/h2integrate/core/utilities.py @@ -560,6 +560,13 @@ def write_yaml( yaml.dump(instance, f) +def write_yaml_readable(instance: dict, foutput: str | Path): + instance = dict_to_yaml_formatting(instance) + + with Path(foutput).open("w", encoding="utf-8") as f: + yaml.dump(instance, f, sort_keys=False, encoding=None, default_flow_style=False) + + def make_unique_case_name(folder, proposed_fname, fext): """Generate a filename that does not already exist in a user-defined folder. diff --git a/h2integrate/preprocess/__init__.py b/h2integrate/preprocess/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/h2integrate/preprocess/test/__init__.py b/h2integrate/preprocess/test/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/h2integrate/preprocess/test/conftest.py b/h2integrate/preprocess/test/conftest.py new file mode 100644 index 000000000..ec036dfa5 --- /dev/null +++ b/h2integrate/preprocess/test/conftest.py @@ -0,0 +1,20 @@ +""" +Pytest configuration file. +""" + +import os + + +def pytest_sessionstart(session): + initial_om_report_setting = os.getenv("OPENMDAO_REPORTS") + if initial_om_report_setting is not None: + os.environ["TMP_OPENMDAO_REPORTS"] = initial_om_report_setting + + os.environ["OPENMDAO_REPORTS"] = "none" + + +def pytest_sessionfinish(session, exitstatus): + initial_om_report_setting = os.getenv("TMP_OPENMDAO_REPORTS") + if initial_om_report_setting is not None: + os.environ["OPENMDAO_REPORTS"] = initial_om_report_setting + os.environ.pop("TMP_OPENMDAO_REPORTS", None) diff --git a/h2integrate/preprocess/test/test_wind_turbine_file_tools.py b/h2integrate/preprocess/test/test_wind_turbine_file_tools.py new file mode 100644 index 000000000..772010619 --- /dev/null +++ b/h2integrate/preprocess/test/test_wind_turbine_file_tools.py @@ -0,0 +1,102 @@ +import numpy as np +import pytest +import openmdao.api as om + +from h2integrate import EXAMPLE_DIR +from h2integrate.core.utilities import load_yaml +from h2integrate.core.inputs.validation import load_tech_yaml, load_plant_yaml +from h2integrate.converters.wind.wind_pysam import PYSAMWindPlantPerformanceModel +from h2integrate.preprocess.wind_turbine_file_tools import ( + export_turbine_to_pysam_format, + export_turbine_to_floris_format, +) +from h2integrate.resource.wind.nrel_developer_wtk_api import WTKNRELDeveloperAPIWindResource + + +def test_turbine_export_error(subtests): + invalid_turbine_name = "NREL_1.5MW" + with pytest.raises(ValueError) as excinfo: + export_turbine_to_pysam_format(invalid_turbine_name) + assert f"Turbine {invalid_turbine_name} was not found" in str(excinfo.value) + + with pytest.raises(ValueError) as excinfo: + export_turbine_to_floris_format(invalid_turbine_name) + assert f"Turbine {invalid_turbine_name} was not found" in str(excinfo.value) + + +def test_pysam_turbine_export(subtests): + turbine_name = "NREL_6MW_196" + output_fpath = export_turbine_to_pysam_format(turbine_name) + + with subtests.test("File was created"): + assert output_fpath.exists() + assert output_fpath.is_file() + + pysam_options = load_yaml(output_fpath) + + plant_config_path = EXAMPLE_DIR / "05_wind_h2_opt" / "plant_config.yaml" + tech_config_path = EXAMPLE_DIR / "05_wind_h2_opt" / "tech_config.yaml" + + plant_config = load_plant_yaml(plant_config_path) + tech_config = load_tech_yaml(tech_config_path) + + updated_parameters = { + "turbine_rating_kw": np.max( + pysam_options["Turbine"].get("wind_turbine_powercurve_powerout") + ), + "rotor_diameter": pysam_options["Turbine"].pop("wind_turbine_rotor_diameter"), + "hub_height": pysam_options["Turbine"].pop("wind_turbine_hub_ht"), + "pysam_options": pysam_options, + } + + tech_config["technologies"]["wind"]["model_inputs"]["performance_parameters"].update( + updated_parameters + ) + + prob = om.Problem() + wind_resource = WTKNRELDeveloperAPIWindResource( + plant_config=plant_config, + resource_config=plant_config["site"]["resources"]["wind_resource"]["resource_parameters"], + driver_config={}, + ) + + wind_plant = PYSAMWindPlantPerformanceModel( + plant_config=plant_config, + tech_config=tech_config["technologies"]["wind"], + driver_config={}, + ) + + prob.model.add_subsystem("wind_resource", wind_resource, promotes=["*"]) + prob.model.add_subsystem("wind_plant", wind_plant, promotes=["*"]) + prob.setup() + prob.run_model() + + with subtests.test("File runs with WindPower, check total capacity"): + assert ( + pytest.approx(prob.get_val("wind_plant.total_capacity", units="MW"), rel=1e-6) == 600.0 + ) + + with subtests.test("File runs with WindPower, check turbine size"): + assert ( + pytest.approx(prob.get_val("wind_plant.wind_turbine_rating", units="MW"), rel=1e-6) + == 6.0 + ) + + with subtests.test("File runs with WindPower, check AEP"): + assert ( + pytest.approx(prob.get_val("wind_plant.annual_energy", units="MW*h/yr")[0], rel=1e-6) + == 2783152.10 + ) + + +def test_floris_turbine_export(subtests): + turbine_name = "NREL_6MW_196" + output_fpath = export_turbine_to_floris_format(turbine_name) + + with subtests.test("File was created"): + assert output_fpath.exists() + assert output_fpath.is_file() + + # TODO: add test with floris model + # with subtests.test("File runs with FLORIS model"): + # pass diff --git a/h2integrate/preprocess/wind_turbine_file_tools.py b/h2integrate/preprocess/wind_turbine_file_tools.py new file mode 100644 index 000000000..51a2aefc5 --- /dev/null +++ b/h2integrate/preprocess/wind_turbine_file_tools.py @@ -0,0 +1,100 @@ +from pathlib import Path + +from attrs import field, define +from turbine_models.tools.library_tools import check_turbine_library_for_turbine +from turbine_models.tools.interface_tools import get_pysam_turbine_specs, get_floris_turbine_specs + +from h2integrate import H2I_LIBRARY_DIR +from h2integrate.core.utilities import BaseConfig, get_path, write_yaml_readable + + +def export_turbine_to_pysam_format( + turbine_name, output_folder: Path | str | None = None, output_filename: str | None = None +): + for group in ["distributed", "offshore", "onshore"]: + is_valid = check_turbine_library_for_turbine(turbine_name, turbine_group=group) + if is_valid: + break + if not is_valid: + msg = ( + f"Turbine {turbine_name} was not found in the turbine-models library. " + "For a list of available turbine names, run `print_turbine_name_list()` method " + "available in `turbine_models.tools.library_tools`." + ) + raise ValueError(msg) + if output_folder is None: + output_folder = H2I_LIBRARY_DIR + else: + output_folder = get_path(output_folder) + + if output_filename is None: + output_filename = f"pysam_options_{turbine_name}.yaml" + + output_filepath = output_folder / output_filename + + turbine_specs = get_pysam_turbine_specs(turbine_name) + + pysam_options = {"Turbine": turbine_specs} + + write_yaml_readable(pysam_options, output_filepath) + + return output_filepath + + +@define +class FlorisTurbineDefaults(BaseConfig): + TSR: float | int = field(default=8.0) + ref_air_density: float | int = field(default=1.225) + ref_tilt: float | int = field(default=5.0) + cosine_loss_exponent_yaw: float | int = field(default=1.88) + cosine_loss_exponent_tilt: float | int = field(default=1.88) + + def power_thrust_defaults(self): + d = self.as_dict() + power_thrust_variables = {k: v for k, v in d.items() if k != "TSR"} + return power_thrust_variables + + +def export_turbine_to_floris_format( + turbine_name, + output_folder: Path | str | None = None, + output_filename: str | None = None, + floris_defaults: dict | FlorisTurbineDefaults = FlorisTurbineDefaults(), +): + if isinstance(floris_defaults, dict): + floris_defaults = FlorisTurbineDefaults.from_dict(floris_defaults) + for group in ["distributed", "offshore", "onshore"]: + is_valid = check_turbine_library_for_turbine(turbine_name, turbine_group=group) + if is_valid: + break + if not is_valid: + msg = ( + f"Turbine {turbine_name} was not found in the turbine-models library. " + "For a list of available turbine names, run `print_turbine_name_list()` method " + "available in `turbine_models.tools.library_tools`." + ) + raise ValueError(msg) + if output_folder is None: + output_folder = H2I_LIBRARY_DIR + else: + output_folder = get_path(output_folder) + + if output_filename is None: + output_filename = f"floris_turbine_{turbine_name}.yaml" + + output_filepath = output_folder / output_filename + + turbine_specs = get_floris_turbine_specs(turbine_name) + + # add in default values + if turbine_specs.get("TSR", None) is None: + turbine_specs.update({"TSR": floris_defaults.TSR}) + + power_thrust_defaults = floris_defaults.power_thrust_defaults() + for var, default_val in power_thrust_defaults.items(): + if turbine_specs["power_thrust_table"].get(var, None) is None: + turbine_specs["power_thrust_table"].update({var: default_val}) + + write_yaml_readable(turbine_specs, output_filepath) + + return output_filepath diff --git a/pyproject.toml b/pyproject.toml index 938309f5d..d5bfdf417 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,6 +63,7 @@ dependencies = [ "rich>=13.7.0", "requests-cache", "retry_requests", + "turbine-models>=0.2.0" ] keywords = [ "python3", From 9cf05842bddd11e9e5fc23d941c44c6e93f424f5 Mon Sep 17 00:00:00 2001 From: elenya-grant <116225007+elenya-grant@users.noreply.github.com> Date: Wed, 26 Nov 2025 13:15:02 -0700 Subject: [PATCH 2/6] added docstrings --- h2integrate/core/utilities.py | 10 ++++ .../preprocess/wind_turbine_file_tools.py | 52 ++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/h2integrate/core/utilities.py b/h2integrate/core/utilities.py index 87497d53e..96dd63970 100644 --- a/h2integrate/core/utilities.py +++ b/h2integrate/core/utilities.py @@ -561,6 +561,16 @@ def write_yaml( def write_yaml_readable(instance: dict, foutput: str | Path): + """ + Writes a dictionary to a YAML file using the yaml library. + + Args: + instance (dict): Dictionary to be written to the YAML file. + foutput (str | Path): Path to the output YAML file. + + Returns: + None + """ instance = dict_to_yaml_formatting(instance) with Path(foutput).open("w", encoding="utf-8") as f: diff --git a/h2integrate/preprocess/wind_turbine_file_tools.py b/h2integrate/preprocess/wind_turbine_file_tools.py index 51a2aefc5..830ed568b 100644 --- a/h2integrate/preprocess/wind_turbine_file_tools.py +++ b/h2integrate/preprocess/wind_turbine_file_tools.py @@ -9,8 +9,24 @@ def export_turbine_to_pysam_format( - turbine_name, output_folder: Path | str | None = None, output_filename: str | None = None + turbine_name: str, output_folder: Path | str | None = None, output_filename: str | None = None ): + """Make a turbine model file for PySAM.Windpower Turbine using data from the turbine-models + library. + + Args: + turbine_name (str): name of turbine in turbine-models library. + output_folder (Path | str | None, optional): Output folder to save turbine model + file to. If None, uses the H2I_LIBRARY_DIR. Defaults to None. + output_filename (str | None, optional): Output filename for the turbine model file + as. If None, filename is f"pysam_options_{turbine_name}.yaml". Defaults to None. + + Raises: + ValueError: if turbine_name does match a turbine in the turbine-models library. + + Returns: + Path: filepath to .yaml file formatted for PySAM.WindPower Turbine. + """ for group in ["distributed", "offshore", "onshore"]: is_valid = check_turbine_library_for_turbine(turbine_name, turbine_group=group) if is_valid: @@ -43,6 +59,20 @@ def export_turbine_to_pysam_format( @define class FlorisTurbineDefaults(BaseConfig): + """Config class to specify default turbine parameters that are required by FLORIS. + + Attributes: + TSR (float | int): default turbine tip-speed-ratio. Defaults to 8.0 + ref_air_density (float | int): default air density for power-curve in kg/m**3. + Defaults to 1.225. + ref_tilt (float | int): default reference turbine shaft tilt angle in degrees. + Defaults to 5.0 + cosine_loss_exponent_yaw (float | int): default cosine loss exponent for yaw. + Defaults to 1.88 + cosine_loss_exponent_tilt (float | int): default cosine loss exponent for tilt. + Defaults to 1.88 + """ + TSR: float | int = field(default=8.0) ref_air_density: float | int = field(default=1.225) ref_tilt: float | int = field(default=5.0) @@ -56,11 +86,29 @@ def power_thrust_defaults(self): def export_turbine_to_floris_format( - turbine_name, + turbine_name: str, output_folder: Path | str | None = None, output_filename: str | None = None, floris_defaults: dict | FlorisTurbineDefaults = FlorisTurbineDefaults(), ): + """Make a turbine model file for FLORIS using data from the turbine-models library. + + Args: + turbine_name (str): name of turbine in turbine-models library. + output_folder (Path | str | None, optional): Output folder to save turbine model + file to. If None, uses the H2I_LIBRARY_DIR. Defaults to None. + output_filename (str | None, optional): Output filename for the turbine model file + as. If None, filename is f"floris_turbine_{turbine_name}.yaml". Defaults to None. + floris_defaults (dict | FlorisTurbineDefaults, optional): Default values to use to populate + missing parameters from the turbine-models library that are required for the + FLORIS turbine model. Defaults to FlorisTurbineDefaults(). + + Raises: + ValueError: if turbine_name does match a turbine in the turbine-models library. + + Returns: + Path: filepath to .yaml file formatted for FLORIS. + """ if isinstance(floris_defaults, dict): floris_defaults = FlorisTurbineDefaults.from_dict(floris_defaults) for group in ["distributed", "offshore", "onshore"]: From 7b779b97144ee76ee75f8c415754e2d6f471b8e1 Mon Sep 17 00:00:00 2001 From: elenya-grant <116225007+elenya-grant@users.noreply.github.com> Date: Wed, 26 Nov 2025 14:48:06 -0700 Subject: [PATCH 3/6] updated for bugfix in turbine models library --- h2integrate/preprocess/wind_turbine_file_tools.py | 11 +++-------- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/h2integrate/preprocess/wind_turbine_file_tools.py b/h2integrate/preprocess/wind_turbine_file_tools.py index 830ed568b..5015d3306 100644 --- a/h2integrate/preprocess/wind_turbine_file_tools.py +++ b/h2integrate/preprocess/wind_turbine_file_tools.py @@ -27,10 +27,7 @@ def export_turbine_to_pysam_format( Returns: Path: filepath to .yaml file formatted for PySAM.WindPower Turbine. """ - for group in ["distributed", "offshore", "onshore"]: - is_valid = check_turbine_library_for_turbine(turbine_name, turbine_group=group) - if is_valid: - break + is_valid = check_turbine_library_for_turbine(turbine_name) if not is_valid: msg = ( f"Turbine {turbine_name} was not found in the turbine-models library. " @@ -111,10 +108,8 @@ def export_turbine_to_floris_format( """ if isinstance(floris_defaults, dict): floris_defaults = FlorisTurbineDefaults.from_dict(floris_defaults) - for group in ["distributed", "offshore", "onshore"]: - is_valid = check_turbine_library_for_turbine(turbine_name, turbine_group=group) - if is_valid: - break + + is_valid = check_turbine_library_for_turbine(turbine_name) if not is_valid: msg = ( f"Turbine {turbine_name} was not found in the turbine-models library. " diff --git a/pyproject.toml b/pyproject.toml index d5bfdf417..d185e9acf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,7 @@ dependencies = [ "rich>=13.7.0", "requests-cache", "retry_requests", - "turbine-models>=0.2.0" + "turbine-models>=0.2.1" ] keywords = [ "python3", From 83d4326b787e9df5a8bfa93e0b27d2fd84c4ccea Mon Sep 17 00:00:00 2001 From: elenya-grant <116225007+elenya-grant@users.noreply.github.com> Date: Mon, 29 Dec 2025 15:12:56 -0700 Subject: [PATCH 4/6] renamed write_readable_yaml and minor update to dict_to_yaml formatting to handle NoneTypes --- h2integrate/core/utilities.py | 4 +++- h2integrate/preprocess/wind_turbine_file_tools.py | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/h2integrate/core/utilities.py b/h2integrate/core/utilities.py index 96dd63970..cbb373f16 100644 --- a/h2integrate/core/utilities.py +++ b/h2integrate/core/utilities.py @@ -286,6 +286,8 @@ def dict_to_yaml_formatting(orig_dict): elif isinstance(key, str): if isinstance(orig_dict[key], (str, bool, int)): continue + if orig_dict[key] is None: + continue if isinstance(orig_dict[key], (list, np.ndarray)): if any(isinstance(v, dict) for v in val): for vii, v in enumerate(val): @@ -560,7 +562,7 @@ def write_yaml( yaml.dump(instance, f) -def write_yaml_readable(instance: dict, foutput: str | Path): +def write_readable_yaml(instance: dict, foutput: str | Path): """ Writes a dictionary to a YAML file using the yaml library. diff --git a/h2integrate/preprocess/wind_turbine_file_tools.py b/h2integrate/preprocess/wind_turbine_file_tools.py index 5015d3306..25c855d17 100644 --- a/h2integrate/preprocess/wind_turbine_file_tools.py +++ b/h2integrate/preprocess/wind_turbine_file_tools.py @@ -5,7 +5,7 @@ from turbine_models.tools.interface_tools import get_pysam_turbine_specs, get_floris_turbine_specs from h2integrate import H2I_LIBRARY_DIR -from h2integrate.core.utilities import BaseConfig, get_path, write_yaml_readable +from h2integrate.core.utilities import BaseConfig, get_path, write_readable_yaml def export_turbine_to_pysam_format( @@ -49,7 +49,7 @@ def export_turbine_to_pysam_format( pysam_options = {"Turbine": turbine_specs} - write_yaml_readable(pysam_options, output_filepath) + write_readable_yaml(pysam_options, output_filepath) return output_filepath @@ -138,6 +138,6 @@ def export_turbine_to_floris_format( if turbine_specs["power_thrust_table"].get(var, None) is None: turbine_specs["power_thrust_table"].update({var: default_val}) - write_yaml_readable(turbine_specs, output_filepath) + write_readable_yaml(turbine_specs, output_filepath) return output_filepath From af1944224c59471b39f72328e994a414d6eb3a86 Mon Sep 17 00:00:00 2001 From: elenya-grant <116225007+elenya-grant@users.noreply.github.com> Date: Mon, 29 Dec 2025 15:14:58 -0700 Subject: [PATCH 5/6] added doc page for turbine model library preprocessing --- docs/_toc.yml | 1 + ...turbine_models_library_preprocessing.ipynb | 817 ++++++++++++++++++ 2 files changed, 818 insertions(+) create mode 100644 docs/misc_resources/turbine_models_library_preprocessing.ipynb diff --git a/docs/_toc.yml b/docs/_toc.yml index 7269c9e66..b8e1c7684 100644 --- a/docs/_toc.yml +++ b/docs/_toc.yml @@ -84,6 +84,7 @@ parts: - file: misc_resources/FAQ - file: misc_resources/glossary - file: misc_resources/defining_filepaths + - file: misc_resources/turbine_models_library_preprocessing - caption: API Reference maxdepth: 3 diff --git a/docs/misc_resources/turbine_models_library_preprocessing.ipynb b/docs/misc_resources/turbine_models_library_preprocessing.ipynb new file mode 100644 index 000000000..8a9f68f49 --- /dev/null +++ b/docs/misc_resources/turbine_models_library_preprocessing.ipynb @@ -0,0 +1,817 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Turbine Models Library Pre-Processing Tools\n", + "\n", + "The [turbine-models package](https://github.com/NREL/turbine-models/tree/main) hosts wind turbine data for a variety of wind turbines and has tools that can streamline the process to run new turbines with the [PySAM Windpower model](https://nrel-pysam.readthedocs.io/en/main/modules/Windpower.html) or [FLORIS](https://github.com/NREL/floris/tree/main).\n", + "\n", + "The full list of turbine models available in the turbine-models library can be found [here](https://github.com/NREL/turbine-models/blob/main/turbine_models/supported_turbines.py)\n", + "\n", + "H2Integrate has preprocessing tools that leverage the functionality available in the turbine-models library. The function `export_turbine_to_pysam_format()` will save turbine model specifications formatted for the PySAM Windpower model. The PySAM Windpower model is wrapped in H2I and can be utilized with the \"pysam_wind_plant_performance\" model. Example usage of the `export_turbine_to_pysam_format()` function is demonstrated in the following section using Example 8.\n", + "\n", + "\n", + "## Turbine Model Pre-Processing with PySAM Windpower Model\n", + "Example 8 (`08_wind_electrolyzer`) currently uses an 8.3 MW turbine. In the following sections we will demonstrate how to:\n", + "\n", + "1. Save turbine model specifications for the NREL 5 MW turbine in the PySAM Windpower format using `export_turbine_to_pysam_format()`\n", + "2. Load the turbine model specifications for the NREL 5 MW turbine and update performance parameters for the wind technology in the `tech_config` dictionary for the NREL 5 MW turbine.\n", + "3. Run H2I with the updated tech_config dictionary, showcasing two different methods to run H2I with the NREL 5 MW turbine:\n", + " - initializing H2I with a dictionary input\n", + " - saving the updated tech_config dictionary to a new file and initializing H2I by specifying the filepath to the top-level config file.\n", + "\n", + "\n", + "We'll start off by importing the required modules and packages:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/egrant/opt/anaconda3/envs/h2i_env/lib/python3.11/site-packages/fastkml/__init__.py:28: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", + " from pkg_resources import DistributionNotFound\n" + ] + } + ], + "source": [ + "import os\n", + "import numpy as np\n", + "\n", + "\n", + "from h2integrate import EXAMPLE_DIR\n", + "from h2integrate.core.utilities import load_yaml\n", + "from h2integrate.core.inputs.validation import load_tech_yaml\n", + "from h2integrate.preprocess.wind_turbine_file_tools import export_turbine_to_pysam_format\n", + "from h2integrate.core.h2integrate_model import H2IntegrateModel" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load the tech config file that we want to update the turbine model for:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Load the tech config file\n", + "tech_config_path = EXAMPLE_DIR / \"08_wind_electrolyzer\" / \"tech_config.yaml\"\n", + "tech_config = load_tech_yaml(tech_config_path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This example uses the \"pysam_wind_plant_performance\" performance model for the wind plant. Currently, the performance model is using an 8.3MW wind turbine with a rotor diameter of 196 meters and a hub-height of 130 meters. This information is defined in the `tech_config` file:\n", + "\n", + "```yaml\n", + "technologies:\n", + " wind:\n", + " performance_model:\n", + " model: \"pysam_wind_plant_performance\"\n", + " cost_model:\n", + " model: \"atb_wind_cost\"\n", + " model_inputs:\n", + " performance_parameters:\n", + " num_turbines: 100\n", + " turbine_rating_kw: 8300\n", + " rotor_diameter: 196.\n", + " hub_height: 130.\n", + " create_model_from: \"default\"\n", + " config_name: \"WindPowerSingleOwner\"\n", + " pysam_options: !include \"pysam_options_8.3MW.yaml\"\n", + " run_recalculate_power_curve: False\n", + " layout:\n", + " layout_mode: \"basicgrid\"\n", + " layout_options:\n", + " row_D_spacing: 10.0\n", + " turbine_D_spacing: 10.0\n", + " rotation_angle_deg: 0.0\n", + " row_phase_offset: 0.0\n", + " layout_shape: \"square\"\n", + " cost_parameters:\n", + " capex_per_kW: 1500.0\n", + " opex_per_kW_per_year: 45\n", + " cost_year: 2019\n", + "```\n", + "\n", + "\n", + "If we want to replace the 8.3 MW turbine with the NREL 5 MW turbine, we can do so using the `export_turbine_to_pysam_format()` function:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/Users/egrant/Documents/projects/GreenHEART/library/pysam_options_NREL_5MW.yaml\n" + ] + } + ], + "source": [ + "turbine_name = \"NREL_5MW\"\n", + "\n", + "turbine_model_fpath = export_turbine_to_pysam_format(turbine_name)\n", + "\n", + "print(turbine_model_fpath)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Turbine': {'wind_turbine_max_cp': 0.481305875,\n", + " 'wind_turbine_ct_curve': [0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 1.132034888,\n", + " 0.999470963,\n", + " 0.917697381,\n", + " 0.860849503,\n", + " 0.815371198,\n", + " 0.811614904,\n", + " 0.807939328,\n", + " 0.80443352,\n", + " 0.800993851,\n", + " 0.79768116,\n", + " 0.794529244,\n", + " 0.791495834,\n", + " 0.788560434,\n", + " 0.787217182,\n", + " 0.787127977,\n", + " 0.785839257,\n", + " 0.783812219,\n", + " 0.783568108,\n", + " 0.783328285,\n", + " 0.781194418,\n", + " 0.777292539,\n", + " 0.773464375,\n", + " 0.769690236,\n", + " 0.766001924,\n", + " 0.762348072,\n", + " 0.758760824,\n", + " 0.755242872,\n", + " 0.751792927,\n", + " 0.748434131,\n", + " 0.745113997,\n", + " 0.717806682,\n", + " 0.672204789,\n", + " 0.63831272,\n", + " 0.610176496,\n", + " 0.585456847,\n", + " 0.563222111,\n", + " 0.542912273,\n", + " 0.399312061,\n", + " 0.310517829,\n", + " 0.248633226,\n", + " 0.203543725,\n", + " 0.169616419,\n", + " 0.143478955,\n", + " 0.122938861,\n", + " 0.106515296,\n", + " 0.093026095,\n", + " 0.081648606,\n", + " 0.072197368,\n", + " 0.064388275,\n", + " 0.057782745,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0],\n", + " 'wind_turbine_powercurve_windspeeds': [0.0,\n", + " 1.0,\n", + " 2.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 6.0,\n", + " 7.0,\n", + " 7.1,\n", + " 7.2,\n", + " 7.3,\n", + " 7.4,\n", + " 7.5,\n", + " 7.6,\n", + " 7.7,\n", + " 7.8,\n", + " 7.9,\n", + " 8.0,\n", + " 9.0,\n", + " 10.0,\n", + " 10.1,\n", + " 10.2,\n", + " 10.3,\n", + " 10.4,\n", + " 10.5,\n", + " 10.6,\n", + " 10.7,\n", + " 10.8,\n", + " 10.9,\n", + " 11.0,\n", + " 11.1,\n", + " 11.2,\n", + " 11.3,\n", + " 11.4,\n", + " 11.5,\n", + " 11.6,\n", + " 11.7,\n", + " 11.8,\n", + " 11.9,\n", + " 12.0,\n", + " 13.0,\n", + " 14.0,\n", + " 15.0,\n", + " 16.0,\n", + " 17.0,\n", + " 18.0,\n", + " 19.0,\n", + " 20.0,\n", + " 21.0,\n", + " 22.0,\n", + " 23.0,\n", + " 24.0,\n", + " 25.0,\n", + " 26.0,\n", + " 27.0,\n", + " 28.0,\n", + " 29.0,\n", + " 30.0,\n", + " 31.0,\n", + " 32.0,\n", + " 33.0,\n", + " 34.0,\n", + " 35.0,\n", + " 36.0,\n", + " 37.0,\n", + " 38.0,\n", + " 39.0,\n", + " 40.0,\n", + " 41.0,\n", + " 42.0,\n", + " 43.0,\n", + " 44.0,\n", + " 45.0,\n", + " 46.0,\n", + " 47.0,\n", + " 48.0,\n", + " 49.0],\n", + " 'wind_turbine_powercurve_powerout': [0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 40.52,\n", + " 177.67,\n", + " 403.9,\n", + " 737.59,\n", + " 1187.18,\n", + " 1239.25,\n", + " 1292.52,\n", + " 1347.32,\n", + " 1403.26,\n", + " 1460.7,\n", + " 1519.64,\n", + " 1580.17,\n", + " 1642.11,\n", + " 1705.76,\n", + " 1771.17,\n", + " 2518.55,\n", + " 3448.38,\n", + " 3552.14,\n", + " 3657.95,\n", + " 3765.12,\n", + " 3873.93,\n", + " 3984.48,\n", + " 4096.58,\n", + " 4210.72,\n", + " 4326.15,\n", + " 4443.4,\n", + " 4562.5,\n", + " 4683.42,\n", + " 4806.16,\n", + " 4929.93,\n", + " 5000.0,\n", + " 5000.0,\n", + " 4999.98,\n", + " 4999.96,\n", + " 4999.98,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0],\n", + " 'wind_turbine_rotor_diameter': 126,\n", + " 'wind_turbine_hub_ht': 90}}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load the turbine model file formatted for the PySAM Windpower module\n", + "pysam_options = load_yaml(turbine_model_fpath)\n", + "pysam_options" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'num_turbines': 100,\n", + " 'turbine_rating_kw': np.float64(5000.0),\n", + " 'rotor_diameter': 126,\n", + " 'hub_height': 90,\n", + " 'create_model_from': 'default',\n", + " 'config_name': 'WindPowerSingleOwner',\n", + " 'pysam_options': {'Turbine': {'wind_turbine_max_cp': 0.481305875,\n", + " 'wind_turbine_ct_curve': [0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 1.132034888,\n", + " 0.999470963,\n", + " 0.917697381,\n", + " 0.860849503,\n", + " 0.815371198,\n", + " 0.811614904,\n", + " 0.807939328,\n", + " 0.80443352,\n", + " 0.800993851,\n", + " 0.79768116,\n", + " 0.794529244,\n", + " 0.791495834,\n", + " 0.788560434,\n", + " 0.787217182,\n", + " 0.787127977,\n", + " 0.785839257,\n", + " 0.783812219,\n", + " 0.783568108,\n", + " 0.783328285,\n", + " 0.781194418,\n", + " 0.777292539,\n", + " 0.773464375,\n", + " 0.769690236,\n", + " 0.766001924,\n", + " 0.762348072,\n", + " 0.758760824,\n", + " 0.755242872,\n", + " 0.751792927,\n", + " 0.748434131,\n", + " 0.745113997,\n", + " 0.717806682,\n", + " 0.672204789,\n", + " 0.63831272,\n", + " 0.610176496,\n", + " 0.585456847,\n", + " 0.563222111,\n", + " 0.542912273,\n", + " 0.399312061,\n", + " 0.310517829,\n", + " 0.248633226,\n", + " 0.203543725,\n", + " 0.169616419,\n", + " 0.143478955,\n", + " 0.122938861,\n", + " 0.106515296,\n", + " 0.093026095,\n", + " 0.081648606,\n", + " 0.072197368,\n", + " 0.064388275,\n", + " 0.057782745,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0],\n", + " 'wind_turbine_powercurve_windspeeds': [0.0,\n", + " 1.0,\n", + " 2.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 6.0,\n", + " 7.0,\n", + " 7.1,\n", + " 7.2,\n", + " 7.3,\n", + " 7.4,\n", + " 7.5,\n", + " 7.6,\n", + " 7.7,\n", + " 7.8,\n", + " 7.9,\n", + " 8.0,\n", + " 9.0,\n", + " 10.0,\n", + " 10.1,\n", + " 10.2,\n", + " 10.3,\n", + " 10.4,\n", + " 10.5,\n", + " 10.6,\n", + " 10.7,\n", + " 10.8,\n", + " 10.9,\n", + " 11.0,\n", + " 11.1,\n", + " 11.2,\n", + " 11.3,\n", + " 11.4,\n", + " 11.5,\n", + " 11.6,\n", + " 11.7,\n", + " 11.8,\n", + " 11.9,\n", + " 12.0,\n", + " 13.0,\n", + " 14.0,\n", + " 15.0,\n", + " 16.0,\n", + " 17.0,\n", + " 18.0,\n", + " 19.0,\n", + " 20.0,\n", + " 21.0,\n", + " 22.0,\n", + " 23.0,\n", + " 24.0,\n", + " 25.0,\n", + " 26.0,\n", + " 27.0,\n", + " 28.0,\n", + " 29.0,\n", + " 30.0,\n", + " 31.0,\n", + " 32.0,\n", + " 33.0,\n", + " 34.0,\n", + " 35.0,\n", + " 36.0,\n", + " 37.0,\n", + " 38.0,\n", + " 39.0,\n", + " 40.0,\n", + " 41.0,\n", + " 42.0,\n", + " 43.0,\n", + " 44.0,\n", + " 45.0,\n", + " 46.0,\n", + " 47.0,\n", + " 48.0,\n", + " 49.0],\n", + " 'wind_turbine_powercurve_powerout': [0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 40.52,\n", + " 177.67,\n", + " 403.9,\n", + " 737.59,\n", + " 1187.18,\n", + " 1239.25,\n", + " 1292.52,\n", + " 1347.32,\n", + " 1403.26,\n", + " 1460.7,\n", + " 1519.64,\n", + " 1580.17,\n", + " 1642.11,\n", + " 1705.76,\n", + " 1771.17,\n", + " 2518.55,\n", + " 3448.38,\n", + " 3552.14,\n", + " 3657.95,\n", + " 3765.12,\n", + " 3873.93,\n", + " 3984.48,\n", + " 4096.58,\n", + " 4210.72,\n", + " 4326.15,\n", + " 4443.4,\n", + " 4562.5,\n", + " 4683.42,\n", + " 4806.16,\n", + " 4929.93,\n", + " 5000.0,\n", + " 5000.0,\n", + " 4999.98,\n", + " 4999.96,\n", + " 4999.98,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 5000.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0,\n", + " 0.0]}},\n", + " 'run_recalculate_power_curve': False,\n", + " 'layout': {'layout_mode': 'basicgrid',\n", + " 'layout_options': {'row_D_spacing': 10.0,\n", + " 'turbine_D_spacing': 10.0,\n", + " 'rotation_angle_deg': 0.0,\n", + " 'row_phase_offset': 0.0,\n", + " 'layout_shape': 'square'}}}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Create dictionary of updated inputs for the new turbine formatted for\n", + "# the \"pysam_wind_plant_performance\" model\n", + "updated_parameters = {\n", + " \"turbine_rating_kw\": np.max(pysam_options[\"Turbine\"].get(\"wind_turbine_powercurve_powerout\")),\n", + " \"rotor_diameter\": pysam_options[\"Turbine\"].pop(\"wind_turbine_rotor_diameter\"),\n", + " \"hub_height\": pysam_options[\"Turbine\"].pop(\"wind_turbine_hub_ht\"),\n", + " \"pysam_options\": pysam_options,\n", + "}\n", + "\n", + "# Update wind performance parameters with model from PySAM\n", + "tech_config[\"technologies\"][\"wind\"][\"model_inputs\"][\"performance_parameters\"].update(\n", + " updated_parameters\n", + ")\n", + "\n", + "# The technology input for the updated wind turbine model\n", + "tech_config[\"technologies\"][\"wind\"][\"model_inputs\"][\"performance_parameters\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Option 1: Run H2I with dictionary input" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wind LCOE is $68.18/MWh\n", + "LCOH is $6.84/kg\n" + ] + } + ], + "source": [ + "# Create the top-level config input dictionary for H2I\n", + "h2i_config = {\n", + " # \"name\": \"H2Integrate Config\",\n", + " # \"system_summary\": f\"Updated hybrid plant using {turbine_name} turbine\",\n", + " \"driver_config\": EXAMPLE_DIR / \"08_wind_electrolyzer\" / \"driver_config.yaml\",\n", + " \"technology_config\": tech_config,\n", + " \"plant_config\": EXAMPLE_DIR / \"08_wind_electrolyzer\" / \"plant_config.yaml\",\n", + "}\n", + "\n", + "# Create a H2Integrate model with the updated tech config\n", + "h2i = H2IntegrateModel(h2i_config)\n", + "\n", + "# Run the model\n", + "h2i.run()\n", + "\n", + "# Get LCOE of wind plant\n", + "wind_lcoe = h2i.model.get_val(\"finance_subgroup_electricity_profast.LCOE\", units=\"USD/MW/h\")\n", + "print(f\"Wind LCOE is ${wind_lcoe[0]:.2f}/MWh\")\n", + "\n", + "# Get LCOH of wind/electrolyzer plant\n", + "lcoh = h2i.model.get_val(\"finance_subgroup_hydrogen.LCOH_produced_profast_model\", units=\"USD/kg\")\n", + "print(f\"LCOH is ${lcoh[0]:.2f}/kg\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Option 2: Save new tech_config to file and run H2I from file" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wind LCOE is $68.18/MWh\n", + "LCOH is $6.84/kg\n" + ] + } + ], + "source": [ + "from h2integrate.core.utilities import write_readable_yaml\n", + "\n", + "# Define a new filepath for the updated tech config\n", + "tech_config_path_new = EXAMPLE_DIR / \"08_wind_electrolyzer\" / f\"tech_config_{turbine_name}.yaml\"\n", + "\n", + "# Save the updated tech config to the new filepath\n", + "write_readable_yaml(tech_config, tech_config_path_new)\n", + "\n", + "# Load in the top-level H2I config file\n", + "h2i_config_path = EXAMPLE_DIR / \"08_wind_electrolyzer\" / \"wind_plant_electrolyzer.yaml\"\n", + "h2i_config_dict = load_yaml(h2i_config_path)\n", + "\n", + "# Define a new filepath for the updated top-level config\n", + "h2i_config_path_new = (\n", + " EXAMPLE_DIR / \"08_wind_electrolyzer\" / f\"wind_plant_electrolyzer_{turbine_name}.yaml\"\n", + ")\n", + "\n", + "# Update the technology config filepath in the top-level config with the updated\n", + "# tech config filename\n", + "h2i_config_dict[\"technology_config\"] = tech_config_path_new.name\n", + "\n", + "# Save the updated top-level H2I config to the new filepath\n", + "write_readable_yaml(h2i_config_dict, h2i_config_path_new)\n", + "\n", + "# Change the CWD to the example folder since filepaths in h2i_config_dict are relative\n", + "# to the \"08_wind_electrolyzer\" folder\n", + "os.chdir(EXAMPLE_DIR / \"08_wind_electrolyzer\")\n", + "\n", + "# Create a H2Integrate model with the updated tech config\n", + "h2i = H2IntegrateModel(h2i_config_path_new.name)\n", + "\n", + "# Run the model\n", + "h2i.run()\n", + "\n", + "# Get LCOE of wind plant\n", + "wind_lcoe = h2i.model.get_val(\"finance_subgroup_electricity_profast.LCOE\", units=\"USD/MW/h\")\n", + "print(f\"Wind LCOE is ${wind_lcoe[0]:.2f}/MWh\")\n", + "\n", + "# Get LCOH of wind/electrolyzer plant\n", + "lcoh = h2i.model.get_val(\"finance_subgroup_hydrogen.LCOH_produced_profast_model\", units=\"USD/kg\")\n", + "print(f\"LCOH is ${lcoh[0]:.2f}/kg\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Turbine Model Pre-Processing with FLORIS\n", + "\n", + "The function `export_turbine_to_floris_format()` with save turbine model specifications formatted for FLORIS. " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.11.13 ('h2i_env')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.13" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "e55566d5f9cb5003b92ad1d2254e8146f3d62519cfa868f35d73d51fb57327c6" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 62239ed3b052932f4a12b2840149ed5290e31612 Mon Sep 17 00:00:00 2001 From: Genevieve Starke Date: Fri, 2 Jan 2026 16:36:34 -0500 Subject: [PATCH 6/6] Minor docs typo --- ...turbine_models_library_preprocessing.ipynb | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/docs/misc_resources/turbine_models_library_preprocessing.ipynb b/docs/misc_resources/turbine_models_library_preprocessing.ipynb index 8a9f68f49..7cf4a5267 100644 --- a/docs/misc_resources/turbine_models_library_preprocessing.ipynb +++ b/docs/misc_resources/turbine_models_library_preprocessing.ipynb @@ -28,18 +28,9 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 8, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/egrant/opt/anaconda3/envs/h2i_env/lib/python3.11/site-packages/fastkml/__init__.py:28: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n", - " from pkg_resources import DistributionNotFound\n" - ] - } - ], + "outputs": [], "source": [ "import os\n", "import numpy as np\n", @@ -61,7 +52,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -113,14 +104,14 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "/Users/egrant/Documents/projects/GreenHEART/library/pysam_options_NREL_5MW.yaml\n" + "/Users/gstarke/Documents/Research_Programs/H2I/H2Integrate/library/pysam_options_NREL_5MW.yaml\n" ] } ], @@ -134,7 +125,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -376,7 +367,7 @@ " 'wind_turbine_hub_ht': 90}}" ] }, - "execution_count": 4, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -389,7 +380,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -642,7 +633,7 @@ " 'layout_shape': 'square'}}}" ] }, - "execution_count": 5, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -675,7 +666,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -721,7 +712,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -783,13 +774,13 @@ "source": [ "## Turbine Model Pre-Processing with FLORIS\n", "\n", - "The function `export_turbine_to_floris_format()` with save turbine model specifications formatted for FLORIS. " + "The function `export_turbine_to_floris_format()` will save turbine model specifications formatted for FLORIS. " ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.11.13 ('h2i_env')", + "display_name": "h2integrate", "language": "python", "name": "python3" }, @@ -805,12 +796,7 @@ "pygments_lexer": "ipython3", "version": "3.11.13" }, - "orig_nbformat": 4, - "vscode": { - "interpreter": { - "hash": "e55566d5f9cb5003b92ad1d2254e8146f3d62519cfa868f35d73d51fb57327c6" - } - } + "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2