Using TurbSim for large wind farms

Dear NREL

I am in the process of designing the TotalControl wind farm in FAST.Farm. I am having an issue with generating a turbulent wind field for the wind farm using TurbSim, as the specified domain width and height calculated by this Python script (https://github.com/OpenFAST/python-toolbox/tree/main/pyFAST/fastfarm/examples) are too large for TurbSim to run.

I read a post that discussed a similar issue on the forum (About TurbSim Input File. - #17 by Jason.Jonkman), and I understand that I need to use Mod_AmbWind = 3 in Fast.Farm input file which involves creating a coarsely discretized, low-resolution wind domain in TurbSim and then extracting the velocity time series at the hub node of each turbine which I can then use as input for TurbSim again to generate the time-synchronized high-resolution wind field for each of the turbines. The issue, however, is that I do not know the exact methodology for doing the above partly because of a lack of understanding of how Fast.Farm initializes and propagates the wind fields generated by the TurbSim, partially because I am not sure how to extract the required sets of time series and how to time-synchronize them in a manner that Fast.Farm can use all these TurbSim domains correctly.

I have been reading Fast.Farm and TurbSim manuals, and from my understanding, TurbSim generates 2D turbulent wind fields that are time-dependent at an interval and for a duration defined by the user. Fast.Farm then uses the “.bts” output file from TurbSim and initialises the wind field at t=0 (inside the “.bts” file) at the farm’s X0 location and then propagates it through the farm with an “advection speed” (the calculated “U” speed at the “fake” hub height defined in TurbSim input file). Then at 0+delta_t the new wind field is read in and so on until t_max is reached.

If the latter is true,

  1. does this mean that the TurbSim coarsely discretised 2D domain has to be discretized in a way that the domain contains at least each of the Y and Z coordinates of the actual hub of each turbine on the farm? Also,

  2. how can we capture the X_location of each turbine’s hub for when we are extracting its time series from the low-resolution domain?

  3. How can we extract the time series for each turbine’s hub and refeed it to TurbSim in a manner that is time synchronized?

  4. Also, how does Fast.Farm actually run the multiple low and high-resolution domains? Does it initialise all of the low and high-resolution domains at the same instant (starting at time zero) or does it wait until the low-res wind field has reached a turbine’s local x_0 coordinate to initialise the high-res wind field domain associated with this wind turbine?

I could not find any example within the r_test folder that addresses the use of multiple instances of InflowWind (Mod_AmbWind = 3) so I would really appreciate it if you could direct me to one if it is available.

I would highly appreciate it if you would address these questions and provide more clarification on this methodology.

Thank you

Dear @Abdulbaset.Alazhare,

Here are my answers to your questions. But, in general, I recommend using the inflow-generation utilities for FAST.Farm from the Python Toolbox (https://github.com/OpenFAST/python-toolbox/tree/main/pyFAST/fastfarm), which handles all of these details for you. I agree that we need to provide an example FAST.Farm r-test with Mod_AmbWind = 3, which is recommended over Mod_AmbWind = 2; NREL is working on the development of this r-test.

  1. No. But you should extract data from a point in the low-resolution domain that you can prescribe using the TIMESR option of TurbSim for the high-resolution domain. This point does not need to be at the hub.
  2. Effectively by employing a time-shift because the 2D plus time data of TurbSim is turned into 3D plus time data within InflowWind using the relationship X = Ubar*t, where Ubar is the mean wind speed at TurbSim’s assumed hub height (which becomes the propagation speed of the 2D plane) and t is time.
  3. By reading in the TurbSim data of the low-resolution data, selecting the point of interest, and applying the time-shift mentioned in (2).
  4. When Mod_AmbWind = 3, FAST.Farm employs NumTurbines + 1 instances of InflowWind: one high-resolution domain for each wind turbine and one low-resolution domain at the farm level. The origin used by each instance of InflowWind is (0,0,0) for the low-resolution domain and (WT_X,WT_Y,WT_Z) for each high-resolution domain. The relationship between X and t as indicated in (2) is defined relative to the origin of each instance of InflowWind.

Best regards,

Dear @Jason.Jonkman

Many thanks for this answer. I am currently looking into this and I will provide an update soon.

Thank you again.

Dear @Jason.Jonkman

Following my query above, do you have an estimation of when the example of using the Mod_AmbWind = 3 option will become public?
Also, I tried to run my simulation using a single 2D non-turbulent, high-resolution TurbSim wind field with “UsableTime = ALL” to simulate steady conditions across the wind farm. The file seems to be working fine with NREL’s FastFarm r-test simulations.

However, when I run my simulation of the TotalControl wind farm, I get the error message attached below and it seems to be related to the turbine’s controller .dll file. The controller I am using for this simulation is the ROSCO controller which I manually compiled following the instructions provided in this link 1. Installing the ROSCO tools - ROSCO 2.8.0 documentation. A supercontroller is not used in this simulation.

I noticed that when I used the .dll file available in the FastFarm r-test simulations, “DISCON_WT1.dll”, the simulation seemed to run normally. Given that I am using NREL’s 10MW turbines for my simulation, whereas the FastFarm r-test simulations are using the 5MW turbine, can I still use the .dll files of the latter for my simulation?

Please note that I am using the “IEA-10.0-198-RWT_DISCON.IN” and “IEA-10.0-198-RWT_Cp_Ct_Cq.txt” files included in the 10MW turbine’s folder.

Thank you for the assistance

Kind regards



Hi Abdulabaset,

It looks like ROSCO is being loaded more than once. Are you running FAST.Farm with more than one turbine? Are they each calling the same ROSCO dll?

I believe, though not with 100% certainty, that each turbine in a wind farm simulation needs to call a separate ROSCO. You can simply copy the DLL and update the file path in ServoDyn. They can use the same DISCON.IN. The DLL does not depend on the specific turbine or DISCON.IN file.

If this is the issue, please let me know, so I can ensure that ROSCO returns a more helpful error message in the future.

Best, Dan

Dear @Abdulbaset.Alazhare,

To answer your question regarding an r-test example with Mod_AmbWind = 3, I don’t have an estimate at this time.

Best regards,

Thank you @Daniel.Zalkind and @Jason.Jonkman for the responses. Your assistance is highly appreciated.

Regarding the simulation, it uses 32 wind turbines, where each turbine is using the exact .fst file, therefore, they are all calling the same ROSCO .dll file.

What is confusing is that when the .dll file included in the r-test simulation is used in a way that all the turbines are calling the same .dll file, the simulation runs normally with no issues or warnings regarding the controller. However, if I use the .dll file which I compiled according to the instructions provided by NREL, I get the error attached in my original post.

It seems that there is a difference in the way some of the variables are defined in the public ROSCO source code and the source code of the .dll file included in the r-test, hence, the simulation is able to call the same r-test’s .dll (using the same .fst file for all turbines), while it gives an error if my compiled .dll file is called by more than one turbine.

Kind regards

Dear @Abdulbaset.Alazhare,

I would not expect the behavior you are describing. The FAST.Farm documentation states that unique controller DLLs in Bladed format must be used for each wind turbine when running multi-turbine simulations in FAST.Farm that make use of Bladed-style DLL controllers (4.2.15.4. Input Files — OpenFAST v3.5.0 documentation). This is true regardless of how the DLL is compiled.

Best regards,

Dear @Jason.Jonkman,

Thank you for the clarification.

Kind regards

Dear @Jason.Jonkman

I have a number of queries regarding generating high-resolution wind domains from a low-resolution domain, and this follows from my original post above. Throughout this process, I have encountered a few issues and I am still unsure of a few details which I am hoping that you would kindly clear up.

Initially , I generated a low-resolution wind field using TurbSim for the entire wind farm (Domain width and height are big enough to accommodate the wind farm). I then used a number of Python functions from the Python toolbox provided by NREL to,

  • Read the TurbSim.bts file.
  • Extract time-series at a (Y, X) coordinates close to one turbine’s hub.
  • Write out a .txt/.csv file of the obtained time series for a single node (nPoints = 1)

I understand that to generate a time-synchronized high-resolution box for each turbine, I need to use the “TIMESR” option in the TurbSim input file along with a time-synchronized time series of a point near the turbine’s hub.

  1. However, when I run TurbSim, I get a message that “A coherent turbulence time step file cannot be generated with the TIMESR model.” as shown in the screenshot below. Please note that TurbSim is still generating a high-resolution domain as it seems to be defaulting to some other turbulence model. Would you kindly assist with this?

  1. Time-series time-shift
    I understand that the extracted time series used for generating the high-resolution domain has to be shifted in time to reflect the turbine’s X-offset from the low-resolution domain’s origin using the formula (WT_X = V_advect * t) to calculate “t”, however, I am not sure of how exactly the time shifting procedure is done, neither have I found a function in the Python-toolbox to perform this.
    The way I understand this shifting process is explained with this example, one of the turbines in the wind farm is 500 m off the low-resolution domain’s origin (in the X direction), therefore, I would divide 594.366 by the low-resolution wind field advection speed (15 mps; obtained from TurbSim .bts file) which yields 33.333 s. Then I use this latter number to rearrange the time series data in the .csv file by shifting up all the velocity rows that start at the 33rd second (rounded down from 33.333) onwards to the top of the time series data while keeping the time column in the .csv file unchanged. Is this correct?

  2. Coordinates frame of reference for the node(s) referenced in the time-series file:
    I found the following explanation regarding the reference coordinate system in the .csv time series input file, “the inertial reference frame with origin at the ground level and the undisplaced tower centerline. “ in TurbSim’m manual. In this case, is the following reasoning true? assuming that the global location of the turbine in Y and Z is (y1, z1) and the global coordinates of the node nearest to the hub (found using a python function in NREL’s python toolbox) is (y2, z2), is it right to refer to that reference point as (y2 - y1 , z3) in the time series .csv file?

  3. Regarding the calculation DX_Low for the FastFarm domain, the recommended formula for this can be found on pg. 35 of FastFarm manual (shown in screenshot below),

However, in the Python toolbox (fastfarm.py), the value DX_Low is calculated using a different formula (screenshot below). The two methods give significantly different values so which formula do you recommend?

image

Input files

Time series “.csv” file:

TurbSim input file:

Hi Abdulbaset.Alazhare,

A much-improved version of tools to help you set up and run FAST.Farm cases is available in the dev branch here (link 1). There is a complete example here (link 2).

I wanted to note that all of the issues you described here will be taken care of automatically when using the tools linked above (including ROSCO’s multi dll needs, link 3). Small modification to conform to Window’s .dll from Unix .so will be necessary.

To your questions,

  1. To suppress that warning you can set WrACT to false

  2. The time shift is performed here (link 4) on the toolbox scripts. Your understanding is correct. Here is an illustration of a sanity check you can perform yourself. The arrow size represents the offset.

  3. That’s right. An example/comment is also documented in the toolbox here (link 5), with the code performing what you described following. Note that warnings are always printed to the screen when this shift happens.

  4. The equation you shared in the code and what we currently (link 6) have on the toolbox all match the recommendation from the modeling guidance (link 7, third equation under 4.2.15.6.3.1).

-Regis

Apologies for sending the links this way. I can only add two links per post.
Links:

  1. https://github.com/OpenFAST/python-toolbox/blob/dev/pyFAST/fastfarm/FASTFarmCaseCreation.py
  2. https://github.com/OpenFAST/python-toolbox/blob/dev/pyFAST/fastfarm/examples/Ex3_FFarmCompleteSetup.py
1 Like

Apologies for sending the links this way. I can only add two links per post.
Links:
3. https://github.com/OpenFAST/python-toolbox/blob/dev/pyFAST/fastfarm/FASTFarmCaseCreation.py#L954-L967
4. https://github.com/OpenFAST/python-toolbox/blob/dev/pyFAST/fastfarm/FASTFarmCaseCreation.py#L1357-L1364

(Having trouble with links; remove the space from the URL below)
5. github .com/OpenFAST/python-toolbox/blob/dev/pyFAST/fastfarm/FASTFarmCaseCreation.py#L1374-L1381
6. github .com/OpenFAST/python-toolbox/blob/dev/pyFAST/fastfarm/AMRWindSimulation.py#L272C13-L272C60
7. openfast .readthedocs.io/en/main/source/user/fast.farm/ModelGuidance.html

Dear @Regis.Thedin

Thank you very much for the explaination and the links, I highly appreciate your assistance and swift response.

Kind regards

Dear NREL
I had a similar problem with fastfarm. There are two main problems

  1. if fastfarm is using glued code to compute, is it possible to enable parallel computing? Or is parallel computing only possible in python?
  2. when using tursim.exe to generate a very large wind farm, it takes too long to compute, is it better to use python toolbox in this case?

Best regards,
Tianhui

Dear @Tianhui.Liu,

Here are my responses to your questions:

  1. Parallelization of FAST.Farm is feature of how the FAST.Farm executable is compiled; parallelization is independent from the use of Python as a pre-processing step.
  2. The Python Toolbox (now called the OpenFAST Toolbox) supports the use of Mod_AmbWind = 3 in FAST.Farm, which is generally what we recommend using when running FAST.Farm with TurbSim inflow, especially for moderately sized wind farms (10s of turbines or multiple rows/columns). For very large wind farms (100s of turbines), TurbSim may not be able to accurate generate the low-resolution domain and then we’d recommend using Mod_AmbWind = 1.

Best regards,

Dear Jason
Many thanks for your answer.
Another question from me is that when I use the FAST.Farm executable, the main input file that controls the fastffarm, the .fstf file, I couldn’t find a place where I can set up parallel calculations, or does the program automatically do parallel calculations based on the number of turbines?

Best regards,
Tianhui

Dear @Tianhui.Liu,

The parallelization of FAST.Farm is not set within the FAST.Farm input file. Rather, the parallelization of FAST.Farm is determined at compile time; that, is you can compile FAST.Farm in serial mode or with OpenMP parallelization. If you are using the precompiled executables for Windows provided by NREL, the executable of FAST.Farm with OpenMP parallelization is named FAST.Farm_x64_OMP.exe.

Best regards,

Dear @Jason.Jonkman
I want to know how to reduce the resolution of certain areas to 1m or lower in Turbsim. I hope to generate intensive grids in the underlying area, but I encountered an error prompt of “Segmentation Fault (Core Dumped)”. If I want to achieve this effect, what should I do in terms of code?
I sincerely hope to get your help

Best Regards,

Dear @Lei.Xue,

TurbSim currently requires the use of a uniform spatial discretization. Are you trying to change the TurbSim source code to support a nonuniform spatial discretization?

Best regards,