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

Add Nearest-Neighbor interpolation to heterogeneous wind map #1025

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from

Conversation

Bartdoekemeijer
Copy link
Collaborator

Add nearest-neighbor interpolation functionality to the HeterogeneousMap object

As the title reads, allows interpolation using NN rather than linear interpolation for heterogeneous background flows.

Related issue

N/A.

Impacted areas of the software

The heterogeneous_map and flow_field libraries.

Additional supporting information

The main reason for this is computation time. I don't see it being used very often, but can be useful for .WRGs where you have many sample points and you don't want to spend minutes preprocessing and linearly interpolating to the right points in the grid.

FYI, this PR already includes the minor code changes from #1024 for computational speed.

Test results, if applicable

Here's a simple script to benchmark these changes:

import numpy as np
import pandas as pd
from time import perf_counter as timerpc

from floris import (
    FlorisModel,
    TimeSeries,
    HeterogeneousMap
)


if __name__ == "__main__":
    # Create big grid of wind conditions and wind speeds for which we assume to have evaluated het_map
    wd_grid, ws_grid = np.meshgrid(
        np.arange(0.0, 360.0, 3.0),
        np.arange(6.0, 20.01, 1.0)
    )
    df = pd.DataFrame({"wd": wd_grid.flatten(), "ws": ws_grid.flatten()})
    print(f"We have {df.shape[0]} findices.")

    # Create a grid of sensors throughout the farm in x, y, and z
    xg, yg, zg = np.meshgrid(
        np.linspace(-3000.0, 3000.0, 11),
        np.linspace(-3000.0, 3000.0, 11),
        np.arange(0.0, 350.01, 25.0),
    )
    xg = xg.flatten()
    yg = yg.flatten()
    zg = zg.flatten()
    speedups = np.ones((df.shape[0], len(xg)))
    print(f"We have {len(xg)} number of coordinates with het_map information.")

    # Now create FLORIS and a timeseries object with het_map information
    fmodel = FlorisModel("inputs/gch.yaml")
    fmodel.set(
        layout_x = 7.0 * 126.0 * np.arange(30),  # Row of 30 turbines
        layout_y = np.zeros(30),  # Row of 30 turbines
        wind_shear=0.0  # Required when working with 3D het_map objects
    )

    print("")
    for interp_method in ["linear", "nn"]:
        het_map = HeterogeneousMap(
            x=xg,
            y=yg,
            z=zg,
            speed_multipliers=speedups,
            wind_directions=wd_grid.flatten(),
            wind_speeds=ws_grid.flatten(),
            interp_method=interp_method,
        )
        ts = TimeSeries(
            wind_directions=wd_grid.flatten(),
            wind_speeds=ws_grid.flatten(),
            turbulence_intensities=0.06 * np.ones(len(wd_grid.flatten())),
            heterogeneous_map=het_map,
        )

        t0 = timerpc()
        fmodel.set(wind_data=ts)
        print(f"Time spent for fmodel.set() ({interp_method}): {timerpc() - t0:.2f} s")
        fmodel.core.initialize_domain()
        print(f"Time spent for fmodel.set() and .initialize_domain() ({interp_method}): {timerpc() - t0:.2f} s")

Which results in

We have 1800 findices.
We have 1815 number of coordinates with het_map information.

Time spent for fmodel.set() (linear): 1.24 s
Time spent for fmodel.set() and .initialize_domain() (linear): 81.80 s

Time spent for fmodel.set() (nn): 0.67 s
Time spent for fmodel.set() and .initialize_domain() (nn): 1.26 s

Basically bringing time for initializing the domain from 80 seconds to 1 second.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant