4.13.5. User-Defined Wind Fields
This section explains how to implement custom wind fields in InflowWind using WindType = 6.
4.13.5.1. Overview
The user-defined wind field feature allows developers to implement custom wind models by:
Defining a data structure to hold wind field parameters
Initializing that data structure from input files or parameters
Implementing a function to return wind velocities at any position and time
This is useful for:
Analytical wind models (e.g., vortex, wake models)
Custom wind profiles not available in standard formats
Coupling to external wind solvers
Real-time wind measurements from sensors
Research and development of new wind field representations
Important
After modifying the registry files (.txt files), you must rebuild the project
to regenerate the type definition files (*_Types.f90). The modifications to the
.txt files define the extended data structures, but they won’t be available
until after regeneration.
4.13.5.2. Implementation Steps
4.13.5.2.1. Step 1: Define Data Structure
Edit modules/inflowwind/src/IfW_FlowField.txt and add fields to UserFieldType:
typedef ^ UserFieldType ReKi RefHeight - - - "reference height; used to center the wind" meters
typedef ^ ^ IntKi NumDataLines - 0 - "number of data lines (for time-varying user wind)" -
typedef ^ ^ DbKi DTime : - - "time array for user-defined wind" seconds
typedef ^ ^ ReKi Data :: - - "user-defined wind data array [NumDataLines, NumDataColumns]" -
typedef ^ ^ CHARACTER(1024) FileName - - - "name of user wind file (if applicable)" -
Add any custom fields needed for your wind model implementation.
4.13.5.2.2. Step 2: Define Initialization Inputs
Edit modules/inflowwind/src/InflowWind_IO.txt and add fields to User_InitInputType:
typedef ^ User_InitInputType CHARACTER(1024) WindFileName - - - "name of file containing user-defined wind data (if applicable)" -
typedef ^ ^ ReKi RefHt - - - "reference height for user wind field" meters
typedef ^ ^ IntKi NumDataColumns - 0 - "number of data columns in user wind file (if applicable)" -
Add any parameters needed to initialize your wind model.
4.13.5.2.3. Step 3: Regenerate Type Files
After modifying the registry files, rebuild the project to regenerate type definitions. When using Visual Studio to build OpenFAST on Windows, the types files are automatically regenerated. When using CMake, run the following commands to enable generation of the types files.
cd build
cmake .. -DGENERATE_TYPES=ON
make
The build process automatically regenerates the *_Types.f90 files from the .txt registry files.
4.13.5.2.4. Step 4: Implement Initialization
Edit modules/inflowwind/src/InflowWind_IO.f90 and implement IfW_User_Init():
subroutine IfW_User_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg)
! Initialize UF%RefHeight, read data files, allocate arrays
! Set FileDat metadata (wind type, time range, spatial extent, etc.)
! Write summary information to SumFileUnit if > 0
end subroutine
This routine:
Reads any necessary input files specified in
InitInpAllocates and populates the
UserFieldType(UF) data structureSets appropriate metadata in the
WindFileDatstructureWrites initialization information to the summary file
4.13.5.2.5. Step 5: Implement Velocity Function
Edit modules/inflowwind/src/IfW_FlowField.f90 and implement UserField_GetVel():
subroutine UserField_GetVel(UF, Time, Position, Velocity, ErrStat, ErrMsg)
! Use UF data to compute velocity at Position and Time
! Position(1) = X, Position(2) = Y, Position(3) = Z (meters)
! Return Velocity(1) = U, Velocity(2) = V, Velocity(3) = W (m/s)
end subroutine
This function is called for each position where wind velocities are needed during simulation.
4.13.5.3. Coordinate Systems
4.13.5.3.1. Input Coordinates (Position)
X: Downstream direction (after rotation applied by InflowWind)
Y: Lateral/crosswind direction
Z: Vertical direction (measured from ground, Z=0 is ground level)
Units: meters
4.13.5.3.2. Output Velocities (Velocity)
U: Velocity component along X (positive = downwind)
V: Velocity component along Y (positive = to the left when looking downwind)
W: Velocity component along Z (positive = upward)
Units: m/s
Note
InflowWind handles the rotation between global coordinates and wind coordinates. Your implementation should work in the wind coordinate system where X is aligned with the mean wind direction.
4.13.5.4. Example Implementation
4.13.5.4.1. Power-Law Wind Profile
This example implements a simple power-law wind profile.
Velocity Function (in IfW_FlowField.f90):
subroutine UserField_GetVel(UF, Time, Position, Velocity, ErrStat, ErrMsg)
type(UserFieldType), intent(in) :: UF
real(DbKi), intent(in) :: Time
real(ReKi), intent(in) :: Position(3)
real(ReKi), intent(out) :: Velocity(3)
integer(IntKi), intent(out) :: ErrStat
character(*), intent(out) :: ErrMsg
real(ReKi) :: RefSpeed, Exponent, Height
ErrStat = ErrID_None
ErrMsg = ""
! Get reference speed and exponent from UF%Data
RefSpeed = UF%Data(1, 1) ! Reference wind speed (m/s)
Exponent = UF%Data(1, 2) ! Power law exponent
Height = Position(3) ! Height above ground
! Apply power law: U(z) = Uref * (z/zref)^alpha
if (Height > 0.0_ReKi) then
Velocity(1) = RefSpeed * (Height / UF%RefHeight)**Exponent
Velocity(2) = 0.0_ReKi ! No lateral wind
Velocity(3) = 0.0_ReKi ! No vertical wind
else
Velocity = 0.0_ReKi ! Below ground
end if
end subroutine
Initialization (in InflowWind_IO.f90):
subroutine IfW_User_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg)
! ... (declarations)
ErrStat = ErrID_None
ErrMsg = ""
! Set reference height
UF%RefHeight = InitInp%RefHt
! Allocate data array for [RefSpeed, Exponent]
UF%NumDataLines = 1
call AllocAry(UF%Data, 1, 2, 'User wind data', TmpErrStat, TmpErrMsg)
call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName)
if (ErrStat >= AbortErrLev) return
! Set values (could read from file instead)
UF%Data(1, 1) = 10.0_ReKi ! 10 m/s reference speed
UF%Data(1, 2) = 0.2_ReKi ! Power law exponent
! Set metadata
FileDat%WindType = 6
FileDat%RefHt = UF%RefHeight
FileDat%MWS = UF%Data(1, 1)
FileDat%RefHt_Set = .true.
! ... (set other FileDat fields as needed)
end subroutine
4.13.5.5. Common Use Cases
4.13.5.5.1. Steady Analytical Wind Field
Define wind as a function of position only (ignore Time parameter).
Example: Logarithmic wind profile, vortex wind field, uniform flow with shear.
4.13.5.5.2. Time-Varying Wind Field
Store wind data in time series arrays and interpolate based on Time parameter.
Example: Measured wind data, prescribed wind transients, wake models.
4.13.5.5.3. Wind from External Solver
Call external functions to get instantaneous wind fields.
Example: CFD coupling, external wake models, prescribed turbulence.
4.13.5.5.4. Real-Time Sensor Data
Load measured wind data from sensors and interpolate spatially/temporally.
Example: LIDAR measurements, met mast data, field measurements.
4.13.5.6. Limitations and Considerations
4.13.5.6.1. Current Limitations
No Acceleration Support: User-defined wind fields do not currently support acceleration calculations needed by some modules (e.g., MHK turbines).
4.13.5.6.2. Performance Considerations
UserField_GetVel()is called for every point at every time stepImplement efficiently; pre-compute values in
IfW_User_Init()when possibleConsider caching or interpolation strategies for complex calculations
4.13.5.6.3. Error Handling
Always validate input parameters in
IfW_User_Init()Check array bounds in
UserField_GetVel()Verify Position and Time values are within valid ranges
Use
SetErrStat()to report errors appropriately
4.13.5.7. Best Practices
Start Simple: Begin with analytical models before implementing complex wind fields
Document Thoroughly: Add detailed comments explaining your implementation and any file formats
Use SI Units: Always use meters, seconds, and m/s
Pre-compute: Calculate as much as possible during initialization rather than runtime
Validate: Test with known analytical solutions before using in production
Handle Boundaries: Implement appropriate behavior for points outside valid domain
Report Metadata: Properly populate
WindFileDatwith time range, spatial extent, etc.
4.13.5.8. File Locations
File |
Purpose |
|---|---|
|
Source code directory |
|
Type definitions for flow field data structures |
|
Type definitions for initialization inputs |
|
Flow field implementation ( |
|
Initialization implementation ( |
|
Auto-generated type definitions (regenerated from .txt) |
|
Auto-generated type definitions (regenerated from .txt) |
4.13.5.9. Additional Resources
See the original
InflowWind Manualfor general InflowWind informationReview existing wind field implementations (Uniform, Grid3D) in the source code for reference
Check Appendix for example input files
Refer to NWTC Library documentation for array allocation and error handling utilities
See Angles Specified in InflowWind for information about wind coordinate systems and rotations