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
695 stars 459 forks source link

Bug report: Cholesky error in TurbSim API turbulence model #386

Open arodriguezluis opened 4 years ago

arodriguezluis commented 4 years ago

Bug description

The bug found is in relation with the Cholesky error that sometimes is displayed when we run the API model on the TurbSim:

_CalcFourierCoeffs:CalcFourierCoeffs_API: Error in Cholesky factorization: LAPACKSPPTRF: Leading minor order 21 of A is not positive definite, so Cholesky factorization could not be completed. The error occurred in the u-component coherence matrix at frequency 1 (2.63158E-04 Hz). Check the input file for invalid physical properties or modify the coherence. Aborting TurbSim.

We have been doing some tests and it looks like the error comes out when the Coh matrix (shown in the expression below) is big in size and it has many elements close to 1.

coh

This happens specially when:

We found that the reason for the first three points above returning an error is that when the “LAPACK_SPPTRF” subroutine computes the determinant of the matrix, it is below the machine precision (although it should not be zero). This is because all elements are close to one.

We believe that this error may also appear in other models if the spatial coherence matrix is built in a similar way (https://wind.nrel.gov/forum/wind/viewtopic.php?f=4&t=1766).

To reproduce the bug:

Our compilation on linux was based on the file 'compiling/makefile' found individual TurbSim repository (https://github.com/old-NWTC/TurbSim), but we used the latest openFAST Turbsim module source code instead. To get the error, for example, run a case with input: TurbSim.zip

mhank commented 3 years ago

So how could we eliminate that error from happening again? Since most turbulence cases require high wind speeds

bjonkman commented 3 years ago

Are you having an issue with a particular model? I believe "high" is somewhat relative here, and it's usually a combination of things that cause the coherence matrix to not be positive definite.

arodriguezluis commented 3 years ago

I implemented my own approximation to avoid (not fully solve) this problem. On TSsubs.f90, subroutine _CalcFourierCoeffsAPI, I added a previous loop over the frequencies to find the minimum frequency for which the coherence matrix was positive definite. Then, on the original loop, I imposed the frequencies to be equal or larger than this minimum frequency. This introduces some error for the low frequency coherence matrices, but the code works, and, since the really low frequencies do not have an important role in the wind spectrum, the introduced error should not be significative. I also printed the minimum frequency to check that it was in fact among the smaller frequencies. Find the modified function below (see the new loop below comment line "! Compute minumum allowed freq" and note the use of the new variable _minfreq), hope this helps!

!=======================================================================
!> This subroutine returns the complex Fourier coefficients (packed in a
!! real array) of the simulated velocity (wind/water speed). It returns
!! values FOR ONLY the velocity components that use the API method for
!! computing spatial coherence; i.e., for i where SCMod(i) == CohMod_API
SUBROUTINE CalcFourierCoeffs_API( p, U, PhaseAngles, S, V, TRH, ErrStat, ErrMsg )

IMPLICIT                      NONE

   ! Passed variables
TYPE(TurbSim_ParameterType), INTENT(IN   )  :: p                            !< TurbSim parameters
REAL(ReKi),                  INTENT(IN   )  :: U           (:)              !< The steady u-component wind speeds for the grid (NPoints).
REAL(ReKi),                  INTENT(IN   )  :: PhaseAngles (:,:,:)          !< The array that holds the phase angles [number of points, number of frequencies, number of wind components=3].
REAL(ReKi),                  INTENT(IN   )  :: S           (:,:,:)          !< The turbulence PSD array (NumFreq,NPoints,3).
REAL(ReKi),                  INTENT(INOUT)  :: V           (:,:,:)          !< An array containing the summations of the rows of H (NumSteps,NPoints,3).
REAL(ReKi),                  INTENT(INOUT)  :: TRH (:)                      !< The transfer function matrix.  just used as a work array
INTEGER(IntKi),              INTENT(  OUT)  :: ErrStat
CHARACTER(*),                INTENT(  OUT)  :: ErrMsg

   ! Internal variables

REAL(ReKi), ALLOCATABLE      :: Dist_Y(:)        ! The Y distance between points
REAL(ReKi), ALLOCATABLE      :: Dist_Z(:)        ! The Z distance between points
REAL(ReKi), ALLOCATABLE      :: z_g(:)           ! sqrt( Z(IZ)*Z(JZ) ) / H

INTEGER                      :: J
INTEGER                      :: I
INTEGER                      :: K
INTEGER                      :: IFreq
INTEGER                      :: Indx
INTEGER                      :: IVec            ! wind component, 1=u, 2=v, 3=w

INTEGER                      :: UC             ! I/O unit for Coherence debugging file.
LOGICAL,    PARAMETER        :: COH_OUT   = .FALSE.                       ! This parameter has been added to replace the NON-STANDARD compiler directive previously used

INTEGER(IntKi)                :: ErrStat2
CHARACTER(MaxMsgLen)          :: ErrMsg2

INTEGER(IntKi)                :: ErrStat3
CHARACTER(MaxMsgLen)          :: ErrMsg3

REAL, PARAMETER :: Qc(3)     = (/ 1.00, 1.00, 1.25 /)
REAL, PARAMETER :: Pc(3)     = (/ 0.40, 0.40, 0.50 /)
REAL, PARAMETER :: Rc(3)     = (/ 0.92, 0.92, 0.85 /)
REAL, PARAMETER :: Alpha(3) = (/ 2.9 ,45.0 ,13.0  /)

REAL, PARAMETER :: H             = 10. ! Reference height
REAL, PARAMETER :: Coef_1      =   1.0 !3.28

REAL :: A_Y, A_Z

INTEGER :: flag_min_freq, IFreq2
REAL :: min_freq

   ! initialize variables
   ErrStat = ErrID_None
   ErrMsg  = ""
   UC      = -1

   flag_min_freq = 0
   min_freq = p%grid%Freq(1)

   IF (.NOT. ANY(p%met%SCMod == CohMod_API) ) RETURN

   !--------------------------------------------------------------------------------
   ! allocate arrays
   !--------------------------------------------------------------------------------

   CALL AllocAry( Dist_Y,    p%grid%NPacked, 'Dist_Y coherence array', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CalcFourierCoeffs_API')
   CALL AllocAry( Dist_Z,    p%grid%NPacked, 'Dist_Z coherence array', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CalcFourierCoeffs_API')
   !CALL AllocAry( Dist_Z12, p%grid%NPacked, 'Dist_Z12 coherence array', ErrStat2, ErrMsg2); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CalcFourierCoeffs_API')
   CALL AllocAry( z_g,       p%grid%NPacked, 'z_g coherence array', ErrStat2, ErrMsg2 ); CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CalcFourierCoeffs_API')
   IF (ErrStat >= AbortErrLev) THEN
      CALL Cleanup()
      RETURN
   END IF

   !--------------------------------------------------------------------------------
   ! Calculate the distances and other parameters that don't change with frequency
   !---------------------------------------------------------------------------------

   Indx=0
   DO J=1,p%grid%NPoints
      DO I=J,p%grid%NPoints  ! The coherence matrix is symmetric so we're going to skip the other side 
         Indx = Indx + 1      ! Indx = p%grid%NPoints*(J - 1) - J*(J - 1)/2 + I   !Index of packed V matrix, coherence between points I & J

         Dist_Y(Indx)= ABS( p%grid%Y(I) - p%grid%Y(J) )
         Dist_Z(Indx)= ABS( p%grid%Z(I) - p%grid%Z(J) )
         z_g(Indx)  = sqrt( p%grid%Z(I) * p%grid%Z(J) ) / H

      END DO
   END DO

   !.................
   ! DEBUGGING
   !.................
IF ( COH_OUT ) THEN !debugging info...

      ! Write the coherence for three frequencies, for debugging purposes
      CALL GetNewUnit( UC, ErrStat2, ErrMsg2 );  CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CalcFourierCoeffs_API')

      CALL OpenFOutFile( UC, TRIM(p%RootName)//'.coh', ErrStat2, ErrMsg2 )
         CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CalcFourierCoeffs_API')
         IF (ErrStat >= AbortErrLev) THEN
            CALL Cleanup()
            RETURN
         END IF

      WRITE( UC, '(A4,X,A16,1X,'//Num2LSTR(p%grid%NPacked)//'(G10.4,1X))' ) 'Comp','Freq',(I,I=1,p%grid%NPacked)
      WRITE( UC,   '(5X,A16,1X,'//Num2LSTR(p%grid%NPacked)//'(G10.4,1X))' ) 'Distance_Y',   Dist_Y(:)
      WRITE( UC,   '(5X,A16,1X,'//Num2LSTR(p%grid%NPacked)//'(G10.4,1X))' ) 'Distance_Z', Dist_Z(:)
      WRITE( UC,   '(5X,A16,1X,'//Num2LSTR(p%grid%NPacked)//'(G10.4,1X))' ) 'sqrt(Z(IZ)*Z(JZ))/H', z_g(:)
ENDIF

   !--------------------------------------------------------------------------------
   ! Calculate the fourier coefficients
   !---------------------------------------------------------------------------------

   DO IVec = 1,1 !BJJ: note that only the u component is defined, and I don't want to look at how to change the coherence in the other components....

      IF (p%met%SCMod(IVec) /= CohMod_API) CYCLE ! Check the next component (this one doesn't use the API method)

      CALL WrScr ( '    '//Comp(IVec)//'-component matrices (2-dimensional API coherence method)' )

   !--------------------------------------------------------------------------------
   ! Calculate the coherence, Veers' H matrix (CSDs), and the fourier coefficients
   !---------------------------------------------------------------------------------

      ! -----------------------------------------------
      ! Compute minumum allowed freq
      ! -----------------------------------------------
      IFreq2 = 1

      DO WHILE (flag_min_freq.eq.0)

          Indx = 1
          DO J = 1,p%usr%NPoints-1 ! start with user-defined points (which don't get added coherence)

             TRH(Indx) =  1.0_ReKi
             Indx = Indx + 1

             DO I=J+1,p%grid%NPoints
                TRH(Indx) = 0.0_ReKi
                Indx = Indx + 1
             END DO !I

          END DO !J

          DO J=max(1, p%usr%NPoints),p%grid%NPoints
             DO I=J,p%grid%NPoints   

                A_Y = Alpha(2) * (p%grid%Freq(IFreq2)**rc(2)) * ((Dist_Y(Indx)/Coef_1)**qc(2)) * (z_g(Indx)**(-pc(2)))
                A_Z = Alpha(3) * (p%grid%Freq(IFreq2)**rc(3)) * ((Dist_Z(Indx)/Coef_1)**qc(3)) * (z_g(Indx)**(-pc(3)))

                TRH(Indx)=EXP(- Coef_1 * SQRT(A_Y**2 + A_Z**2) / p%met%URef)

                Indx = Indx  + 1                                    

             ENDDO ! I
          ENDDO ! J

          CALL LAPACK_pptrf( 'L', p%grid%NPoints, TRH, ErrStat3, ErrMsg3)  ! 'L'ower triangular 'TRH' matrix (packed form), of order 'NPoints'; returns Stat

          IF (ErrStat3.eq.ErrID_None) THEN
             flag_min_freq = 1
             min_freq = p%grid%Freq(IFreq2)
             print*, 'The minimum frequency that could be used for Cholesky factorization was: ',  min_freq, ' Hz'
          ENDIF

          IFreq2 = IFreq2 + 1

      END DO

      DO IFREQ = 1,p%grid%NumFreq
         ! -----------------------------------------------
         ! Create the coherence matrix for this frequency
         ! -----------------------------------------------

         Indx = 1
         DO J = 1,p%usr%NPoints-1 ! start with user-defined points (which don't get added coherence)

            TRH(Indx) =  1.0_ReKi
            Indx = Indx + 1

            DO I=J+1,p%grid%NPoints
               TRH(Indx) = 0.0_ReKi
               Indx = Indx + 1
            END DO !I

         END DO !J

         DO J=max(1, p%usr%NPoints),p%grid%NPoints
            DO I=J,p%grid%NPoints   

               A_Y = Alpha(2) * (max(p%grid%Freq(IFreq),min_freq)**rc(2)) * ((Dist_Y(Indx)/Coef_1)**qc(2)) * (z_g(Indx)**(-pc(2)))
               A_Z = Alpha(3) * (max(p%grid%Freq(IFreq),min_freq)**rc(3)) * ((Dist_Z(Indx)/Coef_1)**qc(3)) * (z_g(Indx)**(-pc(3)))

               TRH(Indx)=EXP(- Coef_1 * SQRT(A_Y**2 + A_Z**2) / p%met%URef)

               Indx = Indx  + 1                                    

            ENDDO ! I
         ENDDO ! J

   !.................
   ! DEBUGGING
   !.................
         IF (COH_OUT) THEN
   !        IF (IFreq == 1 .OR. IFreq == p%grid%NumFreq) THEN
               WRITE( UC, '(I3,2X,F15.5,1X,'//Num2LSTR(p%grid%NPacked)//'(G10.4,1X))' ) IVec, max(p%grid%Freq(IFreq),min_freq), TRH(1:p%grid%NPacked)
   !        ENDIF
         ENDIF

         ! -----------------------------------------------
         ! Now transform coherence to H matrix and then
         !   use H matrix to calculate coefficients
         ! -----------------------------------------------

         CALL Coh2H(    p, IVec, IFreq, TRH, S, ErrStat2, ErrMsg2 )
            CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CalcFourierCoeffs_API')
            IF (ErrStat >= AbortErrLev) THEN
               CALL Cleanup()
               RETURN
            END IF

         CALL H2Coeffs( IVec, IFreq, TRH, PhaseAngles, V, p%grid%NPoints )

      ENDDO !IFreq
   ENDDO !IVec

   CALL Cleanup()

RETURN
!............................................
mhank commented 3 years ago

Despite amending those "! Compute minimum allowed freq" in TSsubs.f90, the same Cholesky factorization: LAPACK_SPPTRF error has been announced. Even with some changes in WindProfileType (PL/API) and Spatial Coherence Parameters (SCMod1), it still gives the same output. Is there any way to get around this issue?

Here is an example input file that will replicate the error message:

`--------TurbSim v2 (OpenFAST) Input File------------------ Input file for TurbSim. ---------Runtime Options----------------------------------- False Echo - Echo input data to .ech (flag) 4433456 RandSeed1 - First random seed (-2147483648 to 2147483647) "RanLux" RandSeed2 - Second random seed (-2147483648 to 2147483647) for intrinsic pRNG, or an alternative pRNG: "RanLux" or "RNSNLW" False WrBHHTP - Output hub-height turbulence parameters in binary form? (Generates RootName.bin) False WrFHHTP - Output hub-height turbulence parameters in formatted form? (Generates RootName.dat) False WrADHH - Output hub-height time-series data in AeroDyn form? (Generates RootName.hh) True WrADFF - Output full-field time-series data in TurbSim/AeroDyn form? (Generates RootName.bts) False WrBLFF - Output full-field time-series data in BLADED/AeroDyn form? (Generates RootName.wnd) False WrADTWR - Output tower time-series data? (Generates RootName.twr) False WrFMTFF - Output full-field time-series data in formatted (readable) form? (Generates RootName.u, RootName.v, RootName.w) False WrACT - Output coherent turbulence time steps in AeroDyn form? (Generates RootName.cts) True Clockwise - Clockwise rotation looking downwind? (used only for full-field binary files - not necessary for AeroDyn) 0 ScaleIEC - Scale IEC turbulence models to exact target standard deviation? [0=no additional scaling; 1=use hub scale uniformly; 2=use individual scales]

--------Turbine/Model Specifications----------------------- 41 NumGrid_Z - Vertical grid-point matrix dimension 41 NumGrid_Y - Horizontal grid-point matrix dimension 0.05 TimeStep - Time step [seconds] 3600 AnalysisTime - Length of analysis time series [seconds] (program will add time if necessary: AnalysisTime = MAX(AnalysisTime, UsableTime+GridWidth/MeanHHWS) ) "ALL" UsableTime - Usable length of output time series [seconds] (program will add GridWidth/MeanHHWS seconds unless UsableTime is "ALL") 90 HubHt - Hub height [m] (should be > 0.5GridHeight) 138 GridHeight - Grid height [m] 138 GridWidth - Grid width [m] (should be >= 2(RotorRadius+ShaftLength)) 0 VFlowAng - Vertical mean flow (uptilt) angle [degrees] 0 HFlowAng - Horizontal mean flow (skew) angle [degrees]

--------Meteorological Boundary Conditions------------------- "API" TurbModel - Turbulence model ("IECKAI","IECVKM","GP_LLJ","NWTCUP","SMOOTH","WF_UPW","WF_07D","WF_14D","TIDAL","API","USRINP","USRVKM","TIMESR", or "NONE") "unused" UserFile - Name of the file that contains inputs for user-defined spectra or time series inputs (used only for "USRINP" and "TIMESR" models) "1-ED3" IECstandard - Number of IEC 61400-x standard (x=1,2, or 3 with optional 61400-1 edition number (i.e. "1-Ed2") ) "B" IECturbc - IEC turbulence characteristic ("A", "B", "C" or the turbulence intensity in percent) ("KHTEST" option with NWTCUP model, not used for other models) "NTM" IEC_WindType - IEC turbulence type ("NTM"=normal, "xETM"=extreme turbulence, "xEWM1"=extreme 1-year wind, "xEWM50"=extreme 50-year wind, where x=wind turbine class 1, 2, or 3) "default" ETMc - IEC Extreme Turbulence Model "c" parameter [m/s] "PL" WindProfileType - Velocity profile type ("LOG";"PL"=power law;"JET";"H2L"=Log law for TIDAL model;"API";"USR";"TS";"IEC"=PL on rotor disk, LOG elsewhere; or "default") "unused" ProfileFile - Name of the file that contains input profiles for WindProfileType="USR" and/or TurbModel="USRVKM" [-] 10 RefHt - Height of the reference velocity (URef) [m] 16.86 URef - Mean (total) velocity at the reference height [m/s] (or "default" for JET velocity profile) [must be 1-hr mean for API model; otherwise is the mean over AnalysisTime seconds] "default" ZJetMax - Jet height [m] (used only for JET velocity profile, valid 70-490 m) 0.0912 PLExp - Power law exponent [-] (or "default") "default" Z0 - Surface roughness length [m] (or "default")

--------Non-IEC Meteorological Boundary Conditions------------ "default" Latitude - Site latitude [degrees] (or "default") 0 RICH_NO - Gradient Richardson number [-] "default" UStar - Friction or shear velocity [m/s] (or "default") "default" ZI - Mixing layer depth [m] (or "default") "default" PC_UW - Hub mean u'w' Reynolds stress [m^2/s^2] (or "default" or "none") "default" PC_UV - Hub mean u'v' Reynolds stress [m^2/s^2] (or "default" or "none") "default" PC_VW - Hub mean v'w' Reynolds stress [m^2/s^2] (or "default" or "none")

--------Spatial Coherence Parameters---------------------------- "API" SCMod1 - u-component coherence model ("GENERAL","IEC","API","NONE", or "default") "default" SCMod2 - v-component coherence model ("GENERAL","IEC","NONE", or "default") "default" SCMod3 - w-component coherence model ("GENERAL","IEC","NONE", or "default") "default" InCDec1 - u-component coherence parameters for general or IEC models [-, m^-1] (e.g. "10.0 0.3e-3" in quotes) (or "default") "default" InCDec2 - v-component coherence parameters for general or IEC models [-, m^-1] (e.g. "10.0 0.3e-3" in quotes) (or "default") "default" InCDec3 - w-component coherence parameters for general or IEC models [-, m^-1] (e.g. "10.0 0.3e-3" in quotes) (or "default") "default" CohExp - Coherence exponent for general model [-] (or "default")

--------Coherent Turbulence Scaling Parameters------------------- [used only when WrACT=TRUE] ".\EventData" CTEventPath - Name of the path where event data files are located "les" CTEventFile - Type of event files ("LES", "DNS", or "RANDOM") true Randomize - Randomize the disturbance scale and locations? (true/false) 1 DistScl - Disturbance scale [-] (ratio of event dataset height to rotor disk). (Ignored when Randomize = true.) 0.5 CTLy - Fractional location of tower centerline from right [-] (looking downwind) to left side of the dataset. (Ignored when Randomize = true.) 0.5 CTLz - Fractional location of hub height from the bottom of the dataset. [-] (Ignored when Randomize = true.) 10 CTStartTime - Minimum start time for coherent structures in RootName.cts [seconds]

==================================================== ! NOTE: Do not add or remove any lines in this file! ====================================================`

bjonkman commented 3 years ago

@mhank, you can try to decrease the number of points in your grid. You have a pretty small grid spacing, so you could probably try 29 instead of 41 points for NumGrid_Z and NumGrid_Y.

mhank commented 3 years ago

@bjonkman , Instead of 29 points, I managed to run the script when both NumGrid_Z and NumGrid_Y were 11 points and below. That means we need to tune those grid numbers until it can run successfully. It is understood that each individual point on the NumGrid_Y x NumGrid_Z grid will have different random phases. But for the future simulation, is there any specific calculation that can determine which grid number is suitable for use in certain cases? Perhaps if we could determine the maximum range of grid numbers in order to overcome or eliminate the error being generated again.

bjonkman commented 3 years ago

Whether or not that coherence matrix (see the equation in the first comment of this issue) is positive definite depends on a combination of different things: wind speed, grid spacing in Y and Z directions, frequency (AnalysisTime and time step), and height. At each frequency a coherence matrix is formed and the Cholesky factorization is performed on that matrix. If the matrix is not positive definite, that factorization will fail. Generally, it means that there is "too much" coherence (too many values close to 1) in the matrix.

There are methods in literature that will help you find the closest positive-definite matrix to a matrix that is not positive definite; it is possible that the API model needs this.

When you ran the code that @arodriguezluis shared, what frequency did it say was the minimum it was using? And what frequency is it failing at with 29 points?

icnosvbovwb commented 2 years ago

Dear@bjonkman I am currently using a DTU 10MW wind turbine, the diameter of the Rotor is 178.3, how should I define NumGrid_Z and NumGrid_Y, I am not sure how many grids to define?

bjonkman commented 2 years ago

Appendix B in the TurbSim User's guide has some tips for setting up TurbSim grids: https://github.com/OpenFAST/openfast/blob/main/docs/OtherSupporting/TurbSim/TurbSim_v2.00.pdf

For large rotors, we typically recommend about 5-m grid resolution.

icnosvbovwb commented 2 years ago

Dear@bjonkman Is the 5-m grid resolution GridHeight divided by the number of grids? For example, in a 5MW wind turbine, I define GridHeight=175, which is 2 times the hub height reduced a little bit. So do I need 175/5 = 35? And GridWidth=200 meters. If all are correct, what are the GridHeight and GridWidth you recommend for a 10MW wind turbine?

jjonkman commented 2 years ago

Dear @icnosvbovwb,

There are grid points at the boundaries of the domain, so you must add one to your calculations, e.g. 175/5+1 = 36. But a grid size of 200-m width by 175-m high seems excessively large for the NREL 5-MW wind turbine with a rotor diameter of 126 m for an OpenFAST-only simulation (FAST.Farm requires larger domains). Normally the grid need not be more than 10% larger than the rotor diameter unless you are expecting excessive motion, e.g., in floating wind applications.

Our typical rule of them is to define the spatial resolution of the turbulence box to be on the order of max chord, which for the DTU 10-MW turbine is about 6 m.

Best regards,

icnosvbovwb commented 2 years ago

Dear @jjonkman Thank you for your reply, I have some doubts, as you said normally the grid need not be more than 10% larger than the rotor diameter unless you are expecting excessive motion, e.g., in floating wind applications. Do the grid height and the grid width of offshore wind turbines should include the tower section? If more than 10% larger than the rotor diameter, this means that the tower section and platform are not included.

jjonkman commented 2 years ago

Dear @icnosvbovwb,

The TurbSim grid must encompass the tower if aerodynamic analysis nodes are enabled along the tower in the AeroDyn module of OpenFAST. You can extend the domain in TurbSim downwards by changing the GridHeight in TurbSim (generating a full rectangular grid) or by setting WrADTWR = TRUE in TurbSim (generating the so-called "lollipop" grid). See the TurbSim documentation for more information: https://www.nrel.gov/wind/nwtc/assets/downloads/TurbSim/TurbSim_v2.00.pdf.

Best regards,

icnosvbovwb commented 2 years ago

Dear @jjonkman OK, thanks for your answer.