diff --git a/docs/source/user/api_change.rst b/docs/source/user/api_change.rst index 307366ec02..bf7e853f10 100644 --- a/docs/source/user/api_change.rst +++ b/docs/source/user/api_change.rst @@ -13,24 +13,11 @@ Thus, be sure to implement each in order so that subsequent line numbers are cor OpenFAST v3.3.0 to OpenFAST `dev` ---------------------------------- -None - - - -OpenFAST v3.2.0 to OpenFAST v3.3.0 ----------------------------------- - -============================================= ==== ================= ====================================================================================================================================================================================================== -Added in OpenFAST v3.3.0 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +============================================= ==== ================= ======================================================================================================================================================================================================== +Added in OpenFAST `dev` +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Module Line Flag Name Example Value ============================================= ==== ================= ======================================================================================================================================================================================================== -FAST.Farm 9 ModWaveField 2 Mod_WaveField - Wave field handling (-) (switch) {1: use individual HydroDyn inputs without adjustment, 2: adjust wave phases based on turbine offsets from farm origin} -FAST.Farm 10 Mod_SharedMooring 0 Mod_SharedMooring - Shared mooring system model (switch) {0: None, 3=MoorDyn}} -FAST.Farm 13 na ------ SHARED MOORING SYSTEM ------ [used only for Mod_SharedMoor>0] -FAST.Farm 14 SharedMoorFile "" SharedMoorFile - Name of file containing shared mooring system input parameters (quoted string) [used only when Mod_SharedMooring > 0] -FAST.Farm 15 DT_Mooring 0.04 DT_Mooring - Time step for farm-level mooring coupling with each turbine (s) [used only when Mod_SharedMooring > 0] -FAST.Farm 43 Mod_Wake 1 Mod_Wake - Switch between wake formulations {1:Polar, 2:Curl, 3:Cartesian} (-) (switch) FAST.Farm 67 CurlSection --- CURLED-WAKE PARAMETERS [only used if Mod_Wake=2 or 3] --- FAST.Farm 68 Swirl False Swirl - Switch to include swirl velocities in wake [only used if Mod_Wake=2 or Mod_Wake=3] (-) (switch) FAST.Farm 69 k_VortexDecay 0. k_VortexDecay - Vortex decay constant for curl (-) @@ -54,7 +41,6 @@ AeroDyn 15 TwrCb 1.0 AeroDyn blade BlCb 0.187 [additional column in *Blade Properties* table] AeroDyn blade BlCenBn 0.3 [additional column in *Blade Properties* table] AeroDyn blade BlCenBt 0.1 [additional column in *Blade Properties* table] -AeroDyn driver 54\* WrVTK_Type 1 WrVTK_Type - VTK visualization data type: (switch) {1=surfaces; 2=lines; 3=both} ============================================= ==== ================= ======================================================================================================================================================================================================== \*Exact line number depends on number of entries in various preceeding tables. @@ -62,6 +48,23 @@ AeroDyn driver 54\* WrVTK_Type 1 \$ The content of the tail fin input file is described in :numref:`TF_tf_input-file`. +OpenFAST v3.2.0 to OpenFAST v3.3.0 +---------------------------------- + + +============================================= ==== ================= ======================================================================================================================================================================================================== +Added in OpenFAST `3.3.0` +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Module Line Flag Name Example Value +============================================= ==== ================= ======================================================================================================================================================================================================== +FAST.Farm 9 ModWaveField 2 Mod_WaveField - Wave field handling (-) (switch) {1: use individual HydroDyn inputs without adjustment, 2: adjust wave phases based on turbine offsets from farm origin} +FAST.Farm 10 Mod_SharedMooring 0 Mod_SharedMooring - Shared mooring system model (switch) {0: None, 3=MoorDyn}} +FAST.Farm 13 na ------ SHARED MOORING SYSTEM ------ [used only for Mod_SharedMoor>0] +FAST.Farm 14 SharedMoorFile "" SharedMoorFile - Name of file containing shared mooring system input parameters (quoted string) [used only when Mod_SharedMooring > 0] +FAST.Farm 15 DT_Mooring 0.04 DT_Mooring - Time step for farm-level mooring coupling with each turbine (s) [used only when Mod_SharedMooring > 0] +AeroDyn driver 54\* WrVTK_Type 1 WrVTK_Type - VTK visualization data type: (switch) {1=surfaces; 2=lines; 3=both} +============================================= ==== ================= ======================================================================================================================================================================================================== + ============================================= ==== =============== ======================================================================================================================================================================================================== Modified in OpenFAST v3.3.0 diff --git a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 index d34b00431d..86ede99d5f 100644 --- a/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 +++ b/glue-codes/fast-farm/src/FAST_Farm_Subs.f90 @@ -1468,7 +1468,7 @@ SUBROUTINE Farm_ValidateInput( p, WD_InitInp, AWAE_InitInp, SC_InitInp, ErrStat, if ((p%DT_mooring <= 0.0_ReKi) .or. (p%DT_mooring > p%DT_high)) CALL SetErrStat(ErrID_Fatal,'DT_mooring must be greater than zero and no greater than dt_high.',ErrStat,ErrMsg,RoutineName) ! --- WAKE DYNAMICS --- - IF (WD_InitInp%Mod_Wake /= 1) CALL SetErrStat(ErrID_Fatal,'Mod_Wake needs to be 1',ErrStat,ErrMsg,RoutineName) + IF (WD_InitInp%Mod_Wake /= 1 .and. WD_InitInp%Mod_Wake /=3) CALL SetErrStat(ErrID_Fatal,'Mod_Wake needs to be 1 or 3',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%dr <= 0.0_ReKi) CALL SetErrStat(ErrID_Fatal,'dr (radial increment) must be larger than 0.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%NumRadii < 2) CALL SetErrStat(ErrID_Fatal,'NumRadii (number of radii) must be at least 2.',ErrStat,ErrMsg,RoutineName) IF (WD_InitInp%NumPlanes < 2) CALL SetErrStat(ErrID_Fatal,'NumPlanes (number of wake planes) must be at least 2.',ErrStat,ErrMsg,RoutineName) @@ -2045,7 +2045,8 @@ subroutine FARM_InitialCO(farm, ErrStat, ErrMsg) farm%AWAE%u%xhat_plane = 0.0_ReKi ! Orientations of wake planes, normal to wake planes, for each turbine farm%AWAE%u%p_plane = 0.0_ReKi ! Center positions of wake planes for each turbine farm%AWAE%u%Vx_wake = 0.0_ReKi ! Axial wake velocity deficit at wake planes, distributed radially, for each turbine - farm%AWAE%u%Vr_wake = 0.0_ReKi ! Radial wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vy_wake = 0.0_ReKi ! Horizontal wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vz_wake = 0.0_ReKi ! "Vertical" wake velocity deficit at wake planes, distributed radially, for each turbine farm%AWAE%u%D_wake = 0.0_ReKi ! Wake diameters at wake planes for each turbine !-------------------- @@ -2921,8 +2922,9 @@ SUBROUTINE Transfer_WD_to_AWAE(farm) DO nt = 1,farm%p%NumTurbines farm%AWAE%u%xhat_plane(:,:,nt) = farm%WD(nt)%y%xhat_plane ! Orientations of wake planes, normal to wake planes, for each turbine farm%AWAE%u%p_plane(:,:,nt) = farm%WD(nt)%y%p_plane ! Center positions of wake planes for each turbine - farm%AWAE%u%Vx_wake(:,:,nt) = farm%WD(nt)%y%Vx_wake ! Axial wake velocity deficit at wake planes, distributed radially, for each turbine - farm%AWAE%u%Vr_wake(:,:,nt) = farm%WD(nt)%y%Vr_wake ! Radial wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vx_wake(:,:,:,nt) = farm%WD(nt)%y%Vx_wake2 ! Axial wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vy_wake(:,:,:,nt) = farm%WD(nt)%y%Vy_wake2 ! Horizontal wake velocity deficit at wake planes, distributed radially, for each turbine + farm%AWAE%u%Vz_wake(:,:,:,nt) = farm%WD(nt)%y%Vz_wake2 ! "Vertical" wake velocity deficit at wake planes, distributed radially, for each turbine farm%AWAE%u%D_wake(:,nt) = farm%WD(nt)%y%D_wake ! Wake diameters at wake planes for each turbine END DO diff --git a/modules/awae/src/AWAE.f90 b/modules/awae/src/AWAE.f90 index f28e5c47ce..7711cc681d 100644 --- a/modules/awae/src/AWAE.f90 +++ b/modules/awae/src/AWAE.f90 @@ -53,6 +53,7 @@ module AWAE public :: AWAE_TEST_Init_BadData public :: AWAE_TEST_Init_GoodData public :: AWAE_TEST_CalcOutput + public :: AWAE_TEST_Interp2D contains @@ -123,7 +124,7 @@ subroutine ComputeLocals(n, u, p, y, m, errStat, errMsg) errStat = 0 errMsg = "" maxPln = min(n,p%NumPlanes-2) - rmax = p%r(p%NumRadii-1) + rmax = p%y(p%NumRadii-1) do nt = 1,p%NumTurbines do np = 0, maxPln cosTerm = dot_product(u%xhat_plane(:,np+1,nt),u%xhat_plane(:,np,nt)) @@ -185,11 +186,13 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) integer(IntKi) :: nx, ny, nz, nt, np, nw, nx_low, ny_low, nz_low, nr, npsi, wamb, iwsum !< loop counters integer(IntKi) :: nXYZ_low, n_wake, n_r_polar, n_psi_polar !< accumulating counters real(ReKi) :: xhatBar_plane(3) !< + real(ReKi) :: xHat_plane(3), yHat_plane(3), zHat_plane(3) real(ReKi) :: x_end_plane real(ReKi) :: x_start_plane real(ReKi) :: r_vec_plane(3) - real(ReKi) :: tmp_xhatBar_plane - real(ReKi) :: r_tmp_plane + real(ReKi) :: xhatBar_plane_norm + real(ReKi) :: y_tmp_plane + real(ReKi) :: z_tmp_plane real(ReKi) :: Vx_wake_tmp real(ReKi) :: Vr_wake_tmp(3) real(ReKi) :: Vr_term(3) @@ -203,22 +206,22 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) real(ReKi) :: tmp_x,tmp_y,tmp_z !, tm1, tm2 real(ReKi) :: xxplane(3), xyplane(3), yyplane(3), yxplane(3), psi_polar, r_polar, p_polar(3) real(ReKi) :: yzplane_Y(3), xyplane_norm - real(ReKi) :: xplane_sq, yplane_sq, xysq_Z(3), xzplane_X(3), tmp_yhat_plane(3), tmp_zhat_plane(3) - real(ReKi), ALLOCATABLE :: tmp_rhat_plane(:,:), tmp_xhat_plane(:,:) - real(ReKi), ALLOCATABLE :: tmp_Vx_wake(:), tmp_Vr_wake(:) - integer(IntKi) :: ILo + real(ReKi) :: xplane_sq, yplane_sq, xysq_Z(3), xzplane_X(3) + real(ReKi), ALLOCATABLE :: tmp_xhat_plane(:,:), tmp_yhat_plane(:,:), tmp_zhat_plane(:,:) + real(ReKi), ALLOCATABLE :: tmp_Vx_wake(:), tmp_Vz_wake(:), tmp_Vy_wake(:) integer(IntKi) :: maxPln, tmpPln, maxN_wake integer(IntKi) :: i,np1,errStat2 character(*), parameter :: RoutineName = 'LowResGridCalcOutput' logical :: within + real(SiKi), dimension(3,3) :: C_rot + real(SiKi) :: C_rot_norm errStat = ErrID_None errMsg = "" maxPln = min(n,p%NumPlanes-2) tmpPln = min(p%NumPlanes-1, n+1) - - + !#ifdef _OPENMP ! tm1 = omp_get_wtime() @@ -226,21 +229,23 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) maxN_wake = p%NumTurbines*( p%NumPlanes-1 ) ! Temporary variables needed by OpenMP - allocate ( tmp_xhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_xhat_plane.', errStat, errMsg, RoutineName ) - allocate ( tmp_rhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_rhat_plane.', errStat, errMsg, RoutineName ) - allocate ( tmp_Vx_wake ( 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vx_wake.', errStat, errMsg, RoutineName ) - allocate ( tmp_Vr_wake ( 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vr_wake.', errStat, errMsg, RoutineName ) + allocate ( tmp_xhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_xhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_yhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_yhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_zhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_zhat_plane.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vx_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vy_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( tmp_Vz_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for tmp_Vz_wake.', errStat, errMsg, RoutineName ) if (ErrStat >= AbortErrLev) return ! Loop over the entire grid of low resolution ambient wind data to compute: ! 1) the disturbed flow at each point and 2) the averaged disturbed velocity of each wake plane - - !$OMP PARALLEL DO PRIVATE(nx_low,ny_low,nz_low, nXYZ_low, n_wake, xhatBar_plane, x_end_plane,nt,np,ILo,x_start_plane,delta,deltad,p_tmp_plane,tmp_vec,r_vec_plane,r_tmp_plane,tmp_xhatBar_plane, Vx_wake_tmp,Vr_wake_tmp,nw,Vr_term,Vx_term,tmp_x,tmp_y,tmp_z,tmp_xhat_plane,tmp_rhat_plane,tmp_Vx_wake,tmp_Vr_wake,i,np1,errStat2) SHARED(m,u,p,maxPln,errStat,errMsg) DEFAULT(NONE) + !$OMP PARALLEL DO PRIVATE(nx_low,ny_low,nz_low, nXYZ_low, n_wake, xhatBar_plane, x_end_plane,nt,np,x_start_plane,delta,deltad,& + !$OMP& p_tmp_plane,tmp_vec,r_vec_plane,y_tmp_plane,z_tmp_plane,xhatBar_plane_norm, Vx_wake_tmp, Vr_wake_tmp,& + !$OMP& nw,Vr_term,Vx_term,tmp_x,tmp_y,tmp_z,& + !$OMP& xHat_plane, yHat_plane, zHat_plane, C_rot, C_rot_norm, & + !$OMP& tmp_xhat_plane, tmp_yhat_plane, tmp_zhat_plane, tmp_Vx_wake, tmp_Vy_wake, tmp_Vz_wake, i,np1,errStat2) & + !$OMP& SHARED(m,u,p,maxPln,errStat,errMsg) DEFAULT(NONE) !do nz_low=0, p%nZ_low-1 ! do ny_low=0, p%yZ_low-1 ! do nx_low=0, p%nX_low-1 @@ -252,7 +257,8 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) nz_low = int( i / (p%nX_low*p%nY_low) ) ! set the disturbed flow equal to the ambient flow for this time step - m%Vdist_low(:,nx_low,ny_low,nz_low) = m%Vamb_low(:,nx_low,ny_low,nz_low) + m%Vdist_low (:,nx_low,ny_low,nz_low) = m%Vamb_low(:,nx_low,ny_low,nz_low) + m%Vdist_low_full(:,nx_low,ny_low,nz_low) = m%Vamb_low(:,nx_low,ny_low,nz_low) !nXYZ_low = nXYZ_low + 1 nXYZ_low = i + 1 @@ -269,8 +275,6 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) x_end_plane = tmp_x + tmp_y + tmp_z do np = 0, maxPln - ! Reset interpolation counter - ILo = 0 np1 = np + 1 ! Construct the endcaps of the current wake plane volume x_start_plane = x_end_plane @@ -281,49 +285,65 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) tmp_z = u%xhat_plane(3,np1,nt) * (p%Grid_Low(3,nXYZ_low) - u%p_plane(3,np1,nt)) x_end_plane = tmp_x + tmp_y + tmp_z - ! test if the point is within the endcaps of the wake volume - + ! test if the point is within the endcaps of the wake volume if ( ( ( x_start_plane >= 0.0_ReKi ) .and. ( x_end_plane < 0.0_ReKi ) ) .or. & ( ( x_start_plane <= 0.0_ReKi ) .and. ( x_end_plane > 0.0_ReKi ) ) ) then + ! Plane interpolation factor if ( EqualRealNos( x_start_plane, x_end_plane ) ) then delta = 0.5_ReKi else delta = x_start_plane / ( x_start_plane - x_end_plane ) end if deltad = (1.0_ReKi - delta) + + ! Interpolated plane position if ( m%parallelFlag(np,nt) ) then p_tmp_plane = delta*u%p_plane(:,np1,nt) + deltad*u%p_plane(:,np,nt) else - tmp_vec = delta*m%rhat_e(:,np,nt) + deltad*m%rhat_s(:,np,nt) + tmp_vec = delta*m%rhat_e(:,np,nt) + deltad*m%rhat_s(:,np,nt) p_tmp_plane = delta*m%pvec_ce(:,np,nt) + deltad*m%pvec_cs(:,np,nt) + ( delta*m%r_e(np,nt) + deltad*m%r_s(np,nt) )* tmp_vec / TwoNorm(tmp_vec) end if ! Vector between current grid point and plane position r_vec_plane = p%Grid_Low(:,nXYZ_low) - p_tmp_plane - r_tmp_plane = TwoNorm( r_vec_plane ) - - ! test if the point is within radial finite-difference grid - if ( r_tmp_plane <= p%r(p%numRadii-1) ) then + ! Interpolate x_hat, plane normal at grid point + xHat_plane(1:3) = delta*u%xhat_plane(:,np1,nt) + deltad*u%xhat_plane(:,np,nt) + xHat_plane(1:3) = xHat_plane(:) / TwoNorm(xHat_plane(:)) + ! Construct y_hat, orthogonal to x_hat when its z component is neglected (in a projected horizontal plane) + yHat_plane(1:3) = (/ -xHat_plane(2), xHat_plane(1), 0.0_ReKi /) + yHat_plane(1:3) = yHat_plane / TwoNorm(yHat_plane) + ! Construct z_hat + zHat_plane(1) = -xHat_plane(1)*xHat_plane(3) + zHat_plane(2) = -xHat_plane(2)*xHat_plane(3) + zHat_plane(3) = xHat_plane(1)*xHat_plane(1) + xHat_plane(2)*xHat_plane(2) + zHat_plane(1:3) = zHat_plane / TwoNorm(zHat_plane) + + ! Point positions in plane, y = yhat . (p-p_plane), z = zhat . (p-p_plane) + y_tmp_plane = yHat_plane(1)*r_vec_plane(1) + yHat_plane(2)*r_vec_plane(2) + yHat_plane(3)*r_vec_plane(3) + z_tmp_plane = zHat_plane(1)*r_vec_plane(1) + zHat_plane(2)*r_vec_plane(2) + zHat_plane(3)*r_vec_plane(3) + + ! test if the point is within finite-difference grid + if ( (abs(y_tmp_plane) <= p%y(p%numRadii-1)).and.(abs(z_tmp_plane) <= p%z(p%numRadii-1)) ) then + ! Increment number of wakes contributing to current grid point n_wake = n_wake + 1 - - if ( EqualRealNos(r_tmp_plane, 0.0_ReKi) ) then - tmp_rhat_plane(:,n_wake) = 0.0_ReKi - else - tmp_rhat_plane(:,n_wake) = ( r_vec_plane ) / r_tmp_plane - end if - - - ! given r_tmp_plane and Vx_wake at p%dr increments, find value of m%Vx_wake(@r_tmp_plane) using interpolation - tmp_Vx_wake(n_wake) = delta*InterpBin( r_tmp_plane, p%r, u%Vx_wake(:,np1,nt), ILo, p%NumRadii ) + deltad*InterpBin( r_tmp_plane, p%r, u%Vx_wake(:,np,nt), ILo, p%NumRadii ) !( XVal, XAry, YAry, ILo, AryLen ) - tmp_Vr_wake(n_wake) = delta*InterpBin( r_tmp_plane, p%r, u%Vr_wake(:,np1,nt), ILo, p%NumRadii ) + deltad*InterpBin( r_tmp_plane, p%r, u%Vr_wake(:,np,nt), ILo, p%NumRadii ) !( XVal, XAry, YAry, ILo, AryLen ) - - - tmp_xhat_plane(:,n_wake) = delta*u%xhat_plane(:,np1,nt) + deltad*u%xhat_plane(:,np,nt) - tmp_xhat_plane(:,n_wake) = tmp_xhat_plane(:,n_wake) / TwoNorm(tmp_xhat_plane(:,n_wake)) + ! Store unit vectors for projection + tmp_xhat_plane(:,n_wake) = xHat_plane + tmp_yhat_plane(:,n_wake) = yHat_plane + tmp_zhat_plane(:,n_wake) = zHat_plane + + ! Velocity at point (y,z) by 2d interpolation in plane, and interpolations between planes (delta) + tmp_Vx_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vx_wake(:,:,np1,nt)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vx_wake(:,:,np, nt)) + tmp_Vy_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vy_wake(:,:,np1,nt)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vy_wake(:,:,np, nt)) + tmp_Vz_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vz_wake(:,:,np1,nt)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vz_wake(:,:,np, nt)) + ! Average xhat over overlapping wakes xhatBar_plane = xhatBar_plane + abs(tmp_Vx_wake(n_wake))*tmp_xhat_plane(:,n_wake) + end if ! if the point is within radial finite-difference grid end if end do ! do np = 0, p%NumPlanes-2 @@ -331,11 +351,11 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) if (n_wake > 0) then ! Normalize xhatBar to unit vector - tmp_xhatBar_plane = TwoNorm(xhatBar_plane) - if ( EqualRealNos(tmp_xhatBar_plane, 0.0_ReKi) ) then + xhatBar_plane_norm = TwoNorm(xhatBar_plane) + if ( EqualRealNos(xhatBar_plane_norm, 0.0_ReKi) ) then xhatBar_plane = 0.0_ReKi else - xhatBar_plane = xhatBar_plane / tmp_xhatBar_plane + xhatBar_plane = xhatBar_plane / xhatBar_plane_norm end if ! Compute average contributions ! - sqrt[ sum (e_x. V)^2 ] e_x ! Axial (sqrt-avg) @@ -343,14 +363,20 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) Vx_wake_tmp = 0.0_ReKi Vr_wake_tmp = 0.0_ReKi do nw = 1,n_wake - Vr_term = tmp_Vx_wake(nw)*tmp_xhat_plane(:,nw) + tmp_Vr_wake(nw)*tmp_rhat_plane(:,nw) + Vr_term = tmp_Vx_wake(nw)*tmp_xhat_plane(:,nw) + tmp_Vy_wake(nw)*tmp_yhat_plane(:,nw) + tmp_Vz_wake(nw)*tmp_zhat_plane(:,nw) Vx_term = dot_product( xhatBar_plane, Vr_term ) Vx_wake_tmp = Vx_wake_tmp + Vx_term*Vx_term Vr_wake_tmp = Vr_wake_tmp + Vr_term end do ! [I - XX']V = V - (V dot X)X Vr_wake_tmp = Vr_wake_tmp - dot_product(Vr_wake_tmp,xhatBar_plane)*xhatBar_plane - m%Vdist_low(:,nx_low,ny_low,nz_low) = m%Vdist_low(:,nx_low,ny_low,nz_low) + real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi) + ! Compute C matrix and update Vdist_low + if(p%Mod_Projection==1) then + ! We keep the full field (including cross flow components), done for outputs and VTK outputs + m%Vdist_low (:,nx_low,ny_low,nz_low) = m%Vdist_low (:,nx_low,ny_low,nz_low) + real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi) + m%Vdist_low_full(:,nx_low,ny_low,nz_low) = m%Vdist_low_full(:,nx_low,ny_low,nz_low) + real(Vr_wake_tmp - xhatBar_plane*sqrt(Vx_wake_tmp),SiKi) + endif + end if ! (n_wake > 0) end do ! i, loop NumGrid_low points ! end do ! do nx_low=0, p%nX_low-1 @@ -392,8 +418,8 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) xysq_Z = (/0.0_ReKi, 0.0_ReKi, xplane_sq+yplane_sq/) xzplane_X = (/u%xhat_plane(1,np,nt)*u%xhat_plane(3,np,nt), 0.0_ReKi, 0.0_ReKi/) yzplane_Y = (/0.0_ReKi, u%xhat_plane(2,np,nt)*u%xhat_plane(3,np,nt), 0.0_ReKi/) - tmp_yhat_plane = (xyplane-yxplane)/xyplane_norm - tmp_zhat_plane = (xysq_Z-xzplane_X-yzplane_Y)/xyplane_norm + yHat_plane = (xyplane-yxplane)/xyplane_norm + zHat_plane = (xysq_Z-xzplane_X-yzplane_Y)/xyplane_norm ! Calculate y%Vx_wind_disk and y%TI_amb at the rotor disk @@ -412,7 +438,7 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) do npsi = 0,n_psi_polar psi_polar = (TwoPi*REAL(npsi,ReKi))/(REAL(n_psi_polar+1,ReKi)) - p_polar = u%p_plane(:,np,nt) + r_polar*COS(psi_polar)*tmp_yhat_plane + r_polar*SIN(psi_polar)*tmp_zhat_plane + p_polar = u%p_plane(:,np,nt) + r_polar*COS(psi_polar)*yHat_plane + r_polar*SIN(psi_polar)*zHat_plane Vamb_lowpol_tmp = INTERP3D( p_polar, p%Grid_Low(:,1), p%dXYZ_Low, m%Vamb_low, within, p%nX_low, p%nY_low, p%nZ_low, Vbox=Vamb_low_tmp ) if ( within ) then Vsum_low = Vsum_low + Vamb_lowpol_tmp @@ -476,7 +502,7 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) do npsi = 0,n_psi_polar psi_polar = (TwoPi*REAL(npsi,ReKi))/(REAL(n_psi_polar+1,ReKi)) - p_polar = u%p_plane(:,np,nt) + r_polar*COS(psi_polar)*tmp_yhat_plane + r_polar*SIN(psi_polar)*tmp_zhat_plane + p_polar = u%p_plane(:,np,nt) + r_polar*COS(psi_polar)*yHat_plane + r_polar*SIN(psi_polar)*zHat_plane Vdist_lowpol_tmp = INTERP3D( p_polar, p%Grid_Low(:,1), p%dXYZ_Low, m%Vdist_low, within, p%nX_low, p%nY_low, p%nZ_low ) if ( within ) then y%V_plane(:,np,nt) = y%V_plane(:,np,nt) + w*Vdist_lowpol_tmp @@ -505,9 +531,11 @@ subroutine LowResGridCalcOutput(n, u, p, y, m, errStat, errMsg) !#endif if (allocated(tmp_xhat_plane)) deallocate(tmp_xhat_plane) - if (allocated(tmp_rhat_plane)) deallocate(tmp_rhat_plane) - if (allocated(tmp_Vx_wake)) deallocate(tmp_Vx_wake) - if (allocated(tmp_Vr_wake)) deallocate(tmp_Vr_wake) + if (allocated(tmp_yhat_plane)) deallocate(tmp_yhat_plane) + if (allocated(tmp_zhat_plane)) deallocate(tmp_zhat_plane) + if (allocated(tmp_Vx_wake)) deallocate(tmp_Vx_wake) + if (allocated(tmp_Vy_wake)) deallocate(tmp_Vy_wake) + if (allocated(tmp_Vz_wake)) deallocate(tmp_Vz_wake) end subroutine LowResGridCalcOutput @@ -529,11 +557,13 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) integer(IntKi) :: nx, ny, nz, nt, nt2, np, nw, nx_high, ny_high, nz_high, n_hl !< loop counters integer(IntKi) :: nXYZ_high, n_wake !< accumulating counters real(ReKi) :: xhatBar_plane(3) !< - real(ReKi) :: tmp_xhatBar_plane + real(ReKi) :: xHat_plane(3), yHat_plane(3), zHat_plane(3) + real(ReKi) :: xhatBar_plane_norm real(ReKi) :: x_end_plane real(ReKi) :: x_start_plane real(ReKi) :: r_vec_plane(3) - real(ReKi) :: r_tmp_plane + real(ReKi) :: y_tmp_plane + real(ReKi) :: z_tmp_plane real(ReKi) :: Vx_wake_tmp real(ReKi) :: Vr_wake_tmp(3) real(ReKi) :: Vr_term(3) @@ -542,7 +572,7 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) real(ReKi) :: p_tmp_plane(3) real(ReKi) :: tmp_vec(3) real(ReKi) :: delta, deltad - integer(IntKi) :: ILo + integer(IntKi) :: np1 integer(IntKi) :: maxPln integer(IntKi) :: n_high_low character(*), parameter :: RoutineName = 'HighResGridCalcOutput' @@ -586,10 +616,7 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) x_end_plane = dot_product(u%xhat_plane(:,0,nt2), (p%Grid_high(:,nXYZ_high,nt) - u%p_plane(:,0,nt2)) ) do np = 0, maxPln !p%NumPlanes-2 - - ! Reset interpolation counter - ILo = 0 - + np1 = np + 1 ! Construct the endcaps of the current wake plane volume x_start_plane = x_end_plane x_end_plane = dot_product(u%xhat_plane(:,np+1,nt2), (p%Grid_high(:,nXYZ_high,nt) - u%p_plane(:,np+1,nt2)) ) @@ -616,28 +643,41 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) ! Vector between current grid and plane position r_vec_plane = p%Grid_high(:,nXYZ_high,nt) - p_tmp_plane - r_tmp_plane = TwoNorm( r_vec_plane ) - - ! test if the point is within radial finite-difference grid - if ( r_tmp_plane <= p%r(p%numRadii-1) ) then + ! Interpolate x_hat + xHat_plane(1:3) = delta*u%xhat_plane(:,np1,nt2) + deltad*u%xhat_plane(:,np,nt2) + xHat_plane(1:3) = xHat_plane(:) / TwoNorm(xHat_plane(:)) + ! Construct y_hat, orthogonal to x_hat when its z component is neglected (in a projected horizontal plane) + yHat_plane(1:3) = (/ -xHat_plane(2), xHat_plane(1), 0.0_ReKi /) + yHat_plane(1:3) = yHat_plane / TwoNorm(yHat_plane) + ! Construct z_hat + zHat_plane(1) = -xHat_plane(1)*xHat_plane(3) + zHat_plane(2) = -xHat_plane(2)*xHat_plane(3) + zHat_plane(3) = xHat_plane(1)*xHat_plane(1) + xHat_plane(2)*xHat_plane(2) + zHat_plane(1:3) = zHat_plane / TwoNorm(zHat_plane) + + ! Point positions in plane, y = yhat . (p-p_plane), z = zhat . (p-p_plane) + y_tmp_plane = yHat_plane(1)*r_vec_plane(1) + yHat_plane(2)*r_vec_plane(2) + yHat_plane(3)*r_vec_plane(3) + z_tmp_plane = zHat_plane(1)*r_vec_plane(1) + zHat_plane(2)*r_vec_plane(2) + zHat_plane(3)*r_vec_plane(3) + + ! test if the point is within finite-difference grid + if ( (abs(y_tmp_plane) <= p%y(p%numRadii-1)).and.(abs(z_tmp_plane) <= p%z(p%numRadii-1)) ) then + ! Increment number of wakes contributing to current grid point n_wake = n_wake + 1 ! Store unit vectors for projection - if ( EqualRealNos(r_tmp_plane, 0.0_ReKi) ) then - m%rhat_plane(:,n_wake) = 0.0_ReKi - else - m%rhat_plane(:,n_wake) = ( r_vec_plane ) / r_tmp_plane - end if + m%xhat_plane(:,n_wake) = xHat_plane + m%yhat_plane(:,n_wake) = yHat_plane + m%zhat_plane(:,n_wake) = zHat_plane + + ! Velocity at point (y,z) by 2d interpolation in plane, and interpolations between planes (delta) + m%Vx_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vx_wake(:,:,np1,nt2)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vx_wake(:,:,np, nt2)) + m%Vy_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vy_wake(:,:,np1,nt2)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vy_wake(:,:,np, nt2)) + m%Vz_wake(n_wake) = delta *interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vz_wake(:,:,np1,nt2)) & + + deltad*interp2d((/y_tmp_plane, z_tmp_plane/), p%y, p%z, u%Vz_wake(:,:,np, nt2)) - - - ! given r_tmp_plane and Vx_wake at p%dr increments, find value of m%Vx_wake(@r_tmp_plane) using interpolation - m%Vx_wake(n_wake) = delta*InterpBin( r_tmp_plane, p%r, u%Vx_wake(:,np+1,nt2), ILo, p%NumRadii ) + deltad*InterpBin( r_tmp_plane, p%r, u%Vx_wake(:,np,nt2), ILo, p%NumRadii ) !( XVal, XAry, YAry, ILo, AryLen ) - m%Vr_wake(n_wake) = delta*InterpBin( r_tmp_plane, p%r, u%Vr_wake(:,np+1,nt2), ILo, p%NumRadii ) + deltad*InterpBin( r_tmp_plane, p%r, u%Vr_wake(:,np,nt2), ILo, p%NumRadii )!( XVal, XAry, YAry, ILo, AryLen ) - - m%xhat_plane(:,n_wake) = delta*u%xhat_plane(:,np+1,nt2) + deltad*u%xhat_plane(:,np,nt2) - m%xhat_plane(:,n_wake) = m%xhat_plane(:,n_wake) / TwoNorm(m%xhat_plane(:,n_wake)) ! Average xhat over overlapping wakes xhatBar_plane = xhatBar_plane + abs(m%Vx_wake(n_wake))*m%xhat_plane(:,n_wake) @@ -649,11 +689,11 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) end do ! nt2 = 1,p%NumTurbines if (n_wake > 0) then ! Normalize xhatBar to unit vector - tmp_xhatBar_plane = TwoNorm(xhatBar_plane) - if ( EqualRealNos(tmp_xhatBar_plane, 0.0_ReKi) ) then + xhatBar_plane_norm = TwoNorm(xhatBar_plane) + if ( EqualRealNos(xhatBar_plane_norm, 0.0_ReKi) ) then xhatBar_plane = 0.0_ReKi else - xhatBar_plane = xhatBar_plane / tmp_xhatBar_plane + xhatBar_plane = xhatBar_plane / xhatBar_plane_norm end if ! Compute average contributions @@ -662,7 +702,7 @@ subroutine HighResGridCalcOutput(n, u, p, y, m, errStat, errMsg) Vx_wake_tmp = 0.0_ReKi Vr_wake_tmp = 0.0_ReKi do nw = 1,n_wake - Vr_term = m%Vx_wake(nw)*m%xhat_plane(:,nw) + m%Vr_wake(nw)*m%rhat_plane(:,nw) + Vr_term = m%Vx_wake(nw)*m%xhat_plane(:,nw) + m%Vy_wake(nw)*m%yhat_plane(:,nw) + m%Vz_wake(nw)*m%zhat_plane(:,nw) Vx_term = dot_product( xhatBar_plane, Vr_term ) Vx_wake_tmp = Vx_wake_tmp + Vx_term*Vx_term Vr_wake_tmp = Vr_wake_tmp + Vr_term @@ -809,14 +849,14 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Plane grids - allocate( p%r(0:p%NumRadii-1),stat=errStat2) - if (errStat2 /= 0) then - call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%r.', errStat, errMsg, RoutineName ) - return - end if - - do i = 0,p%NumRadii-1 - p%r(i) = InitInp%InputFileData%dr*i + allocate( p%y(-p%Numradii+1:p%NumRadii-1), stat=errStat2); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%y.', errStat, errMsg, RoutineName ) + allocate( p%z(-p%Numradii+1:p%NumRadii-1), stat=errStat2); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%z.', errStat, errMsg, RoutineName ) + if ( ErrStat >= AbortErrLev ) then + return + end if + do i = -p%NumRadii+1,p%NumRadii-1 + p%y(i) = InitInp%InputFileData%dr*i + p%z(i) = InitInp%InputFileData%dr*i end do allocate( p%WT_Position(3,p%NumTurbines),stat=errStat2) @@ -1009,17 +1049,17 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO ! Define and initialize inputs here !............................................................................................ - allocate ( u%xhat_plane(3,0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%xhat_plane.', errStat, errMsg, RoutineName ) - allocate ( u%p_plane (3,0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%p_plane.', errStat, errMsg, RoutineName ) - allocate ( u%Vx_wake (0:p%NumRadii-1,0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vx_wake.', errStat, errMsg, RoutineName ) - allocate ( u%Vr_wake (0:p%NumRadii-1,0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vr_wake.', errStat, errMsg, RoutineName ) - allocate ( u%D_wake (0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%D_wake.', errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return + allocate ( u%xhat_plane(3,0:p%NumPlanes-1,1:p%NumTurbines) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%xhat_plane.', errStat, errMsg, RoutineName ) + allocate ( u%p_plane (3,0:p%NumPlanes-1,1:p%NumTurbines) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%p_plane.', errStat, errMsg, RoutineName ) + allocate ( u%Vx_wake (-p%NumRadii+1:p%NumRadii-1, -p%NumRadii+1:p%NumRadii-1, 0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( u%Vy_wake (-p%NumRadii+1:p%NumRadii-1, -p%NumRadii+1:p%NumRadii-1, 0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( u%Vz_wake (-p%NumRadii+1:p%NumRadii-1, -p%NumRadii+1:p%NumRadii-1, 0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%Vz_wake.', errStat, errMsg, RoutineName ) + allocate ( u%D_wake (0:p%NumPlanes-1,1:p%NumTurbines), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for u%D_wake.', errStat, errMsg, RoutineName ) + if (errStat /= ErrID_None) return + + u%Vx_wake=0.0_ReKi + u%Vy_wake=0.0_ReKi + u%Vz_wake=0.0_ReKi @@ -1092,6 +1132,8 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vamb_lowpol.', errStat, errMsg, RoutineName ) allocate ( m%Vdist_low ( 3, 0:p%nX_low-1 , 0:p%nY_low-1 , 0:p%nZ_low-1 ) , STAT=errStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vdist_low.', errStat, errMsg, RoutineName ) + allocate ( m%Vdist_low_full ( 3, 0:p%nX_low-1 , 0:p%nY_low-1 , 0:p%nZ_low-1 ) , STAT=errStat2 ) + if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vdist_low_full', errStat, errMsg, RoutineName ) allocate ( m%Vamb_high(1:p%NumTurbines), STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vamb_high.', errStat, errMsg, RoutineName ) @@ -1100,14 +1142,12 @@ subroutine AWAE_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitO if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vamb_high%data.', errStat, errMsg, RoutineName ) end do maxN_wake = p%NumTurbines*( p%NumPlanes-1 ) - allocate ( m%xhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%xhat_plane.', errStat, errMsg, RoutineName ) - allocate ( m%rhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%rhat_plane.', errStat, errMsg, RoutineName ) - allocate ( m%Vx_wake ( 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vx_wake.', errStat, errMsg, RoutineName ) - allocate ( m%Vr_wake ( 1:maxN_wake ), STAT=errStat2 ) - if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vr_wake.', errStat, errMsg, RoutineName ) + allocate ( m%xhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%xhat_plane.', errStat, errMsg, RoutineName ) + allocate ( m%yhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%yhat_plane.', errStat, errMsg, RoutineName ) + allocate ( m%zhat_plane ( 3, 1:maxN_wake ), STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%zhat_plane.', errStat, errMsg, RoutineName ) + allocate ( m%Vx_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( m%Vy_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( m%Vz_wake ( 1:maxN_wake ) , STAT=errStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%Vz_wake.', errStat, errMsg, RoutineName ) allocate ( m%parallelFlag( 0:p%NumPlanes-2,1:p%NumTurbines ), STAT=errStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%parallelFlag.', errStat, errMsg, RoutineName ) @@ -1413,7 +1453,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! XY plane slices do k = 1,p%NOutDisWindXY - call ExtractSlice( XYSlice, p%OutDisWindZ(k), p%Z0_low, p%nZ_low, p%nX_low, p%nY_low, p%dZ_low, m%Vdist_low, m%outVizXYPlane(:,:,:,1)) + call ExtractSlice( XYSlice, p%OutDisWindZ(k), p%Z0_low, p%nZ_low, p%nX_low, p%nY_low, p%dZ_low, m%Vdist_low_full, m%outVizXYPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisXY.t.vtk FileName = trim(p%OutFileVTKRoot)//".Low.DisXY"//trim(num2lstr(k))//"."//trim(Tstr)//".vtk" call WrVTK_SP_header( FileName, "Low resolution, disturbed wind of XY Slice at time = "//trim(num2lstr(t))//" seconds.", Un, ErrStat2, ErrMsg2 ) @@ -1427,7 +1467,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! YZ plane slices do k = 1,p%NOutDisWindYZ - call ExtractSlice( YZSlice, p%OutDisWindX(k), p%X0_low, p%nX_low, p%nY_low, p%nZ_low, p%dX_low, m%Vdist_low, m%outVizYZPlane(:,:,:,1)) + call ExtractSlice( YZSlice, p%OutDisWindX(k), p%X0_low, p%nX_low, p%nY_low, p%nZ_low, p%dX_low, m%Vdist_low_full, m%outVizYZPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisYZ.t.vtk FileName = trim(p%OutFileVTKRoot)//".Low.DisYZ"//trim(num2lstr(k))//"."//trim(Tstr)//".vtk" call WrVTK_SP_header( FileName, "Low resolution, disturbed wind of YZ Slice at time = "//trim(num2lstr(t))//" seconds.", Un, ErrStat2, ErrMsg2 ) @@ -1440,7 +1480,7 @@ subroutine AWAE_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ! XZ plane slices do k = 1,p%NOutDisWindXZ - call ExtractSlice( XZSlice, p%OutDisWindY(k), p%Y0_low, p%nY_low, p%nX_low, p%nZ_low, p%dY_low, m%Vdist_low, m%outVizXZPlane(:,:,:,1)) + call ExtractSlice( XZSlice, p%OutDisWindY(k), p%Y0_low, p%nY_low, p%nX_low, p%nZ_low, p%dY_low, m%Vdist_low_full, m%outVizXZPlane(:,:,:,1)) ! Create the output vtk file with naming /Low/DisXZ.t.vtk FileName = trim(p%OutFileVTKRoot)//".Low.DisXZ"//trim(num2lstr(k))//"."//trim(Tstr)//".vtk" call WrVTK_SP_header( FileName, "Low resolution, disturbed wind of XZ Slice at time = "//trim(num2lstr(t))//" seconds.", Un, ErrStat2, ErrMsg2 ) @@ -1661,7 +1701,7 @@ subroutine AWAE_TEST_CalcOutput(errStat, errMsg) type(AWAE_InitOutputType) :: initOut !< Input data for initialization routine - integer(IntKi) :: nt, nr, np + integer(IntKi) :: nt, ny, nz, np real(DbKi) :: t ! This example creates turbine 1 at the global coordinate [0,0,0] @@ -1703,9 +1743,12 @@ subroutine AWAE_TEST_CalcOutput(errStat, errMsg) ! Set up the inputs do nt = 1,p%NumTurbines do np = 0,p%NumPlanes-1 - do nr = 0,p%NumRadii-1 - u%Vx_wake(nr,np,nt) = -1.0_ReKi - u%Vr_wake(nr,np,nt) = 0.1_ReKi + do nz = -p%NumRadii+1,p%NumRadii-1 + do ny = -p%NumRadii+1,p%NumRadii-1 + u%Vx_wake(ny,nz,np,nt) = -1.0_ReKi + u%Vy_wake(ny,nz,np,nt) = 0.1_ReKi ! TODO initialize to radial + u%Vz_wake(ny,nz,np,nt) = 0.1_ReKi + end do end do end do end do @@ -1820,6 +1863,158 @@ FUNCTION INTERP3D(p,p0,del,V,within,nX,nY,nZ,Vbox) ! Output the wind velocities at the 8 points in the 3D spatial domain surrounding the input position (if necessary) IF ( PRESENT( Vbox ) ) Vbox = REAL( Vtmp, ReKi ) -END FUNCTION +END FUNCTION INTERP3D + +! +!> 2D interpolation of a scalar field field defined on a 2D-rectilinear grid, using lambda 1 kernel +function interp2d(Point, v1, v2, mesh) result(PointVal) + ! Argument declarations + real(ReKi), dimension(2) , intent(in) :: Point !< Point where values are to be interpolated + real(ReKi), dimension(:), intent(in) :: v1,v2 !< Array of values along 1st and 2nd dimension + real(ReKi), dimension(:,:), intent(in) :: mesh !< Mesh values + real(ReKi) :: PointVal !< Output + ! Variable declarations + real(ReKi) :: ax1,ax2 !< + integer :: i1,i2 !< + real(ReKi) :: ay1,ay2 !< + integer :: j1,j2 !< + integer :: i + real(ReKi), dimension(2) :: dc !< + integer, dimension(2) :: ic !< + ! Indices (ic) and distances (dc) in grid index space (to nearest left grid point) + call coordRectilinearGrid(Point(1), v1, ic(1), dc(1)) + call coordRectilinearGrid(Point(2), v2, ic(2), dc(2)) + ! Getting the lambda 1 kernel coefficients + call interp_coeff_l1(ic(1),dc(1),size(v1),ax1,ax2,i1,i2) + call interp_coeff_l1(ic(2),dc(2),size(v2),ay1,ay2,j1,j2) + ! Interpolation + PointVal = ax1*ay1*mesh(i1,j1) + & + & ax2*ay1*mesh(i2,j1) + & + & ax1*ay2*mesh(i1,j2) + & + & ax2*ay2*mesh(i2,j2) +end function + +!> Returns index and distance of closest value in vx below x0 +subroutine coordRectilinearGrid(x0, vx, ic, dc) + ! Arguments declarations + real(ReKi), dimension(:), intent(in) :: vx !< Array of values + real(ReKi), intent(in) :: x0 !< Point looked for in array + real(ReKi), intent(out) :: dc !< distance to left grid point + integer, intent(out) :: ic !< index of left grid point + ! + dc=0 + ic=binary_search(vx,x0) ! ic can be -1 + if (ic/=-1 .and. ic Return interpolation coefficients for a lambda 1 kernel (linear interpolation) +subroutine interp_coeff_l1(i, dx, nx, ax1, ax2, i1, i2) + ! Arguments declarations + integer, intent(in) :: i !< Index of left node + real(ReKi), intent(in) :: dx !< Normalized distance to mid left node + integer, intent(in) :: nx !< Maximum number of values + real(ReKi), intent(out) :: ax1 !< Interpolation coefficients + real(ReKi), intent(out) :: ax2 !< + integer, intent(out) :: i1 !< Node indexes spreading over the stencil + integer, intent(out) :: i2 !< + ! --- Find index of other cells + i1 = i + i2 = i+1 + ! --- The Lambda 1 kernel coeffs + ax1 = 1._ReKi-dx + ax2 = dx + ! --- Safety if box exceeded + if (i1<0) then + i1=1; i2=1; ax1=1._ReKi; ax2=0; + elseif (i2>nx) then + i1=nx; i2=nx; ax1=1._ReKi; ax2=0; + end if + i1=max(i1,1) + i2=max(i2,1) + i1=min(i1,nx) + i2=min(i2,nx) +end subroutine interp_coeff_l1 + +!> Perform binary search in an array +integer function binary_search(x, x0) result(i_inf) + ! Arguments declarations + real(ReKi), dimension(:),intent(in) :: x ! < array + real(ReKi), intent(in) :: x0 ! < searched value + ! Variable declarations + integer :: i_sup !< + integer :: mid !< + ! x a sorted vector (typically a grid vector) + ! Performs binary search and return the largest index such that x(i) <= x0 + i_inf=1 + i_sup=size(x) + + ! Safety test + if (x0=x(i_sup)) then + i_inf=i_sup + return + end if + + ! We loop until we narrow down to one index + do while (i_inf+11e-5) then + print*,'>>Error interp2d on points',i,j,Vi,Vi_th + STOP + endif + enddo + enddo + + ! --- Test at different points + do i = 1,size(y2) + do j = 1,size(z2) + Vi = interp2d((/y2(i), z2(j)/), y, z, Vx) + Vi_th = testf(y2(i),z2(j)) + if (abs(Vi-Vi_th)>1e-5) then + print*,'>>Error interp2d on misc points',i,j,Vi,Vi_th + STOP + endif + enddo + enddo + contains + real(ReKi) function testf(y,z) + real(ReKi) :: y, z + testf=3._ReKi*y +5._ReKi*z + 10.0_ReKi + end function +end subroutine + end module AWAE diff --git a/modules/awae/src/AWAE_IO.f90 b/modules/awae/src/AWAE_IO.f90 index 9722d9376c..dd8c868080 100644 --- a/modules/awae/src/AWAE_IO.f90 +++ b/modules/awae/src/AWAE_IO.f90 @@ -283,7 +283,7 @@ subroutine AWAE_IO_InitGridInfo(InitInp, p, InitOut, errStat, errMsg) p%dXYZ_Low = gridSpacing p%dpol = (gridSpacing(1)+gridSpacing(2)+gridSpacing(3))/3.0_ReKi - p%n_rp_max = ceiling(pi*((p%C_Meander*(p%r(p%NumRadii-1)+p%dpol))/p%dpol)**2.0_ReKi) + p%n_rp_max = ceiling(pi*((p%C_Meander*((p%NumRadii-1)*InitInp%InputFileData%dr+p%dpol))/p%dpol)**2.0_ReKi) ! Grid runs from (X0_low, Y0_low, Z0_low) to (X0_low + (p%nX_Low-1)*dX_low, Y0_low+ (p%nY_Low-1)*dY_low, Z0_low+ (p%nZ_Low-1)*dZ_low) ! (0,0,0) to (180,180,180) diff --git a/modules/awae/src/AWAE_Registry.txt b/modules/awae/src/AWAE_Registry.txt index 99adf956f6..b05811f8a0 100644 --- a/modules/awae/src/AWAE_Registry.txt +++ b/modules/awae/src/AWAE_Registry.txt @@ -119,8 +119,11 @@ typedef ^ OtherStateType InflowWind_OtherStateType IfW {:} - - "Dum typedef ^ MiscVarType SiKi Vamb_low {:}{:}{:}{:} - - "UVW components of ambient wind across the low-resolution domain throughout the farm" m/s typedef ^ MiscVarType ReKi Vamb_lowpol {:}{:} - - "UVW components of disturbed wind (ambient + wakes) at points in the polar grid for each wake plane for each turbine" m/s typedef ^ MiscVarType SiKi Vdist_low {:}{:}{:}{:} - - "UVW components of disturbed wind (ambient + deficits) across the low-resolution domain throughout the farm" m/s +typedef ^ MiscVarType SiKi Vdist_low_full {:}{:}{:}{:} - - "UVW components of disturbed wind (ambient + deficits) across the low-resolution domain throughout the farm, for outputs" m/s typedef ^ MiscVarType AWAE_HighWindGrid Vamb_High {:} - - "UVW components of ambient wind across each high-resolution domain around a turbine (one for each turbine) for each high-resolution time step within a low-resolution time step" m/s typedef ^ MiscVarType ReKi xhat_plane {:}{:} - - "Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain" - +typedef ^ MiscVarType ReKi yhat_plane {:}{:} - - "Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain" - +typedef ^ MiscVarType ReKi zhat_plane {:}{:} - - "Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain" - typedef ^ MiscVarType ReKi rhat_plane {:}{:} - - "" - typedef ^ MiscVarType Logical parallelFlag {:}{:} - - "" - typedef ^ MiscVarType ReKi r_s {:}{:} - - "" - @@ -130,7 +133,9 @@ typedef ^ MiscVarType ReKi rhat_e {:}{:}{:} - - "" - typedef ^ MiscVarType ReKi pvec_cs {:}{:}{:} - - "" - typedef ^ MiscVarType ReKi pvec_ce {:}{:}{:} - - "" - typedef ^ MiscVarType ReKi Vx_wake {:} - - "" m/s -typedef ^ MiscVarType ReKi Vr_wake {:} - - "" m/s +typedef ^ MiscVarType ReKi Vy_wake {:} - - "" m/s +typedef ^ MiscVarType ReKi Vz_wake {:} - - "" m/s +# typedef ^ MiscVarType SiKi outVizXYPlane {:}{:}{:}{:} -- "An array holding the output data for a 2D visualization slice" - typedef ^ MiscVarType SiKi outVizYZPlane {:}{:}{:}{:} -- "An array holding the output data for a 2D visualization slice" - typedef ^ MiscVarType SiKi outVizXZPlane {:}{:}{:}{:} -- "An array holding the output data for a 2D visualization slice" - @@ -147,7 +152,8 @@ typedef ^ ParameterType CHARACTER(1024) WindFilePath - - - "Path na typedef ^ ParameterType IntKi NumTurbines - - - "Number of wind turbines in the farm [>=1]" - typedef ^ ParameterType IntKi NumRadii - - - "Number of radii in the radial finite-difference grid [>=2]" - typedef ^ ParameterType IntKi NumPlanes - - - "Number of wake planes downwind of the rotor where the wake is propagated [>=2]" - -typedef ^ ParameterType ReKi r {:} - - "Discretization of radial finite-difference grid" m +typedef ^ ParameterType ReKi y {:} - - "Horizontal discretization of the wake planes" m +typedef ^ ParameterType ReKi z {:} - - "Vertical discretization of the wake planes" m typedef ^ ^ IntKi Mod_AmbWind - - - "Ambient wind model {1: high-fidelity precursor in VTK format, 2: InflowWind module}" - typedef ^ ParameterType IntKi nX_low - - - "Number of low-resolution spatial nodes in X direction" - typedef ^ ParameterType IntKi nY_low - - - "Number of low-resolution spatial nodes in Y direction" - @@ -211,7 +217,8 @@ typedef ^ OutputType ReKi Vx_wind_disk {:} - # Define inputs that are contained on the mesh here: typedef ^ InputType ReKi xhat_plane {:}{:}{:} - - "Orientations of wake planes, normal to wake planes, for each turbine" - typedef ^ InputType ReKi p_plane {:}{:}{:} - - "Center positions of wake planes for each turbine" m -typedef ^ InputType ReKi Vx_wake {:}{:}{:} - - "Axial wake velocity deficit at wake planes, distributed radially, for each turbine" m/s -typedef ^ InputType ReKi Vr_wake {:}{:}{:} - - "Radial wake velocity deficit at wake planes, distributed radially, for each turbine" m/s +typedef ^ InputType ReKi Vx_wake {:}{:}{:}{:} - - "Axial wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT)" m/s +typedef ^ InputType ReKi Vy_wake {:}{:}{:}{:} - - "Transverse horizonal wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT)" m/s +typedef ^ InputType ReKi Vz_wake {:}{:}{:}{:} - - "Transverse nominally vertical wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT)" m/s typedef ^ InputType ReKi D_wake {:}{:} - - "Wake diameters at wake planes for each turbine" m diff --git a/modules/awae/src/AWAE_Types.f90 b/modules/awae/src/AWAE_Types.f90 index 743180c0d2..a384c90666 100644 --- a/modules/awae/src/AWAE_Types.f90 +++ b/modules/awae/src/AWAE_Types.f90 @@ -145,8 +145,11 @@ MODULE AWAE_Types REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vamb_low !< UVW components of ambient wind across the low-resolution domain throughout the farm [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vamb_lowpol !< UVW components of disturbed wind (ambient + wakes) at points in the polar grid for each wake plane for each turbine [m/s] REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vdist_low !< UVW components of disturbed wind (ambient + deficits) across the low-resolution domain throughout the farm [m/s] + REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vdist_low_full !< UVW components of disturbed wind (ambient + deficits) across the low-resolution domain throughout the farm, for outputs [m/s] TYPE(AWAE_HighWindGrid) , DIMENSION(:), ALLOCATABLE :: Vamb_High !< UVW components of ambient wind across each high-resolution domain around a turbine (one for each turbine) for each high-resolution time step within a low-resolution time step [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: xhat_plane !< Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: yhat_plane !< Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: zhat_plane !< Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain Orientations of wake planes, normal to wake planes, associated with a given point in the wind spatial domain [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: rhat_plane !< [-] LOGICAL , DIMENSION(:,:), ALLOCATABLE :: parallelFlag !< [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: r_s !< [-] @@ -156,7 +159,8 @@ MODULE AWAE_Types REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: pvec_cs !< [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: pvec_ce !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vx_wake !< [m/s] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vr_wake !< [m/s] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vy_wake !< [m/s] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vz_wake !< [m/s] REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: outVizXYPlane REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: outVizYZPlane REAL(SiKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: outVizXZPlane @@ -173,7 +177,8 @@ MODULE AWAE_Types INTEGER(IntKi) :: NumTurbines !< Number of wind turbines in the farm [>=1] [-] INTEGER(IntKi) :: NumRadii !< Number of radii in the radial finite-difference grid [>=2] [-] INTEGER(IntKi) :: NumPlanes !< Number of wake planes downwind of the rotor where the wake is propagated [>=2] [-] - REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: r !< Discretization of radial finite-difference grid [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: y !< Horizontal discretization of the wake planes [m] + REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: z !< Vertical discretization of the wake planes [m] INTEGER(IntKi) :: Mod_AmbWind !< Ambient wind model {1: high-fidelity precursor in VTK format, 2: InflowWind module} [-] INTEGER(IntKi) :: nX_low !< Number of low-resolution spatial nodes in X direction [-] INTEGER(IntKi) :: nY_low !< Number of low-resolution spatial nodes in Y direction [-] @@ -234,8 +239,9 @@ MODULE AWAE_Types TYPE, PUBLIC :: AWAE_InputType REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: xhat_plane !< Orientations of wake planes, normal to wake planes, for each turbine [-] REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: p_plane !< Center positions of wake planes for each turbine [m] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vx_wake !< Axial wake velocity deficit at wake planes, distributed radially, for each turbine [m/s] - REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vr_wake !< Radial wake velocity deficit at wake planes, distributed radially, for each turbine [m/s] + REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vx_wake !< Axial wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT) [m/s] + REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vy_wake !< Transverse horizonal wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT) [m/s] + REAL(ReKi) , DIMENSION(:,:,:,:), ALLOCATABLE :: Vz_wake !< Transverse nominally vertical wake velocity deficit at wake planes, distributed across the plane, for each turbine (ny,nz,np,nWT) [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: D_wake !< Wake diameters at wake planes for each turbine [m] END TYPE AWAE_InputType ! ======================= @@ -3381,6 +3387,24 @@ SUBROUTINE AWAE_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%Vdist_low = SrcMiscData%Vdist_low ENDIF +IF (ALLOCATED(SrcMiscData%Vdist_low_full)) THEN + i1_l = LBOUND(SrcMiscData%Vdist_low_full,1) + i1_u = UBOUND(SrcMiscData%Vdist_low_full,1) + i2_l = LBOUND(SrcMiscData%Vdist_low_full,2) + i2_u = UBOUND(SrcMiscData%Vdist_low_full,2) + i3_l = LBOUND(SrcMiscData%Vdist_low_full,3) + i3_u = UBOUND(SrcMiscData%Vdist_low_full,3) + i4_l = LBOUND(SrcMiscData%Vdist_low_full,4) + i4_u = UBOUND(SrcMiscData%Vdist_low_full,4) + IF (.NOT. ALLOCATED(DstMiscData%Vdist_low_full)) THEN + ALLOCATE(DstMiscData%Vdist_low_full(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Vdist_low_full.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%Vdist_low_full = SrcMiscData%Vdist_low_full +ENDIF IF (ALLOCATED(SrcMiscData%Vamb_High)) THEN i1_l = LBOUND(SrcMiscData%Vamb_High,1) i1_u = UBOUND(SrcMiscData%Vamb_High,1) @@ -3411,6 +3435,34 @@ SUBROUTINE AWAE_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%xhat_plane = SrcMiscData%xhat_plane ENDIF +IF (ALLOCATED(SrcMiscData%yhat_plane)) THEN + i1_l = LBOUND(SrcMiscData%yhat_plane,1) + i1_u = UBOUND(SrcMiscData%yhat_plane,1) + i2_l = LBOUND(SrcMiscData%yhat_plane,2) + i2_u = UBOUND(SrcMiscData%yhat_plane,2) + IF (.NOT. ALLOCATED(DstMiscData%yhat_plane)) THEN + ALLOCATE(DstMiscData%yhat_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%yhat_plane.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%yhat_plane = SrcMiscData%yhat_plane +ENDIF +IF (ALLOCATED(SrcMiscData%zhat_plane)) THEN + i1_l = LBOUND(SrcMiscData%zhat_plane,1) + i1_u = UBOUND(SrcMiscData%zhat_plane,1) + i2_l = LBOUND(SrcMiscData%zhat_plane,2) + i2_u = UBOUND(SrcMiscData%zhat_plane,2) + IF (.NOT. ALLOCATED(DstMiscData%zhat_plane)) THEN + ALLOCATE(DstMiscData%zhat_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%zhat_plane.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%zhat_plane = SrcMiscData%zhat_plane +ENDIF IF (ALLOCATED(SrcMiscData%rhat_plane)) THEN i1_l = LBOUND(SrcMiscData%rhat_plane,1) i1_u = UBOUND(SrcMiscData%rhat_plane,1) @@ -3543,17 +3595,29 @@ SUBROUTINE AWAE_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%Vx_wake = SrcMiscData%Vx_wake ENDIF -IF (ALLOCATED(SrcMiscData%Vr_wake)) THEN - i1_l = LBOUND(SrcMiscData%Vr_wake,1) - i1_u = UBOUND(SrcMiscData%Vr_wake,1) - IF (.NOT. ALLOCATED(DstMiscData%Vr_wake)) THEN - ALLOCATE(DstMiscData%Vr_wake(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcMiscData%Vy_wake)) THEN + i1_l = LBOUND(SrcMiscData%Vy_wake,1) + i1_u = UBOUND(SrcMiscData%Vy_wake,1) + IF (.NOT. ALLOCATED(DstMiscData%Vy_wake)) THEN + ALLOCATE(DstMiscData%Vy_wake(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Vr_wake.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Vy_wake.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstMiscData%Vr_wake = SrcMiscData%Vr_wake + DstMiscData%Vy_wake = SrcMiscData%Vy_wake +ENDIF +IF (ALLOCATED(SrcMiscData%Vz_wake)) THEN + i1_l = LBOUND(SrcMiscData%Vz_wake,1) + i1_u = UBOUND(SrcMiscData%Vz_wake,1) + IF (.NOT. ALLOCATED(DstMiscData%Vz_wake)) THEN + ALLOCATE(DstMiscData%Vz_wake(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%Vz_wake.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%Vz_wake = SrcMiscData%Vz_wake ENDIF IF (ALLOCATED(SrcMiscData%outVizXYPlane)) THEN i1_l = LBOUND(SrcMiscData%outVizXYPlane,1) @@ -3669,6 +3733,9 @@ SUBROUTINE AWAE_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) IF (ALLOCATED(MiscData%Vdist_low)) THEN DEALLOCATE(MiscData%Vdist_low) ENDIF +IF (ALLOCATED(MiscData%Vdist_low_full)) THEN + DEALLOCATE(MiscData%Vdist_low_full) +ENDIF IF (ALLOCATED(MiscData%Vamb_High)) THEN DO i1 = LBOUND(MiscData%Vamb_High,1), UBOUND(MiscData%Vamb_High,1) CALL AWAE_Destroyhighwindgrid( MiscData%Vamb_High(i1), ErrStat2, ErrMsg2, DEALLOCATEpointers_local ) @@ -3679,6 +3746,12 @@ SUBROUTINE AWAE_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) IF (ALLOCATED(MiscData%xhat_plane)) THEN DEALLOCATE(MiscData%xhat_plane) ENDIF +IF (ALLOCATED(MiscData%yhat_plane)) THEN + DEALLOCATE(MiscData%yhat_plane) +ENDIF +IF (ALLOCATED(MiscData%zhat_plane)) THEN + DEALLOCATE(MiscData%zhat_plane) +ENDIF IF (ALLOCATED(MiscData%rhat_plane)) THEN DEALLOCATE(MiscData%rhat_plane) ENDIF @@ -3706,8 +3779,11 @@ SUBROUTINE AWAE_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) IF (ALLOCATED(MiscData%Vx_wake)) THEN DEALLOCATE(MiscData%Vx_wake) ENDIF -IF (ALLOCATED(MiscData%Vr_wake)) THEN - DEALLOCATE(MiscData%Vr_wake) +IF (ALLOCATED(MiscData%Vy_wake)) THEN + DEALLOCATE(MiscData%Vy_wake) +ENDIF +IF (ALLOCATED(MiscData%Vz_wake)) THEN + DEALLOCATE(MiscData%Vz_wake) ENDIF IF (ALLOCATED(MiscData%outVizXYPlane)) THEN DEALLOCATE(MiscData%outVizXYPlane) @@ -3785,6 +3861,11 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 2*4 ! Vdist_low upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vdist_low) ! Vdist_low END IF + Int_BufSz = Int_BufSz + 1 ! Vdist_low_full allocated yes/no + IF ( ALLOCATED(InData%Vdist_low_full) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Vdist_low_full upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vdist_low_full) ! Vdist_low_full + END IF Int_BufSz = Int_BufSz + 1 ! Vamb_High allocated yes/no IF ( ALLOCATED(InData%Vamb_High) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Vamb_High upper/lower bounds for each dimension @@ -3814,6 +3895,16 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 2*2 ! xhat_plane upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%xhat_plane) ! xhat_plane END IF + Int_BufSz = Int_BufSz + 1 ! yhat_plane allocated yes/no + IF ( ALLOCATED(InData%yhat_plane) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! yhat_plane upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%yhat_plane) ! yhat_plane + END IF + Int_BufSz = Int_BufSz + 1 ! zhat_plane allocated yes/no + IF ( ALLOCATED(InData%zhat_plane) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! zhat_plane upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%zhat_plane) ! zhat_plane + END IF Int_BufSz = Int_BufSz + 1 ! rhat_plane allocated yes/no IF ( ALLOCATED(InData%rhat_plane) ) THEN Int_BufSz = Int_BufSz + 2*2 ! rhat_plane upper/lower bounds for each dimension @@ -3859,10 +3950,15 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 2*1 ! Vx_wake upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vx_wake) ! Vx_wake END IF - Int_BufSz = Int_BufSz + 1 ! Vr_wake allocated yes/no - IF ( ALLOCATED(InData%Vr_wake) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! Vr_wake upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Vr_wake) ! Vr_wake + Int_BufSz = Int_BufSz + 1 ! Vy_wake allocated yes/no + IF ( ALLOCATED(InData%Vy_wake) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Vy_wake upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vy_wake) ! Vy_wake + END IF + Int_BufSz = Int_BufSz + 1 ! Vz_wake allocated yes/no + IF ( ALLOCATED(InData%Vz_wake) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! Vz_wake upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vz_wake) ! Vz_wake END IF Int_BufSz = Int_BufSz + 1 ! outVizXYPlane allocated yes/no IF ( ALLOCATED(InData%outVizXYPlane) ) THEN @@ -4077,6 +4173,36 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%Vdist_low_full) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vdist_low_full,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vdist_low_full,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vdist_low_full,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vdist_low_full,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vdist_low_full,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vdist_low_full,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vdist_low_full,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vdist_low_full,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Vdist_low_full,4), UBOUND(InData%Vdist_low_full,4) + DO i3 = LBOUND(InData%Vdist_low_full,3), UBOUND(InData%Vdist_low_full,3) + DO i2 = LBOUND(InData%Vdist_low_full,2), UBOUND(InData%Vdist_low_full,2) + DO i1 = LBOUND(InData%Vdist_low_full,1), UBOUND(InData%Vdist_low_full,1) + ReKiBuf(Re_Xferred) = InData%Vdist_low_full(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%Vamb_High) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4138,6 +4264,46 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%yhat_plane) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%yhat_plane,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%yhat_plane,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%yhat_plane,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%yhat_plane,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%yhat_plane,2), UBOUND(InData%yhat_plane,2) + DO i1 = LBOUND(InData%yhat_plane,1), UBOUND(InData%yhat_plane,1) + ReKiBuf(Re_Xferred) = InData%yhat_plane(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%zhat_plane) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%zhat_plane,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%zhat_plane,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%zhat_plane,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%zhat_plane,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%zhat_plane,2), UBOUND(InData%zhat_plane,2) + DO i1 = LBOUND(InData%zhat_plane,1), UBOUND(InData%zhat_plane,1) + ReKiBuf(Re_Xferred) = InData%zhat_plane(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%rhat_plane) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4333,18 +4499,33 @@ SUBROUTINE AWAE_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( .NOT. ALLOCATED(InData%Vr_wake) ) THEN + IF ( .NOT. ALLOCATED(InData%Vy_wake) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%Vy_wake,1), UBOUND(InData%Vy_wake,1) + ReKiBuf(Re_Xferred) = InData%Vy_wake(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vz_wake) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vr_wake,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vr_wake,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%Vr_wake,1), UBOUND(InData%Vr_wake,1) - ReKiBuf(Re_Xferred) = InData%Vr_wake(i1) + DO i1 = LBOUND(InData%Vz_wake,1), UBOUND(InData%Vz_wake,1) + ReKiBuf(Re_Xferred) = InData%Vz_wake(i1) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -4712,6 +4893,39 @@ SUBROUTINE AWAE_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vdist_low_full not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vdist_low_full)) DEALLOCATE(OutData%Vdist_low_full) + ALLOCATE(OutData%Vdist_low_full(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vdist_low_full.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Vdist_low_full,4), UBOUND(OutData%Vdist_low_full,4) + DO i3 = LBOUND(OutData%Vdist_low_full,3), UBOUND(OutData%Vdist_low_full,3) + DO i2 = LBOUND(OutData%Vdist_low_full,2), UBOUND(OutData%Vdist_low_full,2) + DO i1 = LBOUND(OutData%Vdist_low_full,1), UBOUND(OutData%Vdist_low_full,1) + OutData%Vdist_low_full(i1,i2,i3,i4) = REAL(ReKiBuf(Re_Xferred), SiKi) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vamb_High not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4791,6 +5005,52 @@ SUBROUTINE AWAE_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! yhat_plane not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%yhat_plane)) DEALLOCATE(OutData%yhat_plane) + ALLOCATE(OutData%yhat_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%yhat_plane.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%yhat_plane,2), UBOUND(OutData%yhat_plane,2) + DO i1 = LBOUND(OutData%yhat_plane,1), UBOUND(OutData%yhat_plane,1) + OutData%yhat_plane(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! zhat_plane not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%zhat_plane)) DEALLOCATE(OutData%zhat_plane) + ALLOCATE(OutData%zhat_plane(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%zhat_plane.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%zhat_plane,2), UBOUND(OutData%zhat_plane,2) + DO i1 = LBOUND(OutData%zhat_plane,1), UBOUND(OutData%zhat_plane,1) + OutData%zhat_plane(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! rhat_plane not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -5013,21 +5273,39 @@ SUBROUTINE AWAE_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg Re_Xferred = Re_Xferred + 1 END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vr_wake not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vy_wake not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Vr_wake)) DEALLOCATE(OutData%Vr_wake) - ALLOCATE(OutData%Vr_wake(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%Vy_wake)) DEALLOCATE(OutData%Vy_wake) + ALLOCATE(OutData%Vy_wake(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vr_wake.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vy_wake.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%Vr_wake,1), UBOUND(OutData%Vr_wake,1) - OutData%Vr_wake(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%Vy_wake,1), UBOUND(OutData%Vy_wake,1) + OutData%Vy_wake(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vz_wake not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vz_wake)) DEALLOCATE(OutData%Vz_wake) + ALLOCATE(OutData%Vz_wake(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vz_wake.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%Vz_wake,1), UBOUND(OutData%Vz_wake,1) + OutData%Vz_wake(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -5369,17 +5647,29 @@ SUBROUTINE AWAE_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg DstParamData%NumTurbines = SrcParamData%NumTurbines DstParamData%NumRadii = SrcParamData%NumRadii DstParamData%NumPlanes = SrcParamData%NumPlanes -IF (ALLOCATED(SrcParamData%r)) THEN - i1_l = LBOUND(SrcParamData%r,1) - i1_u = UBOUND(SrcParamData%r,1) - IF (.NOT. ALLOCATED(DstParamData%r)) THEN - ALLOCATE(DstParamData%r(i1_l:i1_u),STAT=ErrStat2) +IF (ALLOCATED(SrcParamData%y)) THEN + i1_l = LBOUND(SrcParamData%y,1) + i1_u = UBOUND(SrcParamData%y,1) + IF (.NOT. ALLOCATED(DstParamData%y)) THEN + ALLOCATE(DstParamData%y(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%r.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%y.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstParamData%r = SrcParamData%r + DstParamData%y = SrcParamData%y +ENDIF +IF (ALLOCATED(SrcParamData%z)) THEN + i1_l = LBOUND(SrcParamData%z,1) + i1_u = UBOUND(SrcParamData%z,1) + IF (.NOT. ALLOCATED(DstParamData%z)) THEN + ALLOCATE(DstParamData%z(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%z.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstParamData%z = SrcParamData%z ENDIF DstParamData%Mod_AmbWind = SrcParamData%Mod_AmbWind DstParamData%nX_low = SrcParamData%nX_low @@ -5605,8 +5895,11 @@ SUBROUTINE AWAE_DestroyParam( ParamData, ErrStat, ErrMsg, DEALLOCATEpointers ) DEALLOCATEpointers_local = .true. END IF -IF (ALLOCATED(ParamData%r)) THEN - DEALLOCATE(ParamData%r) +IF (ALLOCATED(ParamData%y)) THEN + DEALLOCATE(ParamData%y) +ENDIF +IF (ALLOCATED(ParamData%z)) THEN + DEALLOCATE(ParamData%z) ENDIF IF (ALLOCATED(ParamData%X0_high)) THEN DEALLOCATE(ParamData%X0_high) @@ -5692,10 +5985,15 @@ SUBROUTINE AWAE_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_BufSz = Int_BufSz + 1 ! NumTurbines Int_BufSz = Int_BufSz + 1 ! NumRadii Int_BufSz = Int_BufSz + 1 ! NumPlanes - Int_BufSz = Int_BufSz + 1 ! r allocated yes/no - IF ( ALLOCATED(InData%r) ) THEN - Int_BufSz = Int_BufSz + 2*1 ! r upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%r) ! r + Int_BufSz = Int_BufSz + 1 ! y allocated yes/no + IF ( ALLOCATED(InData%y) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! y upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%y) ! y + END IF + Int_BufSz = Int_BufSz + 1 ! z allocated yes/no + IF ( ALLOCATED(InData%z) ) THEN + Int_BufSz = Int_BufSz + 2*1 ! z upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%z) ! z END IF Int_BufSz = Int_BufSz + 1 ! Mod_AmbWind Int_BufSz = Int_BufSz + 1 ! nX_low @@ -5851,18 +6149,33 @@ SUBROUTINE AWAE_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_Xferred = Int_Xferred + 1 IntKiBuf(Int_Xferred) = InData%NumPlanes Int_Xferred = Int_Xferred + 1 - IF ( .NOT. ALLOCATED(InData%r) ) THEN + IF ( .NOT. ALLOCATED(InData%y) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%r,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%r,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%y,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%y,1) Int_Xferred = Int_Xferred + 2 - DO i1 = LBOUND(InData%r,1), UBOUND(InData%r,1) - ReKiBuf(Re_Xferred) = InData%r(i1) + DO i1 = LBOUND(InData%y,1), UBOUND(InData%y,1) + ReKiBuf(Re_Xferred) = InData%y(i1) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( .NOT. ALLOCATED(InData%z) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%z,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%z,1) + Int_Xferred = Int_Xferred + 2 + + DO i1 = LBOUND(InData%z,1), UBOUND(InData%z,1) + ReKiBuf(Re_Xferred) = InData%z(i1) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -6220,21 +6533,39 @@ SUBROUTINE AWAE_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs Int_Xferred = Int_Xferred + 1 OutData%NumPlanes = IntKiBuf(Int_Xferred) Int_Xferred = Int_Xferred + 1 - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! r not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! y not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%y)) DEALLOCATE(OutData%y) + ALLOCATE(OutData%y(i1_l:i1_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%y.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i1 = LBOUND(OutData%y,1), UBOUND(OutData%y,1) + OutData%y(i1) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! z not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 i1_l = IntKiBuf( Int_Xferred ) i1_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%r)) DEALLOCATE(OutData%r) - ALLOCATE(OutData%r(i1_l:i1_u),STAT=ErrStat2) + IF (ALLOCATED(OutData%z)) DEALLOCATE(OutData%z) + ALLOCATE(OutData%z(i1_l:i1_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%r.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%z.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i1 = LBOUND(OutData%r,1), UBOUND(OutData%r,1) - OutData%r(i1) = ReKiBuf(Re_Xferred) + DO i1 = LBOUND(OutData%z,1), UBOUND(OutData%z,1) + OutData%z(i1) = ReKiBuf(Re_Xferred) Re_Xferred = Re_Xferred + 1 END DO END IF @@ -7081,6 +7412,7 @@ SUBROUTINE AWAE_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_CopyInput' @@ -7126,8 +7458,10 @@ SUBROUTINE AWAE_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg i2_u = UBOUND(SrcInputData%Vx_wake,2) i3_l = LBOUND(SrcInputData%Vx_wake,3) i3_u = UBOUND(SrcInputData%Vx_wake,3) + i4_l = LBOUND(SrcInputData%Vx_wake,4) + i4_u = UBOUND(SrcInputData%Vx_wake,4) IF (.NOT. ALLOCATED(DstInputData%Vx_wake)) THEN - ALLOCATE(DstInputData%Vx_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + ALLOCATE(DstInputData%Vx_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Vx_wake.', ErrStat, ErrMsg,RoutineName) RETURN @@ -7135,21 +7469,41 @@ SUBROUTINE AWAE_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg END IF DstInputData%Vx_wake = SrcInputData%Vx_wake ENDIF -IF (ALLOCATED(SrcInputData%Vr_wake)) THEN - i1_l = LBOUND(SrcInputData%Vr_wake,1) - i1_u = UBOUND(SrcInputData%Vr_wake,1) - i2_l = LBOUND(SrcInputData%Vr_wake,2) - i2_u = UBOUND(SrcInputData%Vr_wake,2) - i3_l = LBOUND(SrcInputData%Vr_wake,3) - i3_u = UBOUND(SrcInputData%Vr_wake,3) - IF (.NOT. ALLOCATED(DstInputData%Vr_wake)) THEN - ALLOCATE(DstInputData%Vr_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) - IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Vr_wake.', ErrStat, ErrMsg,RoutineName) +IF (ALLOCATED(SrcInputData%Vy_wake)) THEN + i1_l = LBOUND(SrcInputData%Vy_wake,1) + i1_u = UBOUND(SrcInputData%Vy_wake,1) + i2_l = LBOUND(SrcInputData%Vy_wake,2) + i2_u = UBOUND(SrcInputData%Vy_wake,2) + i3_l = LBOUND(SrcInputData%Vy_wake,3) + i3_u = UBOUND(SrcInputData%Vy_wake,3) + i4_l = LBOUND(SrcInputData%Vy_wake,4) + i4_u = UBOUND(SrcInputData%Vy_wake,4) + IF (.NOT. ALLOCATED(DstInputData%Vy_wake)) THEN + ALLOCATE(DstInputData%Vy_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Vy_wake.', ErrStat, ErrMsg,RoutineName) RETURN END IF END IF - DstInputData%Vr_wake = SrcInputData%Vr_wake + DstInputData%Vy_wake = SrcInputData%Vy_wake +ENDIF +IF (ALLOCATED(SrcInputData%Vz_wake)) THEN + i1_l = LBOUND(SrcInputData%Vz_wake,1) + i1_u = UBOUND(SrcInputData%Vz_wake,1) + i2_l = LBOUND(SrcInputData%Vz_wake,2) + i2_u = UBOUND(SrcInputData%Vz_wake,2) + i3_l = LBOUND(SrcInputData%Vz_wake,3) + i3_u = UBOUND(SrcInputData%Vz_wake,3) + i4_l = LBOUND(SrcInputData%Vz_wake,4) + i4_u = UBOUND(SrcInputData%Vz_wake,4) + IF (.NOT. ALLOCATED(DstInputData%Vz_wake)) THEN + ALLOCATE(DstInputData%Vz_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInputData%Vz_wake.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstInputData%Vz_wake = SrcInputData%Vz_wake ENDIF IF (ALLOCATED(SrcInputData%D_wake)) THEN i1_l = LBOUND(SrcInputData%D_wake,1) @@ -7197,8 +7551,11 @@ SUBROUTINE AWAE_DestroyInput( InputData, ErrStat, ErrMsg, DEALLOCATEpointers ) IF (ALLOCATED(InputData%Vx_wake)) THEN DEALLOCATE(InputData%Vx_wake) ENDIF -IF (ALLOCATED(InputData%Vr_wake)) THEN - DEALLOCATE(InputData%Vr_wake) +IF (ALLOCATED(InputData%Vy_wake)) THEN + DEALLOCATE(InputData%Vy_wake) +ENDIF +IF (ALLOCATED(InputData%Vz_wake)) THEN + DEALLOCATE(InputData%Vz_wake) ENDIF IF (ALLOCATED(InputData%D_wake)) THEN DEALLOCATE(InputData%D_wake) @@ -7252,13 +7609,18 @@ SUBROUTINE AWAE_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, END IF Int_BufSz = Int_BufSz + 1 ! Vx_wake allocated yes/no IF ( ALLOCATED(InData%Vx_wake) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! Vx_wake upper/lower bounds for each dimension + Int_BufSz = Int_BufSz + 2*4 ! Vx_wake upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vx_wake) ! Vx_wake END IF - Int_BufSz = Int_BufSz + 1 ! Vr_wake allocated yes/no - IF ( ALLOCATED(InData%Vr_wake) ) THEN - Int_BufSz = Int_BufSz + 2*3 ! Vr_wake upper/lower bounds for each dimension - Re_BufSz = Re_BufSz + SIZE(InData%Vr_wake) ! Vr_wake + Int_BufSz = Int_BufSz + 1 ! Vy_wake allocated yes/no + IF ( ALLOCATED(InData%Vy_wake) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Vy_wake upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vy_wake) ! Vy_wake + END IF + Int_BufSz = Int_BufSz + 1 ! Vz_wake allocated yes/no + IF ( ALLOCATED(InData%Vz_wake) ) THEN + Int_BufSz = Int_BufSz + 2*4 ! Vz_wake upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vz_wake) ! Vz_wake END IF Int_BufSz = Int_BufSz + 1 ! D_wake allocated yes/no IF ( ALLOCATED(InData%D_wake) ) THEN @@ -7356,38 +7718,78 @@ SUBROUTINE AWAE_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Int_Xferred = Int_Xferred + 2 IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake,3) IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake,4) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%Vx_wake,3), UBOUND(InData%Vx_wake,3) - DO i2 = LBOUND(InData%Vx_wake,2), UBOUND(InData%Vx_wake,2) - DO i1 = LBOUND(InData%Vx_wake,1), UBOUND(InData%Vx_wake,1) - ReKiBuf(Re_Xferred) = InData%Vx_wake(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 + DO i4 = LBOUND(InData%Vx_wake,4), UBOUND(InData%Vx_wake,4) + DO i3 = LBOUND(InData%Vx_wake,3), UBOUND(InData%Vx_wake,3) + DO i2 = LBOUND(InData%Vx_wake,2), UBOUND(InData%Vx_wake,2) + DO i1 = LBOUND(InData%Vx_wake,1), UBOUND(InData%Vx_wake,1) + ReKiBuf(Re_Xferred) = InData%Vx_wake(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END DO END IF - IF ( .NOT. ALLOCATED(InData%Vr_wake) ) THEN + IF ( .NOT. ALLOCATED(InData%Vy_wake) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vr_wake,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vr_wake,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vr_wake,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vr_wake,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,2) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%Vr_wake,3) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vr_wake,3) + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake,4) Int_Xferred = Int_Xferred + 2 - DO i3 = LBOUND(InData%Vr_wake,3), UBOUND(InData%Vr_wake,3) - DO i2 = LBOUND(InData%Vr_wake,2), UBOUND(InData%Vr_wake,2) - DO i1 = LBOUND(InData%Vr_wake,1), UBOUND(InData%Vr_wake,1) - ReKiBuf(Re_Xferred) = InData%Vr_wake(i1,i2,i3) - Re_Xferred = Re_Xferred + 1 + DO i4 = LBOUND(InData%Vy_wake,4), UBOUND(InData%Vy_wake,4) + DO i3 = LBOUND(InData%Vy_wake,3), UBOUND(InData%Vy_wake,3) + DO i2 = LBOUND(InData%Vy_wake,2), UBOUND(InData%Vy_wake,2) + DO i1 = LBOUND(InData%Vy_wake,1), UBOUND(InData%Vy_wake,1) + ReKiBuf(Re_Xferred) = InData%Vy_wake(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vz_wake) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,3) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake,4) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake,4) + Int_Xferred = Int_Xferred + 2 + + DO i4 = LBOUND(InData%Vz_wake,4), UBOUND(InData%Vz_wake,4) + DO i3 = LBOUND(InData%Vz_wake,3), UBOUND(InData%Vz_wake,3) + DO i2 = LBOUND(InData%Vz_wake,2), UBOUND(InData%Vz_wake,2) + DO i1 = LBOUND(InData%Vz_wake,1), UBOUND(InData%Vz_wake,1) + ReKiBuf(Re_Xferred) = InData%Vz_wake(i1,i2,i3,i4) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END DO @@ -7430,6 +7832,7 @@ SUBROUTINE AWAE_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 + INTEGER(IntKi) :: i4, i4_l, i4_u ! bounds (upper/lower) for an array dimension 4 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'AWAE_UnPackInput' @@ -7512,22 +7915,27 @@ SUBROUTINE AWAE_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs i3_l = IntKiBuf( Int_Xferred ) i3_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 IF (ALLOCATED(OutData%Vx_wake)) DEALLOCATE(OutData%Vx_wake) - ALLOCATE(OutData%Vx_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + ALLOCATE(OutData%Vx_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vx_wake.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%Vx_wake,3), UBOUND(OutData%Vx_wake,3) - DO i2 = LBOUND(OutData%Vx_wake,2), UBOUND(OutData%Vx_wake,2) - DO i1 = LBOUND(OutData%Vx_wake,1), UBOUND(OutData%Vx_wake,1) - OutData%Vx_wake(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i4 = LBOUND(OutData%Vx_wake,4), UBOUND(OutData%Vx_wake,4) + DO i3 = LBOUND(OutData%Vx_wake,3), UBOUND(OutData%Vx_wake,3) + DO i2 = LBOUND(OutData%Vx_wake,2), UBOUND(OutData%Vx_wake,2) + DO i1 = LBOUND(OutData%Vx_wake,1), UBOUND(OutData%Vx_wake,1) + OutData%Vx_wake(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END DO END IF - IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vr_wake not allocated + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vy_wake not allocated Int_Xferred = Int_Xferred + 1 ELSE Int_Xferred = Int_Xferred + 1 @@ -7540,17 +7948,55 @@ SUBROUTINE AWAE_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMs i3_l = IntKiBuf( Int_Xferred ) i3_u = IntKiBuf( Int_Xferred + 1) Int_Xferred = Int_Xferred + 2 - IF (ALLOCATED(OutData%Vr_wake)) DEALLOCATE(OutData%Vr_wake) - ALLOCATE(OutData%Vr_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vy_wake)) DEALLOCATE(OutData%Vy_wake) + ALLOCATE(OutData%Vy_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) IF (ErrStat2 /= 0) THEN - CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vr_wake.', ErrStat, ErrMsg,RoutineName) + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vy_wake.', ErrStat, ErrMsg,RoutineName) RETURN END IF - DO i3 = LBOUND(OutData%Vr_wake,3), UBOUND(OutData%Vr_wake,3) - DO i2 = LBOUND(OutData%Vr_wake,2), UBOUND(OutData%Vr_wake,2) - DO i1 = LBOUND(OutData%Vr_wake,1), UBOUND(OutData%Vr_wake,1) - OutData%Vr_wake(i1,i2,i3) = ReKiBuf(Re_Xferred) - Re_Xferred = Re_Xferred + 1 + DO i4 = LBOUND(OutData%Vy_wake,4), UBOUND(OutData%Vy_wake,4) + DO i3 = LBOUND(OutData%Vy_wake,3), UBOUND(OutData%Vy_wake,3) + DO i2 = LBOUND(OutData%Vy_wake,2), UBOUND(OutData%Vy_wake,2) + DO i1 = LBOUND(OutData%Vy_wake,1), UBOUND(OutData%Vy_wake,1) + OutData%Vy_wake(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vz_wake not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i4_l = IntKiBuf( Int_Xferred ) + i4_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vz_wake)) DEALLOCATE(OutData%Vz_wake) + ALLOCATE(OutData%Vz_wake(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u,i4_l:i4_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vz_wake.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i4 = LBOUND(OutData%Vz_wake,4), UBOUND(OutData%Vz_wake,4) + DO i3 = LBOUND(OutData%Vz_wake,3), UBOUND(OutData%Vz_wake,3) + DO i2 = LBOUND(OutData%Vz_wake,2), UBOUND(OutData%Vz_wake,2) + DO i1 = LBOUND(OutData%Vz_wake,1), UBOUND(OutData%Vz_wake,1) + OutData%Vz_wake(i1,i2,i3,i4) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO END DO END DO END DO diff --git a/modules/wakedynamics/src/WakeDynamics.f90 b/modules/wakedynamics/src/WakeDynamics.f90 index eec140da2e..86cbb241f9 100644 --- a/modules/wakedynamics/src/WakeDynamics.f90 +++ b/modules/wakedynamics/src/WakeDynamics.f90 @@ -42,7 +42,8 @@ module WakeDynamics ! continuous states, and updating discrete states public :: WD_CalcOutput ! Routine for computing outputs public :: WD_CalcConstrStateResidual ! Tight coupling routine for returning the constraint state residual - + + public :: WD_TEST_Axi2Cart contains function WD_Interp ( yVal, xArr, yArr ) @@ -466,11 +467,19 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut ! Finite difference grid coordinates r, y, z allocate( p%r(0:p%NumRadii-1),stat=errStat2) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%r.', errStat, errMsg, RoutineName ) + allocate(p%y(-p%NumRadii+1:p%NumRadii-1), stat=errStat2); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%y.', errStat, errMsg, RoutineName ) + allocate(p%z(-p%NumRadii+1:p%NumRadii-1), stat=errStat2); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for p%z.', errStat, errMsg, RoutineName ) if (errStat /= ErrID_None) return do i = 0,p%NumRadii-1 p%r(i) = p%dr*i end do + do i = -p%NumRadii+1,p%NumRadii-1 + p%y(i) = p%dr*i + p%z(i) = p%dr*i + end do + + p%filtParam = exp(-2.0_ReKi*pi*p%dt_low*InitInp%InputFileData%f_c) p%oneMinusFiltParam = 1.0_ReKi - p%filtParam @@ -526,6 +535,12 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Cq_azavg_filt.', errStat, errMsg, RoutineName ) allocate ( xd%Vx_wake (0:p%NumRadii-1,0:p%NumPlanes-1) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vx_wake.', errStat, errMsg, RoutineName ) allocate ( xd%Vr_wake (0:p%NumRadii-1,0:p%NumPlanes-1) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vr_wake.', errStat, errMsg, RoutineName ) + allocate ( xd%Vx_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vx_wake.', errStat, errMsg, RoutineName ) + if (errStat /= ErrID_None) return + + ! Curl + allocate ( xd%Vy_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( xd%Vz_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for xd%Vz_wake.', errStat, errMsg, RoutineName ) if (errStat /= ErrID_None) return xd%YawErr_filt = 0.0_ReKi !NOTE: initialized in InitStatesWithInputs @@ -537,6 +552,7 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut xd%x_plane = 0.0_ReKi xd%Vx_wake = 0.0_ReKi xd%Vr_wake = 0.0_ReKi + xd%Vx_wake2 = 0.0_ReKi xd%V_plane_filt = 0.0_ReKi xd%Vx_wind_disk_filt = 0.0_ReKi xd%TI_amb_filt = 0.0_ReKi @@ -553,6 +569,26 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut allocate ( m%vt_tot (0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_tot.', errStat, errMsg, RoutineName ) allocate ( m%vt_amb (0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_amb.', errStat, errMsg, RoutineName ) allocate ( m%vt_shr (0:p%NumRadii-1,0:p%NumPlanes-1 ) , STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_shr.', errStat, errMsg, RoutineName ) + else if (p%Mod_Wake == Mod_Wake_Cartesian) then + allocate ( m%vt_tot2(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_tot2.', errStat, errMsg, RoutineName ) + allocate ( m%vt_amb2(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_amb2.', errStat, errMsg, RoutineName ) + allocate ( m%vt_shr2(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%vt_shr2.', errStat, errMsg, RoutineName ) + + allocate ( m%dvx_dy (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dvx_dy.', errStat, errMsg, RoutineName ) + allocate ( m%dvx_dz (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dvx_dz.', errStat, errMsg, RoutineName ) + allocate ( m%nu_dvx_dy(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%nu_dvx_dy.', errStat, errMsg, RoutineName ) + allocate ( m%nu_dvx_dz(-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%nu_dvx_dz.', errStat, errMsg, RoutineName ) + allocate ( m%dnuvx_dy (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dnuvx_dy.', errStat, errMsg, RoutineName ) + allocate ( m%dnuvx_dz (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for m%dnuvx_dz.', errStat, errMsg, RoutineName ) + m%vt_tot2 = 0.0_ReKi + m%vt_amb2 = 0.0_ReKi + m%vt_shr2 = 0.0_ReKi + m%dvx_dy = 0.0_ReKi + m%dvx_dz = 0.0_ReKi + m%nu_dvx_dy = 0.0_ReKi + m%nu_dvx_dz = 0.0_ReKi + m%dnuvx_dy = 0.0_ReKi + m%dnuvx_dz = 0.0_ReKi else STOP ! should never happen endif @@ -591,6 +627,11 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vx_wake.', errStat, errMsg, RoutineName ) allocate ( y%Vr_wake (0:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vr_wake.', errStat, errMsg, RoutineName ) + + allocate ( y%Vx_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vx_wake.', errStat, errMsg, RoutineName ) + allocate ( y%Vy_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vy_wake.', errStat, errMsg, RoutineName ) + allocate ( y%Vz_wake2 (-p%NumRadii+1:p%NumRadii-1,-p%NumRadii+1:p%NumRadii-1,0:p%NumPlanes-1), STAT=ErrStat2 ); if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%Vz_wake.', errStat, errMsg, RoutineName ) + allocate ( y%D_wake (0:p%NumPlanes-1), STAT=ErrStat2 ) if (errStat2 /= 0) call SetErrStat ( ErrID_Fatal, 'Could not allocate memory for y%D_wake.', errStat, errMsg, RoutineName ) allocate ( y%x_plane (0:p%NumPlanes-1), STAT=ErrStat2 ) @@ -601,6 +642,9 @@ subroutine WD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut y%p_plane = 0.0_Reki y%Vx_wake = 0.0_Reki y%Vr_wake = 0.0_Reki + y%Vx_wake2 = 0.0_Reki + y%Vy_wake2 = 0.0_Reki + y%Vz_wake2 = 0.0_Reki y%D_wake = 0.0_Reki y%x_plane = 0.0_Reki @@ -692,10 +736,12 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg integer(intKi) :: errStat2 ! temporary Error status character(ErrMsgLen) :: errMsg2 ! temporary Error message character(*), parameter :: RoutineName = 'WD_UpdateStates' - real(ReKi) :: dx, absdx, norm2_xhat_plane + real(ReKi) :: dx, norm2_xhat_plane real(ReKi) :: dy_HWkDfl(3), EddyTermA, EddyTermB, lstar, Vx_wake_min + real(ReKi) :: dvdr, r_tmp, C, S, dvdtheta_r integer(intKi) :: i,j, maxPln - + integer(intKi) :: iy, iz ! indices on y and z + errStat = ErrID_None errMsg = "" @@ -737,7 +783,9 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg lstar = WakeDiam( p%Mod_WakeDiam, p%numRadii, p%dr, p%r, xd%Vx_wake(:,i-1), xd%Vx_wind_disk_filt(i-1), xd%D_rotor_filt(i-1), p%C_WakeDiam) / 2.0_ReKi Vx_wake_min = huge(ReKi) - if (p%Mod_Wake == Mod_Wake_Polar) then + if (p%Mod_Wake == Mod_Wake_Cartesian) then + Vx_wake_min = minval(xd%Vx_wake2(:,:,i-1)) + else if (p%Mod_Wake == Mod_Wake_Polar) then do j = 0,p%NumRadii-1 Vx_wake_min = min(Vx_wake_min, xd%Vx_wake(j,i-1)) end do @@ -761,11 +809,40 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg m%vt_tot(j,i-1) = m%vt_amb(j,i-1) + m%vt_shr(j,i-1) end do + else if (p%Mod_Wake == Mod_Wake_Cartesian) then + ! First compute gradients of dVx/dy and dVx/dz + call gradient_y(xd%Vx_wake2(:,:,i-1), p%dr, m%dvx_dy(:,:,i-1)) + call gradient_z(xd%Vx_wake2(:,:,i-1), p%dr, m%dvx_dz(:,:,i-1)) + + ! Eddy viscosity + do iz = -p%NumRadii+1, p%NumRadii-1 + do iy = -p%NumRadii+1, p%NumRadii-1 + + r_tmp = sqrt(p%y(iy)**2 + p%z(iz)**2) + if (EqualRealNos(r_tmp,0.0_ReKi) ) then + S = 0.0_ReKi + C = 0.0_ReKi + dvdtheta_r = 0.0_ReKi + else + S=p%z(iz)/r_tmp + C=p%y(iy)/r_tmp + dvdtheta_r = (m%dvx_dy(iy,iz,i-1) * (-p%z(iz)) + m%dvx_dz(iy,iz,i-1) * p%y(iy)) / r_tmp + endif + + dvdr = m%dvx_dy(iy,iz,i-1) * C + m%dvx_dz(iy,iz,i-1) * S + m%vt_amb2(iy,iz,i-1) = EddyTermA + m%vt_shr2(iy,iz,i-1) = EddyTermB * max( (lstar**2)* (abs(dvdr) + abs(dvdtheta_r)) , lstar*(xd%Vx_wind_disk_filt(i-1) + Vx_wake_min ) ) + m%vt_tot2(iy,iz,i-1) = m%vt_amb2(iy,iz,i-1) + p%k_vCurl*m%vt_shr2(iy,iz,i-1) + + enddo + enddo endif end do ! loop on planes i = maxPln+1, 1, -1 ! --- Update Vx and Vr if (p%Mod_Wake == Mod_Wake_Polar) then call updateVelocityPolar() + else if (p%Mod_Wake == Mod_Wake_Cartesian) then + call updateVelocityCartesian() else ! Should never happen endif @@ -855,6 +932,24 @@ subroutine WD_UpdateStates( t, n, u, p, x, xd, z, OtherState, m, errStat, errMsg ! Compute wake deficit of first plane based on rotor loading, outputs: Vx_Wake, m call NearWakeCorrection( xd%Ct_azavg_filt, xd%Cq_azavg_filt, xd%Vx_rel_disk_filt, p, m, xd%Vx_wake(:,0), m%Vt_wake, xd%D_rotor_filt(0), errStat, errMsg ) + else if (p%Mod_Wake == Mod_Wake_Cartesian) then + + ! Initialize the spanwise velocities to zero. + ! Thses will be changed by AddSwirl and/or AddVelocityCurl + xd%Vy_wake2(:,:,0) = 0._ReKi + xd%Vz_wake2(:,:,0) = 0._ReKi + + ! --- Compute Vx + ! Compute Vx(r) + call NearWakeCorrection( xd%Ct_azavg_filt, xd%Cq_azavg_filt, xd%Vx_rel_disk_filt, p, m, m%Vx_polar(:), m%Vt_wake, xd%D_rotor_filt(0), errStat, errMsg ) + ! Convert to Cartesian + call Axisymmetric2CartesianVx(m%Vx_polar, p%r, p%y, p%z, xd%Vx_wake2(:,:,0)) + call FilterVx(xd%Vx_wake2(:,:,0), p%FilterInit) ! don't filter if FilterInit is 0 + m%Ct_avg = get_Ctavg(p%r, xd%Ct_azavg_filt, xd%D_rotor_filt(0)) + ! --- Add Swirl + if (p%Swirl) then + call AddSwirl(p%r, m%Vt_wake, p%y, p%z, xd%Vy_wake2(:,:,0), xd%Vz_wake2(:,:,0)) + endif endif !Used for debugging: write(51,'(I5,100(1x,ES10.2E2))') n, xd%x_plane(n), xd%x_plane(n)/xd%D_rotor_filt(n), xd%Vx_wind_disk_filt(n) + xd%Vx_wake(:,n), xd%Vr_wake(:,n) @@ -927,12 +1022,125 @@ subroutine updateVelocityPolar() end do ! i = 1,min(n+2,p%NumPlanes-1) end subroutine updateVelocityPolar + !> + subroutine updateVelocityCartesian() + integer(intKi) :: iy,iz,i + real(ReKi) :: dx + real(ReKi) :: xp !< x position of the plane + real(ReKi) :: divTau + divTau =0.0_ReKi + + ! This is the formulation of curled wake algorithm (Martinez et al WES 2019) + ! The quantities in these loops are all at time [n], so we need to compute prior to updating the states to [n+1] (loop in reversed) + do i = maxPln, 1, -1 + + ! NOTE: we cannot use data at i here since positions of planes have not been updated yet + dx = abs(dot_product(xd%xhat_plane(:,i-1),xd%V_plane_filt(:,i-1))*p%DT_low) + !xp = xd%p_plane(1,i-1)/u%D_rotor ! Current plane downstream x position in D + xp = (xd%x_plane(i-1) + abs(dx))/u%D_rotor + + ! Gradients for eddy viscosity term + ! NOTE: the gradient of Vx have been computed for the eddy viscosity already + m%nu_dvx_dy(:,:) = m%vt_tot2(:,:,i-1) * m%dvx_dy(:,:,i-1) + m%nu_dvx_dz(:,:) = m%vt_tot2(:,:,i-1) * m%dvx_dz(:,:,i-1) + call gradient_y(m%nu_dvx_dy, p%dr, m%dnuvx_dy ) + call gradient_z(m%nu_dvx_dz, p%dr, m%dnuvx_dz ) + + ! Loop through all the points on the plane (y, z) + do iz = -p%NumRadii+2, p%NumRadii-2 + do iy = -p%NumRadii+2, p%NumRadii-2 + + ! Eddy viscosity term + divTau = m%dnuvx_dy(iy,iz) + m%dnuvx_dz(iy,iz) + ! Update state of Vx + xd%Vx_wake2(iy,iz,i) = xd%Vx_wake2(iy,iz,i-1) - & + p%DT_low * ( & + ( (xd%Vy_wake2(iy,iz,i-1) ) * m%dvx_dy(iy,iz,i-1) + & + (xd%Vz_wake2(iy,iz,i-1) ) * m%dvx_dz(iy,iz,i-1) & + - divTau) & + ) + ! Update state (decay) of Vy and Vz + xd%Vy_wake2(iy,iz,i) = xd%Vy_wake2(iy,iz,i-1) * exp( - p%k_VortexDecay * dx) + xd%Vz_wake2(iy,iz,i) = xd%Vz_wake2(iy,iz,i-1) * exp( - p%k_VortexDecay * dx) + + enddo ! iy + enddo ! iz + enddo ! i, planes + + end subroutine updateVelocityCartesian subroutine Cleanup() end subroutine Cleanup end subroutine WD_UpdateStates +! A subroutine to compute 2D gradient in y +subroutine gradient_y(field, dy, gradient) + real(ReKi), intent(in), dimension(:,:) :: field ! The field to compute the gradient + real(ReKi), intent(in) :: dy ! The finite difference + real(ReKi), intent(inout), dimension(:,:) :: gradient ! The field to compute the gradient + integer :: iy,iz + gradient=0.0_ReKi + do iz=2,size(field,2)-1 + do iy=2,size(field,1)-1 + gradient(iy,iz) = (field(iy+1,iz) - field(iy-1,iz)) / (2 * dy) + enddo + enddo +end subroutine gradient_y + +! A subroutine to compute 2D gradient in z +subroutine gradient_z(field, dz, gradient) + real(ReKi), intent(in), dimension(:,:) :: field ! The field to compute the gradient + real(ReKi), intent(in) :: dz ! The finite difference + real(ReKi), intent(inout), dimension(:,:) :: gradient ! The field to compute the gradient + integer :: iy,iz + gradient=0.0_ReKi + do iz=2,size(field,2)-1 + do iy=2,size(field,1)-1 + gradient(iy,iz) = (field(iy,iz+1) - field(iy,iz-1)) / (2 * dz) + enddo + enddo +end subroutine gradient_z + + + +!> This subroutine computes the near wake correction : Vx_wake +subroutine AddSwirl(r, Vt_wake, y, z, Vy_curl, Vz_curl) + real(ReKi), intent(in) :: r(:) !< Tangential wake velocity deficit at first plane + real(ReKi), intent(in) :: Vt_wake(:) !< Tangential wake velocity deficit at first plane + real(ReKi), dimension(:), intent(in) :: y !< Spanwise Cartesian coordinate (m) + real(ReKi), dimension(:), intent(in) :: z !< Wall-normal Cartesian coordinate (m) + real(ReKi), dimension(:,:), intent(inout) :: Vy_curl !< Curl velocity in the y direction (m/s) + real(ReKi), dimension(:,:), intent(inout) :: Vz_curl !< Curl velocity in the z direction (m/s) + + real(ReKi) :: alpha + integer(IntKi) :: iz, iy, iLow, nr + real(ReKi) :: r_tmp, r_max + real(ReKi) :: Vt, S, C ! Sine and cosine + nr = size(r) + r_max = r(nr) + iLow=0 + ! Loop through all plane points + do iz = 1,size(z) + do iy = 1,size(y) + ! Project into cartesian + r_tmp = sqrt(y(iy)**2 + z(iz)**2) + if (r_tmp<=r_max) then + if (EqualRealNos(r_tmp, 0.0_ReKi) ) then + S = 0.0_ReKi + C = 0.0_ReKi + else + S=z(iz)/r_tmp + C=y(iy)/r_tmp + endif + Vt = InterpBin(r_tmp, r, Vt_wake, iLow, nr) !( XVal, XAry, YAry, ILo, AryLen ) + Vy_curl(iy, iz) = Vy_curl(iy, iz) + Vt * S + Vz_curl(iy, iz) = Vz_curl(iy, iz) - Vt * C + endif + enddo + enddo + +end subroutine AddSwirl !> Weighted average of two angles @@ -976,6 +1184,133 @@ subroutine filter_angles2(psi_filt, chi_filt, psi, chi, alpha, alpha_bar) chi_filt = theta_out(3) !print*,'Output ', psi_filt, chi_filt, theta_out(2) end subroutine filter_angles2 + + +!> Converts velocity vectors from an axisymmetric system in radial coordinates to a Cartesian system in Cartesian coordinates +subroutine Axisymmetric2Cartesian(Vx_axi, Vr_axi, r, y, z, Vx, Vy, Vz) + real(ReKi), dimension(:), intent(in) :: Vx_axi !< Axial velocity, distributed radially (m/s) + real(ReKi), dimension(:), intent(in) :: Vr_axi !< Radial velocity deficit, distributed radially (m/s) + real(ReKi), dimension(:), intent(in) :: r !< Discretization of radial finite-difference grid (m + real(ReKi), dimension(:), intent(in) :: y !< Horizontal discretization of Cartesian grid (m) + real(ReKi), dimension(:), intent(in) :: z !< Nominally vertical discretization of Cartesian grid (m) + real(ReKi), dimension(:,:), intent(inout) :: Vx !< Axial velocity, distributed across the plane (m/s) + real(ReKi), dimension(:,:), intent(inout) :: Vy !< Transverse horizontal velocity, distributed across the plane (m/s) + real(ReKi), dimension(:,:), intent(inout) :: Vz !< Transverse nominally vertical velocity, distributed across the plane (m/s) + integer(IntKi) :: iz, iy, nr, iLow + real(ReKi) :: r_tmp, r_max + real(ReKi) :: Vr, S, C ! Sine and cosine + nr = size(r) + r_max = r(nr) + do iz = 1,size(z) + do iy = 1,size(y) + r_tmp = sqrt(y(iy)**2 + z(iz)**2) + if (EqualRealNos(r_tmp,0.0_ReKi) ) then + S = 0.0_ReKi + C = 0.0_ReKi + else + S=z(iz)/r_tmp + C=y(iy)/r_tmp + endif + r_tmp = min(r_tmp, r_max) ! we can't interpolate beyond r_max + iLow=0 + Vx(iy,iz) = InterpBin(r_tmp, r, Vx_axi, iLow, nr) !( XVal, XAry, YAry, ILo, AryLen ) + Vr = InterpBin(r_tmp, r, Vr_axi, iLow, nr) + Vy(iy,iz) = Vr * C + Vz(iy,iz) = Vr * S + enddo + enddo +end subroutine Axisymmetric2Cartesian + +!> Converts velocity vector Vx from an axisymmetric system in radial coordinates to a Cartesian system in Cartesian coordinates +subroutine Axisymmetric2CartesianVx(Vx_axi, r, y, z, Vx) + real(ReKi), dimension(:), intent(in) :: Vx_axi !< Axial velocity, distributed radially (m/s) + real(ReKi), dimension(:), intent(in) :: r !< Discretization of radial finite-difference grid (m + real(ReKi), dimension(:), intent(in) :: y !< Horizontal discretization of Cartesian grid (m) + real(ReKi), dimension(:), intent(in) :: z !< Nominally vertical discretization of Cartesian grid (m) + real(ReKi), dimension(:,:), intent(inout) :: Vx !< Axial velocity, distributed across the plane (m/s) + integer(IntKi) :: iz, iy, nr, iLow + real(ReKi) :: r_tmp, r_max + real(ReKi) :: Vr, S, C ! Sine and cosine + nr = size(r) + r_max = r(nr) + do iz = 1,size(z) + do iy = 1,size(y) + r_tmp = sqrt(y(iy)**2 + z(iz)**2) + r_tmp = min(r_tmp, r_max) ! we can't interpolate beyond r_max + iLow=0 + Vx(iy,iz) = InterpBin(r_tmp, r, Vx_axi, iLow, nr) !( XVal, XAry, YAry, ILo, AryLen ) + enddo + enddo +end subroutine Axisymmetric2CartesianVx + +!> Filters the velocity using a box filter +subroutine FilterVx(Vx, nf) + real(ReKi), dimension(:,:), intent(inout) :: Vx !< Axial velocity, distributed across the plane (m/s) + integer(IntKi), intent(in) :: nf ! The filter width (number of grid points) + real(ReKi), dimension(size(Vx,1),size(Vx,2)) :: Vx_filt !< Axial velocity, distributed across the plane (m/s) + integer(IntKi) :: iz, iy, n1, n2 + + ! No filter if filter width is 0 + if(nf==0) return + + ! Initialize the filtered vars + Vx_filt = 0.0_ReKi + + do iz = 1+nf, size(Vx,2) - nf + do iy = 1+nf, size(Vx,1) - nf + + do n1=-nf,nf + + do n2=-nf,nf + + Vx_filt(iy,iz) = Vx_filt(iy,iz) + Vx(iy + n1, iz + n2) + + enddo + + enddo + enddo + enddo + + Vx = Vx_filt / ((2. * nf +1)**2 ) + +end subroutine FilterVx + + +subroutine WD_TEST_Axi2Cart() + real(ReKi) :: r(4)=(/0.,1.,2.,3./) +! real(ReKi) :: y(4)=(/-1.,0.,1.5,2./) +! real(ReKi) :: z(5)=(/-2.5,-1.5,0.,1.5,2./) + real(ReKi) :: y(4)=(/0.,1. ,1.5, 2./) + real(ReKi) :: z(5)=(/0.,0.5,1. ,1.5,2./) + real(ReKi) :: Vr_axi(4) + real(ReKi) :: Vx_axi(4) + real(ReKi) :: Vx(4,5)=0.0_ReKi + real(ReKi) :: Vy(4,5)=0.0_ReKi + real(ReKi) :: Vz(4,5)=0.0_ReKi + integer :: i,j + real(ReKi) :: Vr, r_tmp + Vr_axi=4._ReKi*r + Vx_axi=3._ReKi*r + call Axisymmetric2Cartesian(Vx_axi, Vr_axi, r, y, z, Vx, Vy, Vz) + + do i = 1,size(y) + do j = 1,size(z) + r_tmp = sqrt(y(i)**2+z(j)**2) + Vr = sqrt(Vy(i,j)**2 + Vz(i,j)**2) + if (abs(Vr-4*r_tmp)>1e-3) then + print*,'>>Error Axi2Cart Vr',Vr,4*r_tmp + STOP + endif + if (abs(Vx(i,j)-3*r_tmp)>1e-3) then + print*,'>>Error Axi2Cart Vx',Vx(i,j),3*r_tmp + STOP + endif + enddo + enddo +end subroutine + + + !---------------------------------------------------------------------------------------------------------------------------------- !> Routine for computing outputs, used in both loose and tight coupling. !! This subroutine is used to compute the output channels (motions and loads) and place them in the WriteOutput() array. @@ -1054,6 +1389,25 @@ subroutine WD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, errStat, errMsg ) end do end if + + if (p%Mod_Wake == Mod_Wake_Polar) then + ! Convert to Cartesian + do i = 0, maxPln + call Axisymmetric2Cartesian(y%Vx_wake(:,i), y%Vr_wake(:,i), p%r, p%y, p%z, y%Vx_wake2(:,:,i), y%Vy_wake2(:,:,i), y%Vz_wake2(:,:,i)) + enddo + else if (p%Mod_Wake == Mod_Wake_Cartesian) then + do i = 0, maxPln + y%Vx_wake2(:,:,i) = xd%Vx_wake2(:,:,i) + y%Vy_wake2(:,:,i) = xd%Vy_wake2(:,:,i) + y%Vz_wake2(:,:,i) = xd%Vz_wake2(:,:,i) + enddo + endif ! Curl or Polar + + + + ! --- VTK outputs per plane + if (p%Mod_Wake == Mod_Wake_Cartesian) then + endif end subroutine WD_CalcOutput diff --git a/modules/wakedynamics/src/WakeDynamics_Registry.txt b/modules/wakedynamics/src/WakeDynamics_Registry.txt index 3ea6190a34..4eaf38695c 100644 --- a/modules/wakedynamics/src/WakeDynamics_Registry.txt +++ b/modules/wakedynamics/src/WakeDynamics_Registry.txt @@ -82,6 +82,9 @@ typedef ^ DiscreteStateType ReKi p_plane {:}{:} - - "Center posi typedef ^ DiscreteStateType ReKi x_plane {:} - - "Downwind distance from rotor to each wake plane" m typedef ^ DiscreteStateType ReKi Vx_wake {:}{:} - - "Axial wake velocity deficit at wake planes, distributed radially" m/s typedef ^ DiscreteStateType ReKi Vr_wake {:}{:} - - "Radial wake velocity deficit at wake planes, distributed radially" m/s +typedef ^ DiscreteStateType ReKi Vx_wake2 {:}{:}{:} - - "Axial wake velocity deficit at wake planes, distributed radially" m/s +typedef ^ DiscreteStateType ReKi Vy_wake2 {:}{:}{:} - - "Longitudinal wake velocity deficit at wake planes, distributed radially" m/s +typedef ^ DiscreteStateType ReKi Vz_wake2 {:}{:}{:} - - "Vertical wake velocity deficit at wake planes, distributed radially" m/s typedef ^ DiscreteStateType ReKi Vx_wind_disk_filt {:} - - "Time-filtered rotor-disk-averaged ambient wind speed of wake planes, normal to planes" m/s typedef ^ DiscreteStateType ReKi TI_amb_filt {:} - - "Time-filtered ambient turbulence intensity of wind at wake planes" - typedef ^ DiscreteStateType ReKi D_rotor_filt {:} - - "Time-filtered rotor diameter associated with each wake plane" m @@ -103,6 +106,15 @@ typedef ^ MiscVarType ReKi dvtdr {:} - - "" typedef ^ MiscVarType ReKi vt_tot {:}{:} - - "" typedef ^ MiscVarType ReKi vt_amb {:}{:} - - "" typedef ^ MiscVarType ReKi vt_shr {:}{:} - - "" +typedef ^ MiscVarType ReKi vt_tot2 {:}{:}{:} - - "" +typedef ^ MiscVarType ReKi vt_amb2 {:}{:}{:} - - "" +typedef ^ MiscVarType ReKi vt_shr2 {:}{:}{:} - - "" +typedef ^ MiscVarType ReKi dvx_dy {:}{:}{:} - - "" +typedef ^ MiscVarType ReKi dvx_dz {:}{:}{:} - - "" +typedef ^ MiscVarType ReKi nu_dvx_dy {:}{:} - - "" +typedef ^ MiscVarType ReKi nu_dvx_dz {:}{:} - - "" +typedef ^ MiscVarType ReKi dnuvx_dy {:}{:} - - "" +typedef ^ MiscVarType ReKi dnuvx_dz {:}{:} - - "" typedef ^ MiscVarType ReKi a {:} - - "" typedef ^ MiscVarType ReKi b {:} - - "" typedef ^ MiscVarType ReKi c {:} - - "" @@ -176,6 +188,9 @@ typedef ^ OutputType ReKi xhat_plane {:}{:} - typedef ^ OutputType ReKi p_plane {:}{:} - - "Center positions of wake planes" m typedef ^ OutputType ReKi Vx_wake {:}{:} - - "Axial wake velocity deficit at wake planes, distributed radially" m/s typedef ^ OutputType ReKi Vr_wake {:}{:} - - "Radial wake velocity deficit at wake planes, distributed radially" m/s +typedef ^ OutputType ReKi Vx_wake2 {:}{:}{:} - - "Axial wake velocity deficit at wake planes, distributed across the plane" m/s +typedef ^ OutputType ReKi Vy_wake2 {:}{:}{:} - - "Transverse horizontal wake velocity deficit at wake planes, distributed across the plane" m/s +typedef ^ OutputType ReKi Vz_wake2 {:}{:}{:} - - "Transverse nominally vertical wake velocity deficit at wake planes, distributed across the plane" m/s typedef ^ OutputType ReKi D_wake {:} - - "Wake diameters at wake planes" m typedef ^ OutputType ReKi x_plane {:} - - "Downwind distance from rotor to each wake plane" m diff --git a/modules/wakedynamics/src/WakeDynamics_Types.f90 b/modules/wakedynamics/src/WakeDynamics_Types.f90 index 62face5e11..0bdf98876d 100644 --- a/modules/wakedynamics/src/WakeDynamics_Types.f90 +++ b/modules/wakedynamics/src/WakeDynamics_Types.f90 @@ -103,6 +103,9 @@ MODULE WakeDynamics_Types REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: x_plane !< Downwind distance from rotor to each wake plane [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vx_wake !< Axial wake velocity deficit at wake planes, distributed radially [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vr_wake !< Radial wake velocity deficit at wake planes, distributed radially [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vx_wake2 !< Axial wake velocity deficit at wake planes, distributed radially [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vy_wake2 !< Longitudinal wake velocity deficit at wake planes, distributed radially [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vz_wake2 !< Vertical wake velocity deficit at wake planes, distributed radially [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: Vx_wind_disk_filt !< Time-filtered rotor-disk-averaged ambient wind speed of wake planes, normal to planes [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: TI_amb_filt !< Time-filtered ambient turbulence intensity of wind at wake planes [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: D_rotor_filt !< Time-filtered rotor diameter associated with each wake plane [m] @@ -128,6 +131,15 @@ MODULE WakeDynamics_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_tot !< [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_amb !< [-] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: vt_shr !< [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: vt_tot2 !< [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: vt_amb2 !< [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: vt_shr2 !< [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: dvx_dy !< [-] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: dvx_dz !< [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: nu_dvx_dy !< [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: nu_dvx_dz !< [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: dnuvx_dy !< [-] + REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: dnuvx_dz !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: a !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: b !< [-] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: c !< [-] @@ -201,6 +213,9 @@ MODULE WakeDynamics_Types REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: p_plane !< Center positions of wake planes [m] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vx_wake !< Axial wake velocity deficit at wake planes, distributed radially [m/s] REAL(ReKi) , DIMENSION(:,:), ALLOCATABLE :: Vr_wake !< Radial wake velocity deficit at wake planes, distributed radially [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vx_wake2 !< Axial wake velocity deficit at wake planes, distributed across the plane [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vy_wake2 !< Transverse horizontal wake velocity deficit at wake planes, distributed across the plane [m/s] + REAL(ReKi) , DIMENSION(:,:,:), ALLOCATABLE :: Vz_wake2 !< Transverse nominally vertical wake velocity deficit at wake planes, distributed across the plane [m/s] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: D_wake !< Wake diameters at wake planes [m] REAL(ReKi) , DIMENSION(:), ALLOCATABLE :: x_plane !< Downwind distance from rotor to each wake plane [m] END TYPE WD_OutputType @@ -216,6 +231,7 @@ SUBROUTINE WD_CopyInputFileType( SrcInputFileTypeData, DstInputFileTypeData, Ctr INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WD_CopyInputFileType' @@ -442,6 +458,7 @@ SUBROUTINE WD_UnPackInputFileType( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WD_UnPackInputFileType' @@ -1238,6 +1255,7 @@ SUBROUTINE WD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WD_CopyDiscState' @@ -1340,6 +1358,54 @@ SUBROUTINE WD_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrSt END IF DstDiscStateData%Vr_wake = SrcDiscStateData%Vr_wake ENDIF +IF (ALLOCATED(SrcDiscStateData%Vx_wake2)) THEN + i1_l = LBOUND(SrcDiscStateData%Vx_wake2,1) + i1_u = UBOUND(SrcDiscStateData%Vx_wake2,1) + i2_l = LBOUND(SrcDiscStateData%Vx_wake2,2) + i2_u = UBOUND(SrcDiscStateData%Vx_wake2,2) + i3_l = LBOUND(SrcDiscStateData%Vx_wake2,3) + i3_u = UBOUND(SrcDiscStateData%Vx_wake2,3) + IF (.NOT. ALLOCATED(DstDiscStateData%Vx_wake2)) THEN + ALLOCATE(DstDiscStateData%Vx_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%Vx_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDiscStateData%Vx_wake2 = SrcDiscStateData%Vx_wake2 +ENDIF +IF (ALLOCATED(SrcDiscStateData%Vy_wake2)) THEN + i1_l = LBOUND(SrcDiscStateData%Vy_wake2,1) + i1_u = UBOUND(SrcDiscStateData%Vy_wake2,1) + i2_l = LBOUND(SrcDiscStateData%Vy_wake2,2) + i2_u = UBOUND(SrcDiscStateData%Vy_wake2,2) + i3_l = LBOUND(SrcDiscStateData%Vy_wake2,3) + i3_u = UBOUND(SrcDiscStateData%Vy_wake2,3) + IF (.NOT. ALLOCATED(DstDiscStateData%Vy_wake2)) THEN + ALLOCATE(DstDiscStateData%Vy_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%Vy_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDiscStateData%Vy_wake2 = SrcDiscStateData%Vy_wake2 +ENDIF +IF (ALLOCATED(SrcDiscStateData%Vz_wake2)) THEN + i1_l = LBOUND(SrcDiscStateData%Vz_wake2,1) + i1_u = UBOUND(SrcDiscStateData%Vz_wake2,1) + i2_l = LBOUND(SrcDiscStateData%Vz_wake2,2) + i2_u = UBOUND(SrcDiscStateData%Vz_wake2,2) + i3_l = LBOUND(SrcDiscStateData%Vz_wake2,3) + i3_u = UBOUND(SrcDiscStateData%Vz_wake2,3) + IF (.NOT. ALLOCATED(DstDiscStateData%Vz_wake2)) THEN + ALLOCATE(DstDiscStateData%Vz_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstDiscStateData%Vz_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstDiscStateData%Vz_wake2 = SrcDiscStateData%Vz_wake2 +ENDIF IF (ALLOCATED(SrcDiscStateData%Vx_wind_disk_filt)) THEN i1_l = LBOUND(SrcDiscStateData%Vx_wind_disk_filt,1) i1_u = UBOUND(SrcDiscStateData%Vx_wind_disk_filt,1) @@ -1445,6 +1511,15 @@ SUBROUTINE WD_DestroyDiscState( DiscStateData, ErrStat, ErrMsg, DEALLOCATEpointe IF (ALLOCATED(DiscStateData%Vr_wake)) THEN DEALLOCATE(DiscStateData%Vr_wake) ENDIF +IF (ALLOCATED(DiscStateData%Vx_wake2)) THEN + DEALLOCATE(DiscStateData%Vx_wake2) +ENDIF +IF (ALLOCATED(DiscStateData%Vy_wake2)) THEN + DEALLOCATE(DiscStateData%Vy_wake2) +ENDIF +IF (ALLOCATED(DiscStateData%Vz_wake2)) THEN + DEALLOCATE(DiscStateData%Vz_wake2) +ENDIF IF (ALLOCATED(DiscStateData%Vx_wind_disk_filt)) THEN DEALLOCATE(DiscStateData%Vx_wind_disk_filt) ENDIF @@ -1534,6 +1609,21 @@ SUBROUTINE WD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg Int_BufSz = Int_BufSz + 2*2 ! Vr_wake upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vr_wake) ! Vr_wake END IF + Int_BufSz = Int_BufSz + 1 ! Vx_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vx_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vx_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vx_wake2) ! Vx_wake2 + END IF + Int_BufSz = Int_BufSz + 1 ! Vy_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vy_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vy_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vy_wake2) ! Vy_wake2 + END IF + Int_BufSz = Int_BufSz + 1 ! Vz_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vz_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vz_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vz_wake2) ! Vz_wake2 + END IF Int_BufSz = Int_BufSz + 1 ! Vx_wind_disk_filt allocated yes/no IF ( ALLOCATED(InData%Vx_wind_disk_filt) ) THEN Int_BufSz = Int_BufSz + 2*1 ! Vx_wind_disk_filt upper/lower bounds for each dimension @@ -1721,6 +1811,81 @@ SUBROUTINE WD_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%Vx_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vx_wake2,3), UBOUND(InData%Vx_wake2,3) + DO i2 = LBOUND(InData%Vx_wake2,2), UBOUND(InData%Vx_wake2,2) + DO i1 = LBOUND(InData%Vx_wake2,1), UBOUND(InData%Vx_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vx_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vy_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vy_wake2,3), UBOUND(InData%Vy_wake2,3) + DO i2 = LBOUND(InData%Vy_wake2,2), UBOUND(InData%Vy_wake2,2) + DO i1 = LBOUND(InData%Vy_wake2,1), UBOUND(InData%Vy_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vy_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vz_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vz_wake2,3), UBOUND(InData%Vz_wake2,3) + DO i2 = LBOUND(InData%Vz_wake2,2), UBOUND(InData%Vz_wake2,2) + DO i1 = LBOUND(InData%Vz_wake2,1), UBOUND(InData%Vz_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vz_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%Vx_wind_disk_filt) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -1815,6 +1980,7 @@ SUBROUTINE WD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WD_UnPackDiscState' @@ -1983,6 +2149,90 @@ SUBROUTINE WD_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, Err END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vx_wake2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vx_wake2)) DEALLOCATE(OutData%Vx_wake2) + ALLOCATE(OutData%Vx_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vx_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vx_wake2,3), UBOUND(OutData%Vx_wake2,3) + DO i2 = LBOUND(OutData%Vx_wake2,2), UBOUND(OutData%Vx_wake2,2) + DO i1 = LBOUND(OutData%Vx_wake2,1), UBOUND(OutData%Vx_wake2,1) + OutData%Vx_wake2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vy_wake2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vy_wake2)) DEALLOCATE(OutData%Vy_wake2) + ALLOCATE(OutData%Vy_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vy_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vy_wake2,3), UBOUND(OutData%Vy_wake2,3) + DO i2 = LBOUND(OutData%Vy_wake2,2), UBOUND(OutData%Vy_wake2,2) + DO i1 = LBOUND(OutData%Vy_wake2,1), UBOUND(OutData%Vy_wake2,1) + OutData%Vy_wake2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vz_wake2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vz_wake2)) DEALLOCATE(OutData%Vz_wake2) + ALLOCATE(OutData%Vz_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vz_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vz_wake2,3), UBOUND(OutData%Vz_wake2,3) + DO i2 = LBOUND(OutData%Vz_wake2,2), UBOUND(OutData%Vz_wake2,2) + DO i1 = LBOUND(OutData%Vz_wake2,1), UBOUND(OutData%Vz_wake2,1) + OutData%Vz_wake2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vx_wind_disk_filt not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -2361,6 +2611,7 @@ SUBROUTINE WD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WD_CopyMisc' @@ -2433,6 +2684,142 @@ SUBROUTINE WD_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg ) END IF DstMiscData%vt_shr = SrcMiscData%vt_shr ENDIF +IF (ALLOCATED(SrcMiscData%vt_tot2)) THEN + i1_l = LBOUND(SrcMiscData%vt_tot2,1) + i1_u = UBOUND(SrcMiscData%vt_tot2,1) + i2_l = LBOUND(SrcMiscData%vt_tot2,2) + i2_u = UBOUND(SrcMiscData%vt_tot2,2) + i3_l = LBOUND(SrcMiscData%vt_tot2,3) + i3_u = UBOUND(SrcMiscData%vt_tot2,3) + IF (.NOT. ALLOCATED(DstMiscData%vt_tot2)) THEN + ALLOCATE(DstMiscData%vt_tot2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%vt_tot2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%vt_tot2 = SrcMiscData%vt_tot2 +ENDIF +IF (ALLOCATED(SrcMiscData%vt_amb2)) THEN + i1_l = LBOUND(SrcMiscData%vt_amb2,1) + i1_u = UBOUND(SrcMiscData%vt_amb2,1) + i2_l = LBOUND(SrcMiscData%vt_amb2,2) + i2_u = UBOUND(SrcMiscData%vt_amb2,2) + i3_l = LBOUND(SrcMiscData%vt_amb2,3) + i3_u = UBOUND(SrcMiscData%vt_amb2,3) + IF (.NOT. ALLOCATED(DstMiscData%vt_amb2)) THEN + ALLOCATE(DstMiscData%vt_amb2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%vt_amb2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%vt_amb2 = SrcMiscData%vt_amb2 +ENDIF +IF (ALLOCATED(SrcMiscData%vt_shr2)) THEN + i1_l = LBOUND(SrcMiscData%vt_shr2,1) + i1_u = UBOUND(SrcMiscData%vt_shr2,1) + i2_l = LBOUND(SrcMiscData%vt_shr2,2) + i2_u = UBOUND(SrcMiscData%vt_shr2,2) + i3_l = LBOUND(SrcMiscData%vt_shr2,3) + i3_u = UBOUND(SrcMiscData%vt_shr2,3) + IF (.NOT. ALLOCATED(DstMiscData%vt_shr2)) THEN + ALLOCATE(DstMiscData%vt_shr2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%vt_shr2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%vt_shr2 = SrcMiscData%vt_shr2 +ENDIF +IF (ALLOCATED(SrcMiscData%dvx_dy)) THEN + i1_l = LBOUND(SrcMiscData%dvx_dy,1) + i1_u = UBOUND(SrcMiscData%dvx_dy,1) + i2_l = LBOUND(SrcMiscData%dvx_dy,2) + i2_u = UBOUND(SrcMiscData%dvx_dy,2) + i3_l = LBOUND(SrcMiscData%dvx_dy,3) + i3_u = UBOUND(SrcMiscData%dvx_dy,3) + IF (.NOT. ALLOCATED(DstMiscData%dvx_dy)) THEN + ALLOCATE(DstMiscData%dvx_dy(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%dvx_dy = SrcMiscData%dvx_dy +ENDIF +IF (ALLOCATED(SrcMiscData%dvx_dz)) THEN + i1_l = LBOUND(SrcMiscData%dvx_dz,1) + i1_u = UBOUND(SrcMiscData%dvx_dz,1) + i2_l = LBOUND(SrcMiscData%dvx_dz,2) + i2_u = UBOUND(SrcMiscData%dvx_dz,2) + i3_l = LBOUND(SrcMiscData%dvx_dz,3) + i3_u = UBOUND(SrcMiscData%dvx_dz,3) + IF (.NOT. ALLOCATED(DstMiscData%dvx_dz)) THEN + ALLOCATE(DstMiscData%dvx_dz(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%dvx_dz = SrcMiscData%dvx_dz +ENDIF +IF (ALLOCATED(SrcMiscData%nu_dvx_dy)) THEN + i1_l = LBOUND(SrcMiscData%nu_dvx_dy,1) + i1_u = UBOUND(SrcMiscData%nu_dvx_dy,1) + i2_l = LBOUND(SrcMiscData%nu_dvx_dy,2) + i2_u = UBOUND(SrcMiscData%nu_dvx_dy,2) + IF (.NOT. ALLOCATED(DstMiscData%nu_dvx_dy)) THEN + ALLOCATE(DstMiscData%nu_dvx_dy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%nu_dvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%nu_dvx_dy = SrcMiscData%nu_dvx_dy +ENDIF +IF (ALLOCATED(SrcMiscData%nu_dvx_dz)) THEN + i1_l = LBOUND(SrcMiscData%nu_dvx_dz,1) + i1_u = UBOUND(SrcMiscData%nu_dvx_dz,1) + i2_l = LBOUND(SrcMiscData%nu_dvx_dz,2) + i2_u = UBOUND(SrcMiscData%nu_dvx_dz,2) + IF (.NOT. ALLOCATED(DstMiscData%nu_dvx_dz)) THEN + ALLOCATE(DstMiscData%nu_dvx_dz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%nu_dvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%nu_dvx_dz = SrcMiscData%nu_dvx_dz +ENDIF +IF (ALLOCATED(SrcMiscData%dnuvx_dy)) THEN + i1_l = LBOUND(SrcMiscData%dnuvx_dy,1) + i1_u = UBOUND(SrcMiscData%dnuvx_dy,1) + i2_l = LBOUND(SrcMiscData%dnuvx_dy,2) + i2_u = UBOUND(SrcMiscData%dnuvx_dy,2) + IF (.NOT. ALLOCATED(DstMiscData%dnuvx_dy)) THEN + ALLOCATE(DstMiscData%dnuvx_dy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dnuvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%dnuvx_dy = SrcMiscData%dnuvx_dy +ENDIF +IF (ALLOCATED(SrcMiscData%dnuvx_dz)) THEN + i1_l = LBOUND(SrcMiscData%dnuvx_dz,1) + i1_u = UBOUND(SrcMiscData%dnuvx_dz,1) + i2_l = LBOUND(SrcMiscData%dnuvx_dz,2) + i2_u = UBOUND(SrcMiscData%dnuvx_dz,2) + IF (.NOT. ALLOCATED(DstMiscData%dnuvx_dz)) THEN + ALLOCATE(DstMiscData%dnuvx_dz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstMiscData%dnuvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstMiscData%dnuvx_dz = SrcMiscData%dnuvx_dz +ENDIF IF (ALLOCATED(SrcMiscData%a)) THEN i1_l = LBOUND(SrcMiscData%a,1) i1_u = UBOUND(SrcMiscData%a,1) @@ -2568,6 +2955,33 @@ SUBROUTINE WD_DestroyMisc( MiscData, ErrStat, ErrMsg, DEALLOCATEpointers ) IF (ALLOCATED(MiscData%vt_shr)) THEN DEALLOCATE(MiscData%vt_shr) ENDIF +IF (ALLOCATED(MiscData%vt_tot2)) THEN + DEALLOCATE(MiscData%vt_tot2) +ENDIF +IF (ALLOCATED(MiscData%vt_amb2)) THEN + DEALLOCATE(MiscData%vt_amb2) +ENDIF +IF (ALLOCATED(MiscData%vt_shr2)) THEN + DEALLOCATE(MiscData%vt_shr2) +ENDIF +IF (ALLOCATED(MiscData%dvx_dy)) THEN + DEALLOCATE(MiscData%dvx_dy) +ENDIF +IF (ALLOCATED(MiscData%dvx_dz)) THEN + DEALLOCATE(MiscData%dvx_dz) +ENDIF +IF (ALLOCATED(MiscData%nu_dvx_dy)) THEN + DEALLOCATE(MiscData%nu_dvx_dy) +ENDIF +IF (ALLOCATED(MiscData%nu_dvx_dz)) THEN + DEALLOCATE(MiscData%nu_dvx_dz) +ENDIF +IF (ALLOCATED(MiscData%dnuvx_dy)) THEN + DEALLOCATE(MiscData%dnuvx_dy) +ENDIF +IF (ALLOCATED(MiscData%dnuvx_dz)) THEN + DEALLOCATE(MiscData%dnuvx_dz) +ENDIF IF (ALLOCATED(MiscData%a)) THEN DEALLOCATE(MiscData%a) ENDIF @@ -2654,6 +3068,51 @@ SUBROUTINE WD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz Int_BufSz = Int_BufSz + 2*2 ! vt_shr upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%vt_shr) ! vt_shr END IF + Int_BufSz = Int_BufSz + 1 ! vt_tot2 allocated yes/no + IF ( ALLOCATED(InData%vt_tot2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! vt_tot2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%vt_tot2) ! vt_tot2 + END IF + Int_BufSz = Int_BufSz + 1 ! vt_amb2 allocated yes/no + IF ( ALLOCATED(InData%vt_amb2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! vt_amb2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%vt_amb2) ! vt_amb2 + END IF + Int_BufSz = Int_BufSz + 1 ! vt_shr2 allocated yes/no + IF ( ALLOCATED(InData%vt_shr2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! vt_shr2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%vt_shr2) ! vt_shr2 + END IF + Int_BufSz = Int_BufSz + 1 ! dvx_dy allocated yes/no + IF ( ALLOCATED(InData%dvx_dy) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! dvx_dy upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dvx_dy) ! dvx_dy + END IF + Int_BufSz = Int_BufSz + 1 ! dvx_dz allocated yes/no + IF ( ALLOCATED(InData%dvx_dz) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! dvx_dz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dvx_dz) ! dvx_dz + END IF + Int_BufSz = Int_BufSz + 1 ! nu_dvx_dy allocated yes/no + IF ( ALLOCATED(InData%nu_dvx_dy) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! nu_dvx_dy upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%nu_dvx_dy) ! nu_dvx_dy + END IF + Int_BufSz = Int_BufSz + 1 ! nu_dvx_dz allocated yes/no + IF ( ALLOCATED(InData%nu_dvx_dz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! nu_dvx_dz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%nu_dvx_dz) ! nu_dvx_dz + END IF + Int_BufSz = Int_BufSz + 1 ! dnuvx_dy allocated yes/no + IF ( ALLOCATED(InData%dnuvx_dy) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! dnuvx_dy upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dnuvx_dy) ! dnuvx_dy + END IF + Int_BufSz = Int_BufSz + 1 ! dnuvx_dz allocated yes/no + IF ( ALLOCATED(InData%dnuvx_dz) ) THEN + Int_BufSz = Int_BufSz + 2*2 ! dnuvx_dz upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%dnuvx_dz) ! dnuvx_dz + END IF Int_BufSz = Int_BufSz + 1 ! a allocated yes/no IF ( ALLOCATED(InData%a) ) THEN Int_BufSz = Int_BufSz + 2*1 ! a upper/lower bounds for each dimension @@ -2798,16 +3257,221 @@ SUBROUTINE WD_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, Siz ELSE IntKiBuf( Int_Xferred ) = 1 Int_Xferred = Int_Xferred + 1 - IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr,1) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr,1) + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%vt_shr,2), UBOUND(InData%vt_shr,2) + DO i1 = LBOUND(InData%vt_shr,1), UBOUND(InData%vt_shr,1) + ReKiBuf(Re_Xferred) = InData%vt_shr(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%vt_tot2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_tot2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_tot2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_tot2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_tot2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_tot2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_tot2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%vt_tot2,3), UBOUND(InData%vt_tot2,3) + DO i2 = LBOUND(InData%vt_tot2,2), UBOUND(InData%vt_tot2,2) + DO i1 = LBOUND(InData%vt_tot2,1), UBOUND(InData%vt_tot2,1) + ReKiBuf(Re_Xferred) = InData%vt_tot2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%vt_amb2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_amb2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_amb2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_amb2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_amb2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_amb2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_amb2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%vt_amb2,3), UBOUND(InData%vt_amb2,3) + DO i2 = LBOUND(InData%vt_amb2,2), UBOUND(InData%vt_amb2,2) + DO i1 = LBOUND(InData%vt_amb2,1), UBOUND(InData%vt_amb2,1) + ReKiBuf(Re_Xferred) = InData%vt_amb2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%vt_shr2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%vt_shr2,3), UBOUND(InData%vt_shr2,3) + DO i2 = LBOUND(InData%vt_shr2,2), UBOUND(InData%vt_shr2,2) + DO i1 = LBOUND(InData%vt_shr2,1), UBOUND(InData%vt_shr2,1) + ReKiBuf(Re_Xferred) = InData%vt_shr2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dvx_dy) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dy,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dy,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dy,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dy,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dy,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dy,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%dvx_dy,3), UBOUND(InData%dvx_dy,3) + DO i2 = LBOUND(InData%dvx_dy,2), UBOUND(InData%dvx_dy,2) + DO i1 = LBOUND(InData%dvx_dy,1), UBOUND(InData%dvx_dy,1) + ReKiBuf(Re_Xferred) = InData%dvx_dy(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dvx_dz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dz,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dvx_dz,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dvx_dz,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%dvx_dz,3), UBOUND(InData%dvx_dz,3) + DO i2 = LBOUND(InData%dvx_dz,2), UBOUND(InData%dvx_dz,2) + DO i1 = LBOUND(InData%dvx_dz,1), UBOUND(InData%dvx_dz,1) + ReKiBuf(Re_Xferred) = InData%dvx_dz(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%nu_dvx_dy) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nu_dvx_dy,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nu_dvx_dy,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nu_dvx_dy,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nu_dvx_dy,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%nu_dvx_dy,2), UBOUND(InData%nu_dvx_dy,2) + DO i1 = LBOUND(InData%nu_dvx_dy,1), UBOUND(InData%nu_dvx_dy,1) + ReKiBuf(Re_Xferred) = InData%nu_dvx_dy(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%nu_dvx_dz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nu_dvx_dz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nu_dvx_dz,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%nu_dvx_dz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%nu_dvx_dz,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%nu_dvx_dz,2), UBOUND(InData%nu_dvx_dz,2) + DO i1 = LBOUND(InData%nu_dvx_dz,1), UBOUND(InData%nu_dvx_dz,1) + ReKiBuf(Re_Xferred) = InData%nu_dvx_dz(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dnuvx_dy) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dnuvx_dy,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dnuvx_dy,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dnuvx_dy,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dnuvx_dy,2) + Int_Xferred = Int_Xferred + 2 + + DO i2 = LBOUND(InData%dnuvx_dy,2), UBOUND(InData%dnuvx_dy,2) + DO i1 = LBOUND(InData%dnuvx_dy,1), UBOUND(InData%dnuvx_dy,1) + ReKiBuf(Re_Xferred) = InData%dnuvx_dy(i1,i2) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%dnuvx_dz) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%dnuvx_dz,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dnuvx_dz,1) Int_Xferred = Int_Xferred + 2 - IntKiBuf( Int_Xferred ) = LBOUND(InData%vt_shr,2) - IntKiBuf( Int_Xferred + 1) = UBOUND(InData%vt_shr,2) + IntKiBuf( Int_Xferred ) = LBOUND(InData%dnuvx_dz,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%dnuvx_dz,2) Int_Xferred = Int_Xferred + 2 - DO i2 = LBOUND(InData%vt_shr,2), UBOUND(InData%vt_shr,2) - DO i1 = LBOUND(InData%vt_shr,1), UBOUND(InData%vt_shr,1) - ReKiBuf(Re_Xferred) = InData%vt_shr(i1,i2) + DO i2 = LBOUND(InData%dnuvx_dz,2), UBOUND(InData%dnuvx_dz,2) + DO i1 = LBOUND(InData%dnuvx_dz,1), UBOUND(InData%dnuvx_dz,1) + ReKiBuf(Re_Xferred) = InData%dnuvx_dz(i1,i2) Re_Xferred = Re_Xferred + 1 END DO END DO @@ -2951,6 +3615,7 @@ SUBROUTINE WD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WD_UnPackMisc' @@ -3069,6 +3734,238 @@ SUBROUTINE WD_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg ) END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! vt_tot2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%vt_tot2)) DEALLOCATE(OutData%vt_tot2) + ALLOCATE(OutData%vt_tot2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%vt_tot2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%vt_tot2,3), UBOUND(OutData%vt_tot2,3) + DO i2 = LBOUND(OutData%vt_tot2,2), UBOUND(OutData%vt_tot2,2) + DO i1 = LBOUND(OutData%vt_tot2,1), UBOUND(OutData%vt_tot2,1) + OutData%vt_tot2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! vt_amb2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%vt_amb2)) DEALLOCATE(OutData%vt_amb2) + ALLOCATE(OutData%vt_amb2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%vt_amb2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%vt_amb2,3), UBOUND(OutData%vt_amb2,3) + DO i2 = LBOUND(OutData%vt_amb2,2), UBOUND(OutData%vt_amb2,2) + DO i1 = LBOUND(OutData%vt_amb2,1), UBOUND(OutData%vt_amb2,1) + OutData%vt_amb2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! vt_shr2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%vt_shr2)) DEALLOCATE(OutData%vt_shr2) + ALLOCATE(OutData%vt_shr2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%vt_shr2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%vt_shr2,3), UBOUND(OutData%vt_shr2,3) + DO i2 = LBOUND(OutData%vt_shr2,2), UBOUND(OutData%vt_shr2,2) + DO i1 = LBOUND(OutData%vt_shr2,1), UBOUND(OutData%vt_shr2,1) + OutData%vt_shr2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dvx_dy not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dvx_dy)) DEALLOCATE(OutData%dvx_dy) + ALLOCATE(OutData%dvx_dy(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%dvx_dy,3), UBOUND(OutData%dvx_dy,3) + DO i2 = LBOUND(OutData%dvx_dy,2), UBOUND(OutData%dvx_dy,2) + DO i1 = LBOUND(OutData%dvx_dy,1), UBOUND(OutData%dvx_dy,1) + OutData%dvx_dy(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dvx_dz not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dvx_dz)) DEALLOCATE(OutData%dvx_dz) + ALLOCATE(OutData%dvx_dz(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%dvx_dz,3), UBOUND(OutData%dvx_dz,3) + DO i2 = LBOUND(OutData%dvx_dz,2), UBOUND(OutData%dvx_dz,2) + DO i1 = LBOUND(OutData%dvx_dz,1), UBOUND(OutData%dvx_dz,1) + OutData%dvx_dz(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nu_dvx_dy not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%nu_dvx_dy)) DEALLOCATE(OutData%nu_dvx_dy) + ALLOCATE(OutData%nu_dvx_dy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nu_dvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%nu_dvx_dy,2), UBOUND(OutData%nu_dvx_dy,2) + DO i1 = LBOUND(OutData%nu_dvx_dy,1), UBOUND(OutData%nu_dvx_dy,1) + OutData%nu_dvx_dy(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! nu_dvx_dz not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%nu_dvx_dz)) DEALLOCATE(OutData%nu_dvx_dz) + ALLOCATE(OutData%nu_dvx_dz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%nu_dvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%nu_dvx_dz,2), UBOUND(OutData%nu_dvx_dz,2) + DO i1 = LBOUND(OutData%nu_dvx_dz,1), UBOUND(OutData%nu_dvx_dz,1) + OutData%nu_dvx_dz(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dnuvx_dy not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dnuvx_dy)) DEALLOCATE(OutData%dnuvx_dy) + ALLOCATE(OutData%dnuvx_dy(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dnuvx_dy.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%dnuvx_dy,2), UBOUND(OutData%dnuvx_dy,2) + DO i1 = LBOUND(OutData%dnuvx_dy,1), UBOUND(OutData%dnuvx_dy,1) + OutData%dnuvx_dy(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! dnuvx_dz not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%dnuvx_dz)) DEALLOCATE(OutData%dnuvx_dz) + ALLOCATE(OutData%dnuvx_dz(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%dnuvx_dz.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i2 = LBOUND(OutData%dnuvx_dz,2), UBOUND(OutData%dnuvx_dz,2) + DO i1 = LBOUND(OutData%dnuvx_dz,1), UBOUND(OutData%dnuvx_dz,1) + OutData%dnuvx_dz(i1,i2) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! a not allocated Int_Xferred = Int_Xferred + 1 ELSE @@ -4093,6 +4990,7 @@ SUBROUTINE WD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs INTEGER(IntKi) :: i,j,k INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WD_CopyOutput' @@ -4155,6 +5053,54 @@ SUBROUTINE WD_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMs END IF DstOutputData%Vr_wake = SrcOutputData%Vr_wake ENDIF +IF (ALLOCATED(SrcOutputData%Vx_wake2)) THEN + i1_l = LBOUND(SrcOutputData%Vx_wake2,1) + i1_u = UBOUND(SrcOutputData%Vx_wake2,1) + i2_l = LBOUND(SrcOutputData%Vx_wake2,2) + i2_u = UBOUND(SrcOutputData%Vx_wake2,2) + i3_l = LBOUND(SrcOutputData%Vx_wake2,3) + i3_u = UBOUND(SrcOutputData%Vx_wake2,3) + IF (.NOT. ALLOCATED(DstOutputData%Vx_wake2)) THEN + ALLOCATE(DstOutputData%Vx_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Vx_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Vx_wake2 = SrcOutputData%Vx_wake2 +ENDIF +IF (ALLOCATED(SrcOutputData%Vy_wake2)) THEN + i1_l = LBOUND(SrcOutputData%Vy_wake2,1) + i1_u = UBOUND(SrcOutputData%Vy_wake2,1) + i2_l = LBOUND(SrcOutputData%Vy_wake2,2) + i2_u = UBOUND(SrcOutputData%Vy_wake2,2) + i3_l = LBOUND(SrcOutputData%Vy_wake2,3) + i3_u = UBOUND(SrcOutputData%Vy_wake2,3) + IF (.NOT. ALLOCATED(DstOutputData%Vy_wake2)) THEN + ALLOCATE(DstOutputData%Vy_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Vy_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Vy_wake2 = SrcOutputData%Vy_wake2 +ENDIF +IF (ALLOCATED(SrcOutputData%Vz_wake2)) THEN + i1_l = LBOUND(SrcOutputData%Vz_wake2,1) + i1_u = UBOUND(SrcOutputData%Vz_wake2,1) + i2_l = LBOUND(SrcOutputData%Vz_wake2,2) + i2_u = UBOUND(SrcOutputData%Vz_wake2,2) + i3_l = LBOUND(SrcOutputData%Vz_wake2,3) + i3_u = UBOUND(SrcOutputData%Vz_wake2,3) + IF (.NOT. ALLOCATED(DstOutputData%Vz_wake2)) THEN + ALLOCATE(DstOutputData%Vz_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%Vz_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + END IF + DstOutputData%Vz_wake2 = SrcOutputData%Vz_wake2 +ENDIF IF (ALLOCATED(SrcOutputData%D_wake)) THEN i1_l = LBOUND(SrcOutputData%D_wake,1) i1_u = UBOUND(SrcOutputData%D_wake,1) @@ -4214,6 +5160,15 @@ SUBROUTINE WD_DestroyOutput( OutputData, ErrStat, ErrMsg, DEALLOCATEpointers ) IF (ALLOCATED(OutputData%Vr_wake)) THEN DEALLOCATE(OutputData%Vr_wake) ENDIF +IF (ALLOCATED(OutputData%Vx_wake2)) THEN + DEALLOCATE(OutputData%Vx_wake2) +ENDIF +IF (ALLOCATED(OutputData%Vy_wake2)) THEN + DEALLOCATE(OutputData%Vy_wake2) +ENDIF +IF (ALLOCATED(OutputData%Vz_wake2)) THEN + DEALLOCATE(OutputData%Vz_wake2) +ENDIF IF (ALLOCATED(OutputData%D_wake)) THEN DEALLOCATE(OutputData%D_wake) ENDIF @@ -4277,6 +5232,21 @@ SUBROUTINE WD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S Int_BufSz = Int_BufSz + 2*2 ! Vr_wake upper/lower bounds for each dimension Re_BufSz = Re_BufSz + SIZE(InData%Vr_wake) ! Vr_wake END IF + Int_BufSz = Int_BufSz + 1 ! Vx_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vx_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vx_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vx_wake2) ! Vx_wake2 + END IF + Int_BufSz = Int_BufSz + 1 ! Vy_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vy_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vy_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vy_wake2) ! Vy_wake2 + END IF + Int_BufSz = Int_BufSz + 1 ! Vz_wake2 allocated yes/no + IF ( ALLOCATED(InData%Vz_wake2) ) THEN + Int_BufSz = Int_BufSz + 2*3 ! Vz_wake2 upper/lower bounds for each dimension + Re_BufSz = Re_BufSz + SIZE(InData%Vz_wake2) ! Vz_wake2 + END IF Int_BufSz = Int_BufSz + 1 ! D_wake allocated yes/no IF ( ALLOCATED(InData%D_wake) ) THEN Int_BufSz = Int_BufSz + 2*1 ! D_wake upper/lower bounds for each dimension @@ -4394,6 +5364,81 @@ SUBROUTINE WD_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, S END DO END DO END IF + IF ( .NOT. ALLOCATED(InData%Vx_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vx_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vx_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vx_wake2,3), UBOUND(InData%Vx_wake2,3) + DO i2 = LBOUND(InData%Vx_wake2,2), UBOUND(InData%Vx_wake2,2) + DO i1 = LBOUND(InData%Vx_wake2,1), UBOUND(InData%Vx_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vx_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vy_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vy_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vy_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vy_wake2,3), UBOUND(InData%Vy_wake2,3) + DO i2 = LBOUND(InData%Vy_wake2,2), UBOUND(InData%Vy_wake2,2) + DO i1 = LBOUND(InData%Vy_wake2,1), UBOUND(InData%Vy_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vy_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( .NOT. ALLOCATED(InData%Vz_wake2) ) THEN + IntKiBuf( Int_Xferred ) = 0 + Int_Xferred = Int_Xferred + 1 + ELSE + IntKiBuf( Int_Xferred ) = 1 + Int_Xferred = Int_Xferred + 1 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,1) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,1) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,2) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,2) + Int_Xferred = Int_Xferred + 2 + IntKiBuf( Int_Xferred ) = LBOUND(InData%Vz_wake2,3) + IntKiBuf( Int_Xferred + 1) = UBOUND(InData%Vz_wake2,3) + Int_Xferred = Int_Xferred + 2 + + DO i3 = LBOUND(InData%Vz_wake2,3), UBOUND(InData%Vz_wake2,3) + DO i2 = LBOUND(InData%Vz_wake2,2), UBOUND(InData%Vz_wake2,2) + DO i1 = LBOUND(InData%Vz_wake2,1), UBOUND(InData%Vz_wake2,1) + ReKiBuf(Re_Xferred) = InData%Vz_wake2(i1,i2,i3) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF IF ( .NOT. ALLOCATED(InData%D_wake) ) THEN IntKiBuf( Int_Xferred ) = 0 Int_Xferred = Int_Xferred + 1 @@ -4441,6 +5486,7 @@ SUBROUTINE WD_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg INTEGER(IntKi) :: i INTEGER(IntKi) :: i1, i1_l, i1_u ! bounds (upper/lower) for an array dimension 1 INTEGER(IntKi) :: i2, i2_l, i2_u ! bounds (upper/lower) for an array dimension 2 + INTEGER(IntKi) :: i3, i3_l, i3_u ! bounds (upper/lower) for an array dimension 3 INTEGER(IntKi) :: ErrStat2 CHARACTER(ErrMsgLen) :: ErrMsg2 CHARACTER(*), PARAMETER :: RoutineName = 'WD_UnPackOutput' @@ -4546,6 +5592,90 @@ SUBROUTINE WD_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg END DO END DO END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vx_wake2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vx_wake2)) DEALLOCATE(OutData%Vx_wake2) + ALLOCATE(OutData%Vx_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vx_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vx_wake2,3), UBOUND(OutData%Vx_wake2,3) + DO i2 = LBOUND(OutData%Vx_wake2,2), UBOUND(OutData%Vx_wake2,2) + DO i1 = LBOUND(OutData%Vx_wake2,1), UBOUND(OutData%Vx_wake2,1) + OutData%Vx_wake2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vy_wake2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vy_wake2)) DEALLOCATE(OutData%Vy_wake2) + ALLOCATE(OutData%Vy_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vy_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vy_wake2,3), UBOUND(OutData%Vy_wake2,3) + DO i2 = LBOUND(OutData%Vy_wake2,2), UBOUND(OutData%Vy_wake2,2) + DO i1 = LBOUND(OutData%Vy_wake2,1), UBOUND(OutData%Vy_wake2,1) + OutData%Vy_wake2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF + IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! Vz_wake2 not allocated + Int_Xferred = Int_Xferred + 1 + ELSE + Int_Xferred = Int_Xferred + 1 + i1_l = IntKiBuf( Int_Xferred ) + i1_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i2_l = IntKiBuf( Int_Xferred ) + i2_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + i3_l = IntKiBuf( Int_Xferred ) + i3_u = IntKiBuf( Int_Xferred + 1) + Int_Xferred = Int_Xferred + 2 + IF (ALLOCATED(OutData%Vz_wake2)) DEALLOCATE(OutData%Vz_wake2) + ALLOCATE(OutData%Vz_wake2(i1_l:i1_u,i2_l:i2_u,i3_l:i3_u),STAT=ErrStat2) + IF (ErrStat2 /= 0) THEN + CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%Vz_wake2.', ErrStat, ErrMsg,RoutineName) + RETURN + END IF + DO i3 = LBOUND(OutData%Vz_wake2,3), UBOUND(OutData%Vz_wake2,3) + DO i2 = LBOUND(OutData%Vz_wake2,2), UBOUND(OutData%Vz_wake2,2) + DO i1 = LBOUND(OutData%Vz_wake2,1), UBOUND(OutData%Vz_wake2,1) + OutData%Vz_wake2(i1,i2,i3) = ReKiBuf(Re_Xferred) + Re_Xferred = Re_Xferred + 1 + END DO + END DO + END DO + END IF IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN ! D_wake not allocated Int_Xferred = Int_Xferred + 1 ELSE diff --git a/reg_tests/r-test b/reg_tests/r-test index 7daae2e05c..db919459be 160000 --- a/reg_tests/r-test +++ b/reg_tests/r-test @@ -1 +1 @@ -Subproject commit 7daae2e05cb6e18d269dd80c2b00845923f0fcf5 +Subproject commit db919459bee6ffe5d01e2b121362112201b5829d