NREL / floris

A controls-oriented engineering wake model.
http://nrel.github.io/floris
BSD 3-Clause "New" or "Revised" License
198 stars 152 forks source link

Interpolation issue: x_new below the range #504

Closed Josue9740 closed 1 year ago

Josue9740 commented 1 year ago

Hi,

I am trying to conduct a very simple example with Floris. The code is almost identical to the one in the example 08_calc_aep_from_rose_use_class.py https://github.com/NREL/floris/blob/main/examples/08_calc_aep_from_rose_use_class.py. The only difference is that I am using my own wind_rose data, but it has the same structure than the data in the example provided. Every time I execute the sentence:

aep = fi.get_farm_AEP_wind_rose_class(wind_rose=wind_rose)

I get the error:

File "D:\Programas\EntornosA3\wisdem\lib\site-packages\scipy\interpolate\_interpolate.py", line 695, in _evaluate
    below_bounds, above_bounds = self._check_bounds(x_new)

  File "D:\Programas\EntornosA3\wisdem\lib\site-packages\scipy\interpolate\_interpolate.py", line 724, in _check_bounds
    raise ValueError("A value in x_new is below the interpolation "

ValueError: A value in x_new is below the interpolation range.

Does this error suggest something to you? Any ideas?

Bartdoekemeijer commented 1 year ago

Hi @Josue9740,

Have you changed the input file, for example the turbine definitions or the farm layout? The error seems to suggest something inside FLORIS is trying to interpolate over a table, but asking for a value outside of the predefined values. My guess is that is has to do with the turbine power and thrust curves.

For example, if you have the turbine Cp and Ct table defined from 4 m/s to 20 m/s, and you're trying to interpolate them at a wind speed of 2 m/s, it should give you the error you are seeing. Typically, you should define your turbine power and thrust curves from 0 m/s to 50 m/s. Note that even if you specify a freestream wind speed of 8 m/s, your wind speed at downstream turbines may be much lower than that because of wakes.

If you still get this error even after expanding your Cp/Ct tables from 0 through 50 m/s, it could be that you are seeing negative wind speeds and trying to interpolate the Cp/Ct tables at a negative value, giving you the same error you are seeing. That would be indicative of a much too close turbine spacing.

Cheers, Bart

Josue9740 commented 1 year ago

Hi!

Thank you for this very detailed answer. It helps a lot!! Your are right, I changed turbine parameters. Just one question, I am working with experimental turbines, so I have data for Cp and Ct, but only between 3 m/s and 25 m/s. Is there any way I can make Floris works with this range? I tried using the parameters cut_in_wind_speed=3 and cut_in_wind_speed=25, but it did not work.

Regards, Josue

Bartdoekemeijer commented 1 year ago

I would suggest simply expanding your Cp/Ct tables:, for example, you can add a 0.0 0.0 entry and a 50.0 0.0 entry for both tables, indicating zero power/thrust at 0 m/s and zero power/thrust at 50 m/s. Take a look at the NREL 5MW definition https://github.com/NREL/floris/blob/main/floris/turbine_library/nrel_5MW.yaml as an example.

Cp at 0 m/s: https://github.com/NREL/floris/blob/0c2adf3e702b6427da946a6ba9dbedbea22738be/floris/turbine_library/nrel_5MW.yaml#L11

Ct at 0 m/s: https://github.com/NREL/floris/blob/0c2adf3e702b6427da946a6ba9dbedbea22738be/floris/turbine_library/nrel_5MW.yaml#L63

Josue9740 commented 1 year ago

Ok! Simple and effective. Thank you so much!

JarneVB commented 1 year ago

Hi there! I've had the same problem for a large wind farm with different turbine types. All of the self defined turbines have a Cp/Ct table that goes from 0 to 50 m/s, but I still got the error. I also can't change the layout of the farm, as it is an existing farm. I fixed the problem by adding a 0 entry for both Ct and Cp at -50 m/s. Is this a good fix, or will this give bad results? And is there any other way to fix it then?

Bartdoekemeijer commented 1 year ago

All of the self defined turbines have a Cp/Ct table that goes from 0 to 50 m/s, but I still got the error. I also can't change the layout of the farm, as it is an existing farm. I fixed the problem by adding a 0 entry for both Ct and Cp at -50 m/s. Is this a good fix, or will this give bad results? And is there any other way to fix it then?

If this works, it would mean one or multiple turbines in your simulation have a negative inflow wind speed. It would be worth investigating whether these negative wind speeds are due to a problem in your simulation setup or whether it is simply a result of very close turbine spacing and a very low turbulence intensity.

JarneVB commented 1 year ago

If this works, it would mean one or multiple turbines in your simulation have a negative inflow wind speed. It would be worth investigating whether these negative wind speeds are due to a problem in your simulation setup or whether it is simply a result of very close turbine spacing and a very low turbulence intensity.

How can I investigate this? Does this give any clue: when I used 1 wind turbine type for the whole farm instead of multiple types on the correct position, for some turbine types it wasn't a problem, but for others the problem occurred.

Bartdoekemeijer commented 1 year ago

How can I investigate this? Does this give any clue: when I used 1 wind turbine type for the whole farm instead of multiple types on the correct position, for some turbine types it wasn't a problem, but for others the problem occurred.

You can investigate the wind speed at each turbine's rotor by looking at fi.floris.flow_field.u. This will have shape (n_wind_directions, n_wind_speeds, n_turbines, n_turbine_grid_points, n_turbine_grid_points). Namely, the wind speed at each rotor is calculated on multiple points on the rotor plane (called the "rotor grid"). To get the average wind speed at each turbine, do

fi.floris.flow_field.u.mean(axis=(3, 4))

which shows the rotor-averaged wind speed at each turbine. This variable has shape (n_wind_directions, n_wind_speeds, n_turbines).

JarneVB commented 1 year ago

Hi there, I fixed this problem back in November by changing the superposition method of my site from fls to sofs. But now, I want to recalculate again using fls. I already changed my Ct and Cp curves so they range from -50 to 100 m/s. I tried to investigate the wind speed at each rotor using your suggestion, but it gives:

RuntimeWarning: Mean of empty slice.

Do you have any other suggestions on how I could fix this? It seems crazy to me that the wind speed would be less than -50m/s locally.

Bartdoekemeijer commented 1 year ago

Hi @JarneVB. This seems like a problem unrelated to the cp and ct curves. Surely the wind speed will not be below -50 m/s. Can you come up with a minimal example that reproduces the issue for us?

JarneVB commented 1 year ago

So I made an example that has the same problem. This is using a self-defined wake input, I couldn't add a .yaml so I made a .txt from it. Here you have the file and under it the example with the issue: Bastankah Gauss.txt

import numpy as np import pandas as pd from scipy.interpolate import NearestNDInterpolator from floris.floris.tools import FlorisInterface

D =120 X = [0]19 + [3D]19 + [6D]19 + [9D]19 + [12D]19 + [15D]19 + [18D]19 + [21D]19 + [24D]19 + [27D]19 + [30D]19 + [33D]19 + [36D]19 + [39D]19 + [42D]19 + [45D]19 + [48D]19 + [51D]19 + [54D]19 Y = [0, 360, 720, 1080, 1440, 1800, 2160, 2520, 2880, 3240, 3600, 3960, 4320, 4680, 5040, 5400, 5760, 6120, 6480]19

fi_gauss= FlorisInterface("floris/examples/inputs/BakGauss_fls.yaml") turbine_type = ['nrel_5MW']50 + ['iea_10MW']311 turbine_weights = [1]50 + [0]311

df_wr = pd.read_csv("floris/examples/inputs/wind_rose.csv") wd_array = np.array(df_wr["wd"].unique(), dtype=float) ws_array = np.array(df_wr["ws"].unique(), dtype=float)

wd_grid, ws_grid = np.meshgrid(wd_array, ws_array, indexing="ij") freq_interp = NearestNDInterpolator(df_wr[["wd", "ws"]], df_wr["freq_val"]) freq = freq_interp(wd_grid, ws_grid) freq = freq / np.sum(freq)

fi_gauss.reinitialize(layout_x=X, layout_y=Y, wind_directions=wd_array, wind_speeds=ws_array, turbine_type=turbine_type)

SR_gauss = fi_gauss.get_farm_AEP(freq=freq, turbine_weights = turbine_weights)/ 1.0e9 print(SR_gauss)

With the error: ValueError: A value in x_new is below the interpolation range.

JarneVB commented 1 year ago

Were you by any change able to solve this problem? When I try to change parameters of the site, I either get the same ValueError or just a nan. I should really be able to finish this by the end of the week.

Bartdoekemeijer commented 1 year ago

Hi @JarneVB, am I correctly reading that your turbines are spaced 360 meters apart? I see you both have NREL 5MW and IEA 10MW turbines, with rotor diameters of 126 meters and 198 meters, respectively. This means your turbines are spaced 3D (NREL 5MW) and 1.8 D (IEA 10MW) apart. A spacing of 1.8D is unrealistically close and therefore FLORIS will not produce sensible results. Almost certainly, this is why you're getting errors. Try placing your turbines at least 4-5D apart.