Skip to content

Commit ee352bf

Browse files
committed
Generated some documentation, reviewed it, everything looks right
1 parent 98c8d0e commit ee352bf

File tree

10 files changed

+790
-12
lines changed

10 files changed

+790
-12
lines changed

docs/source/user/inflowwind/appendix.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ turbulence files from Bladed.
3232

3333
This file includes lines that define uniform (deterministic) wind data files.
3434

35+
5) User-Defined Wind Input Files
36+
37+
- :download:`InflowWind input file for user-defined wind <examples/inflowwind_user_example.dat>`
38+
- :download:`Driver input file for testing user-defined wind <examples/inflowwind_driver_user_example.inp>`
39+
- :download:`Test points file <examples/user_wind_points.txt>`
40+
41+
These files demonstrate how to set up and test user-defined wind fields (WindType = 6).
42+
See :ref:`ifw_user_defined` for detailed implementation instructions.
43+
3544

3645
.. _ifw_output_channels:
3746

docs/source/user/inflowwind/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ InflowWind Users Guide and Theory Manual
1919

2020
driver.rst
2121
input.rst
22+
user_defined.rst
2223
appendix.rst
Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
.. _ifw_user_defined:
2+
3+
User-Defined Wind Fields
4+
=========================
5+
6+
This section explains how to implement custom wind fields in InflowWind using ``WindType = 6``.
7+
8+
Overview
9+
--------
10+
11+
The user-defined wind field feature allows developers to implement custom wind models by:
12+
13+
1. Defining a data structure to hold wind field parameters
14+
2. Initializing that data structure from input files or parameters
15+
3. Implementing a function to return wind velocities at any position and time
16+
17+
This is useful for:
18+
19+
- Analytical wind models (e.g., vortex, wake models)
20+
- Custom wind profiles not available in standard formats
21+
- Coupling to external wind solvers
22+
- Real-time wind measurements from sensors
23+
- Research and development of new wind field representations
24+
25+
.. important::
26+
After modifying the registry files (``.txt`` files), you must rebuild the project
27+
to regenerate the type definition files (``*_Types.f90``). The modifications to the
28+
``.txt`` files define the extended data structures, but they won't be available
29+
until after regeneration.
30+
31+
Implementation Steps
32+
--------------------
33+
34+
Step 1: Define Data Structure
35+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
36+
37+
Edit ``modules/inflowwind/src/IfW_FlowField.txt`` and add fields to ``UserFieldType``:
38+
39+
.. code-block:: text
40+
41+
typedef ^ UserFieldType ReKi RefHeight - - - "reference height; used to center the wind" meters
42+
typedef ^ ^ IntKi NumDataLines - 0 - "number of data lines (for time-varying user wind)" -
43+
typedef ^ ^ DbKi DTime : - - "time array for user-defined wind" seconds
44+
typedef ^ ^ ReKi Data :: - - "user-defined wind data array [NumDataLines, NumDataColumns]" -
45+
typedef ^ ^ CHARACTER(1024) FileName - - - "name of user wind file (if applicable)" -
46+
47+
Add any custom fields needed for your wind model implementation.
48+
49+
Step 2: Define Initialization Inputs
50+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
51+
52+
Edit ``modules/inflowwind/src/InflowWind_IO.txt`` and add fields to ``User_InitInputType``:
53+
54+
.. code-block:: text
55+
56+
typedef ^ User_InitInputType CHARACTER(1024) WindFileName - - - "name of file containing user-defined wind data (if applicable)" -
57+
typedef ^ ^ ReKi RefHt - - - "reference height for user wind field" meters
58+
typedef ^ ^ IntKi NumDataColumns - 0 - "number of data columns in user wind file (if applicable)" -
59+
60+
Add any parameters needed to initialize your wind model.
61+
62+
Step 3: Regenerate Type Files
63+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64+
65+
After modifying the registry files, rebuild the project to regenerate type definitions:
66+
67+
.. code-block:: bash
68+
69+
cd build
70+
cmake ..
71+
make
72+
73+
The build process automatically regenerates the ``*_Types.f90`` files from the ``.txt`` registry files.
74+
75+
Step 4: Implement Initialization
76+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77+
78+
Edit ``modules/inflowwind/src/InflowWind_IO.f90`` and implement ``IfW_User_Init()``:
79+
80+
.. code-block:: fortran
81+
82+
subroutine IfW_User_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg)
83+
! Initialize UF%RefHeight, read data files, allocate arrays
84+
! Set FileDat metadata (wind type, time range, spatial extent, etc.)
85+
! Write summary information to SumFileUnit if > 0
86+
end subroutine
87+
88+
This routine:
89+
90+
- Reads any necessary input files specified in ``InitInp``
91+
- Allocates and populates the ``UserFieldType`` (``UF``) data structure
92+
- Sets appropriate metadata in the ``WindFileDat`` structure
93+
- Writes initialization information to the summary file
94+
95+
Step 5: Implement Velocity Function
96+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97+
98+
Edit ``modules/inflowwind/src/IfW_FlowField.f90`` and implement ``UserField_GetVel()``:
99+
100+
.. code-block:: fortran
101+
102+
subroutine UserField_GetVel(UF, Time, Position, Velocity, ErrStat, ErrMsg)
103+
! Use UF data to compute velocity at Position and Time
104+
! Position(1) = X, Position(2) = Y, Position(3) = Z (meters)
105+
! Return Velocity(1) = U, Velocity(2) = V, Velocity(3) = W (m/s)
106+
end subroutine
107+
108+
This function is called for each position where wind velocities are needed during simulation.
109+
110+
Coordinate Systems
111+
------------------
112+
113+
Input Coordinates (Position)
114+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115+
116+
- **X**: Downstream direction (after rotation applied by InflowWind)
117+
- **Y**: Lateral/crosswind direction
118+
- **Z**: Vertical direction (measured from ground, Z=0 is ground level)
119+
- **Units**: meters
120+
121+
Output Velocities (Velocity)
122+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123+
124+
- **U**: Velocity component along X (positive = downwind)
125+
- **V**: Velocity component along Y (positive = to the left when looking downwind)
126+
- **W**: Velocity component along Z (positive = upward)
127+
- **Units**: m/s
128+
129+
.. note::
130+
InflowWind handles the rotation between global coordinates and wind coordinates.
131+
Your implementation should work in the wind coordinate system where X is aligned
132+
with the mean wind direction.
133+
134+
Example Implementation
135+
----------------------
136+
137+
Power-Law Wind Profile
138+
~~~~~~~~~~~~~~~~~~~~~~
139+
140+
This example implements a simple power-law wind profile.
141+
142+
**Velocity Function** (in ``IfW_FlowField.f90``):
143+
144+
.. code-block:: fortran
145+
146+
subroutine UserField_GetVel(UF, Time, Position, Velocity, ErrStat, ErrMsg)
147+
type(UserFieldType), intent(in) :: UF
148+
real(DbKi), intent(in) :: Time
149+
real(ReKi), intent(in) :: Position(3)
150+
real(ReKi), intent(out) :: Velocity(3)
151+
integer(IntKi), intent(out) :: ErrStat
152+
character(*), intent(out) :: ErrMsg
153+
154+
real(ReKi) :: RefSpeed, Exponent, Height
155+
156+
ErrStat = ErrID_None
157+
ErrMsg = ""
158+
159+
! Get reference speed and exponent from UF%Data
160+
RefSpeed = UF%Data(1, 1) ! Reference wind speed (m/s)
161+
Exponent = UF%Data(1, 2) ! Power law exponent
162+
Height = Position(3) ! Height above ground
163+
164+
! Apply power law: U(z) = Uref * (z/zref)^alpha
165+
if (Height > 0.0_ReKi) then
166+
Velocity(1) = RefSpeed * (Height / UF%RefHeight)**Exponent
167+
Velocity(2) = 0.0_ReKi ! No lateral wind
168+
Velocity(3) = 0.0_ReKi ! No vertical wind
169+
else
170+
Velocity = 0.0_ReKi ! Below ground
171+
end if
172+
173+
end subroutine
174+
175+
**Initialization** (in ``InflowWind_IO.f90``):
176+
177+
.. code-block:: fortran
178+
179+
subroutine IfW_User_Init(InitInp, SumFileUnit, UF, FileDat, ErrStat, ErrMsg)
180+
! ... (declarations)
181+
182+
ErrStat = ErrID_None
183+
ErrMsg = ""
184+
185+
! Set reference height
186+
UF%RefHeight = InitInp%RefHt
187+
188+
! Allocate data array for [RefSpeed, Exponent]
189+
UF%NumDataLines = 1
190+
call AllocAry(UF%Data, 1, 2, 'User wind data', TmpErrStat, TmpErrMsg)
191+
call SetErrStat(TmpErrStat, TmpErrMsg, ErrStat, ErrMsg, RoutineName)
192+
if (ErrStat >= AbortErrLev) return
193+
194+
! Set values (could read from file instead)
195+
UF%Data(1, 1) = 10.0_ReKi ! 10 m/s reference speed
196+
UF%Data(1, 2) = 0.2_ReKi ! Power law exponent
197+
198+
! Set metadata
199+
FileDat%WindType = 6
200+
FileDat%RefHt = UF%RefHeight
201+
FileDat%MWS = UF%Data(1, 1)
202+
FileDat%RefHt_Set = .true.
203+
! ... (set other FileDat fields as needed)
204+
205+
end subroutine
206+
207+
Common Use Cases
208+
----------------
209+
210+
Steady Analytical Wind Field
211+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212+
213+
Define wind as a function of position only (ignore ``Time`` parameter).
214+
215+
**Example**: Logarithmic wind profile, vortex wind field, uniform flow with shear.
216+
217+
Time-Varying Wind Field
218+
~~~~~~~~~~~~~~~~~~~~~~~
219+
220+
Store wind data in time series arrays and interpolate based on ``Time`` parameter.
221+
222+
**Example**: Measured wind data, prescribed wind transients, wake models.
223+
224+
Wind from External Solver
225+
~~~~~~~~~~~~~~~~~~~~~~~~~~
226+
227+
Call external functions or read shared memory to get instantaneous wind fields.
228+
229+
**Example**: CFD coupling, external wake models, prescribed turbulence.
230+
231+
Real-Time Sensor Data
232+
~~~~~~~~~~~~~~~~~~~~~
233+
234+
Load measured wind data from sensors and interpolate spatially/temporally.
235+
236+
**Example**: LIDAR measurements, met mast data, field measurements.
237+
238+
Limitations and Considerations
239+
-------------------------------
240+
241+
Current Limitations
242+
~~~~~~~~~~~~~~~~~~~
243+
244+
1. **No Acceleration Support**: User-defined wind fields do not currently support
245+
acceleration calculations needed by some modules (e.g., MHK turbines).
246+
247+
2. **No Persistence**: Data must be recalculated if simulation is restarted.
248+
249+
Performance Considerations
250+
~~~~~~~~~~~~~~~~~~~~~~~~~~
251+
252+
- ``UserField_GetVel()`` is called for every point at every time step
253+
- Implement efficiently; pre-compute values in ``IfW_User_Init()`` when possible
254+
- Consider caching or interpolation strategies for complex calculations
255+
256+
Error Handling
257+
~~~~~~~~~~~~~~
258+
259+
- Always validate input parameters in ``IfW_User_Init()``
260+
- Check array bounds in ``UserField_GetVel()``
261+
- Verify Position and Time values are within valid ranges
262+
- Use ``SetErrStat()`` to report errors appropriately
263+
264+
Best Practices
265+
--------------
266+
267+
1. **Start Simple**: Begin with analytical models before implementing complex wind fields
268+
269+
2. **Document Thoroughly**: Add detailed comments explaining your implementation and any file formats
270+
271+
3. **Use SI Units**: Always use meters, seconds, and m/s
272+
273+
4. **Pre-compute**: Calculate as much as possible during initialization rather than runtime
274+
275+
5. **Validate**: Test with known analytical solutions before using in production
276+
277+
6. **Handle Boundaries**: Implement appropriate behavior for points outside valid domain
278+
279+
7. **Report Metadata**: Properly populate ``WindFileDat`` with time range, spatial extent, etc.
280+
281+
File Locations
282+
--------------
283+
284+
========================================== ==========================================================
285+
File Purpose
286+
========================================== ==========================================================
287+
``modules/inflowwind/src/`` Source code directory
288+
``IfW_FlowField.txt`` Type definitions for flow field data structures
289+
``InflowWind_IO.txt`` Type definitions for initialization inputs
290+
``IfW_FlowField.f90`` Flow field implementation (``UserField_GetVel()``)
291+
``InflowWind_IO.f90`` Initialization implementation (``IfW_User_Init()``)
292+
``IfW_FlowField_Types.f90`` Auto-generated type definitions (regenerated from .txt)
293+
``InflowWind_IO_Types.f90`` Auto-generated type definitions (regenerated from .txt)
294+
========================================== ==========================================================
295+
296+
Additional Resources
297+
--------------------
298+
299+
- See the original :download:`InflowWind Manual <InflowWind_Manual.pdf>` for general InflowWind information
300+
- Review existing wind field implementations (Uniform, Grid3D) in the source code for reference
301+
- Check :ref:`ifw_appendix` for example input files
302+
- Refer to NWTC Library documentation for array allocation and error handling utilities
303+
- See :ref:`ifw_angles` for information about wind coordinate systems and rotations

0 commit comments

Comments
 (0)