diff --git a/.github/workflows/check-working-examples.yaml b/.github/workflows/check-working-examples.yaml index 7580ae3b5..28dd11e07 100644 --- a/.github/workflows/check-working-examples.yaml +++ b/.github/workflows/check-working-examples.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] os: [ubuntu-latest] #, macos-latest, windows-latest] fail-fast: False diff --git a/.github/workflows/continuous-integration-workflow.yaml b/.github/workflows/continuous-integration-workflow.yaml index 0035cdb0e..69bc7f857 100644 --- a/.github/workflows/continuous-integration-workflow.yaml +++ b/.github/workflows/continuous-integration-workflow.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] os: [ubuntu-latest] #, macos-latest, windows-latest] fail-fast: False env: diff --git a/README.md b/README.md index 28954775a..16fa26752 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ FLORIS is a controls-focused wind farm simulation software incorporating steady-state engineering wake models into a performance-focused Python framework. It has been in active development at NREL since 2013 and the latest -release is [FLORIS v4.1.1](https://github.com/NREL/floris/releases/latest). +release is [FLORIS v4.2.1](https://github.com/NREL/floris/releases/latest). Online documentation is available at https://nrel.github.io/floris. The software is in active development and engagement with the development team @@ -13,6 +13,9 @@ the conversation in [GitHub Discussions](https://github.com/NREL/floris/discussi ## Installation +**WARNING:** +Support for python version 3.8 will be dropped in FLORIS v4.3. See [Installation documentation](https://nrel.github.io/floris/installation.html#installation) for details. + **If upgrading from a previous version, it is recommended to install FLORIS v4 into a new virtual environment**. If you intend to use [pyOptSparse](https://mdolab-pyoptsparse.readthedocs-hosted.com/en/latest/) with FLORIS, it is recommended to install that package first before installing FLORIS. @@ -79,7 +82,7 @@ PACKAGE CONTENTS wind_data VERSION - 4.2 + 4.2.1 FILE ~/floris/floris/__init__.py diff --git a/docs/index.md b/docs/index.md index 202627695..3bd73151d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,6 +8,10 @@ is highly encouraged. If you are interested in using FLORIS to conduct studies of a wind farm or extending FLORIS to include your own wake model, please join the conversation in [GitHub Discussions](https://github.com/NREL/floris/discussions/)! +```{note} +Support for python version 3.8 will be dropped in FLORIS v4.3. See {ref}`installation` for details. +``` + ## Quick Start FLORIS is a Python package run on the command line typically by providing diff --git a/docs/installation.md b/docs/installation.md index 4a06260e6..0e1c22f9d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -7,11 +7,16 @@ The following sections detail how download and install FLORIS for each use case. (requirements)= ## Requirements -FLORIS is intended to be used with Python 3.8 and up, and it is highly recommended that users +FLORIS is a python package. FLORIS is intended to work with all [active versions of python](https://devguide.python.org/versions/). Support will drop for python versions once they reach end-of-life. +It is highly recommended that users work within a virtual environment for both working with and working on FLORIS, to maintain a clean and sandboxed environment. The simplest way to get started with virtual environments is through [conda](https://docs.conda.io/en/latest/miniconda.html). +```{warning} +Support for python version 3.8 will be dropped in FLORIS v4.3. +``` + Installing into a Python environment that contains a previous version of FLORIS may cause conflicts. If you intend to use [pyOptSparse](https://mdolab-pyoptsparse.readthedocs-hosted.com/en/latest/) with FLORIS, it is recommended to install that package first before installing FLORIS. diff --git a/floris/floris_model.py b/floris/floris_model.py index 81fefddfd..00c23bc72 100644 --- a/floris/floris_model.py +++ b/floris/floris_model.py @@ -1754,9 +1754,16 @@ def reinitialize(self, **_): @staticmethod def merge_floris_models(fmodel_list, reference_wind_height=None): - """Merge a list of FlorisModel objects into a single FlorisModel object. Note that it uses - the very first object specified in fmodel_list to build upon, + """Merge a list of FlorisModel objects into a single FlorisModel object. + Note that it uses the first object specified in fmodel_list to build upon, so it uses those wake model parameters, air density, and so on. + Currently, this function supports merging the following components of the FLORIS inputs: + - farm + - layout_x + - layout_y + - turbine_type + - flow_field + - reference_wind_height Args: fmodel_list (list): Array-like of FlorisModel objects. @@ -1773,8 +1780,8 @@ def merge_floris_models(fmodel_list, reference_wind_height=None): or general solver settings. """ - if not isinstance(fmodel_list[0], FlorisModel): - raise ValueError( + if not all( type(fm) == FlorisModel for fm in fmodel_list ): + raise TypeError( "Incompatible input specified. fmodel_list must be a list of FlorisModel objects." ) diff --git a/pyproject.toml b/pyproject.toml index 295756d84..79785ff6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta" [project] name = "floris" -version = "4.2" +version = "4.2.1" description = "A controls-oriented engineering wake model." readme = "README.md" -requires-python = ">=3.8" +requires-python = ">=3.9" authors = [ { name = "Rafael Mudafort", email = "rafael.mudafort@nrel.gov" }, { name = "Paul Fleming", email = "paul.fleming@nrel.gov" }, @@ -21,9 +21,11 @@ classifiers = [ "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy" ] @@ -42,17 +44,17 @@ dependencies = [ [project.optional-dependencies] docs = [ - "jupyter-book", - "sphinx-book-theme", - "sphinx-autodoc-typehints", - "sphinxcontrib-autoyaml==1.1.1", - "sphinxcontrib.mermaid", + "jupyter-book~=1.0", + "sphinx-book-theme~=1.0", + "sphinx-autodoc-typehints~=2.0", + "sphinxcontrib-autoyaml~=1.0", + "sphinxcontrib.mermaid~=1.0", ] develop = [ - "pytest", - "pre-commit", - "ruff", - "isort" + "pytest~=8.0", + "pre-commit~=4.0", + "ruff~=0.7", + "isort~=5.0" ] [tool.setuptools.packages.find] diff --git a/tests/floris_model_integration_test.py b/tests/floris_model_integration_test.py index 9af375c78..3ba94b955 100644 --- a/tests/floris_model_integration_test.py +++ b/tests/floris_model_integration_test.py @@ -844,3 +844,30 @@ def test_reference_wind_height_methods(caplog): turbine_type=["nrel_5MW", "iea_15MW"] ) fmodel.assign_hub_height_to_ref_height() # Shouldn't allow due to multiple turbine types + +def test_merge_floris_models(): + + # Check that the merge function extends the data as expected + fmodel1 = FlorisModel(configuration=YAML_INPUT) + fmodel1.set( + layout_x=[0, 1000], + layout_y=[0, 0] + ) + fmodel2 = FlorisModel(configuration=YAML_INPUT) + fmodel2.set( + layout_x=[2000, 3000], + layout_y=[0, 0] + ) + + merged_fmodel = FlorisModel.merge_floris_models([fmodel1, fmodel2]) + assert merged_fmodel.n_turbines == 4 + + # Check that this model will run without error + merged_fmodel.run() + + # Verify error handling + + ## Input list with incorrect types + fmodel_list = [fmodel1, "not a floris model"] + with pytest.raises(TypeError): + merged_fmodel = FlorisModel.merge_floris_models(fmodel_list)