Gridded Wind Farm on a Rectangular Domain

This demonstration will show how to set up a 2D rectangular mesh with a wind farm consisting of a 36 turbines laid out in a 6x6 grid. This demo is associated with two files:

Setting up the parameters:

To write a WindSE driver script, we first need to define the parameters. This must be completed before building any WindSE objects. There are two way to define the parameters:

  1. Loading a parameters yaml file
  2. Manually creating the parameter dictionary directly in the driver.

Both methods will be discussed below and demonstrated in the next section.

The parameter file:

First we will discuss the parameters file method. The parameter file is the main way to customize a simulation. The driver file uses the options specified in the parameters file to run the simulation. Ideally, multiple simulations can use a single driver file and multiple parameter files.

The parameter file is formated as a yaml structure and requires pyyaml to be read. The driver file is written in python.

The parameter file is broken up into several sections: general, domain, boundaries, and wind_farm, etc.

The full parameter file can be found here: params.yaml and more information can be found here: Parameter File Explained.

Manual parameter dictionary:

The manual method involve creating a blank nested dictionary and populating it with the parameters needed for the simulation. The windse_driver.driver_functions.BlankParameters() will create the blank nested dictionary for you.

Creating the driver code:

The full driver file can be found here: 2D_Grid_driver.py First, we start off with the import statements:

import windse
import windse_driver.driver_functions as df

Next, we need to set up the parameters. If we want to load them from a yaml file we would run:

# windse.initialize("params.yaml")
# params = windse.windse_parameters

However, in this demo, we will define the parameters manually. Start by creating a blank parameters object:

params = df.BlankParameters()

Next, populate the general options:

params["general"]["name"]        = "2D_driver"
params["general"]["output"]      = ["mesh","initial_guess","turbine_force","solution"]
params["general"]["output_type"] = "xdmf"

Then, the wind farm options:

params["wind_farm"]["type"]      = "grid"
params["wind_farm"]["grid_rows"] = 6
params["wind_farm"]["grid_cols"] = 6
params["wind_farm"]["ex_x"]      = [-1800,1800]
params["wind_farm"]["ex_y"]      = [-1800,1800]
params["wind_farm"]["HH"]        = 90
params["wind_farm"]["RD"]        = 126
params["wind_farm"]["thickness"] = 10
params["wind_farm"]["yaw"]       = 0
params["wind_farm"]["axial"]     = 0.33

and the domain options:

params["domain"]["type"]    = "rectangle"
params["domain"]["x_range"] = [-2500, 2500]
params["domain"]["y_range"] = [-2500, 2500]
params["domain"]["nx"]      = 50
params["domain"]["ny"]      = 50

Lastly, we just need to define the type of boundary conditons, function space, problem formulation and solver we want:

params["boundary_conditions"]["vel_profile"] = "uniform"
params["function_space"]["type"] = "taylor_hood"
params["problem"]["type"]        = "taylor_hood"
params["solver"]["type"]         = "steady"

Now that the dictionary is set up, we need to initialize WindSE:

params = df.Initialize(params)

That was basically the hard part. Now with just a few more commands, our simulation will be running. First we need to build the domain and wind farm objects:

dom, farm = df.BuildDomain(params)

We can inspect the wind farm by running:

farm.Plot(True)

This results in a wind farm that looks like this:

../../_images/wind_farm.png

Alternatively, we could have use False to generate and save the plot, but not display it. This is useful for running batch test or on a HPC. We could also manually save the mesh using dom.Save(), but since we specified the mesh as an output in the parameters file, this will be done automatically when we solve.

Next, we need to setup the simulation problem:

problem = df.BuildProblem(params,dom,farm)

For this problem we are going to use Taylor-Hood elements, which are comprised of 2nd order Lagrange elements for velocity and 1st order elements for pressure.

The last step is to build the solver:

solver = df.BuildSolver(params,problem)

This problem has uniform inflow from the west. The east boundary is our outflow and has a no-stress boundary condition.

Finally, it’s time to solve:

solver.Solve()

Running solver.Solve() will save all the inputs according to the parameters file, solve the problem, and save the solution. If everything went smoothly, the solution for wind speed should be:

../../_images/solution.png