|
24 | 24 | import matplotlib.pyplot as plt |
25 | 25 | import numpy as np |
26 | 26 | import pandas as pd |
| 27 | +from scipy.interpolate import LinearNDInterpolator, NearestNDInterpolator |
27 | 28 |
|
28 | 29 | import floris.utilities as geo |
29 | 30 |
|
@@ -446,6 +447,68 @@ def internal_resample_average_ws_by_wd(self, wd=np.arange(0, 360, 5.0)): |
446 | 447 | # Update internal data frame |
447 | 448 | self.df = self.resample_average_ws_by_wd(self.df) |
448 | 449 |
|
| 450 | + def interpolate( |
| 451 | + self, |
| 452 | + wind_directions: np.ndarray, |
| 453 | + wind_speeds: np.ndarray, |
| 454 | + mirror_0_to_360=True, |
| 455 | + fill_value=0.0, |
| 456 | + method="linear" |
| 457 | + ): |
| 458 | + """ |
| 459 | + This method returns a linear interpolant that will return the occurrence |
| 460 | + frequency for any given wind direction and wind speed combination(s). |
| 461 | + This can be particularly useful when evaluating the wind rose at a |
| 462 | + higher frequency than the input data is provided. |
| 463 | +
|
| 464 | + Args: |
| 465 | + wind_directions (np.ndarray): One or multi-dimensional array containing |
| 466 | + the wind direction values at which the wind rose frequency of occurrence |
| 467 | + should be evaluated. |
| 468 | + wind_speeds (np.ndarray): One or multi-dimensional array containing |
| 469 | + the wind speed values at which the wind rose frequency of occurrence |
| 470 | + should be evaluated. |
| 471 | + mirror_0_to_360 (bool, optional): This function copies the wind rose |
| 472 | + frequency values from 0 deg to 360 deg. This can be useful when, for example, |
| 473 | + the wind rose is only calculated until 357 deg but then interpolant is |
| 474 | + requesting values at 359 deg. Defaults to True. |
| 475 | + fill_value (float, optional): Fill value for the interpolant when |
| 476 | + interpolating values outside of the data region. Defaults to 0.0. |
| 477 | + method (str, optional): The interpolation method. Options are 'linear' and |
| 478 | + 'nearest'. Recommended usage is 'linear'. Defaults to 'linear'. |
| 479 | +
|
| 480 | + Returns: |
| 481 | + scipy.interpolate.LinearNDInterpolant: Linear interpolant for the |
| 482 | + wind rose currently available in the class (self.df). |
| 483 | +
|
| 484 | + Example: |
| 485 | + wr = wind_rose.WindRose() |
| 486 | + wr.make_wind_rose_from_user_data(...) |
| 487 | + freq_floris = wr.interpolate(floris_wind_direction_grid, floris_wind_speed_grid) |
| 488 | + """ |
| 489 | + if method == "linear": |
| 490 | + interpolator = LinearNDInterpolator |
| 491 | + elif method == "nearest": |
| 492 | + interpolator = NearestNDInterpolator |
| 493 | + else: |
| 494 | + UserWarning("Unknown interpolation method: '{:s}'".format(method)) |
| 495 | + |
| 496 | + # Load windrose information from self |
| 497 | + df = self.df.copy() |
| 498 | + |
| 499 | + if mirror_0_to_360: |
| 500 | + # Copy values from 0 deg over to 360 deg |
| 501 | + df_copy = df[df["wd"] == 0.0].copy() |
| 502 | + df_copy["wd"] = 360.0 |
| 503 | + df = pd.concat([df, df_copy], axis=0) |
| 504 | + |
| 505 | + interp = interpolator( |
| 506 | + points=df[["wd", "ws"]], |
| 507 | + values=df["freq_val"], |
| 508 | + fill_value=fill_value |
| 509 | + ) |
| 510 | + return interp(wind_directions, wind_speeds) |
| 511 | + |
449 | 512 | def weibull(self, x, k=2.5, lam=8.0): |
450 | 513 | """ |
451 | 514 | This method returns a Weibull distribution corresponding to the input |
|
0 commit comments