OpenFAST / openfast

Main repository for the NREL-supported OpenFAST whole-turbine and FAST.Farm wind farm simulation codes.
http://openfast.readthedocs.io
Apache License 2.0
690 stars 457 forks source link

Feature request: specify smaller VTK slice in FAST.Farm output #2383

Open andrew-platt opened 2 months ago

andrew-platt commented 2 months ago

FAST.Farm can output slices of the low resolution grid. When a very large farm is modeled, a single slice may be very large compared to the region of actual interest.

Describe the solution you'd like In addition to the current slice outputs, add the ability to read a custom slice file with different reduced grids. For example, if we have a low res grid with XY extents of [-1500:3000, -2000:2000] and wanted to look at VTK slices only around a specific turbine (number 137 and 139 in this example) located at [2000,1400] and [1850,1225], a smaller sampling volume around those turbine could be specified of only 1000 m x 600 m for the VTK slicing. Perhaps this could be specified

!------- VTK Box volumes --------
1      NumVTKvolBoxes - number of VTK volume boxes for extracting slices (-)
BoxName    X0    X1      Y0    Y1      Z0    Z1
(-)        (m)   (m)     (m)   (m)     (m)   (m)
T137      1800  2800    1100  1700     "default" "default"         ! Default on Z for full extent of height
T139      1650  2650     925  1525     "default" "default"         ! Default on Z for full extent of height
!------- Slices ---------------
5      NumSlices - total number of slices across all custom boxes (-)
BoxName    SliceDir    Loc
(-)        (-)         (m)
T137       YZ          *200            ! "*" for relative to X0
T137       YZ          2000            ! absolute plane position
T137       XY          80                ! at 80m height
T137       XZ          *200            ! at 200 m relative to Y0
T137       XZ          1400            ! absolute location of Y slice
T139       YZ          *200             ! same offset as first slice from Box T137
T139       XZ          *200             ! same offset as slice 4 from Box T137

The above might live in a separate file specified in the Visualization section.

Describe alternatives you've considered An alternative approach could be to include the extents into the plane location itself. Example:

87.6          OutDisWindZ   - Z coordinates of XY planes for output of disturbed wind data across the low-resolution domain (m) [1 to NOutDisWindXY] [unused for NOutDisWindXY=0]
2             NOutDisWindYZ - Number of YZ planes for output of disturbed wind data across the low-resolution domain to <RootName>/Low.DisYZ<n_out>.t<n>.vtk (-) [0 to 99]
10.0[-300:300], 640.0[-200:400]    OutDisWindX   - X coordinates of YZ planes for output of disturbed wind data across the low-resolution domain (m) [1 to NOutDisWindYZ] [unused for NOutDisWindYZ=0] {Append [<Y0lim>:<Y1lim>] to distance to truncate in Y direction bounds at user specified bounds of <Y0lim> and <Y1lim>}

where the [-300:300] indicates to truncate the box Y dimensions (don't allow in Z). This would be rather clumsy to specify and tricky to implement into a reasonable parser. It could also be really clumsy for an XY plane to specify [<X0lim>:<X1lim>; <Y0lim>:<Y1lim>]

Additional context This was never really an issue until we started modeling large farms with 150 or more turbines spread out over very large areas. So this may not be an issue that most casual users face, but I expect more industry users will find this modification useful.

@rthedin, any thoughts on this method? Or suggestions based on AMR-Wind?

hgopalan commented 2 months ago

Will it be possible to provide a cloud of points to FF and get the outputs at those locations as CSV or VTKPoints ? When we have a terrain, we will not have a perfect plane. However, we can move the terrain points upwards to the location of interest.

andrew-platt commented 2 months ago

@hgopalan, I hadn't considered doing a point cloud, but it would not be difficult to add as an option.

rthedin commented 2 months ago

I had some conversations with Andy and here are some of my thoughts. I have a strong preference for the approach described in the first method. The second will be hard to setup in a manual way without errors, which might affect some users. It is also very hard to read and double check some large scenarios.

Regarding the first method, I like how clean it is. I think it would be nice to have slices de-coupled from boxes, though. I don't see an immediate need for full 3-D boxes, especially when those can be achieved with lots of stacked planes. How about merging the two?

Another detail is that I think we should move towards allowing the user to specify any arbitrary slice in the domain, and not necessary aligned with the Cartesian axes. I also think it would be nice (not essential) to have an offset parameter for those slices that are aligned (think of sampling behind a turbine at x diameters downstream).

Here's what I'm thinking, drawing inspiration from amrwind and openfoam. To make sense of the numbers I'm using, consider two turbines with rotors at (0,0,150) and (500,0,150). Both suggestions sample the very same planes.

One option is to let the user define the center of the slice, its normal, and then the extent in each direction:

!------- Slices ---------------
6      NumSlices - total number of slices across all custom boxes (-)
SliceName    center         normal    extent1  extent2  extent3
  (-)          (m)           (-)        (m)      (m)      (-)
T1_0D      (0    0  200)   (1 0 0)       0       600      400  # 600x400 YZ slice at the rotor plane
T1_1D      (240  0  200)   (1 0 0)       0       600      400  # 600x400 YZ slice at 240 downstream the rotor plane
T2_0D      (0    0  200)   (1 0 0)       0       600      400  # 600x400 YZ slice at the rotor plane
T2_1D      (240  0  200)   (1 0 0)       0       600      400  # 600x400 YZ slice at 240 downstream the rotor plane
T2_2D      (480  0  200)   (1 0 0)       0       600      400  # 600x400 YZ slice at 480 downstream the rotor plane
cross      (300  0  250)   (0 1 0)     1000       0       500  # 1000x500 XZ slice through both turbines

Another option is more generic and similar to AMR-Wind, where the user specifies the origin and the two axis of the plane in vector form (such that the normal is implied).

!------- Slices ---------------
6      NumSlices - total number of slices across all custom boxes (-)
SliceName     origin        axis1        axis2      offset     offset_normal
  (-)          (m)           (m)          (m)        (m)           (-)
T1_0D      (0   -300 0)   (600 0 0)    (0 0 400)   "default"    "default"  # 600x400 YZ slice at the rotor plane
T1_1D      (240 -300 0)   (600 0 0)    (0 0 400)   "default"    "default"  # 600x400 YZ slice at 240 downstream the rotor plane
T2         (500 -300 0)   (600 0 0)    (0 0 400)   0, 240, 480   (1 0 0)   # Three 600x400 YZ slices at 0, 240, and 480 m downstream (in the x-direction sense)
cross     (-200  0   0)   (0 1000 0)   (0 0 500)   "default"    "default"  # 1000x500 XZ slice through both turbines

Some comments:

rthedin commented 2 months ago

And regarding a cloud of points, I think it would be good to have the ability to pass a file with the desired points. The main use case I see for this is terrain-following slices. Maybe something like this?

!------- Slices ---------------
6      NumSlices - total number of slices across all custom boxes (-)
SliceName    offset       offset_normal  cloud_file
  (-)          (m)           (-)          (-)
terr       100 200 300     (0 0 1)      "elevation.txt"

where elevation.txt something simple like this:

<p1_x> <p1_y> <p1_z>
<p2_x> <p2_y> <p2_z>
...
<pN_x> <pN_y> <pN_z>

This would create 3 slices at 100, 200, and 300 m above the terrain elevation given in elevation.txt. This could also potentially be a csv file.