Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support initializing FLORIS with default values #1040

Merged
merged 8 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 134 additions & 2 deletions docs/advanced_concepts.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,148 @@
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## FLORIS as a library\n",
"\n",
"FLORIS is commonly used as a library in other software packages.\n",
"In cases where the calling-code will create inputs for FLORIS rather than require them from the\n",
"user, it can be helpful to initialize the FLORIS model with default inputs and then\n",
"change them in code.\n",
"In this case, the following workflow is recommended."
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": []
"source": [
"import floris\n",
"\n",
"# Initialize FLORIS with defaults\n",
"fmodel = floris.FlorisModel(\"defaults\")\n",
"\n",
"# Within the calling-code's setup step, update FLORIS as needed\n",
"fmodel.set(\n",
" wind_directions=[i for i in range(10)],\n",
" wind_speeds=[5 + i for i in range(10)],\n",
" turbulence_intensities=[i for i in range(10)],\n",
" # turbine_library_path=\"path/to/turbine_library\", # Shown here for reference\n",
" # turbine_type=[\"my_turbine\"]\n",
")\n",
"\n",
"# Within the calling code's computation, run FLORIS\n",
"fmodel.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively, the calling-code can import the FLORIS default inputs as a Python dictionary\n",
"and modify them directly before initializing the FLORIS model.\n",
"This is especially helpful when the calling-code will modify a parameter that isn't\n",
"supported by the `FlorisModel.set(...)` command.\n",
"In particular, the wake model parameters are not directly accessible, so these can be updated\n",
"externally, as shown below.\n",
"Note that the `FlorisModel.get_defaults()` function returns a deep copy of the default inputs,\n",
"so these can be modified directly without side effects."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"solver\n",
" type\n",
" turbine_grid\n",
" turbine_grid_points\n",
" 3\n",
"wake\n",
" model_strings\n",
" combination_model\n",
" sosfs\n",
" deflection_model\n",
" gauss\n",
" turbulence_model\n",
" crespo_hernandez\n",
" velocity_model\n",
" jensen\n",
"farm\n",
" layout_x\n",
" [0.0]\n",
" layout_y\n",
" [0.0]\n",
" turbine_type\n",
" ['nrel_5MW']\n",
" turbine_library_path\n",
" /Users/rmudafor/Development/floris/floris/turbine_library\n",
"flow_field\n",
" wind_speeds\n",
" [5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0]\n",
" wind_directions\n",
" [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]\n",
" wind_veer\n",
" 0.0\n",
" wind_shear\n",
" 0.12\n",
" air_density\n",
" 1.225\n",
" turbulence_intensities\n",
" [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]\n",
" reference_wind_height\n",
" 90.0\n",
"name\n",
" GCH\n",
"description\n",
" Default initialization: Gauss-Curl hybrid model (GCH)\n",
"floris_version\n",
" v4\n"
]
}
],
"source": [
"import floris\n",
"\n",
"# Retrieve the default parameters\n",
"fdefaults = floris.FlorisModel.get_defaults()\n",
"\n",
"# Update wake model parameters\n",
"fdefaults[\"wake\"][\"model_strings\"][\"velocity_model\"] = \"jensen\"\n",
"fdefaults[\"wake\"][\"wake_velocity_parameters\"][\"jensen\"][\"we\"] = 0.05\n",
"\n",
"# Initialize FLORIS with modified parameters\n",
"fmodel = floris.FlorisModel(configuration=fdefaults)\n",
"\n",
"# Within the calling-code's setup step, update FLORIS as needed\n",
"fmodel.set(\n",
" wind_directions=[i for i in range(10)],\n",
" wind_speeds=[5 + i for i in range(10)],\n",
" turbulence_intensities=[i for i in range(10)],\n",
" # turbine_library_path=\"path/to/turbine_library\", # Shown here for reference\n",
" # turbine_type=[\"my_turbine\"]\n",
")\n",
"\n",
"# Verify settings are correct\n",
"fmodel.show_config() # Shows truncated set of inputs; show all with fmodel.show_config(full=True)\n",
"\n",
"# Within the calling code's computation, run FLORIS\n",
"fmodel.run()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
Expand Down
106 changes: 106 additions & 0 deletions floris/default_inputs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

name: GCH
description: "Default initialization: Gauss-Curl hybrid model (GCH)"
floris_version: v4

logging:
console:
enable: true
level: WARNING
file:
enable: false
level: WARNING

solver:
type: turbine_grid
turbine_grid_points: 3

farm:
layout_x:
- 0.0
layout_y:
- 0.0
turbine_type:
- nrel_5MW

flow_field:
air_density: 1.225
reference_wind_height: -1
turbulence_intensities: []
wind_directions: []
wind_shear: 0.12
wind_speeds: []
wind_veer: 0.0

wake:
model_strings:
combination_model: sosfs
deflection_model: gauss
turbulence_model: crespo_hernandez
velocity_model: gauss

enable_secondary_steering: true
enable_yaw_added_recovery: true
enable_transverse_velocities: true
enable_active_wake_mixing: false

wake_deflection_parameters:
gauss:
ad: 0.0
alpha: 0.58
bd: 0.0
beta: 0.077
dm: 1.0
ka: 0.38
kb: 0.004
jimenez:
ad: 0.0
bd: 0.0
kd: 0.05
empirical_gauss:
horizontal_deflection_gain_D: 3.0
vertical_deflection_gain_D: -1
deflection_rate: 22
mixing_gain_deflection: 0.0
yaw_added_mixing_gain: 0.0

wake_velocity_parameters:
gauss:
alpha: 0.58
beta: 0.077
ka: 0.38
kb: 0.004
jensen:
we: 0.05
cc:
a_s: 0.179367259
b_s: 0.0118889215
c_s1: 0.0563691592
c_s2: 0.13290157
a_f: 3.11
b_f: -0.68
c_f: 2.41
alpha_mod: 1.0
turbopark:
A: 0.04
sigma_max_rel: 4.0
turboparkgauss:
A: 0.04
include_mirror_wake: True
empirical_gauss:
wake_expansion_rates: [0.023, 0.008]
breakpoints_D: [10]
sigma_0_D: 0.28
smoothing_length_D: 2.0
mixing_gain_velocity: 2.0
awc_wake_exp: 1.2
awc_wake_denominator: 400

wake_turbulence_parameters:
crespo_hernandez:
initial: 0.1
constant: 0.5
ai: 0.8
downstream: -0.32
wake_induced_mixing:
atmospheric_ti_gain: 0.0
31 changes: 29 additions & 2 deletions floris/floris_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
NDArrayStr,
)
from floris.utilities import (
load_yaml,
nested_get,
nested_set,
print_nested_dict,
Expand Down Expand Up @@ -63,7 +64,15 @@ class FlorisModel(LoggingManager):
- **logging**: See `floris.simulation.core.Core` for more details.
"""

@staticmethod
def get_defaults() -> dict:
return copy.deepcopy(load_yaml(Path(__file__).parent / "default_inputs.yaml"))

def __init__(self, configuration: dict | str | Path):

if configuration == "defaults":
configuration = FlorisModel.get_defaults()

self.configuration = configuration

if isinstance(self.configuration, (str, Path)):
Expand Down Expand Up @@ -1627,11 +1636,29 @@ def get_turbine_layout(self, z=False):
else:
return xcoords, ycoords

def print_dict(self) -> None:
def show_config(self, full=False) -> None:
"""Print the FlorisModel dictionary.
"""
print_nested_dict(self.core.as_dict())
config_dict = self.core.as_dict()
if not full:
del config_dict["logging"]
del config_dict["wake"]["enable_secondary_steering"]
del config_dict["wake"]["enable_yaw_added_recovery"]
del config_dict["wake"]["enable_transverse_velocities"]
del config_dict["wake"]["enable_active_wake_mixing"]
del config_dict["wake"]["wake_deflection_parameters"]
del config_dict["wake"]["wake_velocity_parameters"]
del config_dict["wake"]["wake_turbulence_parameters"]
print_nested_dict(config_dict)

def print_dict(self) -> None:
"""Print the FlorisModel dictionary.
"""
self.logger.warning(
"The print_dict() method has been deprecated."
" Please use the show_config() method instead."
)
self.show_config(full=True)

### Properties

Expand Down
28 changes: 14 additions & 14 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ description = "A controls-oriented engineering wake model."
readme = "README.md"
requires-python = ">=3.9"
authors = [
{ name = "Rafael Mudafort", email = "rafael.mudafort@nrel.gov" },
{ name = "Paul Fleming", email = "paul.fleming@nrel.gov" },
{ name = "Rafael Mudafort", email = "Rafael.Mudafort@nrel.gov" },
{ name = "Paul Fleming", email = "Paul.Fleming@nrel.gov" },
{ name = "Michael (Misha) Sinner", email = "[email protected]" },
{ name = "Eric Simley", email = "[email protected]" },
{ name = "Christopher Bay", email = "[email protected]" },
]
license = { file = "LICENSE.txt" }
keywords = ["floris"]
classifiers = [
"License :: OSI Approved :: BSD License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"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"
"License :: OSI Approved :: BSD License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"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"
]
dependencies = [
"attrs",
Expand Down Expand Up @@ -63,7 +63,8 @@ include = ["floris*"]
[tool.setuptools.package-data]
floris = [
"turbine_library/*.yaml",
"core/wake_velocity/turbopark_lookup_table.mat"
"core/wake_velocity/turbopark_lookup_table.mat",
"default_inputs.yaml"
]

[project.urls]
Expand All @@ -76,7 +77,6 @@ Documentation = "https://nrel.github.io/floris/"
branch = true
source = "floris/*"
omit = [
"setup.py",
"tests/*"
]

Expand Down
Loading