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

Bug report: calling reinitialize_flow_field leads to incorrect turbine model information in FLORIS 2.4 #712

Open
pjireland opened this issue Sep 18, 2023 · 6 comments
Labels
v2.x Related to any version of FLORIS less than v3

Comments

@pjireland
Copy link
Contributor

Bug report: calling reinitialize_flow_field leads to incorrect turbine model information in FLORIS 2.4

When calling FlorisInterface.reinitialize_flow_field with layout_array not None, turbine-model-specific settings (e.g., hub height, rotor diameter, power-thrust curves) are overwritten with settings from the first turbine. This leads to problems if I want to simulate turbines of different models on the same farm when changing the farm layout.

Note that I haven't explored FLORIS 3.x to see if this issue persists, but given the significant restructuring in FLORIS 3.x, I would assume it does not. However, I am focused on using FLORIS 2.4 in my work, since FLORIS 3.x does not have support for wind direction heterogeneity, which is an important feature I need for simulations of large farms (see #441).

How to reproduce

First set up an example wind farm (based on the AEP example in FLORIS 2.4):

from floris.tools.floris_interface import FlorisInterface

# Use `example_input.json` file from FLORIS 2.4
# Taken from here:
# https://github.com/NREL/floris/blob/ef4934ec7feb7afd2615772d364a1eaa28db93e9/examples/example_input.json
fi = FlorisInterface("example_input.json")

# Set wind farm to N_row x N_row grid with constant spacing
# (2 x 2 grid, 5 D spacing)
D = fi.floris.farm.turbines[0].rotor_diameter
N_row = 2
spc = 5
layout_x = []
layout_y = []
for i in range(N_row):
    for k in range(N_row):
        layout_x.append(i * spc * D)
        layout_y.append(k * spc * D)
N_turb = len(layout_x)

fi.reinitialize_flow_field(
    layout_array=(layout_x, layout_y), wind_direction=[270.0], wind_speed=[8.0]
)
fi.calculate_wake()

Then modify the rotor diameter of the last turbine.

print(fi.floris.farm.turbines[-1].rotor_diameter) # 126.0
fi.floris.farm.turbines[-1].rotor_diameter = 100
print(fi.floris.farm.turbines[-1].rotor_diameter) # 100

Finally, reinitialize the flow field, changing just the layout and notice the the rotor diameter of the last turbine is now incorrectly equal to that of the first turbine:

fi.reinitialize_flow_field(
    layout_array=(
        [0, 0, 320, 320],
        [0, 320, 0, 320]
    )
)
print(fi.floris.farm.turbines[-1].rotor_diameter) # 126.0

Floris version

2.4

System Information

  • OS: Ubuntu 20.04.1 LTS (GNU/Linux 5.10.16.3-microsoft-standard-WSL2 x86_64)
  • Python version: Python 3.9.15
  • Library versions
    • matplotlib: 3.6.2
    • numpy: 1.23.5
    • numexpr: 2.8.3
    • scipy: 1.8.1
    • pandas: 1.5.2
@pjireland
Copy link
Contributor Author

The root of the issue seems to be these lines in floris.tools.floris_interface.FlorisInterface.reinitialize_flow_field:

                turbine_map = TurbineMap(
                    layout_array[0],
                    layout_array[1],
                    [
                        copy.deepcopy(self.floris.farm.turbines[0])
                        for ii in range(len(layout_array[0]))
                    ],
                )

where we see that the first turbine's information is used to overwrite those of the other turbines.

@rafmudaf rafmudaf added the v2.x Related to any version of FLORIS less than v3 label Sep 18, 2023
@rafmudaf
Copy link
Collaborator

Thanks for documenting this nicely @pjireland. Unfortunately, I don't recall why we used the first turbine for all in the reinitialize routine in v2. Have you checked whether it's valid to do this:

# change this
copy.deepcopy(self.floris.farm.turbines[0])

# to this
copy.deepcopy(self.floris.farm.turbines[ii])

If the indexes in the layout array do not correspond to the correct indexes in the floris.farm.turbines array, then this won't work.

@pjireland
Copy link
Contributor Author

@rafmudaf Thanks for the feedback. It looks like that works if you already have 4 turbines in self.floris.farm.turbines. But it will cause problems in the example I provided (and I would assume many of the examples in the codebase, which are similar) because there are not yet 4 turbines when reinitialize_flow_field is called.

Perhaps something like this could work?

assert len(self.floris.farm.turbines) in [1, len(layout_array[0])]
...
                turbine_map = TurbineMap(
                    layout_array[0],
                    layout_array[1],
                    [
                        copy.deepcopy(self.floris.farm.turbines[0])
                        if len(self.floris.farm.turbines) == 1
                        else copy.deepcopy(self.floris.farm.turbines[ii])
                        for ii in range(len(layout_array[0])) 
                    ],
                )

@rafmudaf
Copy link
Collaborator

Without having tested it, that looks right to me.

Regarding incorporating a fix, we haven't considered how to maintain FLORIS v2 in the case of users being tied to functionality that isn't available in v3. However, this and #684 seem like straightforward changes and easy enough to include as patches. I'll discuss it with the NREL team and let you know what we decide.

@rafmudaf
Copy link
Collaborator

Hey @pjireland if you're interested to submit a pull request with this change and any corresponding tests showing that it fixes the bug, I'm happy to review, merge, and complete the release process for a bug fix.

After some discussion, we've described the policy regarding v2 updates in #715, for reference.

@pjireland
Copy link
Contributor Author

Hey @pjireland if you're interested to submit a pull request with this change and any corresponding tests showing that it fixes the bug, I'm happy to review, merge, and complete the release process for a bug fix.

After some discussion, we've described the policy regarding v2 updates in #715, for reference.

Thanks for the feedback, @rafmudaf. For now, we have a workaround that will allow us to continue v2.4, but I'll submit a pull request if this capability becomes necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v2.x Related to any version of FLORIS less than v3
Projects
None yet
Development

No branches or pull requests

2 participants