From cbc03ddacc8881256b611d01fb140fb5e0284be7 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 09:37:50 -0700 Subject: [PATCH 01/58] Update AeroDyn.f90 --- modules-local/aerodyn/src/AeroDyn.f90 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/AeroDyn.f90 b/modules-local/aerodyn/src/AeroDyn.f90 index da07a82a2..619381fdb 100644 --- a/modules-local/aerodyn/src/AeroDyn.f90 +++ b/modules-local/aerodyn/src/AeroDyn.f90 @@ -867,6 +867,8 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) p%AirDens = InputFileData%AirDens p%KinVisc = InputFileData%KinVisc p%SpdSound = InputFileData%SpdSound + p%Patm = InputFileData%Patm + p%Pvap = InputFileData%Pvap !p%AFI ! set in call to AFI_Init() [called early because it wants to use the same echo file as AD] !p%BEMT ! set in call to BEMT_Init() @@ -1699,7 +1701,11 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, InitInp%numBlades = p%NumBlades InitInp%airDens = InputFileData%AirDens - InitInp%kinVisc = InputFileData%KinVisc + InitInp%kinVisc = InputFileData%KinVisc + InitInp%Patm = InputFileData%Patm + InitInp%Pvap = InputFileData%Pvap + InitInp%FluidDepth = InputFileData%FluidDepth + InitInp%CavitCheck = InputFileData%CavitCheck InitInp%skewWakeMod = InputFileData%SkewMod InitInp%aTol = InputFileData%IndToler InitInp%useTipLoss = InputFileData%TipLoss @@ -1752,6 +1758,7 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, InitInp%UAMod = InputFileData%UAMod InitInp%Flookup = InputFileData%Flookup InitInp%a_s = InputFileData%SpdSound + InitInp%CavitCheck = InputFileData%CavitCheck if (ErrStat >= AbortErrLev) then call cleanup() From 35b21619dc82c23a5f08ee9ac35b831dcedc0e51 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 09:40:09 -0700 Subject: [PATCH 02/58] Update AeroDyn_IO.f90 --- modules-local/aerodyn/src/AeroDyn_IO.f90 | 1143 ++++++++++++---------- 1 file changed, 605 insertions(+), 538 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index d36c97d3f..52485b74e 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -25,20 +25,20 @@ MODULE AeroDyn_IO use NWTC_Library use AeroDyn_Types - use BEMTUncoupled, only : SkewMod_Uncoupled, SkewMod_PittPeters, VelocityIsZero + use BEMTUncoupled, only : SkewMod_Uncoupled, SkewMod_PittPeters implicit none - type(ProgDesc), parameter :: AD_Ver = ProgDesc( 'AeroDyn', 'v15.04.00', '29-Oct-2016' ) + type(ProgDesc), parameter :: AD_Ver = ProgDesc( 'AeroDyn', 'v15.03.00', '27-Jul-2016' ) character(*), parameter :: AD_Nickname = 'AD' ! =================================================================================================== ! NOTE: The following lines of code were generated by a Matlab script called "Write_ChckOutLst.m" -! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these +! using the parameters listed in the "OutListParameters_RMurray.xlsx" Excel file. Any changes to these ! lines should be modified in the Matlab script and/or Excel worksheet as necessary. ! =================================================================================================== -! This code was generated by Write_ChckOutLst.m at 11-Mar-2016 14:45:58. +! This code was generated by Write_ChckOutLst.m at 16-Feb-2017 15:50:51. ! Parameters related to output length (number of characters allowed in the output data headers): @@ -1148,34 +1148,116 @@ MODULE AeroDyn_IO INTEGER(IntKi), PARAMETER :: B3N7Clrnc = 1084 INTEGER(IntKi), PARAMETER :: B3N8Clrnc = 1085 INTEGER(IntKi), PARAMETER :: B3N9Clrnc = 1086 + INTEGER(IntKi), PARAMETER :: B1N1Cpmin = 1087 + INTEGER(IntKi), PARAMETER :: B1N2Cpmin = 1088 + INTEGER(IntKi), PARAMETER :: B1N3Cpmin = 1089 + INTEGER(IntKi), PARAMETER :: B1N4Cpmin = 1090 + INTEGER(IntKi), PARAMETER :: B1N5Cpmin = 1091 + INTEGER(IntKi), PARAMETER :: B1N6Cpmin = 1092 + INTEGER(IntKi), PARAMETER :: B1N7Cpmin = 1093 + INTEGER(IntKi), PARAMETER :: B1N8Cpmin = 1094 + INTEGER(IntKi), PARAMETER :: B1N9Cpmin = 1095 + INTEGER(IntKi), PARAMETER :: B2N1Cpmin = 1096 + INTEGER(IntKi), PARAMETER :: B2N2Cpmin = 1097 + INTEGER(IntKi), PARAMETER :: B2N3Cpmin = 1098 + INTEGER(IntKi), PARAMETER :: B2N4Cpmin = 1099 + INTEGER(IntKi), PARAMETER :: B2N5Cpmin = 1100 + INTEGER(IntKi), PARAMETER :: B2N6Cpmin = 1101 + INTEGER(IntKi), PARAMETER :: B2N7Cpmin = 1102 + INTEGER(IntKi), PARAMETER :: B2N8Cpmin = 1103 + INTEGER(IntKi), PARAMETER :: B2N9Cpmin = 1104 + INTEGER(IntKi), PARAMETER :: B3N1Cpmin = 1105 + INTEGER(IntKi), PARAMETER :: B3N2Cpmin = 1106 + INTEGER(IntKi), PARAMETER :: B3N3Cpmin = 1107 + INTEGER(IntKi), PARAMETER :: B3N4Cpmin = 1108 + INTEGER(IntKi), PARAMETER :: B3N5Cpmin = 1109 + INTEGER(IntKi), PARAMETER :: B3N6Cpmin = 1110 + INTEGER(IntKi), PARAMETER :: B3N7Cpmin = 1111 + INTEGER(IntKi), PARAMETER :: B3N8Cpmin = 1112 + INTEGER(IntKi), PARAMETER :: B3N9Cpmin = 1113 + INTEGER(IntKi), PARAMETER :: B1N1SigCr = 1114 + INTEGER(IntKi), PARAMETER :: B1N2SigCr = 1115 + INTEGER(IntKi), PARAMETER :: B1N3SigCr = 1116 + INTEGER(IntKi), PARAMETER :: B1N4SigCr = 1117 + INTEGER(IntKi), PARAMETER :: B1N5SigCr = 1118 + INTEGER(IntKi), PARAMETER :: B1N6SigCr = 1119 + INTEGER(IntKi), PARAMETER :: B1N7SigCr = 1120 + INTEGER(IntKi), PARAMETER :: B1N8SigCr = 1121 + INTEGER(IntKi), PARAMETER :: B1N9SigCr = 1122 + INTEGER(IntKi), PARAMETER :: B2N1SigCr = 1123 + INTEGER(IntKi), PARAMETER :: B2N2SigCr = 1124 + INTEGER(IntKi), PARAMETER :: B2N3SigCr = 1125 + INTEGER(IntKi), PARAMETER :: B2N4SigCr = 1126 + INTEGER(IntKi), PARAMETER :: B2N5SigCr = 1127 + INTEGER(IntKi), PARAMETER :: B2N6SigCr = 1128 + INTEGER(IntKi), PARAMETER :: B2N7SigCr = 1129 + INTEGER(IntKi), PARAMETER :: B2N8SigCr = 1130 + INTEGER(IntKi), PARAMETER :: B2N9SigCr = 1131 + INTEGER(IntKi), PARAMETER :: B3N1SigCr = 1132 + INTEGER(IntKi), PARAMETER :: B3N2SigCr = 1133 + INTEGER(IntKi), PARAMETER :: B3N3SigCr = 1134 + INTEGER(IntKi), PARAMETER :: B3N4SigCr = 1135 + INTEGER(IntKi), PARAMETER :: B3N5SigCr = 1136 + INTEGER(IntKi), PARAMETER :: B3N6SigCr = 1137 + INTEGER(IntKi), PARAMETER :: B3N7SigCr = 1138 + INTEGER(IntKi), PARAMETER :: B3N8SigCr = 1139 + INTEGER(IntKi), PARAMETER :: B3N9SigCr = 1140 + INTEGER(IntKi), PARAMETER :: B1N1SgCav = 1141 + INTEGER(IntKi), PARAMETER :: B1N2SgCav = 1142 + INTEGER(IntKi), PARAMETER :: B1N3SgCav = 1143 + INTEGER(IntKi), PARAMETER :: B1N4SgCav = 1144 + INTEGER(IntKi), PARAMETER :: B1N5SgCav = 1145 + INTEGER(IntKi), PARAMETER :: B1N6SgCav = 1146 + INTEGER(IntKi), PARAMETER :: B1N7SgCav = 1147 + INTEGER(IntKi), PARAMETER :: B1N8SgCav = 1148 + INTEGER(IntKi), PARAMETER :: B1N9SgCav = 1149 + INTEGER(IntKi), PARAMETER :: B2N1SgCav = 1150 + INTEGER(IntKi), PARAMETER :: B2N2SgCav = 1151 + INTEGER(IntKi), PARAMETER :: B2N3SgCav = 1152 + INTEGER(IntKi), PARAMETER :: B2N4SgCav = 1153 + INTEGER(IntKi), PARAMETER :: B2N5SgCav = 1154 + INTEGER(IntKi), PARAMETER :: B2N6SgCav = 1155 + INTEGER(IntKi), PARAMETER :: B2N7SgCav = 1156 + INTEGER(IntKi), PARAMETER :: B2N8SgCav = 1157 + INTEGER(IntKi), PARAMETER :: B2N9SgCav = 1158 + INTEGER(IntKi), PARAMETER :: B3N1SgCav = 1159 + INTEGER(IntKi), PARAMETER :: B3N2SgCav = 1160 + INTEGER(IntKi), PARAMETER :: B3N3SgCav = 1161 + INTEGER(IntKi), PARAMETER :: B3N4SgCav = 1162 + INTEGER(IntKi), PARAMETER :: B3N5SgCav = 1163 + INTEGER(IntKi), PARAMETER :: B3N6SgCav = 1164 + INTEGER(IntKi), PARAMETER :: B3N7SgCav = 1165 + INTEGER(IntKi), PARAMETER :: B3N8SgCav = 1166 + INTEGER(IntKi), PARAMETER :: B3N9SgCav = 1167 ! Rotor: - INTEGER(IntKi), PARAMETER :: RtSpeed = 1087 - INTEGER(IntKi), PARAMETER :: RtTSR = 1088 - INTEGER(IntKi), PARAMETER :: RtVAvgxh = 1089 - INTEGER(IntKi), PARAMETER :: RtVAvgyh = 1090 - INTEGER(IntKi), PARAMETER :: RtVAvgzh = 1091 - INTEGER(IntKi), PARAMETER :: RtSkew = 1092 - INTEGER(IntKi), PARAMETER :: RtAeroFxh = 1093 - INTEGER(IntKi), PARAMETER :: RtAeroFyh = 1094 - INTEGER(IntKi), PARAMETER :: RtAeroFzh = 1095 - INTEGER(IntKi), PARAMETER :: RtAeroMxh = 1096 - INTEGER(IntKi), PARAMETER :: RtAeroMyh = 1097 - INTEGER(IntKi), PARAMETER :: RtAeroMzh = 1098 - INTEGER(IntKi), PARAMETER :: RtAeroPwr = 1099 - INTEGER(IntKi), PARAMETER :: RtArea = 1100 - INTEGER(IntKi), PARAMETER :: RtAeroCp = 1101 - INTEGER(IntKi), PARAMETER :: RtAeroCq = 1102 - INTEGER(IntKi), PARAMETER :: RtAeroCt = 1103 + INTEGER(IntKi), PARAMETER :: RtSpeed = 1168 + INTEGER(IntKi), PARAMETER :: RtTSR = 1169 + INTEGER(IntKi), PARAMETER :: RtVAvgxh = 1170 + INTEGER(IntKi), PARAMETER :: RtVAvgyh = 1171 + INTEGER(IntKi), PARAMETER :: RtVAvgzh = 1172 + INTEGER(IntKi), PARAMETER :: RtSkew = 1173 + INTEGER(IntKi), PARAMETER :: RtAeroFxh = 1174 + INTEGER(IntKi), PARAMETER :: RtAeroFyh = 1175 + INTEGER(IntKi), PARAMETER :: RtAeroFzh = 1176 + INTEGER(IntKi), PARAMETER :: RtAeroMxh = 1177 + INTEGER(IntKi), PARAMETER :: RtAeroMyh = 1178 + INTEGER(IntKi), PARAMETER :: RtAeroMzh = 1179 + INTEGER(IntKi), PARAMETER :: RtAeroPwr = 1180 + INTEGER(IntKi), PARAMETER :: RtArea = 1181 + INTEGER(IntKi), PARAMETER :: RtAeroCp = 1182 + INTEGER(IntKi), PARAMETER :: RtAeroCq = 1183 + INTEGER(IntKi), PARAMETER :: RtAeroCt = 1184 ! The maximum number of output channels which can be output by the code. - INTEGER(IntKi), PARAMETER :: MaxOutPts = 1103 + INTEGER(IntKi), PARAMETER :: MaxOutPts = 1184 !End of code generated by Matlab script ! =================================================================================================== + INTEGER, PARAMETER :: TwNVUnd(3, 9) = RESHAPE( (/ & ! Undisturbed wind velocity TwN1VUndx,TwN1VUndy,TwN1VUndz, & @@ -1333,6 +1415,25 @@ MODULE AeroDyn_IO B2N1Cm,B2N2Cm,B2N3Cm,B2N4Cm,B2N5Cm,B2N6Cm,B2N7Cm,B2N8Cm,B2N9Cm, & B3N1Cm,B3N2Cm,B3N3Cm,B3N4Cm,B3N5Cm,B3N6Cm,B3N7Cm,B3N8Cm,B3N9Cm & /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNCpmin(9, 3) = RESHAPE( (/ & ! pressure coefficient + B1N1Cpmin,B1N2Cpmin,B1N3Cpmin,B1N4Cpmin,B1N5Cpmin,B1N6Cpmin,B1N7Cpmin,B1N8Cpmin,B1N9Cpmin, & + B2N1Cpmin,B2N2Cpmin,B2N3Cpmin,B2N4Cpmin,B2N5Cpmin,B2N6Cpmin,B2N7Cpmin,B2N8Cpmin,B2N9Cpmin, & + B3N1Cpmin,B3N2Cpmin,B3N3Cpmin,B3N4Cpmin,B3N5Cpmin,B3N6Cpmin,B3N7Cpmin,B3N8Cpmin,B3N9Cpmin & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNSigCr(9, 3) = RESHAPE( (/ & ! Critical cavitation number + B1N1SigCr,B1N2SigCr,B1N3SigCr,B1N4SigCr,B1N5SigCr,B1N6SigCr,B1N7SigCr,B1N8SigCr,B1N9SigCr, & + B2N1SigCr,B2N2SigCr,B2N3SigCr,B2N4SigCr,B2N5SigCr,B2N6SigCr,B2N7SigCr,B2N8SigCr,B2N9SigCr, & + B3N1SigCr,B3N2SigCr,B3N3SigCr,B3N4SigCr,B3N5SigCr,B3N6SigCr,B3N7SigCr,B3N8SigCr,B3N9SigCr & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNSgCav(9, 3) = RESHAPE( (/ & ! Cavitation number + B1N1SgCav,B1N2SgCav,B1N3SgCav,B1N4SgCav,B1N5SgCav,B1N6SgCav,B1N7SgCav,B1N8SgCav,B1N9SgCav, & + B2N1SgCav,B2N2SgCav,B2N3SgCav,B2N4SgCav,B2N5SgCav,B2N6SgCav,B2N7SgCav,B2N8SgCav,B2N9SgCav, & + B3N1SgCav,B3N2SgCav,B3N3SgCav,B3N4SgCav,B3N5SgCav,B3N6SgCav,B3N7SgCav,B3N8SgCav,B3N9SgCav & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCx(9, 3) = RESHAPE( (/ & ! normal force (to plane) coefficient B1N1Cx,B1N2Cx,B1N3Cx,B1N4Cx,B1N5Cx,B1N6Cx,B1N7Cx,B1N8Cx,B1N9Cx, & B2N1Cx,B2N2Cx,B2N3Cx,B2N4Cx,B2N5Cx,B2N6Cx,B2N7Cx,B2N8Cx,B2N9Cx, & @@ -1573,7 +1674,7 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, indx, ErrStat, ErrMsg ) m%AllOuts( BNAxInd(beta,k) ) = m%BEMT_y%axInduction(j,k) m%AllOuts( BNTnInd(beta,k) ) = m%BEMT_y%tanInduction(j,k) - m%AllOuts( BNAlpha(beta,k) ) = Rad2M180to180Deg( m%BEMT_y%phi(j,k) - m%BEMT_u(indx)%theta(j,k) ) + m%AllOuts( BNAlpha(beta,k) ) = (m%BEMT_y%phi(j,k) - m%BEMT_u(indx)%theta(j,k))*R2D m%AllOuts( BNTheta(beta,k) ) = m%BEMT_u(indx)%theta(j,k)*R2D m%AllOuts( BNPhi( beta,k) ) = m%BEMT_y%phi(j,k)*R2D m%AllOuts( BNCurve(beta,k) ) = m%Curve(j,k)*R2D @@ -1586,7 +1687,11 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, indx, ErrStat, ErrMsg ) m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cx(j,k)*sp - m%BEMT_y%Cy(j,k)*cp m%AllOuts( BNCm( beta,k) ) = m%BEMT_y%Cm(j,k) m%AllOuts( BNCx( beta,k) ) = m%BEMT_y%Cx(j,k) - m%AllOuts( BNCy( beta,k) ) = m%BEMT_y%Cy(j,k) + m%AllOuts( BNCy( beta,k) ) = m%BEMT_y%Cy(j,k) + + m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cpmin(j,k) + m%AllOuts( BNSigCr( beta,k) ) = m%BEMT_y%SigmaCavitCrit(j,k) + m%AllOuts( BNSgCav( beta,k) ) = m%BEMT_y%SigmaCavit(j,k) ct=cos(m%BEMT_u(indx)%theta(j,k)) st=sin(m%BEMT_u(indx)%theta(j,k)) @@ -1908,6 +2013,11 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadVar( UnIn, InputFile, InputFileData%FrozenWake, "FrozenWake", "Assume frozen wake during linearization? (flag)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! CavitCheck - Perform cavitation check? (flag): + CALL ReadVar( UnIn, InputFile, InputFileData%CavitCheck, "CavitCheck", "Perform cavitation check? (flag)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Return on error at end of section IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -1919,14 +2029,32 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! AirDens - Air density (kg/m^3): - CALL ReadVar( UnIn, InputFile, InputFileData%AirDens, "AirDens", "Air density (kg/m^3)", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, InputFileData%FluidDens, "FluidDens", "Air density (kg/m^3)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + InputFileData%AirDens= InputFileData%FluidDens ! KinVisc - Kinematic air viscosity (m^2/s): CALL ReadVar( UnIn, InputFile, InputFileData%KinVisc, "KinVisc", "Kinematic air viscosity (m^2/s)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! SpdSound - Speed of sound (m/s): + + ! Patm - Atmospheric pressure (Pa): + CALL ReadVar( UnIn, InputFile, InputFileData%Patm, "Patm", "Atmospheric pressure (Pa)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + ! Pvap - Vapour pressure of fluid (Pa): + CALL ReadVar( UnIn, InputFile, InputFileData%Pvap, "Pvap", "Vapour pressure of fluid (Pa)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + ! FluidDepth - Water depth above mid-hub height (m) - used for caviation check: + CALL ReadVar( UnIn, InputFile, InputFileData%FluidDepth, "FluidDepth", "Water depth above mid-hub height (MHK only, for cavitation check) (m)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! call WrScr( NewLine//'FluidDepth_input '//trim(num2lstr(InputFileData%FluidDepth)) ) + + ! SpdSound - Speed of sound (m/s): CALL ReadVar( UnIn, InputFile, InputFileData%SpdSound, "SpdSound", "Speed of sound (m/s)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -1998,12 +2126,12 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadCom( UnIn, InputFile, 'Section Header: Beddoes-Leishman Unsteady Airfoil Aerodynamics Options', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! UAMod - Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-): - CALL ReadVar( UnIn, InputFile, InputFileData%UAMod, "UAMod", "Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-)", ErrStat2, ErrMsg2, UnEc) + ! UAMod - Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez’s variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-): + CALL ReadVar( UnIn, InputFile, InputFileData%UAMod, "UAMod", "Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez’s variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! FLookup - Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%FLookup, "FLookup", "Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag)", ErrStat2, ErrMsg2, UnEc) + ! FLookup - Flag to indicate whether a lookup for f’ will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag): + CALL ReadVar( UnIn, InputFile, InputFileData%FLookup, "FLookup", "Flag to indicate whether a lookup for f’ will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! UACutout - Angle-of-attach beyond which unsteady aerodynamics are disabled (deg) @@ -2041,11 +2169,21 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) RETURN - ! InCol_Cpmin - The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-): - CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cpmin, "InCol_Cpmin", "The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-)", ErrStat2, ErrMsg2, UnEc) + ! InCol_Cpmin - The column in the airfoil tables that contains the pressure coefficient; use zero if there is no Cpmin column (-): + CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cpmin, "InCol_Cpmin", "The column in the airfoil tables that contains the pressure coefficient; use zero if there is no Cpmin column (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) RETURN - + + + + !if statement in case there is no Cpmin data, we warn the user + if (InputFileData%InCol_Cpmin == 0 .and. InputFileData%CavitCheck== .true.) then + InputFileData%CavitCheck = .false. + call WrScr( NewLine//' Warning: No Cpmin data. Cavitation check NOT performed.................') + end if + + + ! NumAFfiles - Number of airfoil files used (-): CALL ReadVar( UnIn, InputFile, InputFileData%NumAFfiles, "NumAFfiles", "Number of airfoil files used (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -2511,7 +2649,7 @@ SUBROUTINE AD_PrintSum( InputFileData, p, u, y, ErrStat, ErrMsg ) case (1) Msg = 'baseline model (original)' case (2) - Msg = "Gonzalez's variant (changes in Cn, Cc, and Cm)" + Msg = 'Gonzalez’s variant (changes in Cn, Cc, and Cm)' case (3) Msg = 'Minemma/Pierce variant (changes in Cc and Cm)' !case (4) @@ -2590,7 +2728,7 @@ END SUBROUTINE AD_PrintSum !! the sign is set to 0 if the channel is invalid. !! It sets assumes the value p%NumOuts has been set before this routine has been called, and it sets the values of p%OutParam here. !! -!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 11-Mar-2016 14:45:58. +!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 16-Feb-2017 15:50:51. SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) !.................................................................................................................................. @@ -2607,6 +2745,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) INTEGER :: ErrStat2 ! temporary (local) error status INTEGER :: I ! Generic loop-counting index + INTEGER :: J ! Generic loop-counting index INTEGER :: INDX ! Index for valid arrays LOGICAL :: CheckOutListAgain ! Flag used to determine if output parameter starting with "M" is valid (or the negative of another parameter) @@ -2614,467 +2753,506 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) CHARACTER(*), PARAMETER :: RoutineName = "SetOutParam" - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(1103) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(1184) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically "B1AZIMUTH","B1N1ALPHA","B1N1AXIND","B1N1CD ","B1N1CL ","B1N1CLRNC","B1N1CM ", & - "B1N1CN ","B1N1CT ","B1N1CURVE","B1N1CX ","B1N1CY ","B1N1DYNP ","B1N1FD ", & - "B1N1FL ","B1N1FN ","B1N1FT ","B1N1FX ","B1N1FY ","B1N1M ","B1N1MM ", & - "B1N1PHI ","B1N1RE ","B1N1STVX ","B1N1STVY ","B1N1STVZ ","B1N1THETA","B1N1TNIND", & - "B1N1VDISX","B1N1VDISY","B1N1VDISZ","B1N1VINDX","B1N1VINDY","B1N1VREL ","B1N1VUNDX", & - "B1N1VUNDY","B1N1VUNDZ","B1N2ALPHA","B1N2AXIND","B1N2CD ","B1N2CL ","B1N2CLRNC", & - "B1N2CM ","B1N2CN ","B1N2CT ","B1N2CURVE","B1N2CX ","B1N2CY ","B1N2DYNP ", & - "B1N2FD ","B1N2FL ","B1N2FN ","B1N2FT ","B1N2FX ","B1N2FY ","B1N2M ", & - "B1N2MM ","B1N2PHI ","B1N2RE ","B1N2STVX ","B1N2STVY ","B1N2STVZ ","B1N2THETA", & - "B1N2TNIND","B1N2VDISX","B1N2VDISY","B1N2VDISZ","B1N2VINDX","B1N2VINDY","B1N2VREL ", & - "B1N2VUNDX","B1N2VUNDY","B1N2VUNDZ","B1N3ALPHA","B1N3AXIND","B1N3CD ","B1N3CL ", & - "B1N3CLRNC","B1N3CM ","B1N3CN ","B1N3CT ","B1N3CURVE","B1N3CX ","B1N3CY ", & + "B1N1CN ","B1N1CPMIN","B1N1CT ","B1N1CURVE","B1N1CX ","B1N1CY ","B1N1DYNP ", & + "B1N1FD ","B1N1FL ","B1N1FN ","B1N1FT ","B1N1FX ","B1N1FY ","B1N1M ", & + "B1N1MM ","B1N1PHI ","B1N1RE ","B1N1SGCAV","B1N1SIGCR","B1N1STVX ","B1N1STVY ", & + "B1N1STVZ ","B1N1THETA","B1N1TNIND","B1N1VDISX","B1N1VDISY","B1N1VDISZ","B1N1VINDX", & + "B1N1VINDY","B1N1VREL ","B1N1VUNDX","B1N1VUNDY","B1N1VUNDZ","B1N2ALPHA","B1N2AXIND", & + "B1N2CD ","B1N2CL ","B1N2CLRNC","B1N2CM ","B1N2CN ","B1N2CPMIN","B1N2CT ", & + "B1N2CURVE","B1N2CX ","B1N2CY ","B1N2DYNP ","B1N2FD ","B1N2FL ","B1N2FN ", & + "B1N2FT ","B1N2FX ","B1N2FY ","B1N2M ","B1N2MM ","B1N2PHI ","B1N2RE ", & + "B1N2SGCAV","B1N2SIGCR","B1N2STVX ","B1N2STVY ","B1N2STVZ ","B1N2THETA","B1N2TNIND", & + "B1N2VDISX","B1N2VDISY","B1N2VDISZ","B1N2VINDX","B1N2VINDY","B1N2VREL ","B1N2VUNDX", & + "B1N2VUNDY","B1N2VUNDZ","B1N3ALPHA","B1N3AXIND","B1N3CD ","B1N3CL ","B1N3CLRNC", & + "B1N3CM ","B1N3CN ","B1N3CPMIN","B1N3CT ","B1N3CURVE","B1N3CX ","B1N3CY ", & "B1N3DYNP ","B1N3FD ","B1N3FL ","B1N3FN ","B1N3FT ","B1N3FX ","B1N3FY ", & - "B1N3M ","B1N3MM ","B1N3PHI ","B1N3RE ","B1N3STVX ","B1N3STVY ","B1N3STVZ ", & - "B1N3THETA","B1N3TNIND","B1N3VDISX","B1N3VDISY","B1N3VDISZ","B1N3VINDX","B1N3VINDY", & - "B1N3VREL ","B1N3VUNDX","B1N3VUNDY","B1N3VUNDZ","B1N4ALPHA","B1N4AXIND","B1N4CD ", & - "B1N4CL ","B1N4CLRNC","B1N4CM ","B1N4CN ","B1N4CT ","B1N4CURVE","B1N4CX ", & - "B1N4CY ","B1N4DYNP ","B1N4FD ","B1N4FL ","B1N4FN ","B1N4FT ","B1N4FX ", & - "B1N4FY ","B1N4M ","B1N4MM ","B1N4PHI ","B1N4RE ","B1N4STVX ","B1N4STVY ", & - "B1N4STVZ ","B1N4THETA","B1N4TNIND","B1N4VDISX","B1N4VDISY","B1N4VDISZ","B1N4VINDX", & - "B1N4VINDY","B1N4VREL ","B1N4VUNDX","B1N4VUNDY","B1N4VUNDZ","B1N5ALPHA","B1N5AXIND", & - "B1N5CD ","B1N5CL ","B1N5CLRNC","B1N5CM ","B1N5CN ","B1N5CT ","B1N5CURVE", & - "B1N5CX ","B1N5CY ","B1N5DYNP ","B1N5FD ","B1N5FL ","B1N5FN ","B1N5FT ", & - "B1N5FX ","B1N5FY ","B1N5M ","B1N5MM ","B1N5PHI ","B1N5RE ","B1N5STVX ", & - "B1N5STVY ","B1N5STVZ ","B1N5THETA","B1N5TNIND","B1N5VDISX","B1N5VDISY","B1N5VDISZ", & - "B1N5VINDX","B1N5VINDY","B1N5VREL ","B1N5VUNDX","B1N5VUNDY","B1N5VUNDZ","B1N6ALPHA", & - "B1N6AXIND","B1N6CD ","B1N6CL ","B1N6CLRNC","B1N6CM ","B1N6CN ","B1N6CT ", & - "B1N6CURVE","B1N6CX ","B1N6CY ","B1N6DYNP ","B1N6FD ","B1N6FL ","B1N6FN ", & - "B1N6FT ","B1N6FX ","B1N6FY ","B1N6M ","B1N6MM ","B1N6PHI ","B1N6RE ", & - "B1N6STVX ","B1N6STVY ","B1N6STVZ ","B1N6THETA","B1N6TNIND","B1N6VDISX","B1N6VDISY", & - "B1N6VDISZ","B1N6VINDX","B1N6VINDY","B1N6VREL ","B1N6VUNDX","B1N6VUNDY","B1N6VUNDZ", & - "B1N7ALPHA","B1N7AXIND","B1N7CD ","B1N7CL ","B1N7CLRNC","B1N7CM ","B1N7CN ", & - "B1N7CT ","B1N7CURVE","B1N7CX ","B1N7CY ","B1N7DYNP ","B1N7FD ","B1N7FL ", & - "B1N7FN ","B1N7FT ","B1N7FX ","B1N7FY ","B1N7M ","B1N7MM ","B1N7PHI ", & - "B1N7RE ","B1N7STVX ","B1N7STVY ","B1N7STVZ ","B1N7THETA","B1N7TNIND","B1N7VDISX", & + "B1N3M ","B1N3MM ","B1N3PHI ","B1N3RE ","B1N3SGCAV","B1N3SIGCR","B1N3STVX ", & + "B1N3STVY ","B1N3STVZ ","B1N3THETA","B1N3TNIND","B1N3VDISX","B1N3VDISY","B1N3VDISZ", & + "B1N3VINDX","B1N3VINDY","B1N3VREL ","B1N3VUNDX","B1N3VUNDY","B1N3VUNDZ","B1N4ALPHA", & + "B1N4AXIND","B1N4CD ","B1N4CL ","B1N4CLRNC","B1N4CM ","B1N4CN ","B1N4CPMIN", & + "B1N4CT ","B1N4CURVE","B1N4CX ","B1N4CY ","B1N4DYNP ","B1N4FD ","B1N4FL ", & + "B1N4FN ","B1N4FT ","B1N4FX ","B1N4FY ","B1N4M ","B1N4MM ","B1N4PHI ", & + "B1N4RE ","B1N4SGCAV","B1N4SIGCR","B1N4STVX ","B1N4STVY ","B1N4STVZ ","B1N4THETA", & + "B1N4TNIND","B1N4VDISX","B1N4VDISY","B1N4VDISZ","B1N4VINDX","B1N4VINDY","B1N4VREL ", & + "B1N4VUNDX","B1N4VUNDY","B1N4VUNDZ","B1N5ALPHA","B1N5AXIND","B1N5CD ","B1N5CL ", & + "B1N5CLRNC","B1N5CM ","B1N5CN ","B1N5CPMIN","B1N5CT ","B1N5CURVE","B1N5CX ", & + "B1N5CY ","B1N5DYNP ","B1N5FD ","B1N5FL ","B1N5FN ","B1N5FT ","B1N5FX ", & + "B1N5FY ","B1N5M ","B1N5MM ","B1N5PHI ","B1N5RE ","B1N5SGCAV","B1N5SIGCR", & + "B1N5STVX ","B1N5STVY ","B1N5STVZ ","B1N5THETA","B1N5TNIND","B1N5VDISX","B1N5VDISY", & + "B1N5VDISZ","B1N5VINDX","B1N5VINDY","B1N5VREL ","B1N5VUNDX","B1N5VUNDY","B1N5VUNDZ", & + "B1N6ALPHA","B1N6AXIND","B1N6CD ","B1N6CL ","B1N6CLRNC","B1N6CM ","B1N6CN ", & + "B1N6CPMIN","B1N6CT ","B1N6CURVE","B1N6CX ","B1N6CY ","B1N6DYNP ","B1N6FD ", & + "B1N6FL ","B1N6FN ","B1N6FT ","B1N6FX ","B1N6FY ","B1N6M ","B1N6MM ", & + "B1N6PHI ","B1N6RE ","B1N6SGCAV","B1N6SIGCR","B1N6STVX ","B1N6STVY ","B1N6STVZ ", & + "B1N6THETA","B1N6TNIND","B1N6VDISX","B1N6VDISY","B1N6VDISZ","B1N6VINDX","B1N6VINDY", & + "B1N6VREL ","B1N6VUNDX","B1N6VUNDY","B1N6VUNDZ","B1N7ALPHA","B1N7AXIND","B1N7CD ", & + "B1N7CL ","B1N7CLRNC","B1N7CM ","B1N7CN ","B1N7CPMIN","B1N7CT ","B1N7CURVE", & + "B1N7CX ","B1N7CY ","B1N7DYNP ","B1N7FD ","B1N7FL ","B1N7FN ","B1N7FT ", & + "B1N7FX ","B1N7FY ","B1N7M ","B1N7MM ","B1N7PHI ","B1N7RE ","B1N7SGCAV", & + "B1N7SIGCR","B1N7STVX ","B1N7STVY ","B1N7STVZ ","B1N7THETA","B1N7TNIND","B1N7VDISX", & "B1N7VDISY","B1N7VDISZ","B1N7VINDX","B1N7VINDY","B1N7VREL ","B1N7VUNDX","B1N7VUNDY", & "B1N7VUNDZ","B1N8ALPHA","B1N8AXIND","B1N8CD ","B1N8CL ","B1N8CLRNC","B1N8CM ", & - "B1N8CN ","B1N8CT ","B1N8CURVE","B1N8CX ","B1N8CY ","B1N8DYNP ","B1N8FD ", & - "B1N8FL ","B1N8FN ","B1N8FT ","B1N8FX ","B1N8FY ","B1N8M ","B1N8MM ", & - "B1N8PHI ","B1N8RE ","B1N8STVX ","B1N8STVY ","B1N8STVZ ","B1N8THETA","B1N8TNIND", & - "B1N8VDISX","B1N8VDISY","B1N8VDISZ","B1N8VINDX","B1N8VINDY","B1N8VREL ","B1N8VUNDX", & - "B1N8VUNDY","B1N8VUNDZ","B1N9ALPHA","B1N9AXIND","B1N9CD ","B1N9CL ","B1N9CLRNC", & - "B1N9CM ","B1N9CN ","B1N9CT ","B1N9CURVE","B1N9CX ","B1N9CY ","B1N9DYNP ", & - "B1N9FD ","B1N9FL ","B1N9FN ","B1N9FT ","B1N9FX ","B1N9FY ","B1N9M ", & - "B1N9MM ","B1N9PHI ","B1N9RE ","B1N9STVX ","B1N9STVY ","B1N9STVZ ","B1N9THETA", & - "B1N9TNIND","B1N9VDISX","B1N9VDISY","B1N9VDISZ","B1N9VINDX","B1N9VINDY","B1N9VREL ", & - "B1N9VUNDX","B1N9VUNDY","B1N9VUNDZ","B1PITCH ","B2AZIMUTH","B2N1ALPHA","B2N1AXIND", & - "B2N1CD ","B2N1CL ","B2N1CLRNC","B2N1CM ","B2N1CN ","B2N1CT ","B2N1CURVE", & + "B1N8CN ","B1N8CPMIN","B1N8CT ","B1N8CURVE","B1N8CX ","B1N8CY ","B1N8DYNP ", & + "B1N8FD ","B1N8FL ","B1N8FN ","B1N8FT ","B1N8FX ","B1N8FY ","B1N8M ", & + "B1N8MM ","B1N8PHI ","B1N8RE ","B1N8SGCAV","B1N8SIGCR","B1N8STVX ","B1N8STVY ", & + "B1N8STVZ ","B1N8THETA","B1N8TNIND","B1N8VDISX","B1N8VDISY","B1N8VDISZ","B1N8VINDX", & + "B1N8VINDY","B1N8VREL ","B1N8VUNDX","B1N8VUNDY","B1N8VUNDZ","B1N9ALPHA","B1N9AXIND", & + "B1N9CD ","B1N9CL ","B1N9CLRNC","B1N9CM ","B1N9CN ","B1N9CPMIN","B1N9CT ", & + "B1N9CURVE","B1N9CX ","B1N9CY ","B1N9DYNP ","B1N9FD ","B1N9FL ","B1N9FN ", & + "B1N9FT ","B1N9FX ","B1N9FY ","B1N9M ","B1N9MM ","B1N9PHI ","B1N9RE ", & + "B1N9SGCAV","B1N9SIGCR","B1N9STVX ","B1N9STVY ","B1N9STVZ ","B1N9THETA","B1N9TNIND", & + "B1N9VDISX","B1N9VDISY","B1N9VDISZ","B1N9VINDX","B1N9VINDY","B1N9VREL ","B1N9VUNDX", & + "B1N9VUNDY","B1N9VUNDZ","B1PITCH ","B2AZIMUTH","B2N1ALPHA","B2N1AXIND","B2N1CD ", & + "B2N1CL ","B2N1CLRNC","B2N1CM ","B2N1CN ","B2N1CPMIN","B2N1CT ","B2N1CURVE", & "B2N1CX ","B2N1CY ","B2N1DYNP ","B2N1FD ","B2N1FL ","B2N1FN ","B2N1FT ", & - "B2N1FX ","B2N1FY ","B2N1M ","B2N1MM ","B2N1PHI ","B2N1RE ","B2N1STVX ", & - "B2N1STVY ","B2N1STVZ ","B2N1THETA","B2N1TNIND","B2N1VDISX","B2N1VDISY","B2N1VDISZ", & - "B2N1VINDX","B2N1VINDY","B2N1VREL ","B2N1VUNDX","B2N1VUNDY","B2N1VUNDZ","B2N2ALPHA", & - "B2N2AXIND","B2N2CD ","B2N2CL ","B2N2CLRNC","B2N2CM ","B2N2CN ","B2N2CT ", & - "B2N2CURVE","B2N2CX ","B2N2CY ","B2N2DYNP ","B2N2FD ","B2N2FL ","B2N2FN ", & - "B2N2FT ","B2N2FX ","B2N2FY ","B2N2M ","B2N2MM ","B2N2PHI ","B2N2RE ", & - "B2N2STVX ","B2N2STVY ","B2N2STVZ ","B2N2THETA","B2N2TNIND","B2N2VDISX","B2N2VDISY", & - "B2N2VDISZ","B2N2VINDX","B2N2VINDY","B2N2VREL ","B2N2VUNDX","B2N2VUNDY","B2N2VUNDZ", & - "B2N3ALPHA","B2N3AXIND","B2N3CD ","B2N3CL ","B2N3CLRNC","B2N3CM ","B2N3CN ", & - "B2N3CT ","B2N3CURVE","B2N3CX ","B2N3CY ","B2N3DYNP ","B2N3FD ","B2N3FL ", & - "B2N3FN ","B2N3FT ","B2N3FX ","B2N3FY ","B2N3M ","B2N3MM ","B2N3PHI ", & - "B2N3RE ","B2N3STVX ","B2N3STVY ","B2N3STVZ ","B2N3THETA","B2N3TNIND","B2N3VDISX", & - "B2N3VDISY","B2N3VDISZ","B2N3VINDX","B2N3VINDY","B2N3VREL ","B2N3VUNDX","B2N3VUNDY", & - "B2N3VUNDZ","B2N4ALPHA","B2N4AXIND","B2N4CD ","B2N4CL ","B2N4CLRNC","B2N4CM ", & - "B2N4CN ","B2N4CT ","B2N4CURVE","B2N4CX ","B2N4CY ","B2N4DYNP ","B2N4FD ", & - "B2N4FL ","B2N4FN ","B2N4FT ","B2N4FX ","B2N4FY ","B2N4M ","B2N4MM ", & - "B2N4PHI ","B2N4RE ","B2N4STVX ","B2N4STVY ","B2N4STVZ ","B2N4THETA","B2N4TNIND", & - "B2N4VDISX","B2N4VDISY","B2N4VDISZ","B2N4VINDX","B2N4VINDY","B2N4VREL ","B2N4VUNDX", & - "B2N4VUNDY","B2N4VUNDZ","B2N5ALPHA","B2N5AXIND","B2N5CD ","B2N5CL ","B2N5CLRNC", & - "B2N5CM ","B2N5CN ","B2N5CT ","B2N5CURVE","B2N5CX ","B2N5CY ","B2N5DYNP ", & - "B2N5FD ","B2N5FL ","B2N5FN ","B2N5FT ","B2N5FX ","B2N5FY ","B2N5M ", & - "B2N5MM ","B2N5PHI ","B2N5RE ","B2N5STVX ","B2N5STVY ","B2N5STVZ ","B2N5THETA", & + "B2N1FX ","B2N1FY ","B2N1M ","B2N1MM ","B2N1PHI ","B2N1RE ","B2N1SGCAV", & + "B2N1SIGCR","B2N1STVX ","B2N1STVY ","B2N1STVZ ","B2N1THETA","B2N1TNIND","B2N1VDISX", & + "B2N1VDISY","B2N1VDISZ","B2N1VINDX","B2N1VINDY","B2N1VREL ","B2N1VUNDX","B2N1VUNDY", & + "B2N1VUNDZ","B2N2ALPHA","B2N2AXIND","B2N2CD ","B2N2CL ","B2N2CLRNC","B2N2CM ", & + "B2N2CN ","B2N2CPMIN","B2N2CT ","B2N2CURVE","B2N2CX ","B2N2CY ","B2N2DYNP ", & + "B2N2FD ","B2N2FL ","B2N2FN ","B2N2FT ","B2N2FX ","B2N2FY ","B2N2M ", & + "B2N2MM ","B2N2PHI ","B2N2RE ","B2N2SGCAV","B2N2SIGCR","B2N2STVX ","B2N2STVY ", & + "B2N2STVZ ","B2N2THETA","B2N2TNIND","B2N2VDISX","B2N2VDISY","B2N2VDISZ","B2N2VINDX", & + "B2N2VINDY","B2N2VREL ","B2N2VUNDX","B2N2VUNDY","B2N2VUNDZ","B2N3ALPHA","B2N3AXIND", & + "B2N3CD ","B2N3CL ","B2N3CLRNC","B2N3CM ","B2N3CN ","B2N3CPMIN","B2N3CT ", & + "B2N3CURVE","B2N3CX ","B2N3CY ","B2N3DYNP ","B2N3FD ","B2N3FL ","B2N3FN ", & + "B2N3FT ","B2N3FX ","B2N3FY ","B2N3M ","B2N3MM ","B2N3PHI ","B2N3RE ", & + "B2N3SGCAV","B2N3SIGCR","B2N3STVX ","B2N3STVY ","B2N3STVZ ","B2N3THETA","B2N3TNIND", & + "B2N3VDISX","B2N3VDISY","B2N3VDISZ","B2N3VINDX","B2N3VINDY","B2N3VREL ","B2N3VUNDX", & + "B2N3VUNDY","B2N3VUNDZ","B2N4ALPHA","B2N4AXIND","B2N4CD ","B2N4CL ","B2N4CLRNC", & + "B2N4CM ","B2N4CN ","B2N4CPMIN","B2N4CT ","B2N4CURVE","B2N4CX ","B2N4CY ", & + "B2N4DYNP ","B2N4FD ","B2N4FL ","B2N4FN ","B2N4FT ","B2N4FX ","B2N4FY ", & + "B2N4M ","B2N4MM ","B2N4PHI ","B2N4RE ","B2N4SGCAV","B2N4SIGCR","B2N4STVX ", & + "B2N4STVY ","B2N4STVZ ","B2N4THETA","B2N4TNIND","B2N4VDISX","B2N4VDISY","B2N4VDISZ", & + "B2N4VINDX","B2N4VINDY","B2N4VREL ","B2N4VUNDX","B2N4VUNDY","B2N4VUNDZ","B2N5ALPHA", & + "B2N5AXIND","B2N5CD ","B2N5CL ","B2N5CLRNC","B2N5CM ","B2N5CN ","B2N5CPMIN", & + "B2N5CT ","B2N5CURVE","B2N5CX ","B2N5CY ","B2N5DYNP ","B2N5FD ","B2N5FL ", & + "B2N5FN ","B2N5FT ","B2N5FX ","B2N5FY ","B2N5M ","B2N5MM ","B2N5PHI ", & + "B2N5RE ","B2N5SGCAV","B2N5SIGCR","B2N5STVX ","B2N5STVY ","B2N5STVZ ","B2N5THETA", & "B2N5TNIND","B2N5VDISX","B2N5VDISY","B2N5VDISZ","B2N5VINDX","B2N5VINDY","B2N5VREL ", & "B2N5VUNDX","B2N5VUNDY","B2N5VUNDZ","B2N6ALPHA","B2N6AXIND","B2N6CD ","B2N6CL ", & - "B2N6CLRNC","B2N6CM ","B2N6CN ","B2N6CT ","B2N6CURVE","B2N6CX ","B2N6CY ", & - "B2N6DYNP ","B2N6FD ","B2N6FL ","B2N6FN ","B2N6FT ","B2N6FX ","B2N6FY ", & - "B2N6M ","B2N6MM ","B2N6PHI ","B2N6RE ","B2N6STVX ","B2N6STVY ","B2N6STVZ ", & - "B2N6THETA","B2N6TNIND","B2N6VDISX","B2N6VDISY","B2N6VDISZ","B2N6VINDX","B2N6VINDY", & - "B2N6VREL ","B2N6VUNDX","B2N6VUNDY","B2N6VUNDZ","B2N7ALPHA","B2N7AXIND","B2N7CD ", & - "B2N7CL ","B2N7CLRNC","B2N7CM ","B2N7CN ","B2N7CT ","B2N7CURVE","B2N7CX ", & - "B2N7CY ","B2N7DYNP ","B2N7FD ","B2N7FL ","B2N7FN ","B2N7FT ","B2N7FX ", & - "B2N7FY ","B2N7M ","B2N7MM ","B2N7PHI ","B2N7RE ","B2N7STVX ","B2N7STVY ", & - "B2N7STVZ ","B2N7THETA","B2N7TNIND","B2N7VDISX","B2N7VDISY","B2N7VDISZ","B2N7VINDX", & - "B2N7VINDY","B2N7VREL ","B2N7VUNDX","B2N7VUNDY","B2N7VUNDZ","B2N8ALPHA","B2N8AXIND", & - "B2N8CD ","B2N8CL ","B2N8CLRNC","B2N8CM ","B2N8CN ","B2N8CT ","B2N8CURVE", & + "B2N6CLRNC","B2N6CM ","B2N6CN ","B2N6CPMIN","B2N6CT ","B2N6CURVE","B2N6CX ", & + "B2N6CY ","B2N6DYNP ","B2N6FD ","B2N6FL ","B2N6FN ","B2N6FT ","B2N6FX ", & + "B2N6FY ","B2N6M ","B2N6MM ","B2N6PHI ","B2N6RE ","B2N6SGCAV","B2N6SIGCR", & + "B2N6STVX ","B2N6STVY ","B2N6STVZ ","B2N6THETA","B2N6TNIND","B2N6VDISX","B2N6VDISY", & + "B2N6VDISZ","B2N6VINDX","B2N6VINDY","B2N6VREL ","B2N6VUNDX","B2N6VUNDY","B2N6VUNDZ", & + "B2N7ALPHA","B2N7AXIND","B2N7CD ","B2N7CL ","B2N7CLRNC","B2N7CM ","B2N7CN ", & + "B2N7CPMIN","B2N7CT ","B2N7CURVE","B2N7CX ","B2N7CY ","B2N7DYNP ","B2N7FD ", & + "B2N7FL ","B2N7FN ","B2N7FT ","B2N7FX ","B2N7FY ","B2N7M ","B2N7MM ", & + "B2N7PHI ","B2N7RE ","B2N7SGCAV","B2N7SIGCR","B2N7STVX ","B2N7STVY ","B2N7STVZ ", & + "B2N7THETA","B2N7TNIND","B2N7VDISX","B2N7VDISY","B2N7VDISZ","B2N7VINDX","B2N7VINDY", & + "B2N7VREL ","B2N7VUNDX","B2N7VUNDY","B2N7VUNDZ","B2N8ALPHA","B2N8AXIND","B2N8CD ", & + "B2N8CL ","B2N8CLRNC","B2N8CM ","B2N8CN ","B2N8CPMIN","B2N8CT ","B2N8CURVE", & "B2N8CX ","B2N8CY ","B2N8DYNP ","B2N8FD ","B2N8FL ","B2N8FN ","B2N8FT ", & - "B2N8FX ","B2N8FY ","B2N8M ","B2N8MM ","B2N8PHI ","B2N8RE ","B2N8STVX ", & - "B2N8STVY ","B2N8STVZ ","B2N8THETA","B2N8TNIND","B2N8VDISX","B2N8VDISY","B2N8VDISZ", & - "B2N8VINDX","B2N8VINDY","B2N8VREL ","B2N8VUNDX","B2N8VUNDY","B2N8VUNDZ","B2N9ALPHA", & - "B2N9AXIND","B2N9CD ","B2N9CL ","B2N9CLRNC","B2N9CM ","B2N9CN ","B2N9CT ", & - "B2N9CURVE","B2N9CX ","B2N9CY ","B2N9DYNP ","B2N9FD ","B2N9FL ","B2N9FN ", & - "B2N9FT ","B2N9FX ","B2N9FY ","B2N9M ","B2N9MM ","B2N9PHI ","B2N9RE ", & - "B2N9STVX ","B2N9STVY ","B2N9STVZ ","B2N9THETA","B2N9TNIND","B2N9VDISX","B2N9VDISY", & - "B2N9VDISZ","B2N9VINDX","B2N9VINDY","B2N9VREL ","B2N9VUNDX","B2N9VUNDY","B2N9VUNDZ", & - "B2PITCH ","B3AZIMUTH","B3N1ALPHA","B3N1AXIND","B3N1CD ","B3N1CL ","B3N1CLRNC", & - "B3N1CM ","B3N1CN ","B3N1CT ","B3N1CURVE","B3N1CX ","B3N1CY ","B3N1DYNP ", & - "B3N1FD ","B3N1FL ","B3N1FN ","B3N1FT ","B3N1FX ","B3N1FY ","B3N1M ", & - "B3N1MM ","B3N1PHI ","B3N1RE ","B3N1STVX ","B3N1STVY ","B3N1STVZ ","B3N1THETA", & - "B3N1TNIND","B3N1VDISX","B3N1VDISY","B3N1VDISZ","B3N1VINDX","B3N1VINDY","B3N1VREL ", & - "B3N1VUNDX","B3N1VUNDY","B3N1VUNDZ","B3N2ALPHA","B3N2AXIND","B3N2CD ","B3N2CL ", & - "B3N2CLRNC","B3N2CM ","B3N2CN ","B3N2CT ","B3N2CURVE","B3N2CX ","B3N2CY ", & - "B3N2DYNP ","B3N2FD ","B3N2FL ","B3N2FN ","B3N2FT ","B3N2FX ","B3N2FY ", & - "B3N2M ","B3N2MM ","B3N2PHI ","B3N2RE ","B3N2STVX ","B3N2STVY ","B3N2STVZ ", & - "B3N2THETA","B3N2TNIND","B3N2VDISX","B3N2VDISY","B3N2VDISZ","B3N2VINDX","B3N2VINDY", & - "B3N2VREL ","B3N2VUNDX","B3N2VUNDY","B3N2VUNDZ","B3N3ALPHA","B3N3AXIND","B3N3CD ", & - "B3N3CL ","B3N3CLRNC","B3N3CM ","B3N3CN ","B3N3CT ","B3N3CURVE","B3N3CX ", & - "B3N3CY ","B3N3DYNP ","B3N3FD ","B3N3FL ","B3N3FN ","B3N3FT ","B3N3FX ", & - "B3N3FY ","B3N3M ","B3N3MM ","B3N3PHI ","B3N3RE ","B3N3STVX ","B3N3STVY ", & + "B2N8FX ","B2N8FY ","B2N8M ","B2N8MM ","B2N8PHI ","B2N8RE ","B2N8SGCAV", & + "B2N8SIGCR","B2N8STVX ","B2N8STVY ","B2N8STVZ ","B2N8THETA","B2N8TNIND","B2N8VDISX", & + "B2N8VDISY","B2N8VDISZ","B2N8VINDX","B2N8VINDY","B2N8VREL ","B2N8VUNDX","B2N8VUNDY", & + "B2N8VUNDZ","B2N9ALPHA","B2N9AXIND","B2N9CD ","B2N9CL ","B2N9CLRNC","B2N9CM ", & + "B2N9CN ","B2N9CPMIN","B2N9CT ","B2N9CURVE","B2N9CX ","B2N9CY ","B2N9DYNP ", & + "B2N9FD ","B2N9FL ","B2N9FN ","B2N9FT ","B2N9FX ","B2N9FY ","B2N9M ", & + "B2N9MM ","B2N9PHI ","B2N9RE ","B2N9SGCAV","B2N9SIGCR","B2N9STVX ","B2N9STVY ", & + "B2N9STVZ ","B2N9THETA","B2N9TNIND","B2N9VDISX","B2N9VDISY","B2N9VDISZ","B2N9VINDX", & + "B2N9VINDY","B2N9VREL ","B2N9VUNDX","B2N9VUNDY","B2N9VUNDZ","B2PITCH ","B3AZIMUTH", & + "B3N1ALPHA","B3N1AXIND","B3N1CD ","B3N1CL ","B3N1CLRNC","B3N1CM ","B3N1CN ", & + "B3N1CPMIN","B3N1CT ","B3N1CURVE","B3N1CX ","B3N1CY ","B3N1DYNP ","B3N1FD ", & + "B3N1FL ","B3N1FN ","B3N1FT ","B3N1FX ","B3N1FY ","B3N1M ","B3N1MM ", & + "B3N1PHI ","B3N1RE ","B3N1SGCAV","B3N1SIGCR","B3N1STVX ","B3N1STVY ","B3N1STVZ ", & + "B3N1THETA","B3N1TNIND","B3N1VDISX","B3N1VDISY","B3N1VDISZ","B3N1VINDX","B3N1VINDY", & + "B3N1VREL ","B3N1VUNDX","B3N1VUNDY","B3N1VUNDZ","B3N2ALPHA","B3N2AXIND","B3N2CD ", & + "B3N2CL ","B3N2CLRNC","B3N2CM ","B3N2CN ","B3N2CPMIN","B3N2CT ","B3N2CURVE", & + "B3N2CX ","B3N2CY ","B3N2DYNP ","B3N2FD ","B3N2FL ","B3N2FN ","B3N2FT ", & + "B3N2FX ","B3N2FY ","B3N2M ","B3N2MM ","B3N2PHI ","B3N2RE ","B3N2SGCAV", & + "B3N2SIGCR","B3N2STVX ","B3N2STVY ","B3N2STVZ ","B3N2THETA","B3N2TNIND","B3N2VDISX", & + "B3N2VDISY","B3N2VDISZ","B3N2VINDX","B3N2VINDY","B3N2VREL ","B3N2VUNDX","B3N2VUNDY", & + "B3N2VUNDZ","B3N3ALPHA","B3N3AXIND","B3N3CD ","B3N3CL ","B3N3CLRNC","B3N3CM ", & + "B3N3CN ","B3N3CPMIN","B3N3CT ","B3N3CURVE","B3N3CX ","B3N3CY ","B3N3DYNP ", & + "B3N3FD ","B3N3FL ","B3N3FN ","B3N3FT ","B3N3FX ","B3N3FY ","B3N3M ", & + "B3N3MM ","B3N3PHI ","B3N3RE ","B3N3SGCAV","B3N3SIGCR","B3N3STVX ","B3N3STVY ", & "B3N3STVZ ","B3N3THETA","B3N3TNIND","B3N3VDISX","B3N3VDISY","B3N3VDISZ","B3N3VINDX", & "B3N3VINDY","B3N3VREL ","B3N3VUNDX","B3N3VUNDY","B3N3VUNDZ","B3N4ALPHA","B3N4AXIND", & - "B3N4CD ","B3N4CL ","B3N4CLRNC","B3N4CM ","B3N4CN ","B3N4CT ","B3N4CURVE", & - "B3N4CX ","B3N4CY ","B3N4DYNP ","B3N4FD ","B3N4FL ","B3N4FN ","B3N4FT ", & - "B3N4FX ","B3N4FY ","B3N4M ","B3N4MM ","B3N4PHI ","B3N4RE ","B3N4STVX ", & - "B3N4STVY ","B3N4STVZ ","B3N4THETA","B3N4TNIND","B3N4VDISX","B3N4VDISY","B3N4VDISZ", & - "B3N4VINDX","B3N4VINDY","B3N4VREL ","B3N4VUNDX","B3N4VUNDY","B3N4VUNDZ","B3N5ALPHA", & - "B3N5AXIND","B3N5CD ","B3N5CL ","B3N5CLRNC","B3N5CM ","B3N5CN ","B3N5CT ", & - "B3N5CURVE","B3N5CX ","B3N5CY ","B3N5DYNP ","B3N5FD ","B3N5FL ","B3N5FN ", & - "B3N5FT ","B3N5FX ","B3N5FY ","B3N5M ","B3N5MM ","B3N5PHI ","B3N5RE ", & - "B3N5STVX ","B3N5STVY ","B3N5STVZ ","B3N5THETA","B3N5TNIND","B3N5VDISX","B3N5VDISY", & - "B3N5VDISZ","B3N5VINDX","B3N5VINDY","B3N5VREL ","B3N5VUNDX","B3N5VUNDY","B3N5VUNDZ", & - "B3N6ALPHA","B3N6AXIND","B3N6CD ","B3N6CL ","B3N6CLRNC","B3N6CM ","B3N6CN ", & + "B3N4CD ","B3N4CL ","B3N4CLRNC","B3N4CM ","B3N4CN ","B3N4CPMIN","B3N4CT ", & + "B3N4CURVE","B3N4CX ","B3N4CY ","B3N4DYNP ","B3N4FD ","B3N4FL ","B3N4FN ", & + "B3N4FT ","B3N4FX ","B3N4FY ","B3N4M ","B3N4MM ","B3N4PHI ","B3N4RE ", & + "B3N4SGCAV","B3N4SIGCR","B3N4STVX ","B3N4STVY ","B3N4STVZ ","B3N4THETA","B3N4TNIND", & + "B3N4VDISX","B3N4VDISY","B3N4VDISZ","B3N4VINDX","B3N4VINDY","B3N4VREL ","B3N4VUNDX", & + "B3N4VUNDY","B3N4VUNDZ","B3N5ALPHA","B3N5AXIND","B3N5CD ","B3N5CL ","B3N5CLRNC", & + "B3N5CM ","B3N5CN ","B3N5CPMIN","B3N5CT ","B3N5CURVE","B3N5CX ","B3N5CY ", & + "B3N5DYNP ","B3N5FD ","B3N5FL ","B3N5FN ","B3N5FT ","B3N5FX ","B3N5FY ", & + "B3N5M ","B3N5MM ","B3N5PHI ","B3N5RE ","B3N5SGCAV","B3N5SIGCR","B3N5STVX ", & + "B3N5STVY ","B3N5STVZ ","B3N5THETA","B3N5TNIND","B3N5VDISX","B3N5VDISY","B3N5VDISZ", & + "B3N5VINDX","B3N5VINDY","B3N5VREL ","B3N5VUNDX","B3N5VUNDY","B3N5VUNDZ","B3N6ALPHA", & + "B3N6AXIND","B3N6CD ","B3N6CL ","B3N6CLRNC","B3N6CM ","B3N6CN ","B3N6CPMIN", & "B3N6CT ","B3N6CURVE","B3N6CX ","B3N6CY ","B3N6DYNP ","B3N6FD ","B3N6FL ", & "B3N6FN ","B3N6FT ","B3N6FX ","B3N6FY ","B3N6M ","B3N6MM ","B3N6PHI ", & - "B3N6RE ","B3N6STVX ","B3N6STVY ","B3N6STVZ ","B3N6THETA","B3N6TNIND","B3N6VDISX", & - "B3N6VDISY","B3N6VDISZ","B3N6VINDX","B3N6VINDY","B3N6VREL ","B3N6VUNDX","B3N6VUNDY", & - "B3N6VUNDZ","B3N7ALPHA","B3N7AXIND","B3N7CD ","B3N7CL ","B3N7CLRNC","B3N7CM ", & - "B3N7CN ","B3N7CT ","B3N7CURVE","B3N7CX ","B3N7CY ","B3N7DYNP ","B3N7FD ", & - "B3N7FL ","B3N7FN ","B3N7FT ","B3N7FX ","B3N7FY ","B3N7M ","B3N7MM ", & - "B3N7PHI ","B3N7RE ","B3N7STVX ","B3N7STVY ","B3N7STVZ ","B3N7THETA","B3N7TNIND", & - "B3N7VDISX","B3N7VDISY","B3N7VDISZ","B3N7VINDX","B3N7VINDY","B3N7VREL ","B3N7VUNDX", & - "B3N7VUNDY","B3N7VUNDZ","B3N8ALPHA","B3N8AXIND","B3N8CD ","B3N8CL ","B3N8CLRNC", & - "B3N8CM ","B3N8CN ","B3N8CT ","B3N8CURVE","B3N8CX ","B3N8CY ","B3N8DYNP ", & - "B3N8FD ","B3N8FL ","B3N8FN ","B3N8FT ","B3N8FX ","B3N8FY ","B3N8M ", & - "B3N8MM ","B3N8PHI ","B3N8RE ","B3N8STVX ","B3N8STVY ","B3N8STVZ ","B3N8THETA", & - "B3N8TNIND","B3N8VDISX","B3N8VDISY","B3N8VDISZ","B3N8VINDX","B3N8VINDY","B3N8VREL ", & - "B3N8VUNDX","B3N8VUNDY","B3N8VUNDZ","B3N9ALPHA","B3N9AXIND","B3N9CD ","B3N9CL ", & - "B3N9CLRNC","B3N9CM ","B3N9CN ","B3N9CT ","B3N9CURVE","B3N9CX ","B3N9CY ", & - "B3N9DYNP ","B3N9FD ","B3N9FL ","B3N9FN ","B3N9FT ","B3N9FX ","B3N9FY ", & - "B3N9M ","B3N9MM ","B3N9PHI ","B3N9RE ","B3N9STVX ","B3N9STVY ","B3N9STVZ ", & - "B3N9THETA","B3N9TNIND","B3N9VDISX","B3N9VDISY","B3N9VDISZ","B3N9VINDX","B3N9VINDY", & - "B3N9VREL ","B3N9VUNDX","B3N9VUNDY","B3N9VUNDZ","B3PITCH ","RTAEROCP ","RTAEROCQ ", & - "RTAEROCT ","RTAEROFXH","RTAEROFYH","RTAEROFZH","RTAEROMXH","RTAEROMYH","RTAEROMZH", & - "RTAEROPWR","RTAREA ","RTSKEW ","RTSPEED ","RTTSR ","RTVAVGXH ","RTVAVGYH ", & - "RTVAVGZH ","TWN1DYNP ","TWN1FDX ","TWN1FDY ","TWN1M ","TWN1RE ","TWN1STVX ", & - "TWN1STVY ","TWN1STVZ ","TWN1VREL ","TWN1VUNDX","TWN1VUNDY","TWN1VUNDZ","TWN2DYNP ", & - "TWN2FDX ","TWN2FDY ","TWN2M ","TWN2RE ","TWN2STVX ","TWN2STVY ","TWN2STVZ ", & - "TWN2VREL ","TWN2VUNDX","TWN2VUNDY","TWN2VUNDZ","TWN3DYNP ","TWN3FDX ","TWN3FDY ", & - "TWN3M ","TWN3RE ","TWN3STVX ","TWN3STVY ","TWN3STVZ ","TWN3VREL ","TWN3VUNDX", & - "TWN3VUNDY","TWN3VUNDZ","TWN4DYNP ","TWN4FDX ","TWN4FDY ","TWN4M ","TWN4RE ", & - "TWN4STVX ","TWN4STVY ","TWN4STVZ ","TWN4VREL ","TWN4VUNDX","TWN4VUNDY","TWN4VUNDZ", & - "TWN5DYNP ","TWN5FDX ","TWN5FDY ","TWN5M ","TWN5RE ","TWN5STVX ","TWN5STVY ", & - "TWN5STVZ ","TWN5VREL ","TWN5VUNDX","TWN5VUNDY","TWN5VUNDZ","TWN6DYNP ","TWN6FDX ", & - "TWN6FDY ","TWN6M ","TWN6RE ","TWN6STVX ","TWN6STVY ","TWN6STVZ ","TWN6VREL ", & - "TWN6VUNDX","TWN6VUNDY","TWN6VUNDZ","TWN7DYNP ","TWN7FDX ","TWN7FDY ","TWN7M ", & - "TWN7RE ","TWN7STVX ","TWN7STVY ","TWN7STVZ ","TWN7VREL ","TWN7VUNDX","TWN7VUNDY", & - "TWN7VUNDZ","TWN8DYNP ","TWN8FDX ","TWN8FDY ","TWN8M ","TWN8RE ","TWN8STVX ", & - "TWN8STVY ","TWN8STVZ ","TWN8VREL ","TWN8VUNDX","TWN8VUNDY","TWN8VUNDZ","TWN9DYNP ", & - "TWN9FDX ","TWN9FDY ","TWN9M ","TWN9RE ","TWN9STVX ","TWN9STVY ","TWN9STVZ ", & - "TWN9VREL ","TWN9VUNDX","TWN9VUNDY","TWN9VUNDZ"/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(1103) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + "B3N6RE ","B3N6SGCAV","B3N6SIGCR","B3N6STVX ","B3N6STVY ","B3N6STVZ ","B3N6THETA", & + "B3N6TNIND","B3N6VDISX","B3N6VDISY","B3N6VDISZ","B3N6VINDX","B3N6VINDY","B3N6VREL ", & + "B3N6VUNDX","B3N6VUNDY","B3N6VUNDZ","B3N7ALPHA","B3N7AXIND","B3N7CD ","B3N7CL ", & + "B3N7CLRNC","B3N7CM ","B3N7CN ","B3N7CPMIN","B3N7CT ","B3N7CURVE","B3N7CX ", & + "B3N7CY ","B3N7DYNP ","B3N7FD ","B3N7FL ","B3N7FN ","B3N7FT ","B3N7FX ", & + "B3N7FY ","B3N7M ","B3N7MM ","B3N7PHI ","B3N7RE ","B3N7SGCAV","B3N7SIGCR", & + "B3N7STVX ","B3N7STVY ","B3N7STVZ ","B3N7THETA","B3N7TNIND","B3N7VDISX","B3N7VDISY", & + "B3N7VDISZ","B3N7VINDX","B3N7VINDY","B3N7VREL ","B3N7VUNDX","B3N7VUNDY","B3N7VUNDZ", & + "B3N8ALPHA","B3N8AXIND","B3N8CD ","B3N8CL ","B3N8CLRNC","B3N8CM ","B3N8CN ", & + "B3N8CPMIN","B3N8CT ","B3N8CURVE","B3N8CX ","B3N8CY ","B3N8DYNP ","B3N8FD ", & + "B3N8FL ","B3N8FN ","B3N8FT ","B3N8FX ","B3N8FY ","B3N8M ","B3N8MM ", & + "B3N8PHI ","B3N8RE ","B3N8SGCAV","B3N8SIGCR","B3N8STVX ","B3N8STVY ","B3N8STVZ ", & + "B3N8THETA","B3N8TNIND","B3N8VDISX","B3N8VDISY","B3N8VDISZ","B3N8VINDX","B3N8VINDY", & + "B3N8VREL ","B3N8VUNDX","B3N8VUNDY","B3N8VUNDZ","B3N9ALPHA","B3N9AXIND","B3N9CD ", & + "B3N9CL ","B3N9CLRNC","B3N9CM ","B3N9CN ","B3N9CPMIN","B3N9CT ","B3N9CURVE", & + "B3N9CX ","B3N9CY ","B3N9DYNP ","B3N9FD ","B3N9FL ","B3N9FN ","B3N9FT ", & + "B3N9FX ","B3N9FY ","B3N9M ","B3N9MM ","B3N9PHI ","B3N9RE ","B3N9SGCAV", & + "B3N9SIGCR","B3N9STVX ","B3N9STVY ","B3N9STVZ ","B3N9THETA","B3N9TNIND","B3N9VDISX", & + "B3N9VDISY","B3N9VDISZ","B3N9VINDX","B3N9VINDY","B3N9VREL ","B3N9VUNDX","B3N9VUNDY", & + "B3N9VUNDZ","B3PITCH ","RTAEROCP ","RTAEROCQ ","RTAEROCT ","RTAEROFXH","RTAEROFYH", & + "RTAEROFZH","RTAEROMXH","RTAEROMYH","RTAEROMZH","RTAEROPWR","RTAREA ","RTSKEW ", & + "RTSPEED ","RTTSR ","RTVAVGXH ","RTVAVGYH ","RTVAVGZH ","TWN1DYNP ","TWN1FDX ", & + "TWN1FDY ","TWN1M ","TWN1RE ","TWN1STVX ","TWN1STVY ","TWN1STVZ ","TWN1VREL ", & + "TWN1VUNDX","TWN1VUNDY","TWN1VUNDZ","TWN2DYNP ","TWN2FDX ","TWN2FDY ","TWN2M ", & + "TWN2RE ","TWN2STVX ","TWN2STVY ","TWN2STVZ ","TWN2VREL ","TWN2VUNDX","TWN2VUNDY", & + "TWN2VUNDZ","TWN3DYNP ","TWN3FDX ","TWN3FDY ","TWN3M ","TWN3RE ","TWN3STVX ", & + "TWN3STVY ","TWN3STVZ ","TWN3VREL ","TWN3VUNDX","TWN3VUNDY","TWN3VUNDZ","TWN4DYNP ", & + "TWN4FDX ","TWN4FDY ","TWN4M ","TWN4RE ","TWN4STVX ","TWN4STVY ","TWN4STVZ ", & + "TWN4VREL ","TWN4VUNDX","TWN4VUNDY","TWN4VUNDZ","TWN5DYNP ","TWN5FDX ","TWN5FDY ", & + "TWN5M ","TWN5RE ","TWN5STVX ","TWN5STVY ","TWN5STVZ ","TWN5VREL ","TWN5VUNDX", & + "TWN5VUNDY","TWN5VUNDZ","TWN6DYNP ","TWN6FDX ","TWN6FDY ","TWN6M ","TWN6RE ", & + "TWN6STVX ","TWN6STVY ","TWN6STVZ ","TWN6VREL ","TWN6VUNDX","TWN6VUNDY","TWN6VUNDZ", & + "TWN7DYNP ","TWN7FDX ","TWN7FDY ","TWN7M ","TWN7RE ","TWN7STVX ","TWN7STVY ", & + "TWN7STVZ ","TWN7VREL ","TWN7VUNDX","TWN7VUNDY","TWN7VUNDZ","TWN8DYNP ","TWN8FDX ", & + "TWN8FDY ","TWN8M ","TWN8RE ","TWN8STVX ","TWN8STVY ","TWN8STVZ ","TWN8VREL ", & + "TWN8VUNDX","TWN8VUNDY","TWN8VUNDZ","TWN9DYNP ","TWN9FDX ","TWN9FDY ","TWN9M ", & + "TWN9RE ","TWN9STVX ","TWN9STVY ","TWN9STVZ ","TWN9VREL ","TWN9VUNDX","TWN9VUNDY", & + "TWN9VUNDZ"/) + INTEGER(IntKi), PARAMETER :: ParamIndxAry(1184) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) B1Azimuth , B1N1Alpha , B1N1AxInd , B1N1Cd , B1N1Cl , B1N1Clrnc , B1N1Cm , & - B1N1Cn , B1N1Ct , B1N1Curve , B1N1Cx , B1N1Cy , B1N1DynP , B1N1Fd , & - B1N1Fl , B1N1Fn , B1N1Ft , B1N1Fx , B1N1Fy , B1N1M , B1N1Mm , & - B1N1Phi , B1N1Re , B1N1STVx , B1N1STVy , B1N1STVz , B1N1Theta , B1N1TnInd , & - B1N1VDisx , B1N1VDisy , B1N1VDisz , B1N1Vindx , B1N1Vindy , B1N1VRel , B1N1VUndx , & - B1N1VUndy , B1N1VUndz , B1N2Alpha , B1N2AxInd , B1N2Cd , B1N2Cl , B1N2Clrnc , & - B1N2Cm , B1N2Cn , B1N2Ct , B1N2Curve , B1N2Cx , B1N2Cy , B1N2DynP , & - B1N2Fd , B1N2Fl , B1N2Fn , B1N2Ft , B1N2Fx , B1N2Fy , B1N2M , & - B1N2Mm , B1N2Phi , B1N2Re , B1N2STVx , B1N2STVy , B1N2STVz , B1N2Theta , & - B1N2TnInd , B1N2VDisx , B1N2VDisy , B1N2VDisz , B1N2Vindx , B1N2Vindy , B1N2VRel , & - B1N2VUndx , B1N2VUndy , B1N2VUndz , B1N3Alpha , B1N3AxInd , B1N3Cd , B1N3Cl , & - B1N3Clrnc , B1N3Cm , B1N3Cn , B1N3Ct , B1N3Curve , B1N3Cx , B1N3Cy , & + B1N1Cn , B1N1Cpmin , B1N1Ct , B1N1Curve , B1N1Cx , B1N1Cy , B1N1DynP , & + B1N1Fd , B1N1Fl , B1N1Fn , B1N1Ft , B1N1Fx , B1N1Fy , B1N1M , & + B1N1Mm , B1N1Phi , B1N1Re , B1N1SgCav , B1N1SigCr , B1N1STVx , B1N1STVy , & + B1N1STVz , B1N1Theta , B1N1TnInd , B1N1VDisx , B1N1VDisy , B1N1VDisz , B1N1Vindx , & + B1N1Vindy , B1N1VRel , B1N1VUndx , B1N1VUndy , B1N1VUndz , B1N2Alpha , B1N2AxInd , & + B1N2Cd , B1N2Cl , B1N2Clrnc , B1N2Cm , B1N2Cn , B1N2Cpmin , B1N2Ct , & + B1N2Curve , B1N2Cx , B1N2Cy , B1N2DynP , B1N2Fd , B1N2Fl , B1N2Fn , & + B1N2Ft , B1N2Fx , B1N2Fy , B1N2M , B1N2Mm , B1N2Phi , B1N2Re , & + B1N2SgCav , B1N2SigCr , B1N2STVx , B1N2STVy , B1N2STVz , B1N2Theta , B1N2TnInd , & + B1N2VDisx , B1N2VDisy , B1N2VDisz , B1N2Vindx , B1N2Vindy , B1N2VRel , B1N2VUndx , & + B1N2VUndy , B1N2VUndz , B1N3Alpha , B1N3AxInd , B1N3Cd , B1N3Cl , B1N3Clrnc , & + B1N3Cm , B1N3Cn , B1N3Cpmin , B1N3Ct , B1N3Curve , B1N3Cx , B1N3Cy , & B1N3DynP , B1N3Fd , B1N3Fl , B1N3Fn , B1N3Ft , B1N3Fx , B1N3Fy , & - B1N3M , B1N3Mm , B1N3Phi , B1N3Re , B1N3STVx , B1N3STVy , B1N3STVz , & - B1N3Theta , B1N3TnInd , B1N3VDisx , B1N3VDisy , B1N3VDisz , B1N3Vindx , B1N3Vindy , & - B1N3VRel , B1N3VUndx , B1N3VUndy , B1N3VUndz , B1N4Alpha , B1N4AxInd , B1N4Cd , & - B1N4Cl , B1N4Clrnc , B1N4Cm , B1N4Cn , B1N4Ct , B1N4Curve , B1N4Cx , & - B1N4Cy , B1N4DynP , B1N4Fd , B1N4Fl , B1N4Fn , B1N4Ft , B1N4Fx , & - B1N4Fy , B1N4M , B1N4Mm , B1N4Phi , B1N4Re , B1N4STVx , B1N4STVy , & - B1N4STVz , B1N4Theta , B1N4TnInd , B1N4VDisx , B1N4VDisy , B1N4VDisz , B1N4Vindx , & - B1N4Vindy , B1N4VRel , B1N4VUndx , B1N4VUndy , B1N4VUndz , B1N5Alpha , B1N5AxInd , & - B1N5Cd , B1N5Cl , B1N5Clrnc , B1N5Cm , B1N5Cn , B1N5Ct , B1N5Curve , & - B1N5Cx , B1N5Cy , B1N5DynP , B1N5Fd , B1N5Fl , B1N5Fn , B1N5Ft , & - B1N5Fx , B1N5Fy , B1N5M , B1N5Mm , B1N5Phi , B1N5Re , B1N5STVx , & - B1N5STVy , B1N5STVz , B1N5Theta , B1N5TnInd , B1N5VDisx , B1N5VDisy , B1N5VDisz , & - B1N5Vindx , B1N5Vindy , B1N5VRel , B1N5VUndx , B1N5VUndy , B1N5VUndz , B1N6Alpha , & - B1N6AxInd , B1N6Cd , B1N6Cl , B1N6Clrnc , B1N6Cm , B1N6Cn , B1N6Ct , & - B1N6Curve , B1N6Cx , B1N6Cy , B1N6DynP , B1N6Fd , B1N6Fl , B1N6Fn , & - B1N6Ft , B1N6Fx , B1N6Fy , B1N6M , B1N6Mm , B1N6Phi , B1N6Re , & - B1N6STVx , B1N6STVy , B1N6STVz , B1N6Theta , B1N6TnInd , B1N6VDisx , B1N6VDisy , & - B1N6VDisz , B1N6Vindx , B1N6Vindy , B1N6VRel , B1N6VUndx , B1N6VUndy , B1N6VUndz , & - B1N7Alpha , B1N7AxInd , B1N7Cd , B1N7Cl , B1N7Clrnc , B1N7Cm , B1N7Cn , & - B1N7Ct , B1N7Curve , B1N7Cx , B1N7Cy , B1N7DynP , B1N7Fd , B1N7Fl , & - B1N7Fn , B1N7Ft , B1N7Fx , B1N7Fy , B1N7M , B1N7Mm , B1N7Phi , & - B1N7Re , B1N7STVx , B1N7STVy , B1N7STVz , B1N7Theta , B1N7TnInd , B1N7VDisx , & + B1N3M , B1N3Mm , B1N3Phi , B1N3Re , B1N3SgCav , B1N3SigCr , B1N3STVx , & + B1N3STVy , B1N3STVz , B1N3Theta , B1N3TnInd , B1N3VDisx , B1N3VDisy , B1N3VDisz , & + B1N3Vindx , B1N3Vindy , B1N3VRel , B1N3VUndx , B1N3VUndy , B1N3VUndz , B1N4Alpha , & + B1N4AxInd , B1N4Cd , B1N4Cl , B1N4Clrnc , B1N4Cm , B1N4Cn , B1N4Cpmin , & + B1N4Ct , B1N4Curve , B1N4Cx , B1N4Cy , B1N4DynP , B1N4Fd , B1N4Fl , & + B1N4Fn , B1N4Ft , B1N4Fx , B1N4Fy , B1N4M , B1N4Mm , B1N4Phi , & + B1N4Re , B1N4SgCav , B1N4SigCr , B1N4STVx , B1N4STVy , B1N4STVz , B1N4Theta , & + B1N4TnInd , B1N4VDisx , B1N4VDisy , B1N4VDisz , B1N4Vindx , B1N4Vindy , B1N4VRel , & + B1N4VUndx , B1N4VUndy , B1N4VUndz , B1N5Alpha , B1N5AxInd , B1N5Cd , B1N5Cl , & + B1N5Clrnc , B1N5Cm , B1N5Cn , B1N5Cpmin , B1N5Ct , B1N5Curve , B1N5Cx , & + B1N5Cy , B1N5DynP , B1N5Fd , B1N5Fl , B1N5Fn , B1N5Ft , B1N5Fx , & + B1N5Fy , B1N5M , B1N5Mm , B1N5Phi , B1N5Re , B1N5SgCav , B1N5SigCr , & + B1N5STVx , B1N5STVy , B1N5STVz , B1N5Theta , B1N5TnInd , B1N5VDisx , B1N5VDisy , & + B1N5VDisz , B1N5Vindx , B1N5Vindy , B1N5VRel , B1N5VUndx , B1N5VUndy , B1N5VUndz , & + B1N6Alpha , B1N6AxInd , B1N6Cd , B1N6Cl , B1N6Clrnc , B1N6Cm , B1N6Cn , & + B1N6Cpmin , B1N6Ct , B1N6Curve , B1N6Cx , B1N6Cy , B1N6DynP , B1N6Fd , & + B1N6Fl , B1N6Fn , B1N6Ft , B1N6Fx , B1N6Fy , B1N6M , B1N6Mm , & + B1N6Phi , B1N6Re , B1N6SgCav , B1N6SigCr , B1N6STVx , B1N6STVy , B1N6STVz , & + B1N6Theta , B1N6TnInd , B1N6VDisx , B1N6VDisy , B1N6VDisz , B1N6Vindx , B1N6Vindy , & + B1N6VRel , B1N6VUndx , B1N6VUndy , B1N6VUndz , B1N7Alpha , B1N7AxInd , B1N7Cd , & + B1N7Cl , B1N7Clrnc , B1N7Cm , B1N7Cn , B1N7Cpmin , B1N7Ct , B1N7Curve , & + B1N7Cx , B1N7Cy , B1N7DynP , B1N7Fd , B1N7Fl , B1N7Fn , B1N7Ft , & + B1N7Fx , B1N7Fy , B1N7M , B1N7Mm , B1N7Phi , B1N7Re , B1N7SgCav , & + B1N7SigCr , B1N7STVx , B1N7STVy , B1N7STVz , B1N7Theta , B1N7TnInd , B1N7VDisx , & B1N7VDisy , B1N7VDisz , B1N7Vindx , B1N7Vindy , B1N7VRel , B1N7VUndx , B1N7VUndy , & B1N7VUndz , B1N8Alpha , B1N8AxInd , B1N8Cd , B1N8Cl , B1N8Clrnc , B1N8Cm , & - B1N8Cn , B1N8Ct , B1N8Curve , B1N8Cx , B1N8Cy , B1N8DynP , B1N8Fd , & - B1N8Fl , B1N8Fn , B1N8Ft , B1N8Fx , B1N8Fy , B1N8M , B1N8Mm , & - B1N8Phi , B1N8Re , B1N8STVx , B1N8STVy , B1N8STVz , B1N8Theta , B1N8TnInd , & - B1N8VDisx , B1N8VDisy , B1N8VDisz , B1N8Vindx , B1N8Vindy , B1N8VRel , B1N8VUndx , & - B1N8VUndy , B1N8VUndz , B1N9Alpha , B1N9AxInd , B1N9Cd , B1N9Cl , B1N9Clrnc , & - B1N9Cm , B1N9Cn , B1N9Ct , B1N9Curve , B1N9Cx , B1N9Cy , B1N9DynP , & - B1N9Fd , B1N9Fl , B1N9Fn , B1N9Ft , B1N9Fx , B1N9Fy , B1N9M , & - B1N9Mm , B1N9Phi , B1N9Re , B1N9STVx , B1N9STVy , B1N9STVz , B1N9Theta , & - B1N9TnInd , B1N9VDisx , B1N9VDisy , B1N9VDisz , B1N9Vindx , B1N9Vindy , B1N9VRel , & - B1N9VUndx , B1N9VUndy , B1N9VUndz , B1Pitch , B2Azimuth , B2N1Alpha , B2N1AxInd , & - B2N1Cd , B2N1Cl , B2N1Clrnc , B2N1Cm , B2N1Cn , B2N1Ct , B2N1Curve , & + B1N8Cn , B1N8Cpmin , B1N8Ct , B1N8Curve , B1N8Cx , B1N8Cy , B1N8DynP , & + B1N8Fd , B1N8Fl , B1N8Fn , B1N8Ft , B1N8Fx , B1N8Fy , B1N8M , & + B1N8Mm , B1N8Phi , B1N8Re , B1N8SgCav , B1N8SigCr , B1N8STVx , B1N8STVy , & + B1N8STVz , B1N8Theta , B1N8TnInd , B1N8VDisx , B1N8VDisy , B1N8VDisz , B1N8Vindx , & + B1N8Vindy , B1N8VRel , B1N8VUndx , B1N8VUndy , B1N8VUndz , B1N9Alpha , B1N9AxInd , & + B1N9Cd , B1N9Cl , B1N9Clrnc , B1N9Cm , B1N9Cn , B1N9Cpmin , B1N9Ct , & + B1N9Curve , B1N9Cx , B1N9Cy , B1N9DynP , B1N9Fd , B1N9Fl , B1N9Fn , & + B1N9Ft , B1N9Fx , B1N9Fy , B1N9M , B1N9Mm , B1N9Phi , B1N9Re , & + B1N9SgCav , B1N9SigCr , B1N9STVx , B1N9STVy , B1N9STVz , B1N9Theta , B1N9TnInd , & + B1N9VDisx , B1N9VDisy , B1N9VDisz , B1N9Vindx , B1N9Vindy , B1N9VRel , B1N9VUndx , & + B1N9VUndy , B1N9VUndz , B1Pitch , B2Azimuth , B2N1Alpha , B2N1AxInd , B2N1Cd , & + B2N1Cl , B2N1Clrnc , B2N1Cm , B2N1Cn , B2N1Cpmin , B2N1Ct , B2N1Curve , & B2N1Cx , B2N1Cy , B2N1DynP , B2N1Fd , B2N1Fl , B2N1Fn , B2N1Ft , & - B2N1Fx , B2N1Fy , B2N1M , B2N1Mm , B2N1Phi , B2N1Re , B2N1STVx , & - B2N1STVy , B2N1STVz , B2N1Theta , B2N1TnInd , B2N1VDisx , B2N1VDisy , B2N1VDisz , & - B2N1Vindx , B2N1Vindy , B2N1VRel , B2N1VUndx , B2N1VUndy , B2N1VUndz , B2N2Alpha , & - B2N2AxInd , B2N2Cd , B2N2Cl , B2N2Clrnc , B2N2Cm , B2N2Cn , B2N2Ct , & - B2N2Curve , B2N2Cx , B2N2Cy , B2N2DynP , B2N2Fd , B2N2Fl , B2N2Fn , & - B2N2Ft , B2N2Fx , B2N2Fy , B2N2M , B2N2Mm , B2N2Phi , B2N2Re , & - B2N2STVx , B2N2STVy , B2N2STVz , B2N2Theta , B2N2TnInd , B2N2VDisx , B2N2VDisy , & - B2N2VDisz , B2N2Vindx , B2N2Vindy , B2N2VRel , B2N2VUndx , B2N2VUndy , B2N2VUndz , & - B2N3Alpha , B2N3AxInd , B2N3Cd , B2N3Cl , B2N3Clrnc , B2N3Cm , B2N3Cn , & - B2N3Ct , B2N3Curve , B2N3Cx , B2N3Cy , B2N3DynP , B2N3Fd , B2N3Fl , & - B2N3Fn , B2N3Ft , B2N3Fx , B2N3Fy , B2N3M , B2N3Mm , B2N3Phi , & - B2N3Re , B2N3STVx , B2N3STVy , B2N3STVz , B2N3Theta , B2N3TnInd , B2N3VDisx , & - B2N3VDisy , B2N3VDisz , B2N3Vindx , B2N3Vindy , B2N3VRel , B2N3VUndx , B2N3VUndy , & - B2N3VUndz , B2N4Alpha , B2N4AxInd , B2N4Cd , B2N4Cl , B2N4Clrnc , B2N4Cm , & - B2N4Cn , B2N4Ct , B2N4Curve , B2N4Cx , B2N4Cy , B2N4DynP , B2N4Fd , & - B2N4Fl , B2N4Fn , B2N4Ft , B2N4Fx , B2N4Fy , B2N4M , B2N4Mm , & - B2N4Phi , B2N4Re , B2N4STVx , B2N4STVy , B2N4STVz , B2N4Theta , B2N4TnInd , & - B2N4VDisx , B2N4VDisy , B2N4VDisz , B2N4Vindx , B2N4Vindy , B2N4VRel , B2N4VUndx , & - B2N4VUndy , B2N4VUndz , B2N5Alpha , B2N5AxInd , B2N5Cd , B2N5Cl , B2N5Clrnc , & - B2N5Cm , B2N5Cn , B2N5Ct , B2N5Curve , B2N5Cx , B2N5Cy , B2N5DynP , & - B2N5Fd , B2N5Fl , B2N5Fn , B2N5Ft , B2N5Fx , B2N5Fy , B2N5M , & - B2N5Mm , B2N5Phi , B2N5Re , B2N5STVx , B2N5STVy , B2N5STVz , B2N5Theta , & + B2N1Fx , B2N1Fy , B2N1M , B2N1Mm , B2N1Phi , B2N1Re , B2N1SgCav , & + B2N1SigCr , B2N1STVx , B2N1STVy , B2N1STVz , B2N1Theta , B2N1TnInd , B2N1VDisx , & + B2N1VDisy , B2N1VDisz , B2N1Vindx , B2N1Vindy , B2N1VRel , B2N1VUndx , B2N1VUndy , & + B2N1VUndz , B2N2Alpha , B2N2AxInd , B2N2Cd , B2N2Cl , B2N2Clrnc , B2N2Cm , & + B2N2Cn , B2N2Cpmin , B2N2Ct , B2N2Curve , B2N2Cx , B2N2Cy , B2N2DynP , & + B2N2Fd , B2N2Fl , B2N2Fn , B2N2Ft , B2N2Fx , B2N2Fy , B2N2M , & + B2N2Mm , B2N2Phi , B2N2Re , B2N2SgCav , B2N2SigCr , B2N2STVx , B2N2STVy , & + B2N2STVz , B2N2Theta , B2N2TnInd , B2N2VDisx , B2N2VDisy , B2N2VDisz , B2N2Vindx , & + B2N2Vindy , B2N2VRel , B2N2VUndx , B2N2VUndy , B2N2VUndz , B2N3Alpha , B2N3AxInd , & + B2N3Cd , B2N3Cl , B2N3Clrnc , B2N3Cm , B2N3Cn , B2N3Cpmin , B2N3Ct , & + B2N3Curve , B2N3Cx , B2N3Cy , B2N3DynP , B2N3Fd , B2N3Fl , B2N3Fn , & + B2N3Ft , B2N3Fx , B2N3Fy , B2N3M , B2N3Mm , B2N3Phi , B2N3Re , & + B2N3SgCav , B2N3SigCr , B2N3STVx , B2N3STVy , B2N3STVz , B2N3Theta , B2N3TnInd , & + B2N3VDisx , B2N3VDisy , B2N3VDisz , B2N3Vindx , B2N3Vindy , B2N3VRel , B2N3VUndx , & + B2N3VUndy , B2N3VUndz , B2N4Alpha , B2N4AxInd , B2N4Cd , B2N4Cl , B2N4Clrnc , & + B2N4Cm , B2N4Cn , B2N4Cpmin , B2N4Ct , B2N4Curve , B2N4Cx , B2N4Cy , & + B2N4DynP , B2N4Fd , B2N4Fl , B2N4Fn , B2N4Ft , B2N4Fx , B2N4Fy , & + B2N4M , B2N4Mm , B2N4Phi , B2N4Re , B2N4SgCav , B2N4SigCr , B2N4STVx , & + B2N4STVy , B2N4STVz , B2N4Theta , B2N4TnInd , B2N4VDisx , B2N4VDisy , B2N4VDisz , & + B2N4Vindx , B2N4Vindy , B2N4VRel , B2N4VUndx , B2N4VUndy , B2N4VUndz , B2N5Alpha , & + B2N5AxInd , B2N5Cd , B2N5Cl , B2N5Clrnc , B2N5Cm , B2N5Cn , B2N5Cpmin , & + B2N5Ct , B2N5Curve , B2N5Cx , B2N5Cy , B2N5DynP , B2N5Fd , B2N5Fl , & + B2N5Fn , B2N5Ft , B2N5Fx , B2N5Fy , B2N5M , B2N5Mm , B2N5Phi , & + B2N5Re , B2N5SgCav , B2N5SigCr , B2N5STVx , B2N5STVy , B2N5STVz , B2N5Theta , & B2N5TnInd , B2N5VDisx , B2N5VDisy , B2N5VDisz , B2N5Vindx , B2N5Vindy , B2N5VRel , & B2N5VUndx , B2N5VUndy , B2N5VUndz , B2N6Alpha , B2N6AxInd , B2N6Cd , B2N6Cl , & - B2N6Clrnc , B2N6Cm , B2N6Cn , B2N6Ct , B2N6Curve , B2N6Cx , B2N6Cy , & - B2N6DynP , B2N6Fd , B2N6Fl , B2N6Fn , B2N6Ft , B2N6Fx , B2N6Fy , & - B2N6M , B2N6Mm , B2N6Phi , B2N6Re , B2N6STVx , B2N6STVy , B2N6STVz , & - B2N6Theta , B2N6TnInd , B2N6VDisx , B2N6VDisy , B2N6VDisz , B2N6Vindx , B2N6Vindy , & - B2N6VRel , B2N6VUndx , B2N6VUndy , B2N6VUndz , B2N7Alpha , B2N7AxInd , B2N7Cd , & - B2N7Cl , B2N7Clrnc , B2N7Cm , B2N7Cn , B2N7Ct , B2N7Curve , B2N7Cx , & - B2N7Cy , B2N7DynP , B2N7Fd , B2N7Fl , B2N7Fn , B2N7Ft , B2N7Fx , & - B2N7Fy , B2N7M , B2N7Mm , B2N7Phi , B2N7Re , B2N7STVx , B2N7STVy , & - B2N7STVz , B2N7Theta , B2N7TnInd , B2N7VDisx , B2N7VDisy , B2N7VDisz , B2N7Vindx , & - B2N7Vindy , B2N7VRel , B2N7VUndx , B2N7VUndy , B2N7VUndz , B2N8Alpha , B2N8AxInd , & - B2N8Cd , B2N8Cl , B2N8Clrnc , B2N8Cm , B2N8Cn , B2N8Ct , B2N8Curve , & + B2N6Clrnc , B2N6Cm , B2N6Cn , B2N6Cpmin , B2N6Ct , B2N6Curve , B2N6Cx , & + B2N6Cy , B2N6DynP , B2N6Fd , B2N6Fl , B2N6Fn , B2N6Ft , B2N6Fx , & + B2N6Fy , B2N6M , B2N6Mm , B2N6Phi , B2N6Re , B2N6SgCav , B2N6SigCr , & + B2N6STVx , B2N6STVy , B2N6STVz , B2N6Theta , B2N6TnInd , B2N6VDisx , B2N6VDisy , & + B2N6VDisz , B2N6Vindx , B2N6Vindy , B2N6VRel , B2N6VUndx , B2N6VUndy , B2N6VUndz , & + B2N7Alpha , B2N7AxInd , B2N7Cd , B2N7Cl , B2N7Clrnc , B2N7Cm , B2N7Cn , & + B2N7Cpmin , B2N7Ct , B2N7Curve , B2N7Cx , B2N7Cy , B2N7DynP , B2N7Fd , & + B2N7Fl , B2N7Fn , B2N7Ft , B2N7Fx , B2N7Fy , B2N7M , B2N7Mm , & + B2N7Phi , B2N7Re , B2N7SgCav , B2N7SigCr , B2N7STVx , B2N7STVy , B2N7STVz , & + B2N7Theta , B2N7TnInd , B2N7VDisx , B2N7VDisy , B2N7VDisz , B2N7Vindx , B2N7Vindy , & + B2N7VRel , B2N7VUndx , B2N7VUndy , B2N7VUndz , B2N8Alpha , B2N8AxInd , B2N8Cd , & + B2N8Cl , B2N8Clrnc , B2N8Cm , B2N8Cn , B2N8Cpmin , B2N8Ct , B2N8Curve , & B2N8Cx , B2N8Cy , B2N8DynP , B2N8Fd , B2N8Fl , B2N8Fn , B2N8Ft , & - B2N8Fx , B2N8Fy , B2N8M , B2N8Mm , B2N8Phi , B2N8Re , B2N8STVx , & - B2N8STVy , B2N8STVz , B2N8Theta , B2N8TnInd , B2N8VDisx , B2N8VDisy , B2N8VDisz , & - B2N8Vindx , B2N8Vindy , B2N8VRel , B2N8VUndx , B2N8VUndy , B2N8VUndz , B2N9Alpha , & - B2N9AxInd , B2N9Cd , B2N9Cl , B2N9Clrnc , B2N9Cm , B2N9Cn , B2N9Ct , & - B2N9Curve , B2N9Cx , B2N9Cy , B2N9DynP , B2N9Fd , B2N9Fl , B2N9Fn , & - B2N9Ft , B2N9Fx , B2N9Fy , B2N9M , B2N9Mm , B2N9Phi , B2N9Re , & - B2N9STVx , B2N9STVy , B2N9STVz , B2N9Theta , B2N9TnInd , B2N9VDisx , B2N9VDisy , & - B2N9VDisz , B2N9Vindx , B2N9Vindy , B2N9VRel , B2N9VUndx , B2N9VUndy , B2N9VUndz , & - B2Pitch , B3Azimuth , B3N1Alpha , B3N1AxInd , B3N1Cd , B3N1Cl , B3N1Clrnc , & - B3N1Cm , B3N1Cn , B3N1Ct , B3N1Curve , B3N1Cx , B3N1Cy , B3N1DynP , & - B3N1Fd , B3N1Fl , B3N1Fn , B3N1Ft , B3N1Fx , B3N1Fy , B3N1M , & - B3N1Mm , B3N1Phi , B3N1Re , B3N1STVx , B3N1STVy , B3N1STVz , B3N1Theta , & - B3N1TnInd , B3N1VDisx , B3N1VDisy , B3N1VDisz , B3N1Vindx , B3N1Vindy , B3N1VRel , & - B3N1VUndx , B3N1VUndy , B3N1VUndz , B3N2Alpha , B3N2AxInd , B3N2Cd , B3N2Cl , & - B3N2Clrnc , B3N2Cm , B3N2Cn , B3N2Ct , B3N2Curve , B3N2Cx , B3N2Cy , & - B3N2DynP , B3N2Fd , B3N2Fl , B3N2Fn , B3N2Ft , B3N2Fx , B3N2Fy , & - B3N2M , B3N2Mm , B3N2Phi , B3N2Re , B3N2STVx , B3N2STVy , B3N2STVz , & - B3N2Theta , B3N2TnInd , B3N2VDisx , B3N2VDisy , B3N2VDisz , B3N2Vindx , B3N2Vindy , & - B3N2VRel , B3N2VUndx , B3N2VUndy , B3N2VUndz , B3N3Alpha , B3N3AxInd , B3N3Cd , & - B3N3Cl , B3N3Clrnc , B3N3Cm , B3N3Cn , B3N3Ct , B3N3Curve , B3N3Cx , & - B3N3Cy , B3N3DynP , B3N3Fd , B3N3Fl , B3N3Fn , B3N3Ft , B3N3Fx , & - B3N3Fy , B3N3M , B3N3Mm , B3N3Phi , B3N3Re , B3N3STVx , B3N3STVy , & + B2N8Fx , B2N8Fy , B2N8M , B2N8Mm , B2N8Phi , B2N8Re , B2N8SgCav , & + B2N8SigCr , B2N8STVx , B2N8STVy , B2N8STVz , B2N8Theta , B2N8TnInd , B2N8VDisx , & + B2N8VDisy , B2N8VDisz , B2N8Vindx , B2N8Vindy , B2N8VRel , B2N8VUndx , B2N8VUndy , & + B2N8VUndz , B2N9Alpha , B2N9AxInd , B2N9Cd , B2N9Cl , B2N9Clrnc , B2N9Cm , & + B2N9Cn , B2N9Cpmin , B2N9Ct , B2N9Curve , B2N9Cx , B2N9Cy , B2N9DynP , & + B2N9Fd , B2N9Fl , B2N9Fn , B2N9Ft , B2N9Fx , B2N9Fy , B2N9M , & + B2N9Mm , B2N9Phi , B2N9Re , B2N9SgCav , B2N9SigCr , B2N9STVx , B2N9STVy , & + B2N9STVz , B2N9Theta , B2N9TnInd , B2N9VDisx , B2N9VDisy , B2N9VDisz , B2N9Vindx , & + B2N9Vindy , B2N9VRel , B2N9VUndx , B2N9VUndy , B2N9VUndz , B2Pitch , B3Azimuth , & + B3N1Alpha , B3N1AxInd , B3N1Cd , B3N1Cl , B3N1Clrnc , B3N1Cm , B3N1Cn , & + B3N1Cpmin , B3N1Ct , B3N1Curve , B3N1Cx , B3N1Cy , B3N1DynP , B3N1Fd , & + B3N1Fl , B3N1Fn , B3N1Ft , B3N1Fx , B3N1Fy , B3N1M , B3N1Mm , & + B3N1Phi , B3N1Re , B3N1SgCav , B3N1SigCr , B3N1STVx , B3N1STVy , B3N1STVz , & + B3N1Theta , B3N1TnInd , B3N1VDisx , B3N1VDisy , B3N1VDisz , B3N1Vindx , B3N1Vindy , & + B3N1VRel , B3N1VUndx , B3N1VUndy , B3N1VUndz , B3N2Alpha , B3N2AxInd , B3N2Cd , & + B3N2Cl , B3N2Clrnc , B3N2Cm , B3N2Cn , B3N2Cpmin , B3N2Ct , B3N2Curve , & + B3N2Cx , B3N2Cy , B3N2DynP , B3N2Fd , B3N2Fl , B3N2Fn , B3N2Ft , & + B3N2Fx , B3N2Fy , B3N2M , B3N2Mm , B3N2Phi , B3N2Re , B3N2SgCav , & + B3N2SigCr , B3N2STVx , B3N2STVy , B3N2STVz , B3N2Theta , B3N2TnInd , B3N2VDisx , & + B3N2VDisy , B3N2VDisz , B3N2Vindx , B3N2Vindy , B3N2VRel , B3N2VUndx , B3N2VUndy , & + B3N2VUndz , B3N3Alpha , B3N3AxInd , B3N3Cd , B3N3Cl , B3N3Clrnc , B3N3Cm , & + B3N3Cn , B3N3Cpmin , B3N3Ct , B3N3Curve , B3N3Cx , B3N3Cy , B3N3DynP , & + B3N3Fd , B3N3Fl , B3N3Fn , B3N3Ft , B3N3Fx , B3N3Fy , B3N3M , & + B3N3Mm , B3N3Phi , B3N3Re , B3N3SgCav , B3N3SigCr , B3N3STVx , B3N3STVy , & B3N3STVz , B3N3Theta , B3N3TnInd , B3N3VDisx , B3N3VDisy , B3N3VDisz , B3N3Vindx , & B3N3Vindy , B3N3VRel , B3N3VUndx , B3N3VUndy , B3N3VUndz , B3N4Alpha , B3N4AxInd , & - B3N4Cd , B3N4Cl , B3N4Clrnc , B3N4Cm , B3N4Cn , B3N4Ct , B3N4Curve , & - B3N4Cx , B3N4Cy , B3N4DynP , B3N4Fd , B3N4Fl , B3N4Fn , B3N4Ft , & - B3N4Fx , B3N4Fy , B3N4M , B3N4Mm , B3N4Phi , B3N4Re , B3N4STVx , & - B3N4STVy , B3N4STVz , B3N4Theta , B3N4TnInd , B3N4VDisx , B3N4VDisy , B3N4VDisz , & - B3N4Vindx , B3N4Vindy , B3N4VRel , B3N4VUndx , B3N4VUndy , B3N4VUndz , B3N5Alpha , & - B3N5AxInd , B3N5Cd , B3N5Cl , B3N5Clrnc , B3N5Cm , B3N5Cn , B3N5Ct , & - B3N5Curve , B3N5Cx , B3N5Cy , B3N5DynP , B3N5Fd , B3N5Fl , B3N5Fn , & - B3N5Ft , B3N5Fx , B3N5Fy , B3N5M , B3N5Mm , B3N5Phi , B3N5Re , & - B3N5STVx , B3N5STVy , B3N5STVz , B3N5Theta , B3N5TnInd , B3N5VDisx , B3N5VDisy , & - B3N5VDisz , B3N5Vindx , B3N5Vindy , B3N5VRel , B3N5VUndx , B3N5VUndy , B3N5VUndz , & - B3N6Alpha , B3N6AxInd , B3N6Cd , B3N6Cl , B3N6Clrnc , B3N6Cm , B3N6Cn , & + B3N4Cd , B3N4Cl , B3N4Clrnc , B3N4Cm , B3N4Cn , B3N4Cpmin , B3N4Ct , & + B3N4Curve , B3N4Cx , B3N4Cy , B3N4DynP , B3N4Fd , B3N4Fl , B3N4Fn , & + B3N4Ft , B3N4Fx , B3N4Fy , B3N4M , B3N4Mm , B3N4Phi , B3N4Re , & + B3N4SgCav , B3N4SigCr , B3N4STVx , B3N4STVy , B3N4STVz , B3N4Theta , B3N4TnInd , & + B3N4VDisx , B3N4VDisy , B3N4VDisz , B3N4Vindx , B3N4Vindy , B3N4VRel , B3N4VUndx , & + B3N4VUndy , B3N4VUndz , B3N5Alpha , B3N5AxInd , B3N5Cd , B3N5Cl , B3N5Clrnc , & + B3N5Cm , B3N5Cn , B3N5Cpmin , B3N5Ct , B3N5Curve , B3N5Cx , B3N5Cy , & + B3N5DynP , B3N5Fd , B3N5Fl , B3N5Fn , B3N5Ft , B3N5Fx , B3N5Fy , & + B3N5M , B3N5Mm , B3N5Phi , B3N5Re , B3N5SgCav , B3N5SigCr , B3N5STVx , & + B3N5STVy , B3N5STVz , B3N5Theta , B3N5TnInd , B3N5VDisx , B3N5VDisy , B3N5VDisz , & + B3N5Vindx , B3N5Vindy , B3N5VRel , B3N5VUndx , B3N5VUndy , B3N5VUndz , B3N6Alpha , & + B3N6AxInd , B3N6Cd , B3N6Cl , B3N6Clrnc , B3N6Cm , B3N6Cn , B3N6Cpmin , & B3N6Ct , B3N6Curve , B3N6Cx , B3N6Cy , B3N6DynP , B3N6Fd , B3N6Fl , & B3N6Fn , B3N6Ft , B3N6Fx , B3N6Fy , B3N6M , B3N6Mm , B3N6Phi , & - B3N6Re , B3N6STVx , B3N6STVy , B3N6STVz , B3N6Theta , B3N6TnInd , B3N6VDisx , & - B3N6VDisy , B3N6VDisz , B3N6Vindx , B3N6Vindy , B3N6VRel , B3N6VUndx , B3N6VUndy , & - B3N6VUndz , B3N7Alpha , B3N7AxInd , B3N7Cd , B3N7Cl , B3N7Clrnc , B3N7Cm , & - B3N7Cn , B3N7Ct , B3N7Curve , B3N7Cx , B3N7Cy , B3N7DynP , B3N7Fd , & - B3N7Fl , B3N7Fn , B3N7Ft , B3N7Fx , B3N7Fy , B3N7M , B3N7Mm , & - B3N7Phi , B3N7Re , B3N7STVx , B3N7STVy , B3N7STVz , B3N7Theta , B3N7TnInd , & - B3N7VDisx , B3N7VDisy , B3N7VDisz , B3N7Vindx , B3N7Vindy , B3N7VRel , B3N7VUndx , & - B3N7VUndy , B3N7VUndz , B3N8Alpha , B3N8AxInd , B3N8Cd , B3N8Cl , B3N8Clrnc , & - B3N8Cm , B3N8Cn , B3N8Ct , B3N8Curve , B3N8Cx , B3N8Cy , B3N8DynP , & - B3N8Fd , B3N8Fl , B3N8Fn , B3N8Ft , B3N8Fx , B3N8Fy , B3N8M , & - B3N8Mm , B3N8Phi , B3N8Re , B3N8STVx , B3N8STVy , B3N8STVz , B3N8Theta , & - B3N8TnInd , B3N8VDisx , B3N8VDisy , B3N8VDisz , B3N8Vindx , B3N8Vindy , B3N8VRel , & - B3N8VUndx , B3N8VUndy , B3N8VUndz , B3N9Alpha , B3N9AxInd , B3N9Cd , B3N9Cl , & - B3N9Clrnc , B3N9Cm , B3N9Cn , B3N9Ct , B3N9Curve , B3N9Cx , B3N9Cy , & - B3N9DynP , B3N9Fd , B3N9Fl , B3N9Fn , B3N9Ft , B3N9Fx , B3N9Fy , & - B3N9M , B3N9Mm , B3N9Phi , B3N9Re , B3N9STVx , B3N9STVy , B3N9STVz , & - B3N9Theta , B3N9TnInd , B3N9VDisx , B3N9VDisy , B3N9VDisz , B3N9Vindx , B3N9Vindy , & - B3N9VRel , B3N9VUndx , B3N9VUndy , B3N9VUndz , B3Pitch , RtAeroCp , RtAeroCq , & - RtAeroCt , RtAeroFxh , RtAeroFyh , RtAeroFzh , RtAeroMxh , RtAeroMyh , RtAeroMzh , & - RtAeroPwr , RtArea , RtSkew , RtSpeed , RtTSR , RtVAvgxh , RtVAvgyh , & - RtVAvgzh , TwN1DynP , TwN1Fdx , TwN1Fdy , TwN1M , TwN1Re , TwN1STVx , & - TwN1STVy , TwN1STVz , TwN1Vrel , TwN1VUndx , TwN1VUndy , TwN1VUndz , TwN2DynP , & - TwN2Fdx , TwN2Fdy , TwN2M , TwN2Re , TwN2STVx , TwN2STVy , TwN2STVz , & - TwN2Vrel , TwN2VUndx , TwN2VUndy , TwN2VUndz , TwN3DynP , TwN3Fdx , TwN3Fdy , & - TwN3M , TwN3Re , TwN3STVx , TwN3STVy , TwN3STVz , TwN3Vrel , TwN3VUndx , & - TwN3VUndy , TwN3VUndz , TwN4DynP , TwN4Fdx , TwN4Fdy , TwN4M , TwN4Re , & - TwN4STVx , TwN4STVy , TwN4STVz , TwN4Vrel , TwN4VUndx , TwN4VUndy , TwN4VUndz , & - TwN5DynP , TwN5Fdx , TwN5Fdy , TwN5M , TwN5Re , TwN5STVx , TwN5STVy , & - TwN5STVz , TwN5Vrel , TwN5VUndx , TwN5VUndy , TwN5VUndz , TwN6DynP , TwN6Fdx , & - TwN6Fdy , TwN6M , TwN6Re , TwN6STVx , TwN6STVy , TwN6STVz , TwN6Vrel , & - TwN6VUndx , TwN6VUndy , TwN6VUndz , TwN7DynP , TwN7Fdx , TwN7Fdy , TwN7M , & - TwN7Re , TwN7STVx , TwN7STVy , TwN7STVz , TwN7Vrel , TwN7VUndx , TwN7VUndy , & - TwN7VUndz , TwN8DynP , TwN8Fdx , TwN8Fdy , TwN8M , TwN8Re , TwN8STVx , & - TwN8STVy , TwN8STVz , TwN8Vrel , TwN8VUndx , TwN8VUndy , TwN8VUndz , TwN9DynP , & - TwN9Fdx , TwN9Fdy , TwN9M , TwN9Re , TwN9STVx , TwN9STVy , TwN9STVz , & - TwN9Vrel , TwN9VUndx , TwN9VUndy , TwN9VUndz /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(1103) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + B3N6Re , B3N6SgCav , B3N6SigCr , B3N6STVx , B3N6STVy , B3N6STVz , B3N6Theta , & + B3N6TnInd , B3N6VDisx , B3N6VDisy , B3N6VDisz , B3N6Vindx , B3N6Vindy , B3N6VRel , & + B3N6VUndx , B3N6VUndy , B3N6VUndz , B3N7Alpha , B3N7AxInd , B3N7Cd , B3N7Cl , & + B3N7Clrnc , B3N7Cm , B3N7Cn , B3N7Cpmin , B3N7Ct , B3N7Curve , B3N7Cx , & + B3N7Cy , B3N7DynP , B3N7Fd , B3N7Fl , B3N7Fn , B3N7Ft , B3N7Fx , & + B3N7Fy , B3N7M , B3N7Mm , B3N7Phi , B3N7Re , B3N7SgCav , B3N7SigCr , & + B3N7STVx , B3N7STVy , B3N7STVz , B3N7Theta , B3N7TnInd , B3N7VDisx , B3N7VDisy , & + B3N7VDisz , B3N7Vindx , B3N7Vindy , B3N7VRel , B3N7VUndx , B3N7VUndy , B3N7VUndz , & + B3N8Alpha , B3N8AxInd , B3N8Cd , B3N8Cl , B3N8Clrnc , B3N8Cm , B3N8Cn , & + B3N8Cpmin , B3N8Ct , B3N8Curve , B3N8Cx , B3N8Cy , B3N8DynP , B3N8Fd , & + B3N8Fl , B3N8Fn , B3N8Ft , B3N8Fx , B3N8Fy , B3N8M , B3N8Mm , & + B3N8Phi , B3N8Re , B3N8SgCav , B3N8SigCr , B3N8STVx , B3N8STVy , B3N8STVz , & + B3N8Theta , B3N8TnInd , B3N8VDisx , B3N8VDisy , B3N8VDisz , B3N8Vindx , B3N8Vindy , & + B3N8VRel , B3N8VUndx , B3N8VUndy , B3N8VUndz , B3N9Alpha , B3N9AxInd , B3N9Cd , & + B3N9Cl , B3N9Clrnc , B3N9Cm , B3N9Cn , B3N9Cpmin , B3N9Ct , B3N9Curve , & + B3N9Cx , B3N9Cy , B3N9DynP , B3N9Fd , B3N9Fl , B3N9Fn , B3N9Ft , & + B3N9Fx , B3N9Fy , B3N9M , B3N9Mm , B3N9Phi , B3N9Re , B3N9SgCav , & + B3N9SigCr , B3N9STVx , B3N9STVy , B3N9STVz , B3N9Theta , B3N9TnInd , B3N9VDisx , & + B3N9VDisy , B3N9VDisz , B3N9Vindx , B3N9Vindy , B3N9VRel , B3N9VUndx , B3N9VUndy , & + B3N9VUndz , B3Pitch , RtAeroCp , RtAeroCq , RtAeroCt , RtAeroFxh , RtAeroFyh , & + RtAeroFzh , RtAeroMxh , RtAeroMyh , RtAeroMzh , RtAeroPwr , RtArea , RtSkew , & + RtSpeed , RtTSR , RtVAvgxh , RtVAvgyh , RtVAvgzh , TwN1DynP , TwN1Fdx , & + TwN1Fdy , TwN1M , TwN1Re , TwN1STVx , TwN1STVy , TwN1STVz , TwN1Vrel , & + TwN1VUndx , TwN1VUndy , TwN1VUndz , TwN2DynP , TwN2Fdx , TwN2Fdy , TwN2M , & + TwN2Re , TwN2STVx , TwN2STVy , TwN2STVz , TwN2Vrel , TwN2VUndx , TwN2VUndy , & + TwN2VUndz , TwN3DynP , TwN3Fdx , TwN3Fdy , TwN3M , TwN3Re , TwN3STVx , & + TwN3STVy , TwN3STVz , TwN3Vrel , TwN3VUndx , TwN3VUndy , TwN3VUndz , TwN4DynP , & + TwN4Fdx , TwN4Fdy , TwN4M , TwN4Re , TwN4STVx , TwN4STVy , TwN4STVz , & + TwN4Vrel , TwN4VUndx , TwN4VUndy , TwN4VUndz , TwN5DynP , TwN5Fdx , TwN5Fdy , & + TwN5M , TwN5Re , TwN5STVx , TwN5STVy , TwN5STVz , TwN5Vrel , TwN5VUndx , & + TwN5VUndy , TwN5VUndz , TwN6DynP , TwN6Fdx , TwN6Fdy , TwN6M , TwN6Re , & + TwN6STVx , TwN6STVy , TwN6STVz , TwN6Vrel , TwN6VUndx , TwN6VUndy , TwN6VUndz , & + TwN7DynP , TwN7Fdx , TwN7Fdy , TwN7M , TwN7Re , TwN7STVx , TwN7STVy , & + TwN7STVz , TwN7Vrel , TwN7VUndx , TwN7VUndy , TwN7VUndz , TwN8DynP , TwN8Fdx , & + TwN8Fdy , TwN8M , TwN8Re , TwN8STVx , TwN8STVy , TwN8STVz , TwN8Vrel , & + TwN8VUndx , TwN8VUndy , TwN8VUndz , TwN9DynP , TwN9Fdx , TwN9Fdy , TwN9M , & + TwN9Re , TwN9STVx , TwN9STVy , TwN9STVz , TwN9Vrel , TwN9VUndx , TwN9VUndy , & + TwN9VUndz /) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(1184) = (/ & ! This lists the units corresponding to the allowed parameters "(deg) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & - "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & + "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & + "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(deg) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & - "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & + "(m/s) ","(m/s) ","(deg) ","(deg) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & - "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(deg) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & - "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ", & + "(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & - "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & + "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & + "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ", & "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & - "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & + "(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & + "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(deg) ", & + "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & + "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & + "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & + "(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(N) ","(N) ","(N) ","(N·m) ","(N·m) ","(N·m) ", & - "(W) ","(m^2) ","(deg) ","(rpm) ","(-) ","(m/s) ","(m/s) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(N) ","(N) ", & + "(N) ","(N·m) ","(N·m) ","(N·m) ","(W) ","(m^2) ","(deg) ", & + "(rpm) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ", & + "(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ", & "(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & @@ -3087,10 +3265,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) "(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ", & "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ", & - "(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) "/) + "(m/s) "/) ! Initialize values @@ -3100,115 +3275,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) ! ..... Developer must add checking for invalid inputs here: ..... - !bjj: do we want to avoid outputting this if we haven't used tower aero? - - if ( p%TwrPotent == TwrPotent_none .and. .not. p%TwrShadow ) then - - ! BNClrnc is set only when we're computing the tower influence - do I = 1,MaxBl ! all blades (need to do this in a loop because we need the index of InvalidOutput to be an array of rank one) - InvalidOutput( BNClrnc(:,i) ) = .true. - end do - - end if - - - DO i = p%NTwOuts+1,9 ! Invalid tower nodes - - InvalidOutput( TwNVUnd(:,i) ) = .true. - InvalidOutput( TwNSTV( :,i) ) = .true. - InvalidOutput( TwNVRel( i) ) = .true. - InvalidOutput( TwNDynP( i) ) = .true. - InvalidOutput( TwNRe( i) ) = .true. - InvalidOutput( TwNM( i) ) = .true. - InvalidOutput( TwNFdx( i) ) = .true. - InvalidOutput( TwNFdy( i) ) = .true. - - END DO - - DO I = p%NumBlades+1,MaxBl ! Invalid blades - - InvalidOutput( BAzimuth( i) ) = .true. - InvalidOutput( BPitch( i) ) = .true. - InvalidOutput( BNVUndx(:,i) ) = .true. - InvalidOutput( BNVUndy(:,i) ) = .true. - InvalidOutput( BNVUndz(:,i) ) = .true. - InvalidOutput( BNVDisx(:,i) ) = .true. - InvalidOutput( BNVDisy(:,i) ) = .true. - InvalidOutput( BNVDisz(:,i) ) = .true. - InvalidOutput( BNSTVx( :,i) ) = .true. - InvalidOutput( BNSTVy( :,i) ) = .true. - InvalidOutput( BNSTVz( :,i) ) = .true. - InvalidOutput( BNVRel( :,i) ) = .true. - InvalidOutput( BNDynP( :,i) ) = .true. - InvalidOutput( BNRe( :,i) ) = .true. - InvalidOutput( BNM( :,i) ) = .true. - InvalidOutput( BNVIndx(:,i) ) = .true. - InvalidOutput( BNVIndy(:,i) ) = .true. - InvalidOutput( BNAxInd(:,i) ) = .true. - InvalidOutput( BNTnInd(:,i) ) = .true. - InvalidOutput( BNAlpha(:,i) ) = .true. - InvalidOutput( BNTheta(:,i) ) = .true. - InvalidOutput( BNPhi( :,i) ) = .true. - InvalidOutput( BNCurve(:,i) ) = .true. - InvalidOutput( BNCl( :,i) ) = .true. - InvalidOutput( BNCd( :,i) ) = .true. - InvalidOutput( BNCm( :,i) ) = .true. - InvalidOutput( BNCx( :,i) ) = .true. - InvalidOutput( BNCy( :,i) ) = .true. - InvalidOutput( BNCn( :,i) ) = .true. - InvalidOutput( BNCt( :,i) ) = .true. - InvalidOutput( BNFl( :,i) ) = .true. - InvalidOutput( BNFd( :,i) ) = .true. - InvalidOutput( BNMm( :,i) ) = .true. - InvalidOutput( BNFx( :,i) ) = .true. - InvalidOutput( BNFy( :,i) ) = .true. - InvalidOutput( BNFn( :,i) ) = .true. - InvalidOutput( BNFt( :,i) ) = .true. - InvalidOutput( BNClrnc(:,i) ) = .true. - - END DO - - DO I = p%NBlOuts+1,9 ! Invalid blade nodes - - InvalidOutput( BNVUndx(i,:) ) = .true. - InvalidOutput( BNVUndy(i,:) ) = .true. - InvalidOutput( BNVUndz(i,:) ) = .true. - InvalidOutput( BNVDisx(i,:) ) = .true. - InvalidOutput( BNVDisy(i,:) ) = .true. - InvalidOutput( BNVDisz(i,:) ) = .true. - InvalidOutput( BNSTVx( i,:) ) = .true. - InvalidOutput( BNSTVy( i,:) ) = .true. - InvalidOutput( BNSTVz( i,:) ) = .true. - InvalidOutput( BNVRel( i,:) ) = .true. - InvalidOutput( BNDynP( i,:) ) = .true. - InvalidOutput( BNRe( i,:) ) = .true. - InvalidOutput( BNM( i,:) ) = .true. - InvalidOutput( BNVIndx(i,:) ) = .true. - InvalidOutput( BNVIndy(i,:) ) = .true. - InvalidOutput( BNAxInd(i,:) ) = .true. - InvalidOutput( BNTnInd(i,:) ) = .true. - InvalidOutput( BNAlpha(i,:) ) = .true. - InvalidOutput( BNTheta(i,:) ) = .true. - InvalidOutput( BNPhi( i,:) ) = .true. - InvalidOutput( BNCurve(i,:) ) = .true. - InvalidOutput( BNCl( i,:) ) = .true. - InvalidOutput( BNCd( i,:) ) = .true. - InvalidOutput( BNCm( i,:) ) = .true. - InvalidOutput( BNCx( i,:) ) = .true. - InvalidOutput( BNCy( i,:) ) = .true. - InvalidOutput( BNCn( i,:) ) = .true. - InvalidOutput( BNCt( i,:) ) = .true. - InvalidOutput( BNFl( i,:) ) = .true. - InvalidOutput( BNFd( i,:) ) = .true. - InvalidOutput( BNMm( i,:) ) = .true. - InvalidOutput( BNFx( i,:) ) = .true. - InvalidOutput( BNFy( i,:) ) = .true. - InvalidOutput( BNFn( i,:) ) = .true. - InvalidOutput( BNFt( i,:) ) = .true. - InvalidOutput( BNClrnc(i,:) ) = .true. - - END DO - + ! ................. End of validity checking ................. From cb428f3713f0deb5e65747a2e22f1f6a11250b4c Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 09:42:01 -0700 Subject: [PATCH 03/58] Update AeroDyn_Registry.txt --- modules-local/aerodyn/src/AeroDyn_Registry.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules-local/aerodyn/src/AeroDyn_Registry.txt b/modules-local/aerodyn/src/AeroDyn_Registry.txt index f9373e98e..9b795c908 100644 --- a/modules-local/aerodyn/src/AeroDyn_Registry.txt +++ b/modules-local/aerodyn/src/AeroDyn_Registry.txt @@ -37,6 +37,7 @@ typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the output-to-file channels" - typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - typedef ^ InitOutputType ReKi AirDens - - - "Air density" kg/m^3 +typedef ^ InitOutputType ReKi FluidDens - - - "Fluid density" kg/m^3 typedef ^ InitOutputType AD_BladeShape BladeShape {:} - - "airfoil coordinates for each blade" m typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_z {:} - - "Names of the constraint states used in linearization" - @@ -65,8 +66,13 @@ typedef ^ AD_InputFile IntKi TwrPotent - - - "Type tower influence on wind based typedef ^ AD_InputFile LOGICAL TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow?" - typedef ^ AD_InputFile LOGICAL TwrAero - - - "Calculate tower aerodynamic loads?" flag typedef ^ AD_InputFile Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - +typedef ^ AD_InputFile Logical CavitCheck - - - "Flag that tells us if we want to check for cavitation" - typedef ^ AD_InputFile ReKi AirDens - - - "Air density" kg/m^3 +typedef ^ AD_InputFile ReKi FluidDens - - - "Fluid density" kg/m^3 typedef ^ AD_InputFile ReKi KinVisc - - - "Kinematic air viscosity" m^2/s +typedef ^ AD_InputFile ReKi Patm - - - "Atmospheric pressure" Pa +typedef ^ AD_InputFile ReKi Pvap - - - "Vapour pressure" Pa +typedef ^ AD_InputFile ReKi FluidDepth - - - "Submerged hub depth" m typedef ^ AD_InputFile ReKi SpdSound - - - "Speed of sound" m/s typedef ^ AD_InputFile IntKi SkewMod - - - "Type of skewed-wake correction model {1=uncoupled, 2=Pitt/Peters, 3=coupled} [used only when WakeMod=1]" - typedef ^ AD_InputFile LOGICAL TipLoss - - - "Use the Prandtl tip-loss model? [used only when WakeMod=1]" flag @@ -133,6 +139,7 @@ typedef ^ MiscVarType ReKi V_dot_x - - - typedef ^ MiscVarType MeshType HubLoad - - - "mesh at hub; used to compute an integral for mapping the output blade loads to a single point (for writing to file only)" - typedef ^ MiscVarType MeshMapType B_L_2_H_P {:} - - "mapping data structure to map each bladeLoad output mesh to the MiscVar%HubLoad mesh" + # ..... Parameters ................................................................................................................ # Define parameters here: # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: @@ -142,13 +149,18 @@ typedef ^ ParameterType IntKi TwrPotent - - - "Type tower influence on wind base typedef ^ ParameterType LOGICAL TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow?" - typedef ^ ParameterType LOGICAL TwrAero - - - "Calculate tower aerodynamic loads?" flag typedef ^ ParameterType Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - +typedef ^ ParameterType Logical CavitCheck - - - "Flag that tells us to check cavitation"- typedef ^ ParameterType IntKi NumBlades - - - "Number of blades on the turbine" - typedef ^ ParameterType IntKi NumBlNds - - - "Number of nodes on each blade" - typedef ^ ParameterType IntKi NumTwrNds - - - "Number of nodes on the tower" - typedef ^ ParameterType ReKi TwrDiam {:} - - "Diameter of tower at node" m typedef ^ ParameterType ReKi TwrCd {:} - - "Coefficient of drag at tower node" - typedef ^ ParameterType ReKi AirDens - - - "Air density" kg/m^3 +typedef ^ ParameterType ReKi FluidDens - - - "Fluid density" kg/m^3 typedef ^ ParameterType ReKi KinVisc - - - "Kinematic air viscosity" m^2/s +typedef ^ ParameterType ReKi Patm - - - "Atmospheric pressure" Pa +typedef ^ ParameterType ReKi Pvap - - - "Vapour pressure" Pa +typedef ^ ParameterType ReKi FluidDepth - - - "Depth of water to hub center" m typedef ^ ParameterType ReKi SpdSound - - - "Speed of sound" m/s typedef ^ ParameterType AFI_ParameterType AFI - - - "AirfoilInfo parameters" typedef ^ ParameterType BEMT_ParameterType BEMT - - - "Parameters for BEMT module" @@ -178,5 +190,7 @@ typedef ^ InputType ReKi InflowOnTower {:}{:} "U,V,W at nodes on the tower" m/ # Define outputs that are contained on the mesh here: typedef ^ OutputType MeshType TowerLoad - - - "loads on the tower" - typedef ^ OutputType MeshType BladeLoad {:} - - "loads on each blade" - +typedef ^ OutputType MeshType SigmaCavitCrit {:} - - "Critical cavitation number " - +typedef ^ OutputType MeshType SigmaCavit {:} - - " Cavitation number at node " - # Define outputs that are not on this mesh here: typedef ^ OutputType ReKi WriteOutput {:} - - "Data to be written to an output file: see WriteOutputHdr for names of each variable" "see WriteOutputUnt" From 7ebc735067314f9b84e572bc18088e31c69aac74 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 09:49:12 -0700 Subject: [PATCH 04/58] Update AirfoilInfo_Registry.txt --- modules-local/aerodyn/src/AirfoilInfo_Registry.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt index 62858637e..bd1dbede8 100644 --- a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt +++ b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt @@ -51,7 +51,7 @@ typedef ^ ^ ReKi x_cp_bar typedef ^ ^ ReKi UACutout - - - "" = typedef ^ ^ ReKi filtCutOff - - - "low pass filter cut-off frequency for the pitching rate and accelerations" Hz # The following derived type stores data for an airfoil at a single combination of Re and control setting. -typedef AirfoilInfo/AFI AFI_Table_Type ReKi Alpha {:} - - "Angle-of-attack vector that matches the Coefs matrix" rad +typedef AirfoilInfo/AFI AFI_Table_Type ReKi Alpha {:} - - "Angle-of-attack vector that matches the Coefs matrix" typedef ^ ^ ReKi Coefs {:}{:} - - "Airfoil coefficients for Cd, Cl, and maybe Cm and/or Cpmin" - typedef ^ ^ ReKi SplineCoefs {:}{:}{:} - - "Spline coefficients for Cd, Cl, and maybe Cm and/or Cpmin" - typedef ^ ^ ReKi BEMT_Spline {:}{:}{:}{:} - - "Spline coefficients for Cd, Cl for the two bounding Re when doing BEM" - @@ -94,6 +94,8 @@ typedef ^ ^ INTEGER NumCpminAoAkts - - - "The number of angle-of-attack knots fo typedef ^ ^ INTEGER NumCpminReKts - - - "The number of log(Re) knots for 2D splines of Cpmin" - typedef ^ ^ INTEGER NumTabs - - - "The number of airfoil tables in the airfoil file" - typedef ^ ^ AFI_Table_Type Table {:} - - "The tables of airfoil data for given Re and control setting" - +typedef ^ ^ INTEGER ColCpmin - - - "Column number for Cpmin" - +typedef ^ ^ INTEGER ColCm - - - "Column number for Cpmin" - # ..... Initialization data ....................................................................................................... # The following derived type stores information that comes from the calling module (say, AeroDyn): From 323cbe350ec656ad66a64ea80b5a4e1c81eb4cb6 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 10:05:58 -0700 Subject: [PATCH 05/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 45 ++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index caf0e3300..323f01381 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -208,7 +208,11 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) !p%DT = InitInp%DT p%airDens = InitInp%airDens - p%kinVisc = InitInp%kinVisc + p%kinVisc = InitInp%kinVisc + p%Patm = InitInp%Patm + p%Pvap = InitInp%Pvap + p%CavitCheck = InitInp%CavitCheck + p%FluidDepth = InitInp%FluidDepth p%skewWakeMod = InitInp%skewWakeMod p%useTipLoss = InitInp%useTipLoss p%useHubLoss = InitInp%useHubLoss @@ -219,6 +223,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numReIterations = InitInp%numReIterations p%maxIndIterations = InitInp%maxIndIterations p%aTol = InitInp%aTol + p%InCol_Cpmin = InitInp%InCol_Cpmin end subroutine BEMT_SetParameters @@ -465,6 +470,9 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) call allocAry( y%Cm, p%numBladeNodes, p%numBlades, 'y%Cm', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cl, p%numBladeNodes, p%numBlades, 'y%Cl', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cd, p%numBladeNodes, p%numBlades, 'y%Cd', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cpmin, p%numBladeNodes, p%numBlades, 'y%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%SigmaCavit, p%numBladeNodes, p%numBlades, 'y%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%SigmaCavitCrit, p%numBladeNodes, p%numBlades, 'y%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) RETURN @@ -726,6 +734,12 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte call WrScr( 'Warning: Turning off Unsteady Aerodynamics because C_nalpha is 0. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) end if + if ( p%CavitCheck ) then !Turn off unsteady aerodynamics if we are doing a cavitation check + OtherState%UA_Flag(i,j) = .false. + call WrScr( 'Warning: Turning off Unsteady Aerodynamics because doing cavitation check' ) + call WrScr( 'To run Unsteady Aerodynamics, set CavitCheck to FALSE in input file' ) + end if + end do end do @@ -1082,7 +1096,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat real(ReKi) :: Re, fzero - real(ReKi) :: Rtip ! maximum rlocal value for node j over all blades + real(ReKi) :: Rtip,SigmaCavitCrit, SigmaCavit ! maximum rlocal value for node j over all blades integer(IntKi) :: i ! Generic index integer(IntKi) :: j ! Loops through nodes / elements @@ -1238,8 +1252,33 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) if (errStat >= AbortErrLev) return + + + + if ( p%CavitCheck ) then ! This calculates the cavitation number for the airfoil at the node in quesiton, and compares to the critical cavitation number based on the vapour pressure and submerged depth + + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this + SigmaCavit= -1* y%Cpmin(i,j) ! Actual cavitation number on blade node j + + if (SigmaCavitCrit < SigmaCavit) then + call WrScr( NewLine//'FAILED CAVITATION CHECK'//' Node # = '//trim(num2lstr(i)//'Blade # = '//trim(num2lstr(j)))) + end if + + if (y%Vrel(i,j) == 0) then !if Vrel = 0 in certain cases when Prandtls tip and hub loss factors are used, use the relative verlocity without induction + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * (sqrt((Vx**2 + Vy**2)))**2) ! Critical value of Sigma, cavitation if we go over this + end if + + y%SigmaCavit(i,j)= SigmaCavit + y%SigmaCavitCrit(i,j)=SigmaCavitCrit + + end if + end if + + + + ! Compute Cx, Cy given Cl, Cd and phi ! NOTE: For these calculations we force the useAIDrag and useTIDrag flags to .TRUE. @@ -1932,4 +1971,4 @@ end subroutine BEMT_UnCoupledSolve end module BEMT - \ No newline at end of file + From ebb42cfb46e99e6ff2cce38faab2aee2dfb06ee7 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 10:34:20 -0700 Subject: [PATCH 06/58] Update BEMTUncoupled.f90 --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 24 +++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index 6daa2fc70..d72386fb5 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -129,14 +129,14 @@ end subroutine Transform_ClCd_to_CxCy !---------------------------------------------------------------------------------------------------------------------------------- subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & - Cl, Cd, Cm, errStat, errMsg ) + Cl, Cd, Cm, Cpmin, errStat, errMsg ) ! This routine is called from BEMTU_InductionWithResidual and possibly BEMT_CalcOutput. ! Determine the Cl, Cd, Cm, coeficients for a given angle of attack !.................................................................................................................................. real(ReKi), intent(in ) :: AOA real(ReKi), intent(in ) :: Re ! Unused in the current version! type(AFInfoType), intent(in ) :: AFInfo - real(ReKi), intent( out) :: Cl, Cd, Cm + real(ReKi), intent( out) :: Cl, Cd, Cm, Cpmin integer(IntKi), intent( out) :: errStat ! Error status of the operation character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None @@ -168,7 +168,19 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & Cl = IntAFCoefs(1) Cd = IntAFCoefs(2) - Cm = IntAFCoefs(3) + Cm = IntAFCoefs(0) + Cpmin = IntAFCoefs(0) + + IF ( AFInfo%ColCm > 2 ) THEN ! If there is Cm data, it is in column 3 + Cm = IntAFCoefs(3) + + IF ( AFInfo%ColCpmin > 2 ) THEN + Cpmin = IntAFCoefs(4) + END IF + + ELSE IF ( AFInfo%ColCpmin > 2 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 + Cpmin = IntAFCoefs(3) + END IF @@ -255,7 +267,7 @@ real(ReKi) function BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, real(ReKi) :: fzero - real(ReKi) :: Cl, Cd, Cx, Cy, Cm + real(ReKi) :: Cl, Cd, Cx, Cy, Cm, Cpmin ErrStat = ErrID_None @@ -275,7 +287,7 @@ real(ReKi) function BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, tanInduction = 0.0_ReKi else !if ( (.NOT. VelocityIsZero(Vx)) .AND. (.NOT. VelocityIsZero(Vy)) ) then - call ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, Cl, Cd, Cm, errStat2, errMsg2 ) !bjj: would be nice if this could be done outside this routine (so we don't copy AFInfo so much) + call ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, Cl, Cd, Cm, Cpmin, errStat2, errMsg2 ) !bjj: would be nice if this could be done outside this routine (so we don't copy AFInfo so much) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) if (ErrStat >= AbortErrLev) return @@ -641,4 +653,4 @@ real(reKi) function getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLos end function getHubTipLossCorrection !----------------------------------------------------------------------------------------- -end module BEMTUncoupled \ No newline at end of file +end module BEMTUncoupled From 12ba1d1f01c71d65434aef34b03b22e4569caca7 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 10:36:38 -0700 Subject: [PATCH 07/58] Update BEMT_Registry.txt --- modules-local/aerodyn/src/BEMT_Registry.txt | 32 +++++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT_Registry.txt b/modules-local/aerodyn/src/BEMT_Registry.txt index 8a791bca7..6dafb3e8b 100644 --- a/modules-local/aerodyn/src/BEMT_Registry.txt +++ b/modules-local/aerodyn/src/BEMT_Registry.txt @@ -34,6 +34,9 @@ typedef BEMT/BEMT InitInputType ReKi typedef ^ ^ INTEGER numBlades - - - "Number of blades" - typedef ^ ^ ReKi airDens - - - "Air density" kg/m^3 typedef ^ ^ ReKi kinVisc - - - "Kinematic air viscosity" m^2/s +typedef ^ ^ ReKi Patm - - - "Atmospheric pressure" Pa +typedef ^ ^ ReKi Pvap - - - "Vapour pressure" Pa +typedef ^ ^ ReKi FluidDepth - - - "Submerged hub height" m typedef ^ ^ INTEGER skewWakeMod - - - "Type of skewed-wake correction model [switch] {1=uncoupled, 2=Pitt/Peters, 3=coupled}" - typedef ^ ^ ReKi aTol - - - "Tolerance for the induction solution" - typedef ^ ^ LOGICAL useTipLoss - - - "Use the Prandtl tip-loss model? [flag]" - @@ -51,8 +54,10 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi zTip {:} - - "Distance to blade tip, measured along the blade" m typedef ^ ^ INTEGER UAMod - - - "Model for the dynamic stall equations [1 = Leishman/Beddoes, 2 = Gonzalez, 3 = Minnema]" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - +typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to check for cavitation" - typedef ^ ^ LOGICAL Flookup - - - "Use table lookup for f' and f'' " - typedef ^ ^ ReKi a_s - - - "speed of sound" m/s +typedef ^ ^ INTEGER InCol_Cpmin - - - "InCol_Cpmin" - # # # Define outputs from the initialization routine here: @@ -80,8 +85,9 @@ typedef ^ ConstraintStateType ReKi # typedef ^ OtherStateType UA_OtherStateType UA - - - "other states for UnsteadyAero" - typedef ^ ^ LOGICAL UA_Flag {:}{:} - - "logical flag indicating whether to use UnsteadyAero" - -typedef ^ ^ LOGICAL ValidPhi {:}{:} - - "set to indicate when there is no valid Phi for this node at this time (temporarially turn off induction when this is false)" - -typedef ^ OtherStateType Logical nodesInitialized - - - "the node states have been initialized properly" - +-typedef ^ ^ LOGICAL ValidPhi {:}{:} - - "set to indicate when there is no valid Phi for this node at this time (temporarially turn off induction when this is false)" - +-typedef ^ OtherStateType Logical nodesInitialized - - - "the node states have been initialized properly" - +typedef ^ ^ LOGICAL CavitCheck {:}{:} - - "logical flag indicating whether to check for cavitation" - # ..... Misc/Optimization variables................................................................................................. # Define any data that are used only for efficiency purposes (these variables are not associated with time): @@ -102,6 +108,9 @@ typedef ^ ^ ReKi typedef ^ ^ INTEGER numBlades - - - "Number of blades" - typedef ^ ^ ReKi airDens - - - "Air density" kg/m^3 typedef ^ ^ ReKi kinVisc - - - "Kinematic air viscosity" m^2/s +typedef ^ ^ ReKi Patm - - - "Atmospheric pressure" Pa +typedef ^ ^ ReKi Pvap - - - "Vapour pressure" Pa +typedef ^ ^ ReKi FluidDepth - - - "Submerged hub height" m typedef ^ ^ INTEGER skewWakeMod - - - "Type of skewed-wake correction model [switch] {1=uncoupled, 2=Pitt/Peters, 3=coupled}" - typedef ^ ^ ReKi aTol - - - "Tolerance for the induction solution" - typedef ^ ^ LOGICAL useTipLoss - - - "Use the Prandtl tip-loss model? [flag]" - @@ -119,6 +128,8 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi zHub {:} - - "Distance to hub for each blade" m typedef ^ ^ UA_ParameterType UA - - - "parameters for UnsteadyAero" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - +typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to use cavitation check" - +typedef ^ ^ INTEGER InCol_Cpmin - - - "InCol_Cpmin" - # # @@ -137,13 +148,16 @@ typedef ^ ^ ReKi # Define outputs that are contained on the mesh here: typedef ^ OutputType ReKi Vrel {:}{:} - - "Total local relative velocity" m/s typedef ^ ^ ReKi phi {:}{:} - - "angle between the plane of rotation and the direction of the local wind" rad -typedef ^ ^ ReKi axInduction {:}{:} - - "axial induction" - -typedef ^ ^ ReKi tanInduction {:}{:} - - "tangential induction" - -typedef ^ ^ ReKi Re {:}{:} - - "Reynold's number" - -typedef ^ ^ ReKi AOA {:}{:} - - "angle of attack" rad +typedef ^ ^ ReKi axInduction {:}{:} - - "Distributed viscous drag loads" - +typedef ^ ^ ReKi tanInduction {:}{:} - - "Distributed inertial loads" - +typedef ^ ^ ReKi Re {:}{:} - - "Distributed inertial loads" - +typedef ^ ^ ReKi AOA {:}{:} - - "Distributed inertial loads" - typedef ^ ^ ReKi Cx {:}{:} - - "normal force coefficient (normal to the plane, not chord) of the jth node in the kth blade" - typedef ^ ^ ReKi Cy {:}{:} - - "tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade" - typedef ^ ^ ReKi Cm {:}{:} - - "pitching moment coefficient of the jth node in the kth blade" - -typedef ^ ^ ReKi Cl {:}{:} - - "lift coefficient" - -typedef ^ ^ ReKi Cd {:}{:} - - "drag coefficient" - -typedef ^ ^ ReKi chi {:}{:} - - "wake skew angle" rad +typedef ^ ^ ReKi Cl {:}{:} - - "Distributed inertial loads" - +typedef ^ ^ ReKi Cd {:}{:} - - "Distributed inertial loads" - +typedef ^ ^ ReKi chi {:}{:} - - "Distributed inertial loads" - +typedef ^ ^ ReKi Cpmin {:}{:} - - "min Cpressure" - +typedef ^ ^ ReKi SigmaCavitCrit {:}{:} - - "critical cavitation number- inception value (above which cavit will occur)" - +typedef ^ ^ ReKi SigmaCavit {:}{:} - - "cavitation nubmer at node " - From 52b80b697fc9ccf3d5db6bf660229a4d7febfb0e Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 10:39:07 -0700 Subject: [PATCH 08/58] Update BEMTUncoupled.f90 --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index d72386fb5..887f161e1 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -168,8 +168,8 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & Cl = IntAFCoefs(1) Cd = IntAFCoefs(2) - Cm = IntAFCoefs(0) - Cpmin = IntAFCoefs(0) + Cm = IntAFCoefs(3) + Cpmin = IntAFCoefs(4) IF ( AFInfo%ColCm > 2 ) THEN ! If there is Cm data, it is in column 3 Cm = IntAFCoefs(3) From 9e2c177361a50853d674ccfc0f565552d05eabc1 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 9 Mar 2017 15:59:39 -0700 Subject: [PATCH 09/58] Update AeroDyn_Registry.txt --- modules-local/aerodyn/src/AeroDyn_Registry.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn_Registry.txt b/modules-local/aerodyn/src/AeroDyn_Registry.txt index 9b795c908..e6ba13d2a 100644 --- a/modules-local/aerodyn/src/AeroDyn_Registry.txt +++ b/modules-local/aerodyn/src/AeroDyn_Registry.txt @@ -37,7 +37,6 @@ typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputHdr {:} - - "Names of the typedef ^ InitOutputType CHARACTER(ChanLen) WriteOutputUnt {:} - - "Units of the output-to-file channels" - typedef ^ InitOutputType ProgDesc Ver - - - "This module's name, version, and date" - typedef ^ InitOutputType ReKi AirDens - - - "Air density" kg/m^3 -typedef ^ InitOutputType ReKi FluidDens - - - "Fluid density" kg/m^3 typedef ^ InitOutputType AD_BladeShape BladeShape {:} - - "airfoil coordinates for each blade" m typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_y {:} - - "Names of the outputs used in linearization" - typedef ^ InitOutputType CHARACTER(LinChanLen) LinNames_z {:} - - "Names of the constraint states used in linearization" - @@ -68,7 +67,6 @@ typedef ^ AD_InputFile LOGICAL TwrAero - - - "Calculate tower aerodynamic loads? typedef ^ AD_InputFile Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - typedef ^ AD_InputFile Logical CavitCheck - - - "Flag that tells us if we want to check for cavitation" - typedef ^ AD_InputFile ReKi AirDens - - - "Air density" kg/m^3 -typedef ^ AD_InputFile ReKi FluidDens - - - "Fluid density" kg/m^3 typedef ^ AD_InputFile ReKi KinVisc - - - "Kinematic air viscosity" m^2/s typedef ^ AD_InputFile ReKi Patm - - - "Atmospheric pressure" Pa typedef ^ AD_InputFile ReKi Pvap - - - "Vapour pressure" Pa @@ -139,7 +137,6 @@ typedef ^ MiscVarType ReKi V_dot_x - - - typedef ^ MiscVarType MeshType HubLoad - - - "mesh at hub; used to compute an integral for mapping the output blade loads to a single point (for writing to file only)" - typedef ^ MiscVarType MeshMapType B_L_2_H_P {:} - - "mapping data structure to map each bladeLoad output mesh to the MiscVar%HubLoad mesh" - # ..... Parameters ................................................................................................................ # Define parameters here: # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: @@ -149,14 +146,12 @@ typedef ^ ParameterType IntKi TwrPotent - - - "Type tower influence on wind base typedef ^ ParameterType LOGICAL TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow?" - typedef ^ ParameterType LOGICAL TwrAero - - - "Calculate tower aerodynamic loads?" flag typedef ^ ParameterType Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - -typedef ^ ParameterType Logical CavitCheck - - - "Flag that tells us to check cavitation"- typedef ^ ParameterType IntKi NumBlades - - - "Number of blades on the turbine" - typedef ^ ParameterType IntKi NumBlNds - - - "Number of nodes on each blade" - typedef ^ ParameterType IntKi NumTwrNds - - - "Number of nodes on the tower" - typedef ^ ParameterType ReKi TwrDiam {:} - - "Diameter of tower at node" m typedef ^ ParameterType ReKi TwrCd {:} - - "Coefficient of drag at tower node" - typedef ^ ParameterType ReKi AirDens - - - "Air density" kg/m^3 -typedef ^ ParameterType ReKi FluidDens - - - "Fluid density" kg/m^3 typedef ^ ParameterType ReKi KinVisc - - - "Kinematic air viscosity" m^2/s typedef ^ ParameterType ReKi Patm - - - "Atmospheric pressure" Pa typedef ^ ParameterType ReKi Pvap - - - "Vapour pressure" Pa From ed930dc16033544da1dc76d9820075388b7d2e76 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 9 Mar 2017 16:00:02 -0700 Subject: [PATCH 10/58] Update AeroDyn.f90 --- modules-local/aerodyn/src/AeroDyn.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn.f90 b/modules-local/aerodyn/src/AeroDyn.f90 index 619381fdb..69ff18a52 100644 --- a/modules-local/aerodyn/src/AeroDyn.f90 +++ b/modules-local/aerodyn/src/AeroDyn.f90 @@ -1701,9 +1701,9 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, InitInp%numBlades = p%NumBlades InitInp%airDens = InputFileData%AirDens - InitInp%kinVisc = InputFileData%KinVisc - InitInp%Patm = InputFileData%Patm + InitInp%kinVisc = InputFileData%KinVisc InitInp%Pvap = InputFileData%Pvap + InitInp%Patm = InputFileData%Patm InitInp%FluidDepth = InputFileData%FluidDepth InitInp%CavitCheck = InputFileData%CavitCheck InitInp%skewWakeMod = InputFileData%SkewMod From ec4cc788b288cdaaa6395f74496a6ac319bf41a8 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 9 Mar 2017 16:00:29 -0700 Subject: [PATCH 11/58] Update AeroDyn_IO.f90 --- modules-local/aerodyn/src/AeroDyn_IO.f90 | 75 +++++++++++------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index 52485b74e..52a9e5451 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -2,6 +2,8 @@ ! LICENSING ! Copyright (C) 2015-2016 National Renewable Energy Laboratory ! + + ! This file is part of AeroDyn. ! ! Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,12 +27,12 @@ MODULE AeroDyn_IO use NWTC_Library use AeroDyn_Types - use BEMTUncoupled, only : SkewMod_Uncoupled, SkewMod_PittPeters + use BEMTUncoupled, only : SkewMod_Uncoupled, SkewMod_PittPeters, VelocityIsZero implicit none - type(ProgDesc), parameter :: AD_Ver = ProgDesc( 'AeroDyn', 'v15.03.00', '27-Jul-2016' ) + type(ProgDesc), parameter :: AD_Ver = ProgDesc( 'AeroDyn', 'v15.04.00', '29-Oct-2016' ) character(*), parameter :: AD_Nickname = 'AD' ! =================================================================================================== @@ -1400,23 +1402,26 @@ MODULE AeroDyn_IO B2N1Curve,B2N2Curve,B2N3Curve,B2N4Curve,B2N5Curve,B2N6Curve,B2N7Curve,B2N8Curve,B2N9Curve, & B3N1Curve,B3N2Curve,B3N3Curve,B3N4Curve,B3N5Curve,B3N6Curve,B3N7Curve,B3N8Curve,B3N9Curve & /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCl(9, 3) = RESHAPE( (/ & ! lift force coefficient B1N1Cl,B1N2Cl,B1N3Cl,B1N4Cl,B1N5Cl,B1N6Cl,B1N7Cl,B1N8Cl,B1N9Cl, & B2N1Cl,B2N2Cl,B2N3Cl,B2N4Cl,B2N5Cl,B2N6Cl,B2N7Cl,B2N8Cl,B2N9Cl, & B3N1Cl,B3N2Cl,B3N3Cl,B3N4Cl,B3N5Cl,B3N6Cl,B3N7Cl,B3N8Cl,B3N9Cl & /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCd(9, 3) = RESHAPE( (/ & ! drag force coefficient B1N1Cd,B1N2Cd,B1N3Cd,B1N4Cd,B1N5Cd,B1N6Cd,B1N7Cd,B1N8Cd,B1N9Cd, & B2N1Cd,B2N2Cd,B2N3Cd,B2N4Cd,B2N5Cd,B2N6Cd,B2N7Cd,B2N8Cd,B2N9Cd, & B3N1Cd,B3N2Cd,B3N3Cd,B3N4Cd,B3N5Cd,B3N6Cd,B3N7Cd,B3N8Cd,B3N9Cd & /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCm(9, 3) = RESHAPE( (/ & ! pitching moment coefficient B1N1Cm,B1N2Cm,B1N3Cm,B1N4Cm,B1N5Cm,B1N6Cm,B1N7Cm,B1N8Cm,B1N9Cm, & B2N1Cm,B2N2Cm,B2N3Cm,B2N4Cm,B2N5Cm,B2N6Cm,B2N7Cm,B2N8Cm,B2N9Cm, & B3N1Cm,B3N2Cm,B3N3Cm,B3N4Cm,B3N5Cm,B3N6Cm,B3N7Cm,B3N8Cm,B3N9Cm & /), (/9, 3/) ) - - INTEGER, PARAMETER :: BNCpmin(9, 3) = RESHAPE( (/ & ! pressure coefficient + + INTEGER, PARAMETER :: BNCpmin(9, 3) = RESHAPE( (/ & ! pressure coefficient B1N1Cpmin,B1N2Cpmin,B1N3Cpmin,B1N4Cpmin,B1N5Cpmin,B1N6Cpmin,B1N7Cpmin,B1N8Cpmin,B1N9Cpmin, & B2N1Cpmin,B2N2Cpmin,B2N3Cpmin,B2N4Cpmin,B2N5Cpmin,B2N6Cpmin,B2N7Cpmin,B2N8Cpmin,B2N9Cpmin, & B3N1Cpmin,B3N2Cpmin,B3N3Cpmin,B3N4Cpmin,B3N5Cpmin,B3N6Cpmin,B3N7Cpmin,B3N8Cpmin,B3N9Cpmin & @@ -1433,7 +1438,7 @@ MODULE AeroDyn_IO B2N1SgCav,B2N2SgCav,B2N3SgCav,B2N4SgCav,B2N5SgCav,B2N6SgCav,B2N7SgCav,B2N8SgCav,B2N9SgCav, & B3N1SgCav,B3N2SgCav,B3N3SgCav,B3N4SgCav,B3N5SgCav,B3N6SgCav,B3N7SgCav,B3N8SgCav,B3N9SgCav & /), (/9, 3/) ) - + INTEGER, PARAMETER :: BNCx(9, 3) = RESHAPE( (/ & ! normal force (to plane) coefficient B1N1Cx,B1N2Cx,B1N3Cx,B1N4Cx,B1N5Cx,B1N6Cx,B1N7Cx,B1N8Cx,B1N9Cx, & B2N1Cx,B2N2Cx,B2N3Cx,B2N4Cx,B2N5Cx,B2N6Cx,B2N7Cx,B2N8Cx,B2N9Cx, & @@ -1674,24 +1679,25 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, indx, ErrStat, ErrMsg ) m%AllOuts( BNAxInd(beta,k) ) = m%BEMT_y%axInduction(j,k) m%AllOuts( BNTnInd(beta,k) ) = m%BEMT_y%tanInduction(j,k) - m%AllOuts( BNAlpha(beta,k) ) = (m%BEMT_y%phi(j,k) - m%BEMT_u(indx)%theta(j,k))*R2D + m%AllOuts( BNAlpha(beta,k) ) = Rad2M180to180Deg( m%BEMT_y%phi(j,k) - m%BEMT_u(indx)%theta(j,k) ) m%AllOuts( BNTheta(beta,k) ) = m%BEMT_u(indx)%theta(j,k)*R2D m%AllOuts( BNPhi( beta,k) ) = m%BEMT_y%phi(j,k)*R2D m%AllOuts( BNCurve(beta,k) ) = m%Curve(j,k)*R2D !m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cl(j,k) !m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cd(j,k) + + m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cpmin(j,k) + m%AllOuts( BNSigCr( beta,k) ) = m%BEMT_y%SigmaCavitCrit(j,k) + m%AllOuts( BNSgCav( beta,k) ) = m%BEMT_y%SigmaCavit(j,k) + cp=cos(m%BEMT_y%phi(j,k)) sp=sin(m%BEMT_y%phi(j,k)) - m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cx(j,k)*cp + m%BEMT_y%Cy(j,k)*sp + m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cx(j,k)*cp + m%BEMT_y%Cy(j,k)*sp m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cx(j,k)*sp - m%BEMT_y%Cy(j,k)*cp m%AllOuts( BNCm( beta,k) ) = m%BEMT_y%Cm(j,k) m%AllOuts( BNCx( beta,k) ) = m%BEMT_y%Cx(j,k) - m%AllOuts( BNCy( beta,k) ) = m%BEMT_y%Cy(j,k) - - m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cpmin(j,k) - m%AllOuts( BNSigCr( beta,k) ) = m%BEMT_y%SigmaCavitCrit(j,k) - m%AllOuts( BNSgCav( beta,k) ) = m%BEMT_y%SigmaCavit(j,k) + m%AllOuts( BNCy( beta,k) ) = m%BEMT_y%Cy(j,k) ct=cos(m%BEMT_u(indx)%theta(j,k)) st=sin(m%BEMT_u(indx)%theta(j,k)) @@ -2013,11 +2019,13 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadVar( UnIn, InputFile, InputFileData%FrozenWake, "FrozenWake", "Assume frozen wake during linearization? (flag)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! CavitCheck - Perform cavitation check? (flag): + + ! CavitCheck - Perform cavitation check? (flag): CALL ReadVar( UnIn, InputFile, InputFileData%CavitCheck, "CavitCheck", "Perform cavitation check? (flag)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - + + ! Return on error at end of section IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2029,16 +2037,14 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! AirDens - Air density (kg/m^3): - CALL ReadVar( UnIn, InputFile, InputFileData%FluidDens, "FluidDens", "Air density (kg/m^3)", ErrStat2, ErrMsg2, UnEc) + CALL ReadVar( UnIn, InputFile, InputFileData%AirDens, "AirDens", "Air density (kg/m^3)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - InputFileData%AirDens= InputFileData%FluidDens ! KinVisc - Kinematic air viscosity (m^2/s): CALL ReadVar( UnIn, InputFile, InputFileData%KinVisc, "KinVisc", "Kinematic air viscosity (m^2/s)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! Patm - Atmospheric pressure (Pa): + ! Patm - Atmospheric pressure (Pa): CALL ReadVar( UnIn, InputFile, InputFileData%Patm, "Patm", "Atmospheric pressure (Pa)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -2052,9 +2058,8 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadVar( UnIn, InputFile, InputFileData%FluidDepth, "FluidDepth", "Water depth above mid-hub height (MHK only, for cavitation check) (m)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! call WrScr( NewLine//'FluidDepth_input '//trim(num2lstr(InputFileData%FluidDepth)) ) - - ! SpdSound - Speed of sound (m/s): + + ! SpdSound - Speed of sound (m/s): CALL ReadVar( UnIn, InputFile, InputFileData%SpdSound, "SpdSound", "Speed of sound (m/s)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -2126,12 +2131,12 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadCom( UnIn, InputFile, 'Section Header: Beddoes-Leishman Unsteady Airfoil Aerodynamics Options', ErrStat2, ErrMsg2, UnEc ) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! UAMod - Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez’s variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-): - CALL ReadVar( UnIn, InputFile, InputFileData%UAMod, "UAMod", "Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez’s variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-)", ErrStat2, ErrMsg2, UnEc) + ! UAMod - Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-): + CALL ReadVar( UnIn, InputFile, InputFileData%UAMod, "UAMod", "Unsteady Aero Model Switch (switch) {1=Baseline model (Original), 2=Gonzalez's variant (changes in Cn,Cc,Cm), 3=Minemma/Pierce variant (changes in Cc and Cm)} [used only when AFAreoMod=2] (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! FLookup - Flag to indicate whether a lookup for f’ will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag): - CALL ReadVar( UnIn, InputFile, InputFileData%FLookup, "FLookup", "Flag to indicate whether a lookup for f’ will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag)", ErrStat2, ErrMsg2, UnEc) + ! FLookup - Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag): + CALL ReadVar( UnIn, InputFile, InputFileData%FLookup, "FLookup", "Flag to indicate whether a lookup for f' will be calculated (TRUE) or whether best-fit exponential equations will be used (FALSE); if FALSE S1-S4 must be provided in airfoil input files [used only when AFAreoMod=2] (flag)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! UACutout - Angle-of-attach beyond which unsteady aerodynamics are disabled (deg) @@ -2169,21 +2174,11 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) RETURN - ! InCol_Cpmin - The column in the airfoil tables that contains the pressure coefficient; use zero if there is no Cpmin column (-): - CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cpmin, "InCol_Cpmin", "The column in the airfoil tables that contains the pressure coefficient; use zero if there is no Cpmin column (-)", ErrStat2, ErrMsg2, UnEc) + ! InCol_Cpmin - The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-): + CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cpmin, "InCol_Cpmin", "The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) IF ( ErrStat >= AbortErrLev ) RETURN - - - - !if statement in case there is no Cpmin data, we warn the user - if (InputFileData%InCol_Cpmin == 0 .and. InputFileData%CavitCheck== .true.) then - InputFileData%CavitCheck = .false. - call WrScr( NewLine//' Warning: No Cpmin data. Cavitation check NOT performed.................') - end if - - - + ! NumAFfiles - Number of airfoil files used (-): CALL ReadVar( UnIn, InputFile, InputFileData%NumAFfiles, "NumAFfiles", "Number of airfoil files used (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -2649,7 +2644,7 @@ SUBROUTINE AD_PrintSum( InputFileData, p, u, y, ErrStat, ErrMsg ) case (1) Msg = 'baseline model (original)' case (2) - Msg = 'Gonzalez’s variant (changes in Cn, Cc, and Cm)' + Msg = "Gonzalez's variant (changes in Cn, Cc, and Cm)" case (3) Msg = 'Minemma/Pierce variant (changes in Cc and Cm)' !case (4) @@ -2716,7 +2711,6 @@ END SUBROUTINE AD_PrintSum !---------------------------------------------------------------------------------------------------------------------------------- - !********************************************************************************************************************************** ! NOTE: The following lines of code were generated by a Matlab script called "Write_ChckOutLst.m" ! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these @@ -3363,5 +3357,4 @@ END SUBROUTINE SetOutParam !********************************************************************************************************************************** - END MODULE AeroDyn_IO From 8a4b25125066e0c4fb2196721cedb200f8c4e065 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 9 Mar 2017 16:01:43 -0700 Subject: [PATCH 12/58] Update AirfoilInfo_Registry.txt --- modules-local/aerodyn/src/AirfoilInfo_Registry.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt index bd1dbede8..fe5f6e3b1 100644 --- a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt +++ b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt @@ -51,7 +51,7 @@ typedef ^ ^ ReKi x_cp_bar typedef ^ ^ ReKi UACutout - - - "" = typedef ^ ^ ReKi filtCutOff - - - "low pass filter cut-off frequency for the pitching rate and accelerations" Hz # The following derived type stores data for an airfoil at a single combination of Re and control setting. -typedef AirfoilInfo/AFI AFI_Table_Type ReKi Alpha {:} - - "Angle-of-attack vector that matches the Coefs matrix" +typedef AirfoilInfo/AFI AFI_Table_Type ReKi Alpha {:} - - "Angle-of-attack vector that matches the Coefs matrix" rad typedef ^ ^ ReKi Coefs {:}{:} - - "Airfoil coefficients for Cd, Cl, and maybe Cm and/or Cpmin" - typedef ^ ^ ReKi SplineCoefs {:}{:}{:} - - "Spline coefficients for Cd, Cl, and maybe Cm and/or Cpmin" - typedef ^ ^ ReKi BEMT_Spline {:}{:}{:}{:} - - "Spline coefficients for Cd, Cl for the two bounding Re when doing BEM" - From fe4c1d61714f5fb595c85fd47ca3dd6ed2675ae6 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 9 Mar 2017 16:02:19 -0700 Subject: [PATCH 13/58] Update BEMT_Registry.txt --- modules-local/aerodyn/src/BEMT_Registry.txt | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT_Registry.txt b/modules-local/aerodyn/src/BEMT_Registry.txt index 6dafb3e8b..691228c1d 100644 --- a/modules-local/aerodyn/src/BEMT_Registry.txt +++ b/modules-local/aerodyn/src/BEMT_Registry.txt @@ -54,8 +54,8 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi zTip {:} - - "Distance to blade tip, measured along the blade" m typedef ^ ^ INTEGER UAMod - - - "Model for the dynamic stall equations [1 = Leishman/Beddoes, 2 = Gonzalez, 3 = Minnema]" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - -typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to check for cavitation" - typedef ^ ^ LOGICAL Flookup - - - "Use table lookup for f' and f'' " - +typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to check for cavitation" - typedef ^ ^ ReKi a_s - - - "speed of sound" m/s typedef ^ ^ INTEGER InCol_Cpmin - - - "InCol_Cpmin" - # @@ -85,10 +85,11 @@ typedef ^ ConstraintStateType ReKi # typedef ^ OtherStateType UA_OtherStateType UA - - - "other states for UnsteadyAero" - typedef ^ ^ LOGICAL UA_Flag {:}{:} - - "logical flag indicating whether to use UnsteadyAero" - --typedef ^ ^ LOGICAL ValidPhi {:}{:} - - "set to indicate when there is no valid Phi for this node at this time (temporarially turn off induction when this is false)" - --typedef ^ OtherStateType Logical nodesInitialized - - - "the node states have been initialized properly" - +typedef ^ ^ LOGICAL ValidPhi {:}{:} - - "set to indicate when there is no valid Phi for this node at this time (temporarially turn off induction when this is false)" - +typedef ^ OtherStateType Logical nodesInitialized - - - "the node states have been initialized properly" - typedef ^ ^ LOGICAL CavitCheck {:}{:} - - "logical flag indicating whether to check for cavitation" - + # ..... Misc/Optimization variables................................................................................................. # Define any data that are used only for efficiency purposes (these variables are not associated with time): # e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. @@ -148,16 +149,16 @@ typedef ^ ^ ReKi # Define outputs that are contained on the mesh here: typedef ^ OutputType ReKi Vrel {:}{:} - - "Total local relative velocity" m/s typedef ^ ^ ReKi phi {:}{:} - - "angle between the plane of rotation and the direction of the local wind" rad -typedef ^ ^ ReKi axInduction {:}{:} - - "Distributed viscous drag loads" - -typedef ^ ^ ReKi tanInduction {:}{:} - - "Distributed inertial loads" - -typedef ^ ^ ReKi Re {:}{:} - - "Distributed inertial loads" - -typedef ^ ^ ReKi AOA {:}{:} - - "Distributed inertial loads" - +typedef ^ ^ ReKi axInduction {:}{:} - - "axial induction" - +typedef ^ ^ ReKi tanInduction {:}{:} - - "tangential induction" - +typedef ^ ^ ReKi Re {:}{:} - - "Reynold's number" - +typedef ^ ^ ReKi AOA {:}{:} - - "angle of attack" rad typedef ^ ^ ReKi Cx {:}{:} - - "normal force coefficient (normal to the plane, not chord) of the jth node in the kth blade" - typedef ^ ^ ReKi Cy {:}{:} - - "tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade" - typedef ^ ^ ReKi Cm {:}{:} - - "pitching moment coefficient of the jth node in the kth blade" - -typedef ^ ^ ReKi Cl {:}{:} - - "Distributed inertial loads" - -typedef ^ ^ ReKi Cd {:}{:} - - "Distributed inertial loads" - -typedef ^ ^ ReKi chi {:}{:} - - "Distributed inertial loads" - +typedef ^ ^ ReKi Cl {:}{:} - - "lift coefficient" - +typedef ^ ^ ReKi Cd {:}{:} - - "drag coefficient" - +typedef ^ ^ ReKi chi {:}{:} - - "wake skew angle" rad typedef ^ ^ ReKi Cpmin {:}{:} - - "min Cpressure" - typedef ^ ^ ReKi SigmaCavitCrit {:}{:} - - "critical cavitation number- inception value (above which cavit will occur)" - typedef ^ ^ ReKi SigmaCavit {:}{:} - - "cavitation nubmer at node " - From 612d47de4f54f2526fb3edf338d785478157436a Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 9 Mar 2017 16:02:35 -0700 Subject: [PATCH 14/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 47 ++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 323f01381..296ea3c12 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -162,6 +162,8 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numBladeNodes = InitInp%numBladeNodes p%numBlades = InitInp%numBlades p%UA_Flag = InitInp%UA_Flag + p%CavitCheck = InitInp%CavitCheck + allocate ( p%chord(p%numBladeNodes, p%numBlades), STAT = errStat2 ) if ( errStat2 /= 0 ) then @@ -208,8 +210,8 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) !p%DT = InitInp%DT p%airDens = InitInp%airDens - p%kinVisc = InitInp%kinVisc - p%Patm = InitInp%Patm + p%kinVisc = InitInp%kinVisc + p%Patm = InitInp%Patm p%Pvap = InitInp%Pvap p%CavitCheck = InitInp%CavitCheck p%FluidDepth = InitInp%FluidDepth @@ -470,9 +472,10 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) call allocAry( y%Cm, p%numBladeNodes, p%numBlades, 'y%Cm', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cl, p%numBladeNodes, p%numBlades, 'y%Cl', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cd, p%numBladeNodes, p%numBlades, 'y%Cd', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%Cpmin, p%numBladeNodes, p%numBlades, 'y%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) +call allocAry( y%Cpmin, p%numBladeNodes, p%numBlades, 'y%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%SigmaCavit, p%numBladeNodes, p%numBlades, 'y%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%SigmaCavitCrit, p%numBladeNodes, p%numBlades, 'y%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat >= AbortErrLev) RETURN @@ -491,6 +494,9 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) y%AOA = 0.0_ReKi y%Cl = 0.0_ReKi y%Cd = 0.0_ReKi + y%Cpmin = 0.0_ReKi + y%SigmaCavit = 0.0_ReKi + y%SigmaCavitCrit = 0.0_ReKi end subroutine BEMT_AllocOutput @@ -734,12 +740,13 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte call WrScr( 'Warning: Turning off Unsteady Aerodynamics because C_nalpha is 0. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) end if - if ( p%CavitCheck ) then !Turn off unsteady aerodynamics if we are doing a cavitation check + if ( p%CavitCheck ) then OtherState%UA_Flag(i,j) = .false. call WrScr( 'Warning: Turning off Unsteady Aerodynamics because doing cavitation check' ) call WrScr( 'To run Unsteady Aerodynamics, set CavitCheck to FALSE in input file' ) end if + end do end do @@ -1095,8 +1102,8 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat ! Local variables: - real(ReKi) :: Re, fzero - real(ReKi) :: Rtip,SigmaCavitCrit, SigmaCavit ! maximum rlocal value for node j over all blades + real(ReKi) :: Re, fzero, theta, Vx, Vy + real(ReKi) :: Rtip, SigmaCavitCrit, SigmaCavit ! maximum rlocal value for node j over all blades integer(IntKi) :: i ! Generic index integer(IntKi) :: j ! Loops through nodes / elements @@ -1176,6 +1183,13 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' + ! local velocities and twist angle + Vx = u%Vx(i,j) + Vy = u%Vy(i,j) + theta = u%theta(i,j) + + + ! Set the active blade element for UnsteadyAero m%UA%iBladeNode = i m%UA%iBlade = j @@ -1249,23 +1263,27 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat else ! TODO: When we start using Re, should we use the uninduced Re since we used uninduced Re to solve for the inductions!? Probably this won't change, instead create a Re loop up above. call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & - y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), errStat2, errMsg2 ) + y%Cl(i,j), y%Cd(i,j), y%Cd(i,j), y%Cpmin(i,j), errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) if (errStat >= AbortErrLev) return - - if ( p%CavitCheck ) then ! This calculates the cavitation number for the airfoil at the node in quesiton, and compares to the critical cavitation number based on the vapour pressure and submerged depth - + + if ( p%CavitCheck ) then + ! This calculates the cavitation number for the airfoil at the node in quesiton, and compares to the critical cavitation number based on the vapour pressure and submerged depth + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this SigmaCavit= -1* y%Cpmin(i,j) ! Actual cavitation number on blade node j - + + if (SigmaCavitCrit < SigmaCavit) then call WrScr( NewLine//'FAILED CAVITATION CHECK'//' Node # = '//trim(num2lstr(i)//'Blade # = '//trim(num2lstr(j)))) + end if if (y%Vrel(i,j) == 0) then !if Vrel = 0 in certain cases when Prandtls tip and hub loss factors are used, use the relative verlocity without induction SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * (sqrt((Vx**2 + Vy**2)))**2) ! Critical value of Sigma, cavitation if we go over this + end if y%SigmaCavit(i,j)= SigmaCavit @@ -1273,12 +1291,9 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat end if + end if - - - - ! Compute Cx, Cy given Cl, Cd and phi ! NOTE: For these calculations we force the useAIDrag and useTIDrag flags to .TRUE. @@ -1841,7 +1856,7 @@ subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, cho real(ReKi) :: phi_lower(3), phi_upper(3) ! upper and lower bounds for region of phi in which we are trying to find a solution to the BEM equations integer :: i, TestRegionResult logical :: IsValidSolution - real(ReKi) :: Re, Vrel + real(ReKi) :: Re, Vrel, cpmin ErrStat = ErrID_None ErrMsg = "" From 44f74af5889ab3dd312f4265634f1e49192ab8c8 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 9 Mar 2017 16:02:52 -0700 Subject: [PATCH 15/58] Update BEMTUncoupled.f90 --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index 887f161e1..882c0b26b 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -166,10 +166,10 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & , AFInfo%Table(1)%SplineCoefs & , ErrStat, ErrMsg ) - Cl = IntAFCoefs(1) + Cl = IntAFCoefs(1) Cd = IntAFCoefs(2) Cm = IntAFCoefs(3) - Cpmin = IntAFCoefs(4) + Cpmin = IntAFCoefs(4) IF ( AFInfo%ColCm > 2 ) THEN ! If there is Cm data, it is in column 3 Cm = IntAFCoefs(3) @@ -181,7 +181,7 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & ELSE IF ( AFInfo%ColCpmin > 2 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 Cpmin = IntAFCoefs(3) END IF - + end subroutine ComputeSteadyAirfoilCoefs From aaeb837d15197960fe0b463603467e4b02806a4c Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 08:20:21 -0600 Subject: [PATCH 16/58] Update BEMTUncoupled.f90 --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index 882c0b26b..353ecab57 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -166,12 +166,12 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & , AFInfo%Table(1)%SplineCoefs & , ErrStat, ErrMsg ) - Cl = IntAFCoefs(1) - Cd = IntAFCoefs(2) - Cm = IntAFCoefs(3) - Cpmin = IntAFCoefs(4) - - IF ( AFInfo%ColCm > 2 ) THEN ! If there is Cm data, it is in column 3 + Cl = IntAFCoefs(1) + Cd = IntAFCoefs(2) +! Cm = IntAFCoefs(3) + ! Cpmin = IntAFCoefs(4) + + IF ( AFInfo%ColCm > 2 ) THEN ! If there is Cm data, it is in column 3 Cm = IntAFCoefs(3) IF ( AFInfo%ColCpmin > 2 ) THEN @@ -182,7 +182,7 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & Cpmin = IntAFCoefs(3) END IF - + end subroutine ComputeSteadyAirfoilCoefs From beb780b0356040ef511dd406b59b24e3fcf7794e Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 08:21:41 -0600 Subject: [PATCH 17/58] Compute Cm and Cpmin If statement in ComputeSteadyAirfoilCoefs so that if there is no Cm data, Cpmin gets interpolated from IntAFCoefs(3) --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index 353ecab57..bf2dd6421 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -93,6 +93,7 @@ subroutine BEMTU_Wind( axInduction, tanInduction, Vx, Vy, chord, airDens, mu, W W = sqrt((Vx*(1-axInduction))**2 + (Vy*(1+tanInduction))**2) !end if + Re = airDens * W * chord / mu if ( EqualRealNos(Re, 0.0_ReKi) ) Re = 0.001 ! Do this to avoid a singularity when we take log(Re) in the airfoil lookup. From afe344ba777f21402dd9f1ae05a48e84d1c0757d Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 10:47:26 -0600 Subject: [PATCH 18/58] Update AirfoilInfo.f90 --- modules-local/aerodyn/src/AirfoilInfo.f90 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/AirfoilInfo.f90 b/modules-local/aerodyn/src/AirfoilInfo.f90 index a8ef71e0f..d38f7731e 100644 --- a/modules-local/aerodyn/src/AirfoilInfo.f90 +++ b/modules-local/aerodyn/src/AirfoilInfo.f90 @@ -110,6 +110,7 @@ SUBROUTINE AFI_Init ( InitInput, p, ErrStat, ErrMsg, UnEcho ) p%ColCd = 2 p%ColCm = 0 ! These may or may not be used; initialize to zero in case they aren't used p%ColCpmin = 0 ! These may or may not be used; initialize to zero in case they aren't used + IF ( InitInput%InCol_Cm > 0 ) THEN p%ColCm = 3 IF ( InitInput%InCol_Cpmin > 0 ) THEN @@ -119,8 +120,8 @@ SUBROUTINE AFI_Init ( InitInput, p, ErrStat, ErrMsg, UnEcho ) p%ColCpmin = 3 END IF NumCoefs = MAX(p%ColCd, p%ColCm,p%ColCpmin) ! number of non-zero coefficient columns - + ! Process the airfoil files. ALLOCATE ( p%AFInfo( InitInput%NumAFfiles ), STAT=ErrStat2 ) @@ -129,6 +130,9 @@ SUBROUTINE AFI_Init ( InitInput, p, ErrStat, ErrMsg, UnEcho ) RETURN ENDIF + p%AFInfo( :)%InCol_Cpmin=p%ColCpmin + p%AFInfo( :)%InCol_Cm=p%ColCm + DO File=1,InitInput%NumAFfiles @@ -496,6 +500,7 @@ SUBROUTINE ReadAFfile ( AFfile, NumCoefs, InCol_Alfa, InCol_Cl, InCol_Cd, InCol_ TYPE (AFInfoType), INTENT(INOUT) :: AFInfo ! The derived type for holding the constant parameters for this airfoil. + ! Local declarations. REAL(ReKi) :: Coords (2) ! An array to hold data from the airfoil-shape table. @@ -805,6 +810,8 @@ SUBROUTINE ReadAFfile ( AFfile, NumCoefs, InCol_Alfa, InCol_Cl, InCol_Cd, InCol_ CALL Cleanup() RETURN ENDIF + + DO Row=1,AFInfo%Table(Table)%NumAlf From 189d2dfea2d0b16fb7ae990ae213cd71ffe0dfd2 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 10:47:43 -0600 Subject: [PATCH 19/58] Update AeroDyn_IO.f90 --- modules-local/aerodyn/src/AeroDyn_IO.f90 | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index 52a9e5451..296c7aa93 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -1684,8 +1684,8 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, indx, ErrStat, ErrMsg ) m%AllOuts( BNPhi( beta,k) ) = m%BEMT_y%phi(j,k)*R2D m%AllOuts( BNCurve(beta,k) ) = m%Curve(j,k)*R2D - !m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cl(j,k) - !m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cd(j,k) + m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cl(j,k) + m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cd(j,k) m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cpmin(j,k) m%AllOuts( BNSigCr( beta,k) ) = m%BEMT_y%SigmaCavitCrit(j,k) @@ -2044,25 +2044,23 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadVar( UnIn, InputFile, InputFileData%KinVisc, "KinVisc", "Kinematic air viscosity (m^2/s)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! Patm - Atmospheric pressure (Pa): + ! SpdSound - Speed of sound (m/s): + CALL ReadVar( UnIn, InputFile, InputFileData%SpdSound, "SpdSound", "Speed of sound (m/s)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Patm - Atmospheric pressure (Pa): CALL ReadVar( UnIn, InputFile, InputFileData%Patm, "Patm", "Atmospheric pressure (Pa)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - ! Pvap - Vapour pressure of fluid (Pa): + ! Pvap - Vapour pressure of fluid (Pa): CALL ReadVar( UnIn, InputFile, InputFileData%Pvap, "Pvap", "Vapour pressure of fluid (Pa)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - ! FluidDepth - Water depth above mid-hub height (m) - used for caviation check: + + ! FluidDepth - Water depth above mid-hub height (m) - used for caviation check: CALL ReadVar( UnIn, InputFile, InputFileData%FluidDepth, "FluidDepth", "Water depth above mid-hub height (MHK only, for cavitation check) (m)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - - ! SpdSound - Speed of sound (m/s): - CALL ReadVar( UnIn, InputFile, InputFileData%SpdSound, "SpdSound", "Speed of sound (m/s)", ErrStat2, ErrMsg2, UnEc) - CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - + ! Return on error at end of section IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2177,6 +2175,8 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE ! InCol_Cpmin - The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-): CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cpmin, "InCol_Cpmin", "The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + IF ( ErrStat >= AbortErrLev ) RETURN ! NumAFfiles - Number of airfoil files used (-): From 8620d4c4dc198398a03966985e80492930c0b520 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 10:48:00 -0600 Subject: [PATCH 20/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 38 +++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 296ea3c12..a1a29ff68 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -163,6 +163,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numBlades = InitInp%numBlades p%UA_Flag = InitInp%UA_Flag p%CavitCheck = InitInp%CavitCheck + allocate ( p%chord(p%numBladeNodes, p%numBlades), STAT = errStat2 ) @@ -211,7 +212,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) !p%DT = InitInp%DT p%airDens = InitInp%airDens p%kinVisc = InitInp%kinVisc - p%Patm = InitInp%Patm + p%Patm = InitInp%Patm p%Pvap = InitInp%Pvap p%CavitCheck = InitInp%CavitCheck p%FluidDepth = InitInp%FluidDepth @@ -227,6 +228,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%aTol = InitInp%aTol p%InCol_Cpmin = InitInp%InCol_Cpmin + end subroutine BEMT_SetParameters !---------------------------------------------------------------------------------------------------------------------------------- @@ -719,6 +721,7 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte write (69,'(A)') ' ' #endif + do j = 1,p%numBlades do i = 1,p%numBladeNodes ! Loop over blades and nodes @@ -740,12 +743,17 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte call WrScr( 'Warning: Turning off Unsteady Aerodynamics because C_nalpha is 0. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) end if - if ( p%CavitCheck ) then + + if ( p%CavitCheck .and. OtherState%UA_Flag(i,j)) then OtherState%UA_Flag(i,j) = .false. - call WrScr( 'Warning: Turning off Unsteady Aerodynamics because doing cavitation check' ) - call WrScr( 'To run Unsteady Aerodynamics, set CavitCheck to FALSE in input file' ) + call SetErrStat( ErrID_Fatal, 'Turn off Unsteady Aerodynamics to do a cavitation check', ErrStat, ErrMsg, RoutineName ) end if + + + + call WrScr (' p%InCol_Cpmin='//trim(num2lstr((p%InCol_Cpmin)))) + end do end do @@ -1186,7 +1194,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat ! local velocities and twist angle Vx = u%Vx(i,j) Vy = u%Vy(i,j) - theta = u%theta(i,j) + !theta = u%theta(i,j) @@ -1263,15 +1271,20 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat else ! TODO: When we start using Re, should we use the uninduced Re since we used uninduced Re to solve for the inductions!? Probably this won't change, instead create a Re loop up above. call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & - y%Cl(i,j), y%Cd(i,j), y%Cd(i,j), y%Cpmin(i,j), errStat2, errMsg2 ) + y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), y%Cpmin(i,j), errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) if (errStat >= AbortErrLev) return + + + if ( p%CavitCheck .and. y%Cpmin(i,j)==0) then + call SetErrStat( ErrID_Fatal, 'No Cpmin data for cavitation check', ErrStat, ErrMsg, RoutineName ) + end if + - if ( p%CavitCheck ) then - ! This calculates the cavitation number for the airfoil at the node in quesiton, and compares to the critical cavitation number based on the vapour pressure and submerged depth - + if ( p%CavitCheck ) then ! This calculates the cavitation number for the airfoil at the node in quesiton, and compares to the critical cavitation number based on the vapour pressure and submerged depth + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this SigmaCavit= -1* y%Cpmin(i,j) ! Actual cavitation number on blade node j @@ -1290,7 +1303,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat y%SigmaCavitCrit(i,j)=SigmaCavitCrit end if - + end if @@ -1985,5 +1998,8 @@ end subroutine BEMT_UnCoupledSolve -end module BEMT + end module BEMT + + + From 72a10ad181649d16e8fa61cf1af4983e3732f735 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 10:48:16 -0600 Subject: [PATCH 21/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 2425 +++++++--------------------- 1 file changed, 540 insertions(+), 1885 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index a1a29ff68..24474eeca 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -21,1747 +21,236 @@ ! (File) Revision #: $Rev$ ! URL: $HeadURL$ !********************************************************************************************************************************** -module BEMT - - use NWTC_Library - - use BEMT_Types - use BEMTUncoupled - - - use UnsteadyAero - !USE AeroDyn_Types - use AirfoilInfo - - - implicit none - - - private - - type(ProgDesc), parameter :: BEMT_Ver = ProgDesc( 'BEM', 'v1.03.00', '29-Oct-2016' ) - character(*), parameter :: BEMT_Nickname = 'BEM' - - - ! ..... Public Subroutines ................................................................................................... - - public :: BEMT_Init ! Initialization routine - public :: BEMT_End ! Ending routine (includes clean up) - - public :: BEMT_UpdateStates ! Loose coupling routine for solving for constraint states, integrating - ! continuous states, and updating discrete states - public :: BEMT_CalcOutput ! Routine for computing outputs - - public :: BEMT_CalcConstrStateResidual ! Tight coupling routine for returning the constraint state residual - public :: BEMT_CalcContStateDeriv ! Tight coupling routine for computing derivatives of continuous states - public :: BEMT_UpdateDiscState ! Tight coupling routine for updating discrete states - - ! routines for linearization - public :: Get_phi_perturbations - public :: ComputeFrozenWake - public :: CheckLinearizationInput - - contains - - - -!---------------------------------------------------------------------------------------------------------------------------------- -real(ReKi) function ComputePhiWithInduction( Vx, Vy, a, aprime ) -! This routine is used to compute the inflow angle, phi, from the local velocities and the induction factors. -!.................................................................................................................................. - real(ReKi), intent(in ) :: Vx ! Local velocity component along the thrust direction - real(ReKi), intent(in ) :: Vy ! Local velocity component along the rotor plane-of-rotation direction - real(ReKi), intent(in ) :: a ! Axial induction factor - real(ReKi), intent(in ) :: aprime ! Tangential induction factor - - real(ReKi) :: x - real(ReKi) :: y - - x = Vx*(1-a) - y = Vy*(1+aprime) - - if ( EqualRealNos(y, 0.0_ReKi) .AND. EqualRealNos(x, 0.0_ReKi) ) then - ComputePhiWithInduction = 0.0_ReKi - else - ComputePhiWithInduction = atan2( x , y ) - end if - - -end function ComputePhiWithInduction - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat, errMsg ) -! This routine is called from BEMT_Init. -! The parameters are set here and not changed during the simulation. -!.................................................................................................................................. - type(BEMT_InitInputType), intent(inout) :: InitInp ! Input data for initialization routine, out is needed because of copy below - real(DbKi), intent(in ) :: interval ! time interval - type(UA_InitInputType), intent( out) :: Init_UA_Data ! Parameters - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - integer :: i,j - integer(intKi) :: ErrStat2 ! temporary Error status - - ! Set up initialization data - - Allocate(Init_UA_Data%c(InitInp%numBladeNodes,InitInp%numBlades), STAT = errStat2) - if (ErrStat2 /= 0) then - ErrStat = ErrID_Fatal - ErrMsg = "BEMT_Set_UA_InitData:Error allocating Init_UA_Data%c." - return - else - ErrStat = ErrID_None - ErrMsg = "" - end if - - do j = 1,InitInp%numBlades - do i = 1,InitInp%numBladeNodes - Init_UA_Data%c(i,j) = InitInp%chord(i,j) - end do - end do - - ! TODO:: Fully implement these initialization inputs - - Init_UA_Data%dt = interval - Init_UA_Data%OutRootName = '' - - Init_UA_Data%numBlades = InitInp%numBlades - Init_UA_Data%nNodesPerBlade = InitInp%numBladeNodes - - Init_UA_Data%NumOuts = 0 - Init_UA_Data%UAMod = InitInp%UAMod - Init_UA_Data%Flookup = InitInp%Flookup - Init_UA_Data%a_s = InitInp%a_s ! m/s - -end subroutine BEMT_Set_UA_InitData - - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) -! This routine is called from BEMT_Init. -! The parameters are set here and not changed during the simulation. -!.................................................................................................................................. - type(BEMT_InitInputType), intent(inout) :: InitInp ! Input data for initialization routine, out is needed because of copy below - type(BEMT_ParameterType), intent( out) :: p ! Parameters - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_SetParameters' - integer(IntKi) :: i, j - - - ! Initialize variables for this routine - - errStat = ErrID_None - errMsg = "" - - p%numBladeNodes = InitInp%numBladeNodes - p%numBlades = InitInp%numBlades - p%UA_Flag = InitInp%UA_Flag - p%CavitCheck = InitInp%CavitCheck - - - - allocate ( p%chord(p%numBladeNodes, p%numBlades), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%chord.', errStat, errMsg, RoutineName ) - return - end if - - allocate ( p%zHub(p%numBlades), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%zHub.', errStat, errMsg, RoutineName ) - return - end if - - allocate ( p%AFindx(p%numBladeNodes,p%numBlades), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%AFindx.', errStat, errMsg, RoutineName ) - return - end if - - allocate ( p%tipLossConst(p%numBladeNodes, p%numBlades), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%tipLossConst.', errStat, errMsg, RoutineName ) - return - end if - - allocate ( p%hubLossConst(p%numBladeNodes, p%numBlades), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%hubLossConst.', errStat, errMsg, RoutineName ) - return - end if - - p%AFindx = InitInp%AFindx - - ! Compute the tip and hub loss constants using the distances along the blade (provided as input for now) - do j=1,p%numBlades - p%zHub(j) = InitInp%zHub(j) - do i=1,p%numBladeNodes - p%chord(i,j) = InitInp%chord(i,j) - p%tipLossConst(i,j) = p%numBlades*(InitInp%zTip (j) - InitInp%zLocal(i,j)) / (2.0*InitInp%zLocal(i,j)) - p%hubLossConst(i,j) = p%numBlades*(InitInp%zLocal(i,j) - InitInp%zHub (j)) / (2.0*InitInp%zHub (j)) - end do - end do - - - !p%DT = InitInp%DT - p%airDens = InitInp%airDens - p%kinVisc = InitInp%kinVisc - p%Patm = InitInp%Patm - p%Pvap = InitInp%Pvap - p%CavitCheck = InitInp%CavitCheck - p%FluidDepth = InitInp%FluidDepth - p%skewWakeMod = InitInp%skewWakeMod - p%useTipLoss = InitInp%useTipLoss - p%useHubLoss = InitInp%useHubLoss - p%useInduction = InitInp%useInduction - p%useTanInd = InitInp%useTanInd - p%useAIDrag = InitInp%useAIDrag - p%useTIDrag = InitInp%useTIDrag - p%numReIterations = InitInp%numReIterations - p%maxIndIterations = InitInp%maxIndIterations - p%aTol = InitInp%aTol - p%InCol_Cpmin = InitInp%InCol_Cpmin - - -end subroutine BEMT_SetParameters - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_InitContraintStates( z, p, errStat, errMsg ) -! This routine is called from BEMT_Init. -! The constraint state data is allocated and set to zero. -!.................................................................................................................................. - - type(BEMT_ConstraintStateType), intent( out) :: z ! Input data for initialization routine - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables - character(*), parameter :: RoutineName = 'BEMT_InitContraintStates' - integer(IntKi) :: errStat2 ! temporary Error status of the operation - - ! Initialize variables for this routine - - errStat = ErrID_None - errMsg = "" - - allocate ( z%phi( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for z%phi.', errStat, errMsg, RoutineName ) - return - end if - z%phi = 0.0_ReKi - - -end subroutine BEMT_InitContraintStates - - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_InitOtherStates( OtherState, p, errStat, errMsg ) -! This routine is called from BEMT_Init. -! The OtherState data is allocated and set to zero. -!.................................................................................................................................. - - type(BEMT_OtherStateType), intent(inout) :: OtherState ! OtherState data - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables - character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_InitOtherStates' - - ! Initialize variables for this routine - - errStat = ErrID_None - errMsg = "" - - if (p%UseInduction) then - - allocate ( OtherState%ValidPhi( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for OtherState%ValidPhi.', errStat, errMsg, RoutineName ) - return - end if - OtherState%ValidPhi = .true. - - end if - - OtherState%nodesInitialized = .false. ! z%phi hasn't been initialized properly, so make sure we compute a value for phi until we've updated them in the first call to BEMT_UpdateStates() - -! -! -! allocate ( OtherState%axInduction( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) -! if ( errStat2 /= 0 ) then -! errStat2 = ErrID_Fatal -! errMsg2 = 'Error allocating memory for OtherState%axInduction.' -! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) -! return -! end if -! OtherState%axInduction = 0.0_ReKi -! -! allocate ( OtherState%tanInduction( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) -! if ( errStat2 /= 0 ) then -! errStat2 = ErrID_Fatal -! errMsg2 = 'Error allocating memory for OtherState%tanInduction.' -! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) -! return -! end if -! OtherState%tanInduction = 0.0_ReKi -! -! allocate ( OtherState%Re( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) -! if ( errStat2 /= 0 ) then -! errStat2 = ErrID_Fatal -! errMsg2 = 'Error allocating memory for OtherState%Re.' -! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) -! return -! end if -! OtherState%Re = 0.0_ReKi -! -! allocate ( OtherState%AOA( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) -! if ( errStat2 /= 0 ) then -! errStat2 = ErrID_Fatal -! errMsg2 = 'Error allocating memory for OtherState%AOA.' -! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) -! return -! end if -! OtherState%AOA = 0.0_ReKi -! -! allocate ( OtherState%Cx( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) -! if ( errStat2 /= 0 ) then -! errStat2 = ErrID_Fatal -! errMsg2 = 'Error allocating memory for OtherState%Cx.' -! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) -! return -! end if -! OtherState%Cx = 0.0_ReKi -! -! allocate ( OtherState%Cy( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) -! if ( errStat2 /= 0 ) then -! errStat2 = ErrID_Fatal -! errMsg2 = 'Error allocating memory for OtherState%Cy.' -! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) -! return -! end if -! OtherState%Cy = 0.0_ReKi -! -! allocate ( OtherState%Cl( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) -! if ( errStat2 /= 0 ) then -! errStat2 = ErrID_Fatal -! errMsg2 = 'Error allocating memory for OtherState%Cl.' -! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) -! return -! end if -! OtherState%Cl = 0.0_ReKi -! -! allocate ( OtherState%Cd( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) -! if ( errStat2 /= 0 ) then -! errStat2 = ErrID_Fatal -! errMsg2 = 'Error allocating memory for OtherState%Cd.' -! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) -! return -! end if -! OtherState%Cd = 0.0_ReKi - -end subroutine BEMT_InitOtherStates - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_AllocInput( u, p, errStat, errMsg ) -! This routine is called from BEMT_Init. -! -! -!.................................................................................................................................. - - type(BEMT_InputType), intent( out) :: u ! Input data - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_AllocInput' - - ! Initialize variables for this routine - - errStat = ErrID_None - errMsg = "" - - allocate ( u%theta( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%theta.', errStat, errMsg, RoutineName ) - return - end if - u%theta = 0.0_ReKi - - allocate ( u%psi( p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%psi.', errStat, errMsg, RoutineName ) - return - end if - u%psi = 0.0_ReKi - - allocate ( u%Vx( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%Vx.', errStat, errMsg, RoutineName ) - return - end if - u%Vx = 0.0_ReKi - - allocate ( u%Vy( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%Vy.', errStat, errMsg, RoutineName ) - return - end if - u%Vy = 0.0_ReKi - - - allocate ( u%rLocal( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%rLocal.', errStat, errMsg, RoutineName ) - return - end if - u%rLocal = 0.0_ReKi - - - - u%omega = 0.0_ReKi - -end subroutine BEMT_AllocInput - - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) -! This routine is called from BEMT_Init. -! -! -!.................................................................................................................................. - - type(BEMT_OutputType), intent( out) :: y ! output data - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables - character(ErrMsgLen ) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_AllocOutput' - - ! Initialize variables for this routine - - errStat = ErrID_None - errMsg = "" - - call allocAry( y%Vrel, p%numBladeNodes, p%numBlades, 'y%Vrel', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%phi, p%numBladeNodes, p%numBlades, 'y%phi', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%chi, p%numBladeNodes, p%numBlades, 'y%chi', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%Re, p%numBladeNodes, p%numBlades, 'y%Re', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%axInduction, p%numBladeNodes, p%numBlades, 'y%axInduction', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%tanInduction, p%numBladeNodes, p%numBlades, 'y%tanInduction', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%AOA, p%numBladeNodes, p%numBlades, 'y%AOA', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%Cx, p%numBladeNodes, p%numBlades, 'y%Cx', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%Cy, p%numBladeNodes, p%numBlades, 'y%Cy', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%Cm, p%numBladeNodes, p%numBlades, 'y%Cm', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%Cl, p%numBladeNodes, p%numBlades, 'y%Cl', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%Cd, p%numBladeNodes, p%numBlades, 'y%Cd', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) -call allocAry( y%Cpmin, p%numBladeNodes, p%numBlades, 'y%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%SigmaCavit, p%numBladeNodes, p%numBlades, 'y%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%SigmaCavitCrit, p%numBladeNodes, p%numBlades, 'y%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - - - if (ErrStat >= AbortErrLev) RETURN - - ! outputs documented in AeroDyn - y%Vrel = 0.0_ReKi - y%phi = 0.0_ReKi - y%Cx = 0.0_ReKi - y%Cy = 0.0_ReKi - y%Cm = 0.0_ReKi - - ! others: - y%chi = 0.0_ReKi - y%Re = 0.0_ReKi - y%axInduction = 0.0_ReKi - y%tanInduction = 0.0_ReKi - y%AOA = 0.0_ReKi - y%Cl = 0.0_ReKi - y%Cd = 0.0_ReKi - y%Cpmin = 0.0_ReKi - y%SigmaCavit = 0.0_ReKi - y%SigmaCavitCrit = 0.0_ReKi - -end subroutine BEMT_AllocOutput - - - -subroutine BEMT_MapOutputs(p, OtherState, y, errStat, errMsg) - - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - type(BEMT_OtherStateType), intent(in ) :: OtherState ! other states - type(BEMT_OutputType), intent(inout) :: y ! system outputs - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - ErrStat = ErrID_None - ErrMsg = "" - -end subroutine BEMT_MapOutputs - - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Interval, InitOut, ErrStat, ErrMsg ) -! This routine is called at the start of the simulation to perform initialization steps. -! The parameters are set here and not changed during the simulation. -! The initial states and initial guess for the input are defined. -!.................................................................................................................................. - - type(BEMT_InitInputType), intent(inout) :: InitInp ! Input data for initialization routine, needs to be inout because there is a copy of some data in InitInp in BEMT_SetParameters() - type(BEMT_InputType), intent( out) :: u ! An initial guess for the input; input mesh must be defined - type(BEMT_ParameterType), intent( out) :: p ! Parameters - type(BEMT_ContinuousStateType), intent( out) :: x ! Initial continuous states - type(BEMT_DiscreteStateType), intent( out) :: xd ! Initial discrete states - type(BEMT_ConstraintStateType), intent( out) :: z ! Initial guess of the constraint states - type(BEMT_OtherStateType), intent( out) :: OtherState ! Initial other states - type(BEMT_MiscVarType), intent( out) :: misc ! Initial misc/optimization variables - type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data - type(BEMT_OutputType), intent( out) :: y ! Initial system outputs (outputs are not calculated; - ! only the output mesh is initialized) - real(DbKi), intent(inout) :: interval ! Coupling interval in seconds: the rate that - ! (1) BEMT_UpdateStates() is called in loose coupling & - ! (2) BEMT_UpdateDiscState() is called in tight coupling. - ! Input is the suggested time from the glue code; - ! Output is the actual coupling interval that will be used - ! by the glue code. - type(BEMT_InitOutputType), intent( out) :: InitOut ! Output for initialization routine - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables - character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_Init' - type(UA_InputType) :: u_UA - type(UA_InitInputType) :: Init_UA_Data - type(UA_InitOutputType) :: InitOutData_UA - integer(IntKi) :: i,j - real(ReKi) :: Cn1 ! critical value of Cn_prime at LE separation for alpha >= alpha0 - real(ReKi) :: Cn2 ! critical value of Cn_prime at LE separation for alpha < alpha0 - real(ReKi) :: Cd0 - real(ReKi) :: Cm0 - real(ReKi) :: k0 - real(ReKi) :: k1 - real(ReKi) :: k2 - real(ReKi) :: k3 - real(ReKi) :: T_VL - real(ReKi) :: x_cp_bar - real(ReKi) :: alpha0 ! zero lift angle of attack (radians) - real(ReKi) :: eta_e - real(ReKi) :: St_sh - real(ReKi) :: Re - real(ReKi) :: alpha - - real(ReKi) :: M, alpha1, alpha2, C_nalpha, C_nalpha_circ, T_f0, T_V0, T_p, b1,b2,b5,A1,A2,A5,S1,S2,S3,S4,k1_hat - real(ReKi) :: filtCutOff ! airfoil parameter for the low-pass cut-off frequency for pitching rate and accelerations (Hz) - character(64) :: chanPrefix - ! Initialize variables for this routine - errStat = ErrID_None - errMsg = "" - - - ! Initialize the NWTC Subroutine Library - call NWTC_Init( EchoLibVer=.FALSE. ) - - ! Display the module information - call DispNVD( BEMT_Ver ) - - - - - !............................................................................................ - ! Define parameters here - !............................................................................................ - - call BEMT_SetParameters( InitInp, p, errStat, errMsg ) - if (errStat >= AbortErrLev) return - p%DT = interval - !............................................................................................ - ! Define states here - !............................................................................................ - - ! We need to set an other state version so that we can change this during execution if the AOA is too large! - allocate ( OtherState%UA_Flag( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) - if ( errStat2 /= 0 ) then - errStat2 = ErrID_Fatal - errMsg2 = 'Error allocating memory for OtherState%UA_Flag.' - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - return - end if - OtherState%UA_Flag = p%UA_Flag - - ! initialize the constraint states - call BEMT_InitContraintStates( z, p, errStat2, errMsg2 ) ! initialize the continuous states - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return - - x%DummyContState = 0.0_SiKi - - ! Initialize other states - call BEMT_InitOtherStates( OtherState, p, errStat, errMsg ) ! initialize the other states - if (errStat >= AbortErrLev) return - - if ( p%UA_Flag ) then - call BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) then - call cleanup() - return - end if - - - call UA_Init( Init_UA_Data, u_UA, p%UA, xd%UA, OtherState%UA, misc%y_UA, misc%UA, interval, InitOutData_UA, errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) then - call cleanup() - return - end if - -#ifdef UA_OUTS - !CALL GetNewUnit( UnUAOuts, ErrStat, ErrMsg ) - !IF ( ErrStat /= ErrID_None ) RETURN - - CALL OpenFOutFile ( 69, 'Debug.UA.out', errStat, errMsg ) - IF (ErrStat >= AbortErrLev) RETURN - - - ! Heading: - WRITE (69,'(/,A)') 'This output information was generated by '//TRIM( GetNVD(BEMT_Ver) )// & - ' on '//CurDate()//' at '//CurTime()//'.' - WRITE (69,'(:,A11)', ADVANCE='no' ) 'Time ' - do j = 1, p%numBlades - do i = 1, p%numBladeNodes - chanPrefix = "B"//trim(num2lstr(j))//"N"//trim(num2lstr(i)) - WRITE (69,'(:,A11)', ADVANCE='no' ) 'ALPHA'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'VREL'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CN'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CC'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CL'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CD'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CM'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNCP'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNIQ'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNPOT'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'DPP'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNP'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'FSP'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'DF'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNV'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'TAUV'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'LESF'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'TESF'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'VRTX'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CVN'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CMI'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CMQ'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'CMV'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'AFEP'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'DFAF'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'PMC'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'T_f'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'T_V'//chanPrefix - WRITE (69,'(:,A11)', ADVANCE='no' ) 'dS'//chanPrefix - end do - end do - write (69,'(A)') ' ' - - WRITE (69,'(:,A9)', ADVANCE='no' ) ' (s)' - do j = 1, p%numBlades - do i = 1, p%numBladeNodes - WRITE (69,'(:,A11)', ADVANCE='no' ) '(deg)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(m/s)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' - end do - end do - write (69,'(A)') ' ' - -#endif - - - do j = 1,p%numBlades - do i = 1,p%numBladeNodes ! Loop over blades and nodes - - ! u_UA values were not set in UA_Init, so we will use arbitrary values for M,Re, and alpha, and we need them only because we're trying to determine if C_nalpha is 0 so we can shut off UA. - - M = 0.1_ReKi - Re = 10.0_ReKi - alpha = 2.0*D2R - !M = u_UA%U / p%UA%a_s - !call UA_CheckMachNumber(M, misc%UA%FirstWarn_M, ErrStat2, ErrMsg2 ) - - call AFI_GetAirfoilParams( AFInfo(p%AFindx(i,j)), M, Re, alpha0, alpha1, alpha2, eta_e, C_nalpha, C_nalpha_circ, & - T_f0, T_V0, T_p, T_VL, St_sh, b1, b2, b5, A1, A2, A5, S1, S2, S3, S4, Cn1, Cn2, Cd0, Cm0, k0, k1, k2, k3, k1_hat, x_cp_bar, filtCutOff, errMsg2, errStat2 ) - ! AFI_GetAirfoilParams does not set errors - - if ( EqualRealNos(C_nalpha, 0.0_ReKi) .and. OtherState%UA_Flag(i,j) ) then - OtherState%UA_Flag(i,j) = .false. - call WrScr( 'Warning: Turning off Unsteady Aerodynamics because C_nalpha is 0. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) - end if - - - if ( p%CavitCheck .and. OtherState%UA_Flag(i,j)) then - OtherState%UA_Flag(i,j) = .false. - call SetErrStat( ErrID_Fatal, 'Turn off Unsteady Aerodynamics to do a cavitation check', ErrStat, ErrMsg, RoutineName ) - end if - - - - - call WrScr (' p%InCol_Cpmin='//trim(num2lstr((p%InCol_Cpmin)))) - - - end do - end do - - - end if - !............................................................................................ - ! Define initial guess for the system inputs here: - !............................................................................................ - - ! allocate all the arrays that store data in the input type: - call BEMT_AllocInput( u, p, errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) then - call cleanup() - return - end if - - - - - !............................................................................................ - ! Define system output initializations (set up meshes) here: - !............................................................................................ - !............................................................................................ - ! Define initialization-routine output here: - !............................................................................................ - - !call BEMT_InitOut(p, InitOut, errStat2, errMsg2) - !call CheckError( errStat2, errMsg2 ) - - call BEMT_AllocOutput(y, p, errStat2, errMsg2) !u is sent so we can create sibling meshes - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) then - call cleanup() - return - end if - - - misc%useFrozenWake = .FALSE. - - InitOut%Version = BEMT_Ver - - - - !............................................................................................ - ! If you want to choose your own rate instead of using what the glue code suggests, tell the glue code the rate at which - ! this module must be called here: - !............................................................................................ - - Interval = p%DT - - - ! Print the summary file if requested: - !IF (InputFileData%SumPrint) THEN - ! CALL BEMT_PrintSum( p, OtherState, GetAdamsVals, ErrStat2, ErrMsg2 ) - ! call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - !END IF - - ! Destroy the InputFileData structure (deallocate arrays) - - !CALL BEMT_DestroyInputFile(InputFileData, ErrStat2, ErrMsg2 ) - ! call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - -CONTAINS - !............................................................................................................................... - SUBROUTINE Cleanup() - ! This subroutine cleans up local variables that may have allocatable arrays - !............................................................................................................................... - - call UA_DestroyInput( u_UA, ErrStat2, ErrMsg2 ) - call UA_DestroyInitInput( Init_UA_Data, ErrStat2, ErrMsg2 ) - call UA_DestroyInitOutput( InitOutData_UA, ErrStat2, ErrMsg2 ) - - END SUBROUTINE Cleanup - -END SUBROUTINE BEMT_Init -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_End( u, p, x, xd, z, OtherState, y, ErrStat, ErrMsg ) -! This routine is called at the end of the simulation. -!.................................................................................................................................. - - TYPE(BEMT_InputType), INTENT(INOUT) :: u ! System inputs - TYPE(BEMT_ParameterType), INTENT(INOUT) :: p ! Parameters - TYPE(BEMT_ContinuousStateType), INTENT(INOUT) :: x ! Continuous states - TYPE(BEMT_DiscreteStateType), INTENT(INOUT) :: xd ! Discrete states - TYPE(BEMT_ConstraintStateType), INTENT(INOUT) :: z ! Constraint states - TYPE(BEMT_OtherStateType), INTENT(INOUT) :: OtherState ! Other states - TYPE(BEMT_OutputType), INTENT(INOUT) :: y ! System outputs - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - - ! Place any last minute operations or calculations here: - - - ! Close files here: - - - - ! Destroy the input data: - - CALL BEMT_DestroyInput( u, ErrStat, ErrMsg ) - - - ! Destroy the parameter data: - - CALL BEMT_DestroyParam( p, ErrStat, ErrMsg ) - - - ! Destroy the state data: - - CALL BEMT_DestroyContState( x, ErrStat, ErrMsg ) - CALL BEMT_DestroyDiscState( xd, ErrStat, ErrMsg ) - CALL BEMT_DestroyConstrState( z, ErrStat, ErrMsg ) - CALL BEMT_DestroyOtherState( OtherState, ErrStat, ErrMsg ) - - - ! Destroy the output data: - - CALL BEMT_DestroyOutput( y, ErrStat, ErrMsg ) - -#ifdef UA_OUTS - CLOSE(69) -#endif - - -END SUBROUTINE BEMT_End - - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, errStat, errMsg ) -! Loose coupling routine for solving for constraint states, integrating continuous states, and updating discrete states -! Continuous, constraint, discrete, and other states are updated for t + Interval -! -! NOTE: This is a non-standard framework interface!!!!! GJH -!.................................................................................................................................. - - real(DbKi), intent(in ) :: t ! Current simulation time in seconds - integer(IntKi), intent(in ) :: n ! Current simulation time step n = 0,1,... - type(BEMT_InputType), intent(in ) :: u1,u2 ! Input at t and t+ dt - !real(DbKi), intent(in ) :: utime ! Times associated with u(:), in seconds - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - type(BEMT_ContinuousStateType), intent(inout) :: x ! Input: Continuous states at t; - ! Output: Continuous states at t + Interval - type(BEMT_DiscreteStateType), intent(inout) :: xd ! Input: Discrete states at t; - ! Output: Discrete states at t + Interval - type(BEMT_ConstraintStateType), intent(inout) :: z ! Input: Constraint states at t; - ! Output: Constraint states at t + Interval - type(BEMT_OtherStateType), intent(inout) :: OtherState ! Input: Other states at t; - ! Output: Other states at t + Interval - type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables - type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - integer(IntKi) :: i,j - type(UA_InputType) :: u_UA - real(ReKi) :: chi, axInduction, tanInduction ! BEMT outputs - real(ReKi) :: Rtip, Re, Vrel, fzero, phitemp - logical :: IsValidSolution !< this is set to false if k<=1 in propeller brake region or k<-1 in momentum region, indicating an invalid solution - - character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_UpdateStates' - - character(20) :: NodeTxt - - ErrStat = ErrID_None - ErrMsg = "" - - !............................................................................................................................... - ! if we haven't initialized z%phi, we want to get a better guess as to what the actual values of phi at t are: - !............................................................................................................................... - - if (.not. OtherState%nodesInitialized) then - if (p%useInduction) then - - do j = 1,p%numBlades ! Loop through all blades - do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' - - call BEMT_UnCoupledSolve(z%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u1%rlocal(i,j), p%chord(i,j), u1%theta(i,j), & - u1%Vx(i,j), u1%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & - p%maxIndIterations, p%aTol, OtherState%ValidPhi(i,j), errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return - end do - end do - - else - ! We'll simply compute a geometrical phi based on both induction factors being 0.0 - do j = 1,p%numBlades ! Loop through all blades - do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - z%phi(i,j) = ComputePhiWithInduction(u1%Vx(i,j), u1%Vy(i,j), 0.0_ReKi, 0.0_ReKi) - end do - end do - - end if - OtherState%nodesInitialized = .true. ! state at t+1 - end if - - !............................................................................................................................... - ! compute states at t+1 - !............................................................................................................................... - - - do j = 1,p%numBlades - - ! Locate the maximum rlocal value for this time step and this blade. This is passed to the solve as Rtip - if ( p%useInduction ) then - Rtip = 0.0_ReKi - do i = 1,p%numBladeNodes - Rtip = max( Rtip, u1%rlocal(i,j) ) - end do - end if - - do i = 1,p%numBladeNodes - - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' - - ! We only update the UnsteadyAero states if we have unsteady aero turned on for this node - if (OtherState%UA_Flag(i,j) .and. n > 0) then - - ! Set the active blade element for UnsteadyAero - m%UA%iBladeNode = i - m%UA%iBlade = j - - ! Initialize these variables - u_UA%alpha = z%phi(i,j) - u1%theta(i,j) - axInduction = 0.0_ReKi - tanInduction = 0.0_ReKi - - - if ( p%useInduction ) then - if (OtherState%ValidPhi(i,j)) then - - ! Compute Re based on zero inductions (axInduction, tanInduction), this would needed for the airfoil lookups - ! which occur within BEMTU_InductionWithResidual if we had implemented airfoil tables which are dependent on Reynold's number: Currently unused, 4-Nov-2015 - call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, u1%Vx(i,j), u1%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, Vrel, Re ) - - ! Need to get the induction factors for these conditions without skewed wake correction and without UA - ! COMPUTE: axInduction, tanInduction - fzero = BEMTU_InductionWithResidual(z%phi(i,j), u_UA%alpha, Re, p%numBlades, u1%rlocal(i,j), p%chord(i,j), AFInfo(p%AFIndx(i,j)), & - u1%Vx(i,j), u1%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & - axInduction, tanInduction, IsValidSolution, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return - - ! Apply the skewed wake correction to the axial induction - if ( p%skewWakeMod == SkewMod_PittPeters ) then - if ( .not.( p%useTiploss .and. EqualRealNos(p%tipLossConst(i,j),0.0_ReKi) ) .and. .not. ( p%useHubloss .and. EqualRealNos(p%hubLossConst(i,j),0.0_ReKi) ) ) then - ! Correct for skewed wake, by recomputing axInduction - call ApplySkewedWakeCorrection( u1%Vx(i,j), u1%Vy(i,j), u1%psi(j), u1%chi0, u1%rlocal(i,j)/Rtip, axInduction, tanInduction, chi, ErrStat2, ErrMsg2 ) !replaced phiOut with phitemp RRD - ! ApplySkewedWakeCorrection doesn't produce errors - end if - end if - - ! recompute phi and alpha - - ! we're recomputing phi because we may have modified axInduction or tanInduction in BEMTU_InductionWithResidual and/or ApplySkewedWakeCorrection - phitemp = ComputePhiWithInduction( u1%Vx(i,j), u1%Vy(i,j), axInduction, tanInduction ) - ! angle of attack - u_UA%alpha = phitemp - u1%theta(i,j) - - else - axInduction = 0.0_ReKi - tanInduction = 0.0_ReKi - phitemp = ComputePhiWithInduction( u1%Vx(i,j), u1%Vy(i,j), axInduction, tanInduction ) - ! angle of attack - u_UA%alpha = phitemp - u1%theta(i,j) - - end if - end if - - - ! Need to compute local velocity including both axial and tangential induction - ! COMPUTE: u_UA%U, u_UA%Re - call BEMTU_Wind( axInduction, tanInduction, u1%Vx(i,j), u1%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, u_UA%U, u_UA%Re) !replaced phiOut with phitemp RRD - - if ( abs(u_UA%alpha) >= AFInfo(p%AFIndx(i,j))%Table(1)%UA_BL%UACutout ) then ! Is the angle of attack larger than the UA cut-out for this airfoil? - OtherState%UA_Flag(i,j) = .FALSE. - call WrScr( 'Warning: Turning off Unsteady Aerodynamics due to high angle-of-attack. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) - elseif (EqualRealNos(u_UA%U, 0.0_ReKi) ) then - OtherState%UA_Flag(i,j) = .FALSE. - call WrScr( 'Warning: Turning off Unsteady Aerodynamics due to zero relative velocity. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) - - else - ! COMPUTE: xd%UA, OtherState%UA - call UA_UpdateStates( i, j, u_UA, p%UA, xd%UA, OtherState%UA, AFInfo(p%AFIndx(i,j)), m%UA, errStat2, errMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return - end if - - end if ! if (OtherState%UA_Flag(i,j)) then - - ! Now we need to update the inflow angle state, z%phi, independent of UnsteadyAero - if ( p%useInduction ) then - ! Solve this without any skewed wake correction and without UA - ! call BEMT_UnCoupledSolve2(i, j, u, p, z, Rtip, AFInfo, phiOut, axIndOut, tanIndOut, errStat, errMsg) - ! COMPUTE: z%phi(i,j) - call BEMT_UnCoupledSolve(z%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u2%rlocal(i,j), p%chord(i,j), u2%theta(i,j), & - u2%Vx(i,j), u2%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & - p%maxIndIterations, p%aTol, OtherState%ValidPhi(i,j), errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return - - else - ! We'll simply compute a geometrical phi based on both induction factors being 0.0 - z%phi(i,j) = ComputePhiWithInduction(u2%Vx(i,j), u2%Vy(i,j), 0.0_ReKi, 0.0_ReKi) - end if - - end do - end do - -end subroutine BEMT_UpdateStates - - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat, errMsg ) -! 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. -! NOTE: the descriptions of the output channels are not given here. Please see the included OutListParameters.xlsx sheet for -! for a complete description of each output parameter. -! NOTE: no matter how many channels are selected for output, all of the outputs are calcalated -! All of the calculated output channels are placed into the OtherState%AllOuts(:), while the channels selected for outputs are -! placed in the y%WriteOutput(:) array. -!.................................................................................................................................. - - - real(DbKi), intent(in ) :: t ! Current simulation time in seconds - type(BEMT_InputType), intent(in ) :: u ! Inputs at Time t - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - type(BEMT_ContinuousStateType), intent(in ) :: x ! Continuous states at t - type(BEMT_DiscreteStateType), intent(in ) :: xd ! Discrete states at t - type(BEMT_ConstraintStateType), intent(in ) :: z ! Constraint states at t - type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other states at t - type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables - type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data - type(BEMT_OutputType), intent(inout) :: y ! Outputs computed at t (Input only so that mesh con- - ! nectivity information does not have to be recalculated) - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables: - - - real(ReKi) :: Re, fzero, theta, Vx, Vy - real(ReKi) :: Rtip, SigmaCavitCrit, SigmaCavit ! maximum rlocal value for node j over all blades - - integer(IntKi) :: i ! Generic index - integer(IntKi) :: j ! Loops through nodes / elements - - character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_CalcOutput' - - character(20) :: NodeTxt - - -#ifdef UA_OUTS - integer(IntKi) :: k -#endif - - logical, parameter :: UpdateValues = .TRUE. ! determines if the OtherState values need to be updated - type(BEMT_ContinuousStateType) :: dxdt ! Continuous state derivs at t - real(ReKi) :: Vrel - logical :: IsValidSolution !< this is set to false if k<=1 in propeller brake region or k<-1 in momentum region, indicating an invalid solution - ! Initialize some output values - errStat = ErrID_None - errMsg = "" - - - !............................................................................................................................... - ! if we haven't initialized z%phi, we want to get a better guess as to what the actual values of phi are: - !............................................................................................................................... - - if (OtherState%nodesInitialized) then - y%phi = z%phi - else - if (p%useInduction) then - - do j = 1,p%numBlades ! Loop through all blades - do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' - - y%phi(i,j) = z%phi(i,j) - call BEMT_UnCoupledSolve(y%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u%rlocal(i,j), p%chord(i,j), u%theta(i,j), & - u%Vx(i,j), u%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & - p%maxIndIterations, p%aTol, IsValidSolution, errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return - end do - end do - - else - ! We'll simply compute a geometrical phi based on both induction factors being 0.0 - do j = 1,p%numBlades ! Loop through all blades - do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - y%phi(i,j) = ComputePhiWithInduction(u%Vx(i,j), u%Vy(i,j), 0.0_ReKi, 0.0_ReKi) - end do - end do - - end if - end if - - ! Array OtherState%AllOuts() is initialized to 0.0 in initialization, so we are not going to reinitialize it here. - - - !............................................................................................................................... - ! Calculate all of the total forces and moments using all of the partial forces and moments calculated in RtHS(). Also, - ! calculate all of the total angular and linear accelerations using all of the partial accelerations calculated in RtHS(). - ! To do this, first initialize the variables using the portions not associated with the accelerations. Then add the portions - ! associated with the accelerations one by one: - !............................................................................................................................... - - do j = 1,p%numBlades ! Loop through all blades - - ! Locate the maximum rlocal value for this time step and this blade. This is passed to the solve as Rtip - Rtip = 0.0_ReKi - do i = 1,p%numBladeNodes - Rtip = max( Rtip, u%rlocal(i,j) ) - end do - - do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements - - NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' - - ! local velocities and twist angle - Vx = u%Vx(i,j) - Vy = u%Vy(i,j) - !theta = u%theta(i,j) - - - - ! Set the active blade element for UnsteadyAero - m%UA%iBladeNode = i - m%UA%iBlade = j - - ! Copy the current state to the outputs structure - !y%phi(i,j) = z%phi(i,j) ! this was done above (to take possible initializion into account) - ! angle of attack - y%AOA(i,j) = y%phi(i,j) - u%theta(i,j) - - ! initialize other outputs assuming no induction or skewed wake corrections - y%axInduction(i,j) = 0.0_ReKi - y%tanInduction(i,j) = 0.0_ReKi - y%chi(i,j) = u%chi0 ! with no induction, chi = chi0 - - if ( p%useInduction ) then - - if (m%UseFrozenWake) then - y%axInduction(i,j) = -m%AxInd_op(i,j) / u%Vx(i,j) - y%tanInduction(i,j) = m%TnInd_op(i,j) / u%Vy(i,j) - y%phi(i,j) = ComputePhiWithInduction( u%Vx(i,j), u%Vy(i,j), y%axInduction(i,j), y%tanInduction(i,j) ) - y%AOA(i,j) = y%phi(i,j) - u%theta(i,j) - else - if (OtherState%ValidPhi(i,j)) then - ! Compute Re based on zero inductions (axInduction, tanInduction), this would needed for the airfoil lookups - ! which occur within BEMTU_InductionWithResidual if we had implemented airfoil tables which are dependent on Reynold's number: Currently unused, 4-Nov-2015 - call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, Vrel, Re ) - - ! Compute inductions using steady aero. NOTE: When we use Re, we are using uninduced Re for Steady Airfoil Coef looks here - fzero = BEMTU_InductionWithResidual(y%phi(i,j), y%AOA(i,j), Re, p%numBlades, u%rlocal(i,j), p%chord(i,j), AFInfo(p%AFindx(i,j)), & - u%Vx(i,j), u%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & - y%axInduction(i,j), y%tanInduction(i,j), IsValidSolution, errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return - - ! Apply the skewed wake correction to the axial induction (y%axInduction) - if ( p%skewWakeMod == SkewMod_PittPeters ) then - if ( .not.( p%useTiploss .and. EqualRealNos(p%tipLossConst(i,j),0.0_ReKi) ) .and. .not. ( p%useHubloss .and. EqualRealNos(p%hubLossConst(i,j),0.0_ReKi) ) ) then - call ApplySkewedWakeCorrection( u%Vx(i,j), u%Vy(i,j), u%psi(j), u%chi0, u%rlocal(i,j)/Rtip, y%axInduction(i,j), y%tanInduction(i,j), y%chi(i,j), ErrStat2, ErrMsg2 ) - ! ApplySkewedWakeCorrection doesn't set errors - end if - end if - - ! recompute y%phi, y%AOA: - ! we're recomputing phi because we may have modified axInduction or tanInduction in BEMTU_InductionWithResidual and/or ApplySkewedWakeCorrection - y%phi(i,j) = ComputePhiWithInduction( u%Vx(i,j), u%Vy(i,j), y%axInduction(i,j), y%tanInduction(i,j) ) - ! angle of attack - y%AOA(i,j) = y%phi(i,j) - u%theta(i,j) - end if ! ValidPhi - - end if ! UseFrozenWake - - end if - - ! Compute Re, Vrel based on current values of axInduction, tanInduction - call BEMTU_Wind( y%axInduction(i,j), y%tanInduction(i,j), u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, y%Vrel(I,J), y%Re(i,j) ) - - ! Now depending on the option for UA get the airfoil coefs, Cl, Cd, Cm for unsteady or steady implementation - if (OtherState%UA_Flag(i,j) .and. t > 0.0_DbKi) then - call Compute_UA_AirfoilCoefs( y%AOA(i,j), y%Vrel(I,J), y%Re(i,j), AFInfo(p%AFindx(i,j)), p%UA, xd%UA, OtherState%UA, m%y_UA, m%UA, & - y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), errStat2, errMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return - - ! NOTE: In this version, we are disabling the UA Cm values only we have performed further validation. GJH 3/9/2016 - ! Obtain the steady state Cm value from the static tables - !call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & - ! localCl, localCd, y%Cm(i,j), errStat2, errMsg2 ) - ! call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - ! if (errStat >= AbortErrLev) return - - else - ! TODO: When we start using Re, should we use the uninduced Re since we used uninduced Re to solve for the inductions!? Probably this won't change, instead create a Re loop up above. - call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & - y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), y%Cpmin(i,j), errStat2, errMsg2 ) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) - if (errStat >= AbortErrLev) return - - - - - if ( p%CavitCheck .and. y%Cpmin(i,j)==0) then - call SetErrStat( ErrID_Fatal, 'No Cpmin data for cavitation check', ErrStat, ErrMsg, RoutineName ) - end if - - - if ( p%CavitCheck ) then ! This calculates the cavitation number for the airfoil at the node in quesiton, and compares to the critical cavitation number based on the vapour pressure and submerged depth - - SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this - SigmaCavit= -1* y%Cpmin(i,j) ! Actual cavitation number on blade node j - - - if (SigmaCavitCrit < SigmaCavit) then - call WrScr( NewLine//'FAILED CAVITATION CHECK'//' Node # = '//trim(num2lstr(i)//'Blade # = '//trim(num2lstr(j)))) - - end if - - if (y%Vrel(i,j) == 0) then !if Vrel = 0 in certain cases when Prandtls tip and hub loss factors are used, use the relative verlocity without induction - SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * (sqrt((Vx**2 + Vy**2)))**2) ! Critical value of Sigma, cavitation if we go over this - - end if - - y%SigmaCavit(i,j)= SigmaCavit - y%SigmaCavitCrit(i,j)=SigmaCavitCrit - - end if - - - end if - - - ! Compute Cx, Cy given Cl, Cd and phi - ! NOTE: For these calculations we force the useAIDrag and useTIDrag flags to .TRUE. - call Transform_ClCd_to_CxCy( y%phi(i,j), .TRUE., .TRUE., y%Cl(i,j), y%Cd(i,j),y%Cx(i,j), y%Cy(i,j) ) - - enddo ! I - Blade nodes / elements - - enddo ! J - All blades - -#ifdef UA_OUTS - ! if ( mod(REAL(t,ReKi),.1) < p%dt) then - WRITE (69, '(F9.4,'//trim(num2lstr(p%numBladeNodes*p%numBlades*p%UA%NumOuts))//'(:,A,ES12.3E3))') t, (' ', m%y_UA%WriteOutput(k), k=1,p%UA%NumOuts*p%numBladeNodes*p%numBlades) - ! end if - !WRITE (69, '((F8.3,'//TRIM(num2lstr(13*p%numBladeNodes*p%numBlades))//'(:,A,ES10.3E2))') - !Frmt = '(F8.3,'//TRIM(Int2LStr(p%WAMIT%NumOuts+p%Morison%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' - !Frmt = '('ES10.3E2,'//TRIM(13*p%numBladeNodes*p%numBlades)//'(:,A,'ES10.3E2'))' - - -#endif - - !............................................................................................................................... - ! Place the selected output channels into the WriteOutput(:) array with the proper sign: - !............................................................................................................................... - - call BEMT_MapOutputs(p, OtherState, y, errStat2, errMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (errStat >= AbortErrLev) return - - !DO I = 1,p%NumOuts ! Loop through all selected output channels - ! - ! y%WriteOutput(I) = p%OutParam(I)%SignM * OtherState%AllOuts( p%OutParam(I)%Indx ) - ! - !ENDDO ! I - All selected output channels - - - !............................................................................................................................... - ! Outputs required for AeroDyn - !............................................................................................................................... - - !........... - ! Blade elements: - !........... - - - return - - -end subroutine BEMT_CalcOutput - - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrStat, ErrMsg ) -! Tight coupling routine for computing derivatives of continuous states -!.................................................................................................................................. - - REAL(DbKi), INTENT(IN ) :: t ! Current simulation time in seconds - TYPE(BEMT_InputType), INTENT(IN ) :: u ! Inputs at t - TYPE(BEMT_ParameterType), INTENT(IN ) :: p ! Parameters - TYPE(BEMT_ContinuousStateType), INTENT(IN ) :: x ! Continuous states at t - TYPE(BEMT_DiscreteStateType), INTENT(IN ) :: xd ! Discrete states at t - TYPE(BEMT_ConstraintStateType), INTENT(IN ) :: z ! Constraint states at t - TYPE(BEMT_OtherStateType), INTENT(IN ) :: OtherState ! Other states at t - type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables - TYPE(BEMT_ContinuousStateType), INTENT( OUT) :: dxdt ! Continuous state derivatives at t - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - dxdt%DummyContState = 0.0_ReKi - - -END SUBROUTINE BEMT_CalcContStateDeriv -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_UpdateDiscState( t, n, u, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) -! Tight coupling routine for updating discrete states -!.................................................................................................................................. - - REAL(DbKi), INTENT(IN ) :: t ! Current simulation time in seconds - INTEGER(IntKi), INTENT(IN ) :: n ! Current step of the simulation: t = n*Interval - TYPE(BEMT_InputType), INTENT(IN ) :: u ! Inputs at t - TYPE(BEMT_ParameterType), INTENT(IN ) :: p ! Parameters - TYPE(BEMT_ContinuousStateType), INTENT(IN ) :: x ! Continuous states at t - TYPE(BEMT_DiscreteStateType), INTENT(INOUT) :: xd ! Input: Discrete states at t; - ! Output: Discrete states at t + Interval - TYPE(BEMT_ConstraintStateType), INTENT(IN ) :: z ! Constraint states at t - TYPE(BEMT_OtherStateType), INTENT(IN ) :: OtherState ! Other states at t - type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables - INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation - CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - - ! Initialize ErrStat - - ErrStat = ErrID_None - ErrMsg = "" - - - ! Update discrete states here: - - ! StateData%DiscState = - -END SUBROUTINE BEMT_UpdateDiscState -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_CalcConstrStateResidual( Time, u, p, x, xd, z, OtherState, m, z_residual, AFInfo, ErrStat, ErrMsg ) -! Tight coupling routine for solving for the residual of the constraint state equations -!.................................................................................................................................. - - real(DbKi), intent(in ) :: Time ! Current simulation time in seconds - type(BEMT_InputType), intent(in ) :: u ! Inputs at Time - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - type(BEMT_ContinuousStateType), intent(in ) :: x ! Continuous states at Time - type(BEMT_DiscreteStateType), intent(in ) :: xd ! Discrete states at Time - type(BEMT_ConstraintStateType), intent(in ) :: z ! Constraint states at Time (possibly a guess) - type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other states at Time - type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables - type(BEMT_ConstraintStateType), intent(inout) :: z_residual ! Residual of the constraint state equations using - ! the input values described above - type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data - integer(IntKi), intent( out) :: ErrStat ! Error status of the operation - character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None +module BEMTUnCoupled + + use NWTC_Library + use AirfoilInfo_Types + use UnsteadyAero + use UnsteadyAero_Types - !# set epsilon - !REAL(ReKi), PARAMETER ::epsilon = 1e-6 + implicit none - ! Local variables - INTEGER :: i,j - real(ReKi) axInduction, tanInduction, Vrel, Re - character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_CalcConstrStateResidual' - logical :: IsValidSolution ! placeholder for flag to determine if the residual solution is invalid - + integer(IntKi), public, parameter :: SkewMod_Uncoupled = 1 ! Uncoupled (no correction) [-] + integer(IntKi), public, parameter :: SkewMod_PittPeters = 2 ! Pitt/Peters [-] + integer(IntKi), public, parameter :: SkewMod_Coupled = 3 ! Coupled [-] - ErrStat = ErrID_None - ErrMsg = "" + !1e-6 works for double precision, but not single precision + real(ReKi), public, parameter :: BEMT_epsilon2 = 10.0_ReKi*sqrt(epsilon(1.0_ReKi)) !this is the tolerance in radians for values around singularities in phi (i.e., phi=0 and phi=pi/2); must be large enough so that EqualRealNos(BEMT_epsilon2, 0.0_ReKi) is false - if (p%useInduction) then - - if ( m%UseFrozenWake ) then ! we are linearizing with frozen wake assumption; i.e., p%FrozenWake is true and this was called from the linearization routine - do j = 1,p%numBlades - do i = 1,p%numBladeNodes - Z_residual%phi(i,j) = sin(z%phi(i,j)) * (u%Vy(i,j) + m%TnInd_op(i,j)) - cos(z%phi(i,j)) * (u%Vx(i,j) + m%AxInd_op(i,j)) - end do - end do - - else - - do j = 1,p%numBlades - do i = 1,p%numBladeNodes - - ! Need to initialize the inductions to zero for this calculation (NOTE: They are actually computed within UnCpldReFn(), but still need to be intialized to zero!) - axInduction = 0.0_ReKi - tanInduction = 0.0_ReKi - - ! Need to call BEMTU_Wind to obtain Re, even though we aren't using it in this version. - call BEMTU_Wind( axInduction, tanInduction, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, Vrel, Re ) - - ! Solve for the constraint states here: - Z_residual%phi(i,j) = UncoupledErrFn(z%phi(i,j), u%theta(i,j), Re, p%numBlades, u%rlocal(i,j), p%chord(i,j), AFInfo(p%AFindx(i,j)), & - u%Vx(i,j), u%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & - IsValidSolution, ErrStat2, ErrMsg2) - call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - if (ErrStat >= AbortErrLev) return - - end do - end do - - end if ! not frozen wake - - else - - do j = 1,p%numBlades - do i = 1,p%numBladeNodes - Z_residual%Phi(i,j) = sin(z%phi(i,j)) * u%Vy(i,j) - cos(z%phi(i,j)) * u%Vx(i,j) - end do - end do - - - end if + private + public :: Compute_UA_AirfoilCoefs + public :: ComputeSteadyAirfoilCoefs + public :: UncoupledErrFn + public :: BEMTU_InductionWithResidual + public :: ApplySkewedWakeCorrection + public :: Transform_ClCd_to_CxCy -END SUBROUTINE BEMT_CalcConstrStateResidual - -!---------------------------------------------------------------------------------------------------------------------------------- -!> This subroutine computes the BEMT inductions that are frozen when linearizing with the FrozenWake flag. -!> It first calls BEMT_CalcOutput to compute y%tanInduction and y%axInduction at this operating point. -!SUBROUTINE computeFrozenWake( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat, errMsg ) -SUBROUTINE computeFrozenWake( u, p, y, m ) -!.................................................................................................................................. - + public :: BEMTU_Wind + public :: VelocityIsZero +contains - !real(DbKi), intent(in ) :: t ! Current simulation time in seconds - type(BEMT_InputType), intent(in ) :: u ! Inputs at Time t - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - !type(BEMT_ContinuousStateType), intent(in ) :: x ! Continuous states at t - !type(BEMT_DiscreteStateType), intent(in ) :: xd ! Discrete states at t - !type(BEMT_ConstraintStateType), intent(in ) :: z ! Constraint states at t - !type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other states at t - type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables - !type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data - type(BEMT_OutputType), intent(inout) :: y ! Outputs computed at t (Input only so that mesh con- - ! nectivity information does not have to be recalculated) - !integer(IntKi), intent( out) :: errStat ! Error status of the operation - !character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None +!.................................................................................................................................. + function VelocityIsZero ( v ) + ! passed variables - ! local variables - INTEGER(IntKi) :: j,k ! loop counters - character(*), parameter :: RoutineName = 'computeFrozenWake' - - ! get a and aprime - !call BEMT_CalcOutput(t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat, errMsg) - - do k = 1,p%numBlades - do j = 1,p%numBladeNodes - - m%AxInd_op(j,k) = - u%Vx(j,k) * y%axInduction( j,k) - m%TnInd_op(j,k) = u%Vy(j,k) * y%tanInduction(j,k) - - end do - end do - - - -END SUBROUTINE computeFrozenWake -!---------------------------------------------------------------------------------------------------------------------------------- -!> This subroutine checks for BEMT inputs that are invalid when linearizing constraint state equations. -SUBROUTINE CheckLinearizationInput(p, u, z, m, OtherState, ErrStat, ErrMsg) + REAL(ReKi), INTENT(IN ) :: v !< the velocity that needs to be compared with zero - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - type(BEMT_InputType), intent(in ) :: u ! Inputs at the operating point - type(BEMT_ConstraintStateType), intent(in ) :: z ! Constraint states at the operating point - type(BEMT_MiscVarType), intent(in ) :: m ! Misc/optimization variables - type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other state at the operating point - integer(IntKi), intent( out) :: ErrStat ! Error status of the operation - character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + LOGICAL :: VelocityIsZero !< .true. if and only if the velocity is (almost) equal to zero - ! local variables - INTEGER(IntKi) :: j,k ! loop counters - character(*), parameter :: RoutineName = 'CheckLinearizationInput' + + VelocityIsZero = abs(v) < 0.001_ReKi ! tolerance in m/s for what we consider zero velocity for BEM computations - ErrStat = ErrID_None - ErrMsg = '' + end function VelocityIsZero +!.................................................................................................................................. - if (p%UseInduction) then - - do k = 1,p%numBlades - do j = 1,p%numBladeNodes - if (.not. OtherState%ValidPhi(j,k)) then - call SetErrSTat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& - ": Current operating point does not contain a valid value of phi.",ErrStat,ErrMsg,RoutineName) - return - end if - - end do - end do - - - - if ( m%UseFrozenWake ) then ! we are linearizing with frozen wake assumption (i.e., p%FrozenWake is true and this is called from linearization routine) - - do k = 1,p%numBlades - do j = 1,p%numBladeNodes - - if ( VelocityIsZero( u%Vy(j,k)+m%TnInd_op(j,k)) .and. VelocityIsZero( u%Vx(j,k)+m%AxInd_op(j,k) ) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& - ": residual is undefined because u%Vy + TnInd_op = u%Vx + AxInd_op = 0.",ErrStat,ErrMsg,RoutineName) - return - end if - - end do - end do - - else - - do k = 1,p%numBlades - do j = 1,p%numBladeNodes - - if ( EqualRealNos(z%phi(j,k), 0.0_ReKi) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& - ": residual is discontinuous or undefined because z%phi = 0.",ErrStat,ErrMsg,RoutineName) - return - else if ( VelocityIsZero(u%Vy(j,k)) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& - ": residual is discontinuous or undefined because u%Vy = 0.",ErrStat,ErrMsg,RoutineName) - return - else if ( VelocityIsZero(u%Vx(j,k)) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& - ": residual is discontinuous or undefined because u%Vx = 0.",ErrStat,ErrMsg,RoutineName) - return - end if - - end do - end do - - end if - - - - else ! .not. p%UseInduction: - - do k = 1,p%numBlades - do j = 1,p%numBladeNodes - - if ( EqualRealNos( u%Vy(j,k), 0.0_ReKi ) .and. EqualRealNos( u%Vx(j,k), 0.0_ReKi ) ) then - call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& - ": residual is undefined because u%Vy = u%Vx = 0.",ErrStat,ErrMsg,RoutineName) - return - end if - - end do - end do - + subroutine BEMTU_Wind( axInduction, tanInduction, Vx, Vy, chord, airDens, mu, W, Re ) - - end if - -END SUBROUTINE CheckLinearizationInput -!---------------------------------------------------------------------------------------------------------------------------------- -!> This gets the constraint-state perturbations for linearization about a given operating point. This returns two deltas (one plus -!! and one minus) such that z_op+dz_p and z_op-dz_m are in the same solution region (or that they are in adjacent regions that have -!! continuous solution regions [i.e, the pi/2 boundary is okay because it is continuous across the momentum/empirical regions]). -SUBROUTINE Get_phi_perturbations(p, m, z_op, dz_p, dz_m) + + ! in + real(ReKi), intent(in) :: axInduction, tanInduction, Vx, Vy + real(ReKi), intent(in) :: chord, airDens, mu - type(BEMT_ParameterType), intent(in ) :: p ! Parameters - type(BEMT_MiscVarType), intent(in ) :: m ! Misc/optimization variables + ! out + real(ReKi), intent(out) :: Re, W + + + - REAL(ReKi), intent(in ) :: z_op !< value of z%phi(i,j) at the operating point - REAL(ReKi), intent( out) :: dz_p !< change in z_op in the plus direction - REAL(ReKi), intent( out) :: dz_m !< change in z_op in the minus direction + ! avoid numerical errors when angle is close to 0 or 90 deg + ! and other induction factor is at some ridiculous value + ! this only occurs when iterating on Reynolds number + ! during the phi sweep where a solution has not been found yet + !if ( abs(axInduction) > 10 ) then + ! W = Vy*(1+tanInduction)/cos(phi) + !else if ( abs(tanInduction) > 10 ) then + ! W = Vx*(1-axInduction)/sin(phi) + !else + W = sqrt((Vx*(1-axInduction))**2 + (Vy*(1+tanInduction))**2) + !end if + + Re = airDens * W * chord / mu + if ( EqualRealNos(Re, 0.0_ReKi) ) Re = 0.001 ! Do this to avoid a singularity when we take log(Re) in the airfoil lookup. + + end subroutine BEMTU_Wind + +subroutine Transform_ClCd_to_CxCy( phi, useAIDrag, useTIDrag, Cl, Cd, Cx, Cy ) + real(ReKi), intent(in ) :: phi + logical, intent(in ) :: useAIDrag + logical, intent(in ) :: useTIDrag + real(ReKi), intent(in ) :: Cl + real(ReKi), intent(in ) :: Cd + real(ReKi), intent( out) :: Cx + real(ReKi), intent( out) :: Cy - ! local variables - real(ReKi) :: dz ! size of perturbation - real(ReKi) :: zp ! z_op+dz - real(ReKi) :: zm ! z_op-dz + real(ReKi) cphi, sphi + cphi = cos(phi) + sphi = sin(phi) - dz = 2*D2R - - ! we'll assume a central difference unless we are on the boundaries below [default] - dz_p = dz - dz_m = dz - - - if (p%UseInduction .and. .not. m%UseFrozenWake) then + ! resolve into normal (x) and tangential (y) forces + if ( useAIDrag ) then + Cx = Cl*cphi + Cd*sphi + else + Cx = Cl*cphi + end if + + if ( useTIDrag ) then + Cy = Cl*sphi - Cd*cphi + else + Cy = Cl*sphi + end if - zp = z_op+dz - zm = z_op-dz +end subroutine Transform_ClCd_to_CxCy + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & + Cl, Cd, Cm, Cpmin, errStat, errMsg ) +! This routine is called from BEMTU_InductionWithResidual and possibly BEMT_CalcOutput. +! Determine the Cl, Cd, Cm, coeficients for a given angle of attack +!.................................................................................................................................. + real(ReKi), intent(in ) :: AOA + real(ReKi), intent(in ) :: Re ! Unused in the current version! + type(AFInfoType), intent(in ) :: AFInfo + real(ReKi), intent( out) :: Cl, Cd, Cm, Cpmin + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - ! check if it goes past the pi-eps upper boundary - if ( zp > pi - BEMT_epsilon2 ) then - ! 1-sided difference - dz_p = 0 - dz_m = dz + + real :: IntAFCoefs(4) ! The interpolated airfoil coefficients. + real(reki) :: Alpha + integer :: s1 - ! next we care about the -pi/4-eps boundary: - else if ( zm < -pi/4 - BEMT_epsilon2) then - ! 1-sided difference - dz_p = dz - dz_m = 0 + ErrStat = ErrID_None + ErrMsg = '' + IntAFCoefs = 0.0_ReKi ! initialize in case we only don't have 4 columns in the airfoil data (i.e., so cm is zero if not in the file) - ! next let's check the +eps boundaries: - else if ( z_op > 0.0_ReKi .and. zm < BEMT_epsilon2 ) then - ! 1-sided difference - dz_p = dz - dz_m = 0 - ! next let's check the -eps boundaries: - else if ( z_op < 0.0_ReKi .and. zp > -BEMT_epsilon2 ) then - ! 1-sided difference - dz_p = 0 - dz_m = dz + - ! else ! we don't care about the pi/2 boundary, so let's do a central difference for everything else - end if - end if - + ! NOTE: we use Table(1) because the right now we can only interpolate with AOA and not Re or other variables. If we had multiple tables stored + ! for changes in other variables (Re, Mach #, etc) then then we would need to interpolate across tables. + ! + s1 = size(AFInfo%Table(1)%Coefs,2) -END SUBROUTINE Get_phi_perturbations -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine GetSolveRegionOrdering(Vx, phiIn, test_lower, test_upper) - real(ReKi), intent(in ) :: Vx - real(ReKi), intent(in ) :: phiIn - real(ReKi), intent( out) :: test_lower(3) - real(ReKi), intent( out) :: test_upper(3) - - - if (Vx > 0) then + Alpha = AOA + call MPi2Pi ( Alpha ) ! change AOA into range of -pi to pi + IntAFCoefs(1:s1) = CubicSplineInterpM( Alpha & + , AFInfo%Table(1)%Alpha & + , AFInfo%Table(1)%Coefs & + , AFInfo%Table(1)%SplineCoefs & + , ErrStat, ErrMsg ) - test_lower(1) = BEMT_epsilon2 - test_upper(1) = PiBy2 - BEMT_epsilon2 + + Cl = IntAFCoefs(1) + Cd = IntAFCoefs(2) - if (phiIn < pi/4.0_ReKi .and. phiIn > -pi/4.0_ReKi) then !bjj: added the negative for those cases where the previously calculated non-BEMT phi is in the [-pi,-pi/4] range - test_lower(2) = -pi/4.0_ReKi - test_upper(2) = -BEMT_epsilon2 - - test_lower(3) = PiBy2 + BEMT_epsilon2 - test_upper(3) = pi - BEMT_epsilon2 - else - test_lower(3) = -pi/4.0_ReKi - test_upper(3) = -BEMT_epsilon2 - - test_lower(2) = PiBy2 + BEMT_epsilon2 - test_upper(2) = pi - BEMT_epsilon2 - end if + + IF ( AFInfo%InCol_Cm > 0 ) THEN ! If there is Cm data, it is in column 3 + Cm = IntAFCoefs(3) + + IF ( AFInfo%InCol_Cpmin > 0 ) THEN + Cpmin = IntAFCoefs(4) + END IF + + ELSE IF ( AFInfo%InCol_Cpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 + Cpmin = IntAFCoefs(3) + END IF + - else + + + - test_lower(1) = -BEMT_epsilon2 - test_upper(1) = -PiBy2 + BEMT_epsilon2 + +end subroutine ComputeSteadyAirfoilCoefs + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine Compute_UA_AirfoilCoefs( AOA, U, Re, AFInfo, & + p_UA, xd_UA, OtherState_UA, y_UA, m_UA, & + Cl, Cd, Cm, errStat, errMsg ) +! This routine is called from BEMTU_InductionWithResidual and possibly BEMT_CalcOutput. +! Determine the Cl, Cd, Cm coeficients for a given angle of attack +!.................................................................................................................................. + real(ReKi), intent(in ) :: AOA + real(ReKi), intent(in ) :: U + real(ReKi), intent(in ) :: Re ! Unused in the current version! + type(AFInfoType), intent(in ) :: AFInfo + type(UA_ParameterType), intent(in ) :: p_UA ! Parameters + type(UA_DiscreteStateType), intent(in ) :: xd_UA ! Discrete states at Time + type(UA_OtherStateType), intent(in ) :: OtherState_UA ! Other states at Time + type(UA_OutputType), intent(inout) :: y_UA ! + type(UA_MiscVarType), intent(inout) :: m_UA ! misc/optimization variables + real(ReKi), intent( out) :: Cl, Cd, Cm + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'Compute_UA_AirfoilCoefs' + - if (phiIn > -pi/4.0_ReKi .and. phiIn < pi/4.0_ReKi) then !bjj: added the negative for those cases where the previously calculated non-BEMT phi is in the [-pi,-pi/4] range - test_lower(2) = pi/4.0_ReKi - test_upper(2) = BEMT_epsilon2 + type(UA_InputType) :: u_UA + + ErrStat = ErrID_None + ErrMsg = '' - test_lower(3) = -PiBy2 - BEMT_epsilon2 - test_upper(3) = -pi + BEMT_epsilon2 - else - test_lower(3) = pi/4.0_ReKi - test_upper(3) = BEMT_epsilon2 + u_UA%alpha = AOA + u_UA%Re = Re + u_UA%U = U + + call UA_CalcOutput(u_UA, p_UA, xd_UA, OtherState_UA, AFInfo, y_UA, m_UA, errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) return - test_lower(2) = -PiBy2 - BEMT_epsilon2 - test_upper(2) = -pi + BEMT_epsilon2 - end if + Cl = y_UA%Cl + Cd = y_UA%Cd + Cm = y_UA%Cm + + +end subroutine Compute_UA_AirfoilCoefs +!---------------------------------------------------------------------------------------------------------------------------------- +!>This is the residual calculation for the uncoupled BEM solve +real(ReKi) function BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, chord, AFInfo, & + Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + axInduction, tanInduction, IsValidSolution, ErrStat, ErrMsg) + - end if - - -end subroutine GetSolveRegionOrdering - -integer function TestRegion(phiLower, phiUpper, numBlades, rlocal, chord, theta, AFInfo, & - Vx, Vy, Re, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, atol, & - f1, f2, errStat, errMsg) - real(ReKi), intent(in ) :: phiLower - real(ReKi), intent(in ) :: phiUpper + real(ReKi), intent(in ) :: phi + real(ReKi), intent(in ) :: AOA + real(ReKi), intent(in ) :: Re integer, intent(in ) :: numBlades - !integer, intent(in ) :: numBladeNodes + real(ReKi), intent(in ) :: rlocal + real(ReKi), intent(in ) :: chord type(AFInfoType), intent(in ) :: AFInfo - real(ReKi), intent(in ) :: rlocal - real(ReKi), intent(in ) :: chord - real(ReKi), intent(in ) :: theta - real(ReKi), intent(in ) :: Vx - real(ReKi), intent(in ) :: Vy - real(ReKi), intent(in ) :: Re + real(ReKi), intent(in ) :: Vx + real(ReKi), intent(in ) :: Vy logical, intent(in ) :: useTanInd logical, intent(in ) :: useAIDrag logical, intent(in ) :: useTIDrag @@ -1769,80 +258,76 @@ integer function TestRegion(phiLower, phiUpper, numBlades, rlocal, chord, theta, logical, intent(in ) :: useTipLoss real(ReKi), intent(in ) :: hubLossConst real(ReKi), intent(in ) :: tipLossConst - real(ReKi), intent(in ) :: atol - real(ReKi), intent( out) :: f1 !< value of residual at phiLower - real(ReKi), intent( out) :: f2 !< value of residual at phiUpper + real(ReKi), intent( out) :: axInduction, tanInduction + logical, intent( out) :: IsValidSolution !< this is set to false if k<=1 in the propeller brake region or k<-1 in the momentum region, indicating an invalid solution integer(IntKi), intent( out) :: ErrStat ! Error status of the operation character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + ! Local variables - ! Local variables - character(errMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName='TestRegion' - logical :: IsValidSolution, IsValidSolution2 ! placeholder for flag to determine if the residual solution is invalid (we'll handle that after the brent solve) - - ErrStat = ErrID_None - ErrMsg = "" - - f1 = UncoupledErrFn(phiLower, theta, Re, numBlades, rlocal, chord, AFInfo, & - Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - IsValidSolution, errStat2, errMsg2) + integer(intKi) :: ErrStat2 ! temporary Error status + character(ErrMsgLen) :: ErrMsg2 ! temporary Error message + character(*), parameter :: RoutineName = 'BEMTU_InductionWithResidual' - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return + real(ReKi) :: fzero + + real(ReKi) :: Cl, Cd, Cx, Cy, Cm, Cpmin - f2 = UncoupledErrFn(phiUpper, theta, Re, numBlades, rlocal, chord, AFInfo, & - Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - IsValidSolution2, errStat2, errMsg2) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return + ErrStat = ErrID_None + ErrMsg = "" + BEMTU_InductionWithResidual = 0.0_ReKi + IsValidSolution = .true. - ! Look for zero-crossing - if ( EqualRealNos(f1, 0.0_ReKi) .and. EqualRealNos(f2, 0.0_ReKi) .and. IsValidSolution .and. IsValidSolution2) then - TestRegion = 0 ! all solutions yield zero -- special case - return - else - if ( abs(f1) < aTol ) then - if ( abs(f2) < abs(f1) .and. IsValidSolution2 ) then - TestRegion = 4 ! special case: upper end point is a zero (and it's smaller than the solution at the lower end point) - return - elseif ( IsValidSolution ) then - TestRegion = 3 ! special case: lower end point is a zero - return - end if - elseif ( abs(f2) < aTol .and. IsValidSolution2 ) then - TestRegion = 4 ! special case: upper end point is a zero - return - end if + ! make these return values consistent with what is returned in inductionFactors routine: + + ! Set the local version of the induction factors (use values that set the force to 0) + if ( ( useTiploss .and. EqualRealNos(tipLossConst,0.0_ReKi) ) .or. ( useHubloss .and. EqualRealNos(hubLossConst,0.0_ReKi) ) ) then + ! We are simply going to bail if we are using tiploss and tipLossConst = 0 or using hubloss and hubLossConst=0, regardless of phi! [do this before checking if Vx or Vy is zero or you'll get jumps in the induction and loads] + axInduction = 1.0_ReKi + tanInduction = 0.0_ReKi + elseif ( EqualRealNos(phi, 0.0_ReKi) .or. VelocityIsZero(Vx) .OR. VelocityIsZero(Vy) ) then + axInduction = 0.0_ReKi + tanInduction = 0.0_ReKi + else !if ( (.NOT. VelocityIsZero(Vx)) .AND. (.NOT. VelocityIsZero(Vy)) ) then + + call ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, Cl, Cd, Cm, Cpmin, errStat2, errMsg2 ) !bjj: would be nice if this could be done outside this routine (so we don't copy AFInfo so much) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (ErrStat >= AbortErrLev) return + + ! Compute Cx, Cy given Cl, Cd and phi, we honor the useAIDrag and useTIDrag flag because Cx,Cy are only used for the solution of inductions + call Transform_ClCd_to_CxCy( phi, useAIDrag, useTIDrag, Cl, Cd, Cx, Cy ) + + + ! Determine axInduction, tanInduction for the current Cl, Cd, phi + call inductionFactors( rlocal, chord, phi, Cx, Cy, numBlades, & + Vx, Vy, useTanInd, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + fzero, axInduction, tanInduction, IsValidSolution) + BEMTU_InductionWithResidual = fzero ! the residual end if + - if ( sign(1.0_ReKi,f1) /= sign(1.0_ReKi,f2) ) then - TestRegion = 1 - else - TestRegion = 2 ! No zero - end if - -end function TestRegion +end function BEMTU_InductionWithResidual + + + ! This is the residual calculation for the uncoupled BEM solve + +real(ReKi) function UncoupledErrFn(phi, theta, Re, numBlades, rlocal, chord, AFInfo, & + Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + IsValidSolution, ErrStat, ErrMsg) -subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, chord, theta, & - Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - maxIndIterations, aTol, ValidPhi, ErrStat, ErrMsg) - use fminfcn - use mod_root1dim - !use fminMod - real(ReKi), intent(inout) :: phi + + real(ReKi), intent(in ) :: phi + real(ReKi), intent(in ) :: theta + real(ReKi), intent(in ) :: Re integer, intent(in ) :: numBlades - real(ReKi), intent(in ) :: airDens - real(ReKi), intent(in ) :: mu - TYPE(AFInfoType), INTENT(IN ) :: AFInfo - real(ReKi), intent(in ) :: rlocal - real(ReKi), intent(in ) :: chord - real(ReKi), intent(in ) :: theta - real(ReKi), intent(in ) :: Vx - real(ReKi), intent(in ) :: Vy + real(ReKi), intent(in ) :: rlocal + real(ReKi), intent(in ) :: chord + type(AFInfoType), intent(in ) :: AFInfo + real(ReKi), intent(in ) :: Vx + real(ReKi), intent(in ) :: Vy logical, intent(in ) :: useTanInd logical, intent(in ) :: useAIDrag logical, intent(in ) :: useTIDrag @@ -1850,156 +335,326 @@ subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, cho logical, intent(in ) :: useTipLoss real(ReKi), intent(in ) :: hubLossConst real(ReKi), intent(in ) :: tipLossConst - integer, intent(in ) :: maxIndIterations - real(ReKi), intent(in ) :: aTol - logical, intent(inout) :: ValidPhi - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - - ! Local variables - type(fmin_fcnArgs) :: fcnArgs - - character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None - integer(IntKi) :: errStat2 ! temporary Error status of the operation - character(*), parameter :: RoutineName = 'BEMT_UnCoupledSolve' - real(ReKi), parameter :: MsgLimit = 0.07_ReKi ! don't print a message if we're within about 4 degrees of 0 or +/- pi/2 [arbitrary number picked by bjj] + integer(IntKi), intent( out) :: ErrStat ! Error status of the operation + logical, intent( out) :: IsValidSolution !< this is set to false if k<=1 in the propeller brake region or k<-1 in the momentum region, indicating an invalid solution + character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + ! Local variables - real(ReKi) :: f1, f_lower, f_upper - real(ReKi) :: phi_lower(3), phi_upper(3) ! upper and lower bounds for region of phi in which we are trying to find a solution to the BEM equations - integer :: i, TestRegionResult - logical :: IsValidSolution - real(ReKi) :: Re, Vrel, cpmin + real(ReKi) :: axInduction, tanInduction, AoA ErrStat = ErrID_None ErrMsg = "" - + + AOA = phi - theta - if ( VelocityIsZero(Vx) ) then - phi = 0.0_ReKi - ValidPhi = .true. - return - else if ( VelocityIsZero(Vy) ) then - if (Vx>0.0_ReKi) then - phi = PiBy2 - else - phi = -PiBy2 - end if - ValidPhi = .true. - return - end if + + UncoupledErrFn = BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, chord, AFInfo, & + Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + axInduction, tanInduction, IsValidSolution, ErrStat, ErrMsg) + - ! Need to call BEMTU_Wind to obtain Re, even though we aren't using it in this version. - ! inductions are set to zero! - call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, Vx, Vy, chord, airDens, mu, Vrel, Re ) +end function UncoupledErrFn + + +subroutine ApplySkewedWakeCorrection( Vx, Vy, azimuth, chi0, tipRatio, a, ap, chi, ErrStat, ErrMsg ) + real(ReKi), intent(in ) :: Vx + real(ReKi), intent(in ) :: Vy + real(ReKi), intent(in ) :: azimuth + real(ReKi), intent(in ) :: chi0 + real(ReKi), intent(in ) :: tipRatio ! r/Rtip + real(ReKi), intent(inout) :: a + real(ReKi), intent(inout) :: ap + real(ReKi), intent( out) :: chi + integer(IntKi), intent( out) :: ErrStat ! Error status of the operation + character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None - !# ------ BEM solution method see (Ning, doi:10.1002/we.1636) ------ + ! Local variables + real(ReKi) :: yawCorr, saz - ! See if the previous value of phi still satisfies the residual equation. - ! (If the previous phi wasn't a valid solution to BEMT equations, skip this check and just perform the solve) - if (ValidPhi .and. .NOT. EqualRealNos(phi, 0.0_ReKi) .and. .not. EqualRealNos(abs(phi),PiBy2) ) then - f1 = UncoupledErrFn(phi, theta, Re, numBlades, rlocal, chord, AFInfo, & - Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - IsValidSolution, errStat2, errMsg2) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return - - if ( abs(f1) < aTol .and. IsValidSolution ) then - !phiStar = phiIn - return - end if - end if + ErrStat = ErrID_None + ErrMsg = "" + + ! Skewed wake correction + + saz = sin(azimuth) + chi = chi0 + if ( abs(saz) > 0.005_ReKi ) then + chi = (0.6_ReKi*a + 1.0_ReKi)*chi0 + + !if (chi0 < 40.0*d2r .and. chi > 0.0 ) then + ! TODO: Add check on chi to make sure it is < pi/2 and (positive check should be outside solve) GJH 5/20/2015 + !yawCorr = max(0.0,chi0-0.5236) + !yawCorr = min(0.785,yawCorr) + !bjj: modified 22-Sep-2015: RRD recommends 32 instead of 64 in the denominator (like AD14) + yawCorr = (15.0_ReKi*pi/32.0_ReKi*tan(chi/2.0_ReKi) * (tipRatio) * saz) + + a = a * (1.0 + yawCorr) ! *(-yawCorr/0.785 + 1) ) + !if ((a > 1.0 .AND. ayaw < 1.0) .OR. (a < 1.0 .AND. ayaw > 1.0 )) then + ! call WrScr('Yaw correction crossed over 1.0.') + ! !a = max(1.0, ayaw) + !else if ((a < -1.0 .AND. ayaw > -1.0) .OR. (a > -1.0 .AND. ayaw < -1.0 )) then + ! call WrScr('Yaw correction crossed over -1.0.') + ! + !end if + + else + chi = chi0 + end if - ! - ValidPhi = .false. ! initialize to false while we try to find a new valid solution - !............ - ! - ! Set up the fcn argument settings for Brent's method +end subroutine ApplySkewedWakeCorrection +!----------------------------------------------------------------------------------------- +subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + fzero, a, ap, IsValidSolution) - fcnArgs%airDens = airDens - fcnArgs%mu = mu - fcnArgs%numBlades = numBlades - fcnArgs%rlocal = rlocal - fcnArgs%chord = chord - fcnArgs%theta = theta - fcnArgs%Vx = Vx - fcnArgs%Vy = Vy - fcnArgs%Re = Re - fcnArgs%useTanInd = useTanInd - fcnArgs%useAIDrag = useAIDrag - fcnArgs%useTIDrag = useTIDrag - fcnArgs%useHubLoss = useHubLoss - fcnArgs%useTipLoss = useTipLoss - fcnArgs%hubLossConst = hubLossConst - fcnArgs%tipLossConst = tipLossConst - + implicit none + + ! in + real(ReKi), intent(in) :: r !< local radial position [u%rlocal] + real(ReKi), intent(in) :: chord !< chord [p%chord] + real(ReKi), intent(in) :: phi !< angle between the plane of rotation and the direction of the local wind [y%phi]; must be in range [-pi,pi] + real(ReKi), intent(in) :: cn !< normal force coefficient (normal to the plane, not chord) of the jth node in the kth blade; [y%cx] + real(ReKi), intent(in) :: ct !< tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade; [y%cy] + integer, intent(in) :: B !< number of blades [p%numBlades] + real(ReKi), intent(in) :: Vx !< velocity component [u%Vx] + real(ReKi), intent(in) :: Vy !< velocity component [u%Vy] + real(ReKi), intent(in) :: hubLossConst !< hub loss constant [p%hubLossConst] + real(ReKi), intent(in) :: tipLossConst !< tip loss constant [p%tipLossConst] + logical, intent(in) :: useHubLoss !< hub-loss flag [p%useHubLoss] + logical, intent(in) :: useTipLoss !< tip-loss flag [p%useTipLoss] + logical, intent(in) :: wakerotation !< Include tangential induction in BEMT calculations [flag] [p%useTanInd] + + + ! out + real(ReKi), intent(out) :: fzero !< residual of BEM equations + real(ReKi), intent(out) :: a !< axial induction [y%axInduction] + real(ReKi), intent(out) :: ap !< tangential induction, i.e., a-prime [y%tanInduction] + logical, intent(out) :: IsValidSolution !< this is set to false if k<=1 in the propeller brake region or k<-1 in the momentum region, indicating an invalid solution + + ! local + + real(ReKi) :: sigma_p ! local solidity (B*chord/(TwoPi*r)) + real(ReKi) :: sphi, cphi, lambda_r + real(ReKi) :: k, kp ! non-dimensional parameters + real(ReKi) :: F ! hub/tip loss correction factor + real(ReKi) :: g1, g2, g3 + real(ReKi) :: temp ! temporary variable so we don't have to calculate 2.0_ReKi*F*k multiple times + real(ReKi), parameter :: InductionLimit = 1000000.0_ReKi + real(ReKi), parameter :: MaxTnInd = 2.0_ReKi + real(ReKi), parameter :: MaxAxInd = 2.0_ReKi + + logical :: momentumRegion + + + + IsValidSolution = .true. + + !..................................................... + ! Some special cases (bjj commented out because we have taken care of these in BEMTU_InductionWithResidual, the only routine that calls this function) + !..................................................... + !if ( ( useTiploss .and. EqualRealNos(tipLossConst,0.0_ReKi) ) .or. ( useHubloss .and. EqualRealNos(hubLossConst,0.0_ReKi) ) ) then + ! ! We are simply going to bail if we are using tiploss and tipLossConst = 0 or using hubloss and hubLossConst=0, regardless of phi! + ! fzero = 0.0_ReKi + ! a = 1.0_ReKi + ! ap = -1.0_ReKi + ! return + !else if ( EqualRealNos(phi, 0.0_ReKi) ) then + ! fzero = 0.0_ReKi + ! a = 1.0_ReKi + ! if (wakerotation) then + ! ap = -1.0_ReKi + ! else + ! ap = 0.0_ReKi + ! end if + ! + ! return + !end if + + !..................................................... + ! Temporary variables: + !..................................................... + sphi = sin(phi) + cphi = cos(phi) + + + !..................................................... + ! Prandtl's tip and hub loss factor: + !..................................................... + + F = getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLossConst, tipLossConst) ! Prandtl's tip and hub loss factor - call GetSolveRegionOrdering(Vx, phi, phi_lower, phi_upper) + + !..................................................... + ! compute axial induction factor: + !..................................................... + sigma_p = B*chord/(TwoPi*r) ! local solidity + k = sigma_p*cn/4.0_ReKi/F/sphi/sphi + - do i = 1,size(phi_upper) ! Need to potentially test 3 regions - TestRegionResult = TestRegion(phi_lower(i), phi_upper(i), numBlades, rlocal, chord, theta, AFInfo, & - Vx, Vy, Re, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, atol, & - f_lower, f_upper, errStat2, errMsg2) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - - if ( TestRegionResult == 1 ) then - !............ - ! There is a zero in the solution region [phi_lower(i), phi_upper(i)] because the endpoints have residuals with different signs (SolutionRegion=1) - ! We use Brent's Method to find the zero-residual solution in this region + momentumRegion = (phi > 0.0_ReKi .and. Vx >= 0.0_ReKi) .or. (phi < 0.0_ReKi .and. Vx < 0.0_ReKi) + if (momentumRegion) then ! momentum/empirical + + + ! update axial induction factor + if (k <= 2.0_ReKi/3.0_ReKi) then ! momentum state for a < 0.4 + + if ( EqualRealNos(k,-1.0_ReKi) ) then + a = -sign(InductionLimit, 1.0_ReKi+k) + else + a = k/(1.0_ReKi+k) + end if + + if (k<-1.0_ReKi) then ! k < -1 cannot be a solution in momentum region (this is equivalent to a>1.0) + IsValidSolution = .false. + end if + + + ! note that we'll put a max on the magnitude of 'a' later - call sub_brent(phi,fmin_fcn,phi_lower(i),phi_upper(i), aTol, maxIndIterations, fcnArgs, AFInfo, f_lower, f_upper) - call SetErrStat(fcnArgs%ErrStat, fcnArgs%ErrMsg, ErrStat, ErrMsg, RoutineName) - - if (fcnArgs%IsValidSolution) then ! we have a valid BEMT solution - ValidPhi = .true. - exit - end if - elseif (TestRegionResult == 3) then - phi = phi_lower(i) !this boundary is a solution - ValidPhi = .true. - exit - elseif (TestRegionResult == 4) then - phi = phi_upper(i) !this boundary is a solution - ValidPhi = .true. - exit - elseif (TestRegionResult == 0) then ! Special case where both end points return 0 residual; return value closest to 0 as the solution - if (phi_lower(i) > 0.0_ReKi) then - phi = phi_lower(i) !this boundary is a solution - ValidPhi = .true. - exit + else ! Glauert(Buhl) correction for 0.4 0, but just in case there are numerical issues, I will add the abs() here + end if - if (.not. ValidPhi) then - phi = ComputePhiWithInduction(Vx, Vy, 0.0_ReKi, 0.0_ReKi) + end if + + else ! propeller brake - if (abs(phi)>MsgLimit .and. abs(abs(phi)-PiBy2) > MsgLimit ) then - call SetErrStat( ErrID_Info, 'There is no valid value of phi for these operating conditions: Vx = '//TRIM(Num2Lstr(Vx))//& - ', Vy = '//TRIM(Num2Lstr(Vy))//', rlocal = '//TRIM(Num2Lstr(rLocal))//', theta = '//TRIM(Num2Lstr(theta))//', geometric phi = '//TRIM(Num2Lstr(phi)), errStat, errMsg, RoutineName ) + + if ( EqualRealNos(k,1.0_ReKi) ) then + IsValidSolution = .false. + a = InductionLimit + else + a = k/(k-1.0_ReKi) end if + + + if (k<=1.0_ReKi) then ! k <= 1 cannot be a solution in propeller brake region (this is equivalent to a<1.0) + IsValidSolution = .false. + else if (a > MaxAxInd) then ! propeller brake region is for induction factors > 1, but not too large; + ! note that we use k in the residual equation instead of a in the propeller brake region, so we can put the limit here + a = MaxAxInd + end if - end if + + !..................................................... + ! compute tangential induction factor: + !..................................................... + + if (wakerotation) then + ! compute tangential induction factor + if ( EqualRealNos(cphi,0.0_ReKi) ) then -end subroutine BEMT_UnCoupledSolve - - + ap = -1.0_ReKi + kp = sign(InductionLimit, ct*sphi)*sign(1.0_ReKi,Vx) + + else + + kp = sigma_p*ct/4.0_ReKi/F/sphi/cphi + if (Vx < 0.0_ReKi) then + kp = -kp + end if + + + if ( EqualRealNos(kp,1.0_ReKi) ) then + ap = sign(InductionLimit, 1.0_ReKi-kp) + else + ap = kp/(1.0_ReKi-kp) + end if + + ! bandaid so that this doesn't blow up. Note that we're not using ap in the residual calculation, so we can modify it here. + if (abs(ap) > MaxTnInd) ap = sign(MaxTnInd, ap) + + end if + + + else + + ! we're not computing tangential induction: + ap = 0.0_ReKi + kp = 0.0_ReKi + + end if - end module BEMT - - + !..................................................... + ! error function (residual) + !..................................................... + lambda_r = Vy/Vx + + if (momentumRegion) then ! momentum/empirical + if ( EqualRealNos(a, 1.0_ReKi) ) then + fzero = - cphi/lambda_r*(1-kp) + else + fzero = sphi/(1-a) - cphi/lambda_r*(1-kp) + + ! bandaid so that axial induction doesn't blow up + a = max(a,-MaxAxInd) + end if + + else ! propeller brake region + fzero = sphi*(1-k) - cphi/lambda_r*(1-kp) + end if + if (.not. IsValidSolution) then + a = 0.0_ReKi + ap = 0.0_ReKi + end if + + +end subroutine inductionFactors +!----------------------------------------------------------------------------------------- +!> This function computes \f$F\f$, the hub/tip loss correction +real(reKi) function getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLossConst, tipLossConst) result(F) + + real(ReKi), intent(in) :: sphi !< sine of local inflow angle, sin(phi) + real(ReKi), intent(in) :: hubLossConst !< hub loss constant [p%hubLossConst] + real(ReKi), intent(in) :: tipLossConst !< tip loss constant [p%tipLossConst] + logical, intent(in) :: useHubLoss !< hub-loss flag [p%useHubLoss] + logical, intent(in) :: useTipLoss !< tip-loss flag [p%useTipLoss] + + + real(ReKi) :: factortip, Ftip, factorhub, Fhub + + !..................................................... + ! Prandtl's tip and hub loss factor: + !..................................................... + + Ftip = 1.0_ReKi ! default tip loss value + Fhub = 1.0_ReKi ! default hub loss value + + if (.not. EqualRealNos(sphi,0.0_ReKi)) then + if ( useTipLoss ) then + factortip = tipLossConst/abs(sphi) + Ftip = TwoByPi*acos(min(1.0_ReKi,exp(-factortip))) + ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 + end if + + if ( useHubLoss ) then + factorhub = hubLossConst/abs(sphi) + Fhub = TwoByPi*acos(min(1.0_ReKi,exp(-factorhub))) + ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 + end if + end if + + F = Ftip * Fhub + +end function getHubTipLossCorrection +!----------------------------------------------------------------------------------------- + +end module BEMTUncoupled From 9934921f9da085f451ad96858668680d097a849e Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 10:52:32 -0600 Subject: [PATCH 22/58] Update BEMTUncoupled.f90 --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index bf2dd6421..24474eeca 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -93,7 +93,6 @@ subroutine BEMTU_Wind( axInduction, tanInduction, Vx, Vy, chord, airDens, mu, W W = sqrt((Vx*(1-axInduction))**2 + (Vy*(1+tanInduction))**2) !end if - Re = airDens * W * chord / mu if ( EqualRealNos(Re, 0.0_ReKi) ) Re = 0.001 ! Do this to avoid a singularity when we take log(Re) in the airfoil lookup. @@ -167,23 +166,27 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & , AFInfo%Table(1)%SplineCoefs & , ErrStat, ErrMsg ) + Cl = IntAFCoefs(1) Cd = IntAFCoefs(2) -! Cm = IntAFCoefs(3) - ! Cpmin = IntAFCoefs(4) + - IF ( AFInfo%ColCm > 2 ) THEN ! If there is Cm data, it is in column 3 + IF ( AFInfo%InCol_Cm > 0 ) THEN ! If there is Cm data, it is in column 3 Cm = IntAFCoefs(3) - IF ( AFInfo%ColCpmin > 2 ) THEN + IF ( AFInfo%InCol_Cpmin > 0 ) THEN Cpmin = IntAFCoefs(4) - END IF + END IF - ELSE IF ( AFInfo%ColCpmin > 2 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 + ELSE IF ( AFInfo%InCol_Cpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 Cpmin = IntAFCoefs(3) END IF + + + + end subroutine ComputeSteadyAirfoilCoefs From b8cd5c474f2b8e19add38eab7f399d9c0f22d4d2 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 10:55:02 -0600 Subject: [PATCH 23/58] Update AirfoilInfo_Registry.txt --- modules-local/aerodyn/src/AirfoilInfo_Registry.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt index fe5f6e3b1..7c1e3c583 100644 --- a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt +++ b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt @@ -96,6 +96,8 @@ typedef ^ ^ INTEGER NumTabs - - - "The number of airfoil tables in the airfoil f typedef ^ ^ AFI_Table_Type Table {:} - - "The tables of airfoil data for given Re and control setting" - typedef ^ ^ INTEGER ColCpmin - - - "Column number for Cpmin" - typedef ^ ^ INTEGER ColCm - - - "Column number for Cpmin" - +typedef ^ ^ INTEGER InCol_Cm - - - "The column of the coefficient tables that holds the pitching-moment coefficient" - +typedef ^ ^ INTEGER InCol_Cpmin - - - "The column of the coefficient tables that holds the minimum pressure coefficient" - # ..... Initialization data ....................................................................................................... # The following derived type stores information that comes from the calling module (say, AeroDyn): From 59f6ebc72ce4fa908d2e224659ad68d69b812f0c Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 11:04:29 -0600 Subject: [PATCH 24/58] Update AeroDyn_Driver.f90 --- modules-local/aerodyn/src/AeroDyn_Driver.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn_Driver.f90 b/modules-local/aerodyn/src/AeroDyn_Driver.f90 index a42b0fe4f..42c3512bf 100644 --- a/modules-local/aerodyn/src/AeroDyn_Driver.f90 +++ b/modules-local/aerodyn/src/AeroDyn_Driver.f90 @@ -73,7 +73,7 @@ program AeroDyn_Driver do iCase = 1, DvrData%NumCases - call WrScr( NewLine//'Running case '//trim(num2lstr(iCase))//' of '//trim(num2lstr(DvrData%NumCases))//'.' ) + call WrScr( NewLine//'Running case'//trim(num2lstr(iCase))//' of '//trim(num2lstr(DvrData%NumCases))//'.' ) !dT = TwoPi/DvrData%Cases(iCase)%RotSpeed / DvrData%NumSect ! sec @@ -197,4 +197,4 @@ subroutine Dvr_End() end subroutine Dvr_End !................................ end program AeroDyn_Driver - \ No newline at end of file + From 1517424bf4af17e48ff3f2551d77bc422fb487ca Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 11:05:42 -0600 Subject: [PATCH 25/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 2419 ++++++++++++++++++++++------ 1 file changed, 1882 insertions(+), 537 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 24474eeca..a1a29ff68 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -21,236 +21,1747 @@ ! (File) Revision #: $Rev$ ! URL: $HeadURL$ !********************************************************************************************************************************** -module BEMTUnCoupled - +module BEMT + use NWTC_Library - use AirfoilInfo_Types + + use BEMT_Types + use BEMTUncoupled + + use UnsteadyAero - use UnsteadyAero_Types + !USE AeroDyn_Types + use AirfoilInfo + + + implicit none + + + private + + type(ProgDesc), parameter :: BEMT_Ver = ProgDesc( 'BEM', 'v1.03.00', '29-Oct-2016' ) + character(*), parameter :: BEMT_Nickname = 'BEM' + + + ! ..... Public Subroutines ................................................................................................... + + public :: BEMT_Init ! Initialization routine + public :: BEMT_End ! Ending routine (includes clean up) + + public :: BEMT_UpdateStates ! Loose coupling routine for solving for constraint states, integrating + ! continuous states, and updating discrete states + public :: BEMT_CalcOutput ! Routine for computing outputs + + public :: BEMT_CalcConstrStateResidual ! Tight coupling routine for returning the constraint state residual + public :: BEMT_CalcContStateDeriv ! Tight coupling routine for computing derivatives of continuous states + public :: BEMT_UpdateDiscState ! Tight coupling routine for updating discrete states + + ! routines for linearization + public :: Get_phi_perturbations + public :: ComputeFrozenWake + public :: CheckLinearizationInput + + contains + + + +!---------------------------------------------------------------------------------------------------------------------------------- +real(ReKi) function ComputePhiWithInduction( Vx, Vy, a, aprime ) +! This routine is used to compute the inflow angle, phi, from the local velocities and the induction factors. +!.................................................................................................................................. + real(ReKi), intent(in ) :: Vx ! Local velocity component along the thrust direction + real(ReKi), intent(in ) :: Vy ! Local velocity component along the rotor plane-of-rotation direction + real(ReKi), intent(in ) :: a ! Axial induction factor + real(ReKi), intent(in ) :: aprime ! Tangential induction factor + + real(ReKi) :: x + real(ReKi) :: y + + x = Vx*(1-a) + y = Vy*(1+aprime) + + if ( EqualRealNos(y, 0.0_ReKi) .AND. EqualRealNos(x, 0.0_ReKi) ) then + ComputePhiWithInduction = 0.0_ReKi + else + ComputePhiWithInduction = atan2( x , y ) + end if + + +end function ComputePhiWithInduction + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat, errMsg ) +! This routine is called from BEMT_Init. +! The parameters are set here and not changed during the simulation. +!.................................................................................................................................. + type(BEMT_InitInputType), intent(inout) :: InitInp ! Input data for initialization routine, out is needed because of copy below + real(DbKi), intent(in ) :: interval ! time interval + type(UA_InitInputType), intent( out) :: Init_UA_Data ! Parameters + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + integer :: i,j + integer(intKi) :: ErrStat2 ! temporary Error status + + ! Set up initialization data + + Allocate(Init_UA_Data%c(InitInp%numBladeNodes,InitInp%numBlades), STAT = errStat2) + if (ErrStat2 /= 0) then + ErrStat = ErrID_Fatal + ErrMsg = "BEMT_Set_UA_InitData:Error allocating Init_UA_Data%c." + return + else + ErrStat = ErrID_None + ErrMsg = "" + end if + + do j = 1,InitInp%numBlades + do i = 1,InitInp%numBladeNodes + Init_UA_Data%c(i,j) = InitInp%chord(i,j) + end do + end do + + ! TODO:: Fully implement these initialization inputs + + Init_UA_Data%dt = interval + Init_UA_Data%OutRootName = '' + + Init_UA_Data%numBlades = InitInp%numBlades + Init_UA_Data%nNodesPerBlade = InitInp%numBladeNodes + + Init_UA_Data%NumOuts = 0 + Init_UA_Data%UAMod = InitInp%UAMod + Init_UA_Data%Flookup = InitInp%Flookup + Init_UA_Data%a_s = InitInp%a_s ! m/s + +end subroutine BEMT_Set_UA_InitData + + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) +! This routine is called from BEMT_Init. +! The parameters are set here and not changed during the simulation. +!.................................................................................................................................. + type(BEMT_InitInputType), intent(inout) :: InitInp ! Input data for initialization routine, out is needed because of copy below + type(BEMT_ParameterType), intent( out) :: p ! Parameters + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + ! Local variables + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_SetParameters' + integer(IntKi) :: i, j + + + ! Initialize variables for this routine + + errStat = ErrID_None + errMsg = "" + + p%numBladeNodes = InitInp%numBladeNodes + p%numBlades = InitInp%numBlades + p%UA_Flag = InitInp%UA_Flag + p%CavitCheck = InitInp%CavitCheck + + + + allocate ( p%chord(p%numBladeNodes, p%numBlades), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%chord.', errStat, errMsg, RoutineName ) + return + end if + + allocate ( p%zHub(p%numBlades), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%zHub.', errStat, errMsg, RoutineName ) + return + end if + + allocate ( p%AFindx(p%numBladeNodes,p%numBlades), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%AFindx.', errStat, errMsg, RoutineName ) + return + end if + + allocate ( p%tipLossConst(p%numBladeNodes, p%numBlades), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%tipLossConst.', errStat, errMsg, RoutineName ) + return + end if + + allocate ( p%hubLossConst(p%numBladeNodes, p%numBlades), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for p%hubLossConst.', errStat, errMsg, RoutineName ) + return + end if + + p%AFindx = InitInp%AFindx + + ! Compute the tip and hub loss constants using the distances along the blade (provided as input for now) + do j=1,p%numBlades + p%zHub(j) = InitInp%zHub(j) + do i=1,p%numBladeNodes + p%chord(i,j) = InitInp%chord(i,j) + p%tipLossConst(i,j) = p%numBlades*(InitInp%zTip (j) - InitInp%zLocal(i,j)) / (2.0*InitInp%zLocal(i,j)) + p%hubLossConst(i,j) = p%numBlades*(InitInp%zLocal(i,j) - InitInp%zHub (j)) / (2.0*InitInp%zHub (j)) + end do + end do + + + !p%DT = InitInp%DT + p%airDens = InitInp%airDens + p%kinVisc = InitInp%kinVisc + p%Patm = InitInp%Patm + p%Pvap = InitInp%Pvap + p%CavitCheck = InitInp%CavitCheck + p%FluidDepth = InitInp%FluidDepth + p%skewWakeMod = InitInp%skewWakeMod + p%useTipLoss = InitInp%useTipLoss + p%useHubLoss = InitInp%useHubLoss + p%useInduction = InitInp%useInduction + p%useTanInd = InitInp%useTanInd + p%useAIDrag = InitInp%useAIDrag + p%useTIDrag = InitInp%useTIDrag + p%numReIterations = InitInp%numReIterations + p%maxIndIterations = InitInp%maxIndIterations + p%aTol = InitInp%aTol + p%InCol_Cpmin = InitInp%InCol_Cpmin + + +end subroutine BEMT_SetParameters + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_InitContraintStates( z, p, errStat, errMsg ) +! This routine is called from BEMT_Init. +! The constraint state data is allocated and set to zero. +!.................................................................................................................................. + + type(BEMT_ConstraintStateType), intent( out) :: z ! Input data for initialization routine + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + + ! Local variables + character(*), parameter :: RoutineName = 'BEMT_InitContraintStates' + integer(IntKi) :: errStat2 ! temporary Error status of the operation + + ! Initialize variables for this routine + + errStat = ErrID_None + errMsg = "" + + allocate ( z%phi( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for z%phi.', errStat, errMsg, RoutineName ) + return + end if + z%phi = 0.0_ReKi + + +end subroutine BEMT_InitContraintStates + + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_InitOtherStates( OtherState, p, errStat, errMsg ) +! This routine is called from BEMT_Init. +! The OtherState data is allocated and set to zero. +!.................................................................................................................................. + + type(BEMT_OtherStateType), intent(inout) :: OtherState ! OtherState data + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + + ! Local variables + character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_InitOtherStates' + + ! Initialize variables for this routine + + errStat = ErrID_None + errMsg = "" + + if (p%UseInduction) then + + allocate ( OtherState%ValidPhi( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for OtherState%ValidPhi.', errStat, errMsg, RoutineName ) + return + end if + OtherState%ValidPhi = .true. + + end if + + OtherState%nodesInitialized = .false. ! z%phi hasn't been initialized properly, so make sure we compute a value for phi until we've updated them in the first call to BEMT_UpdateStates() + +! +! +! allocate ( OtherState%axInduction( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) +! if ( errStat2 /= 0 ) then +! errStat2 = ErrID_Fatal +! errMsg2 = 'Error allocating memory for OtherState%axInduction.' +! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) +! return +! end if +! OtherState%axInduction = 0.0_ReKi +! +! allocate ( OtherState%tanInduction( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) +! if ( errStat2 /= 0 ) then +! errStat2 = ErrID_Fatal +! errMsg2 = 'Error allocating memory for OtherState%tanInduction.' +! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) +! return +! end if +! OtherState%tanInduction = 0.0_ReKi +! +! allocate ( OtherState%Re( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) +! if ( errStat2 /= 0 ) then +! errStat2 = ErrID_Fatal +! errMsg2 = 'Error allocating memory for OtherState%Re.' +! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) +! return +! end if +! OtherState%Re = 0.0_ReKi +! +! allocate ( OtherState%AOA( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) +! if ( errStat2 /= 0 ) then +! errStat2 = ErrID_Fatal +! errMsg2 = 'Error allocating memory for OtherState%AOA.' +! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) +! return +! end if +! OtherState%AOA = 0.0_ReKi +! +! allocate ( OtherState%Cx( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) +! if ( errStat2 /= 0 ) then +! errStat2 = ErrID_Fatal +! errMsg2 = 'Error allocating memory for OtherState%Cx.' +! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) +! return +! end if +! OtherState%Cx = 0.0_ReKi +! +! allocate ( OtherState%Cy( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) +! if ( errStat2 /= 0 ) then +! errStat2 = ErrID_Fatal +! errMsg2 = 'Error allocating memory for OtherState%Cy.' +! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) +! return +! end if +! OtherState%Cy = 0.0_ReKi +! +! allocate ( OtherState%Cl( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) +! if ( errStat2 /= 0 ) then +! errStat2 = ErrID_Fatal +! errMsg2 = 'Error allocating memory for OtherState%Cl.' +! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) +! return +! end if +! OtherState%Cl = 0.0_ReKi +! +! allocate ( OtherState%Cd( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) +! if ( errStat2 /= 0 ) then +! errStat2 = ErrID_Fatal +! errMsg2 = 'Error allocating memory for OtherState%Cd.' +! call SetErrStat( errStat2, errMsg2, errStat, errMsg, 'BEMT_InitOtherStates' ) +! return +! end if +! OtherState%Cd = 0.0_ReKi + +end subroutine BEMT_InitOtherStates + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_AllocInput( u, p, errStat, errMsg ) +! This routine is called from BEMT_Init. +! +! +!.................................................................................................................................. + + type(BEMT_InputType), intent( out) :: u ! Input data + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + + ! Local variables + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_AllocInput' + + ! Initialize variables for this routine + + errStat = ErrID_None + errMsg = "" + + allocate ( u%theta( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%theta.', errStat, errMsg, RoutineName ) + return + end if + u%theta = 0.0_ReKi + + allocate ( u%psi( p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%psi.', errStat, errMsg, RoutineName ) + return + end if + u%psi = 0.0_ReKi + + allocate ( u%Vx( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%Vx.', errStat, errMsg, RoutineName ) + return + end if + u%Vx = 0.0_ReKi + + allocate ( u%Vy( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%Vy.', errStat, errMsg, RoutineName ) + return + end if + u%Vy = 0.0_ReKi + + + allocate ( u%rLocal( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + call SetErrStat( ErrID_Fatal, 'Error allocating memory for u%rLocal.', errStat, errMsg, RoutineName ) + return + end if + u%rLocal = 0.0_ReKi + + + + u%omega = 0.0_ReKi + +end subroutine BEMT_AllocInput + + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) +! This routine is called from BEMT_Init. +! +! +!.................................................................................................................................. + + type(BEMT_OutputType), intent( out) :: y ! output data + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + + ! Local variables + character(ErrMsgLen ) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_AllocOutput' + + ! Initialize variables for this routine + + errStat = ErrID_None + errMsg = "" + + call allocAry( y%Vrel, p%numBladeNodes, p%numBlades, 'y%Vrel', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%phi, p%numBladeNodes, p%numBlades, 'y%phi', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%chi, p%numBladeNodes, p%numBlades, 'y%chi', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Re, p%numBladeNodes, p%numBlades, 'y%Re', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%axInduction, p%numBladeNodes, p%numBlades, 'y%axInduction', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%tanInduction, p%numBladeNodes, p%numBlades, 'y%tanInduction', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%AOA, p%numBladeNodes, p%numBlades, 'y%AOA', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cx, p%numBladeNodes, p%numBlades, 'y%Cx', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cy, p%numBladeNodes, p%numBlades, 'y%Cy', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cm, p%numBladeNodes, p%numBlades, 'y%Cm', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cl, p%numBladeNodes, p%numBlades, 'y%Cl', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%Cd, p%numBladeNodes, p%numBlades, 'y%Cd', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) +call allocAry( y%Cpmin, p%numBladeNodes, p%numBlades, 'y%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%SigmaCavit, p%numBladeNodes, p%numBlades, 'y%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( y%SigmaCavitCrit, p%numBladeNodes, p%numBlades, 'y%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + + if (ErrStat >= AbortErrLev) RETURN + + ! outputs documented in AeroDyn + y%Vrel = 0.0_ReKi + y%phi = 0.0_ReKi + y%Cx = 0.0_ReKi + y%Cy = 0.0_ReKi + y%Cm = 0.0_ReKi + + ! others: + y%chi = 0.0_ReKi + y%Re = 0.0_ReKi + y%axInduction = 0.0_ReKi + y%tanInduction = 0.0_ReKi + y%AOA = 0.0_ReKi + y%Cl = 0.0_ReKi + y%Cd = 0.0_ReKi + y%Cpmin = 0.0_ReKi + y%SigmaCavit = 0.0_ReKi + y%SigmaCavitCrit = 0.0_ReKi + +end subroutine BEMT_AllocOutput + + + +subroutine BEMT_MapOutputs(p, OtherState, y, errStat, errMsg) + + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_OtherStateType), intent(in ) :: OtherState ! other states + type(BEMT_OutputType), intent(inout) :: y ! system outputs + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + ErrStat = ErrID_None + ErrMsg = "" + +end subroutine BEMT_MapOutputs + + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Interval, InitOut, ErrStat, ErrMsg ) +! This routine is called at the start of the simulation to perform initialization steps. +! The parameters are set here and not changed during the simulation. +! The initial states and initial guess for the input are defined. +!.................................................................................................................................. + + type(BEMT_InitInputType), intent(inout) :: InitInp ! Input data for initialization routine, needs to be inout because there is a copy of some data in InitInp in BEMT_SetParameters() + type(BEMT_InputType), intent( out) :: u ! An initial guess for the input; input mesh must be defined + type(BEMT_ParameterType), intent( out) :: p ! Parameters + type(BEMT_ContinuousStateType), intent( out) :: x ! Initial continuous states + type(BEMT_DiscreteStateType), intent( out) :: xd ! Initial discrete states + type(BEMT_ConstraintStateType), intent( out) :: z ! Initial guess of the constraint states + type(BEMT_OtherStateType), intent( out) :: OtherState ! Initial other states + type(BEMT_MiscVarType), intent( out) :: misc ! Initial misc/optimization variables + type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data + type(BEMT_OutputType), intent( out) :: y ! Initial system outputs (outputs are not calculated; + ! only the output mesh is initialized) + real(DbKi), intent(inout) :: interval ! Coupling interval in seconds: the rate that + ! (1) BEMT_UpdateStates() is called in loose coupling & + ! (2) BEMT_UpdateDiscState() is called in tight coupling. + ! Input is the suggested time from the glue code; + ! Output is the actual coupling interval that will be used + ! by the glue code. + type(BEMT_InitOutputType), intent( out) :: InitOut ! Output for initialization routine + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + + ! Local variables + character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_Init' + type(UA_InputType) :: u_UA + type(UA_InitInputType) :: Init_UA_Data + type(UA_InitOutputType) :: InitOutData_UA + integer(IntKi) :: i,j + real(ReKi) :: Cn1 ! critical value of Cn_prime at LE separation for alpha >= alpha0 + real(ReKi) :: Cn2 ! critical value of Cn_prime at LE separation for alpha < alpha0 + real(ReKi) :: Cd0 + real(ReKi) :: Cm0 + real(ReKi) :: k0 + real(ReKi) :: k1 + real(ReKi) :: k2 + real(ReKi) :: k3 + real(ReKi) :: T_VL + real(ReKi) :: x_cp_bar + real(ReKi) :: alpha0 ! zero lift angle of attack (radians) + real(ReKi) :: eta_e + real(ReKi) :: St_sh + real(ReKi) :: Re + real(ReKi) :: alpha + + real(ReKi) :: M, alpha1, alpha2, C_nalpha, C_nalpha_circ, T_f0, T_V0, T_p, b1,b2,b5,A1,A2,A5,S1,S2,S3,S4,k1_hat + real(ReKi) :: filtCutOff ! airfoil parameter for the low-pass cut-off frequency for pitching rate and accelerations (Hz) + character(64) :: chanPrefix + ! Initialize variables for this routine + errStat = ErrID_None + errMsg = "" + + + ! Initialize the NWTC Subroutine Library + call NWTC_Init( EchoLibVer=.FALSE. ) + + ! Display the module information + call DispNVD( BEMT_Ver ) + + + + + !............................................................................................ + ! Define parameters here + !............................................................................................ + + call BEMT_SetParameters( InitInp, p, errStat, errMsg ) + if (errStat >= AbortErrLev) return + p%DT = interval + !............................................................................................ + ! Define states here + !............................................................................................ + + ! We need to set an other state version so that we can change this during execution if the AOA is too large! + allocate ( OtherState%UA_Flag( p%numBladeNodes, p%numBlades ), STAT = errStat2 ) + if ( errStat2 /= 0 ) then + errStat2 = ErrID_Fatal + errMsg2 = 'Error allocating memory for OtherState%UA_Flag.' + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + return + end if + OtherState%UA_Flag = p%UA_Flag + + ! initialize the constraint states + call BEMT_InitContraintStates( z, p, errStat2, errMsg2 ) ! initialize the continuous states + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) return + + x%DummyContState = 0.0_SiKi + + ! Initialize other states + call BEMT_InitOtherStates( OtherState, p, errStat, errMsg ) ! initialize the other states + if (errStat >= AbortErrLev) return + + if ( p%UA_Flag ) then + call BEMT_Set_UA_InitData( InitInp, interval, Init_UA_Data, errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) then + call cleanup() + return + end if + + + call UA_Init( Init_UA_Data, u_UA, p%UA, xd%UA, OtherState%UA, misc%y_UA, misc%UA, interval, InitOutData_UA, errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) then + call cleanup() + return + end if + +#ifdef UA_OUTS + !CALL GetNewUnit( UnUAOuts, ErrStat, ErrMsg ) + !IF ( ErrStat /= ErrID_None ) RETURN + + CALL OpenFOutFile ( 69, 'Debug.UA.out', errStat, errMsg ) + IF (ErrStat >= AbortErrLev) RETURN + + + ! Heading: + WRITE (69,'(/,A)') 'This output information was generated by '//TRIM( GetNVD(BEMT_Ver) )// & + ' on '//CurDate()//' at '//CurTime()//'.' + WRITE (69,'(:,A11)', ADVANCE='no' ) 'Time ' + do j = 1, p%numBlades + do i = 1, p%numBladeNodes + chanPrefix = "B"//trim(num2lstr(j))//"N"//trim(num2lstr(i)) + WRITE (69,'(:,A11)', ADVANCE='no' ) 'ALPHA'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'VREL'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CN'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CC'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CL'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CD'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CM'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNCP'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNIQ'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNPOT'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'DPP'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNP'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'FSP'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'DF'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CNV'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'TAUV'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'LESF'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'TESF'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'VRTX'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CVN'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CMI'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CMQ'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'CMV'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'AFEP'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'DFAF'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'PMC'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'T_f'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'T_V'//chanPrefix + WRITE (69,'(:,A11)', ADVANCE='no' ) 'dS'//chanPrefix + end do + end do + write (69,'(A)') ' ' + + WRITE (69,'(:,A9)', ADVANCE='no' ) ' (s)' + do j = 1, p%numBlades + do i = 1, p%numBladeNodes + WRITE (69,'(:,A11)', ADVANCE='no' ) '(deg)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(m/s)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + WRITE (69,'(:,A11)', ADVANCE='no' ) '(-)' + end do + end do + write (69,'(A)') ' ' + +#endif + + + do j = 1,p%numBlades + do i = 1,p%numBladeNodes ! Loop over blades and nodes + + ! u_UA values were not set in UA_Init, so we will use arbitrary values for M,Re, and alpha, and we need them only because we're trying to determine if C_nalpha is 0 so we can shut off UA. + + M = 0.1_ReKi + Re = 10.0_ReKi + alpha = 2.0*D2R + !M = u_UA%U / p%UA%a_s + !call UA_CheckMachNumber(M, misc%UA%FirstWarn_M, ErrStat2, ErrMsg2 ) + + call AFI_GetAirfoilParams( AFInfo(p%AFindx(i,j)), M, Re, alpha0, alpha1, alpha2, eta_e, C_nalpha, C_nalpha_circ, & + T_f0, T_V0, T_p, T_VL, St_sh, b1, b2, b5, A1, A2, A5, S1, S2, S3, S4, Cn1, Cn2, Cd0, Cm0, k0, k1, k2, k3, k1_hat, x_cp_bar, filtCutOff, errMsg2, errStat2 ) + ! AFI_GetAirfoilParams does not set errors + + if ( EqualRealNos(C_nalpha, 0.0_ReKi) .and. OtherState%UA_Flag(i,j) ) then + OtherState%UA_Flag(i,j) = .false. + call WrScr( 'Warning: Turning off Unsteady Aerodynamics because C_nalpha is 0. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) + end if + + + if ( p%CavitCheck .and. OtherState%UA_Flag(i,j)) then + OtherState%UA_Flag(i,j) = .false. + call SetErrStat( ErrID_Fatal, 'Turn off Unsteady Aerodynamics to do a cavitation check', ErrStat, ErrMsg, RoutineName ) + end if + + + + + call WrScr (' p%InCol_Cpmin='//trim(num2lstr((p%InCol_Cpmin)))) + + + end do + end do + + + end if + !............................................................................................ + ! Define initial guess for the system inputs here: + !............................................................................................ + + ! allocate all the arrays that store data in the input type: + call BEMT_AllocInput( u, p, errStat2, errMsg2 ) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) then + call cleanup() + return + end if + + + + + !............................................................................................ + ! Define system output initializations (set up meshes) here: + !............................................................................................ + !............................................................................................ + ! Define initialization-routine output here: + !............................................................................................ + + !call BEMT_InitOut(p, InitOut, errStat2, errMsg2) + !call CheckError( errStat2, errMsg2 ) + + call BEMT_AllocOutput(y, p, errStat2, errMsg2) !u is sent so we can create sibling meshes + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) then + call cleanup() + return + end if + + + misc%useFrozenWake = .FALSE. + + InitOut%Version = BEMT_Ver + + + + !............................................................................................ + ! If you want to choose your own rate instead of using what the glue code suggests, tell the glue code the rate at which + ! this module must be called here: + !............................................................................................ + + Interval = p%DT + + + ! Print the summary file if requested: + !IF (InputFileData%SumPrint) THEN + ! CALL BEMT_PrintSum( p, OtherState, GetAdamsVals, ErrStat2, ErrMsg2 ) + ! call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + !END IF + + ! Destroy the InputFileData structure (deallocate arrays) + + !CALL BEMT_DestroyInputFile(InputFileData, ErrStat2, ErrMsg2 ) + ! call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + +CONTAINS + !............................................................................................................................... + SUBROUTINE Cleanup() + ! This subroutine cleans up local variables that may have allocatable arrays + !............................................................................................................................... + + call UA_DestroyInput( u_UA, ErrStat2, ErrMsg2 ) + call UA_DestroyInitInput( Init_UA_Data, ErrStat2, ErrMsg2 ) + call UA_DestroyInitOutput( InitOutData_UA, ErrStat2, ErrMsg2 ) + + END SUBROUTINE Cleanup + +END SUBROUTINE BEMT_Init +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_End( u, p, x, xd, z, OtherState, y, ErrStat, ErrMsg ) +! This routine is called at the end of the simulation. +!.................................................................................................................................. + + TYPE(BEMT_InputType), INTENT(INOUT) :: u ! System inputs + TYPE(BEMT_ParameterType), INTENT(INOUT) :: p ! Parameters + TYPE(BEMT_ContinuousStateType), INTENT(INOUT) :: x ! Continuous states + TYPE(BEMT_DiscreteStateType), INTENT(INOUT) :: xd ! Discrete states + TYPE(BEMT_ConstraintStateType), INTENT(INOUT) :: z ! Constraint states + TYPE(BEMT_OtherStateType), INTENT(INOUT) :: OtherState ! Other states + TYPE(BEMT_OutputType), INTENT(INOUT) :: y ! System outputs + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + + + ! Initialize ErrStat + + ErrStat = ErrID_None + ErrMsg = "" + + + ! Place any last minute operations or calculations here: + + + ! Close files here: + + + + ! Destroy the input data: + + CALL BEMT_DestroyInput( u, ErrStat, ErrMsg ) + + + ! Destroy the parameter data: + + CALL BEMT_DestroyParam( p, ErrStat, ErrMsg ) + + + ! Destroy the state data: + + CALL BEMT_DestroyContState( x, ErrStat, ErrMsg ) + CALL BEMT_DestroyDiscState( xd, ErrStat, ErrMsg ) + CALL BEMT_DestroyConstrState( z, ErrStat, ErrMsg ) + CALL BEMT_DestroyOtherState( OtherState, ErrStat, ErrMsg ) + + + ! Destroy the output data: + + CALL BEMT_DestroyOutput( y, ErrStat, ErrMsg ) + +#ifdef UA_OUTS + CLOSE(69) +#endif + + +END SUBROUTINE BEMT_End + + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_UpdateStates( t, n, u1, u2, p, x, xd, z, OtherState, AFInfo, m, errStat, errMsg ) +! Loose coupling routine for solving for constraint states, integrating continuous states, and updating discrete states +! Continuous, constraint, discrete, and other states are updated for t + Interval +! +! NOTE: This is a non-standard framework interface!!!!! GJH +!.................................................................................................................................. + + real(DbKi), intent(in ) :: t ! Current simulation time in seconds + integer(IntKi), intent(in ) :: n ! Current simulation time step n = 0,1,... + type(BEMT_InputType), intent(in ) :: u1,u2 ! Input at t and t+ dt + !real(DbKi), intent(in ) :: utime ! Times associated with u(:), in seconds + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_ContinuousStateType), intent(inout) :: x ! Input: Continuous states at t; + ! Output: Continuous states at t + Interval + type(BEMT_DiscreteStateType), intent(inout) :: xd ! Input: Discrete states at t; + ! Output: Discrete states at t + Interval + type(BEMT_ConstraintStateType), intent(inout) :: z ! Input: Constraint states at t; + ! Output: Constraint states at t + Interval + type(BEMT_OtherStateType), intent(inout) :: OtherState ! Input: Other states at t; + ! Output: Other states at t + Interval + type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables + type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + + integer(IntKi) :: i,j + type(UA_InputType) :: u_UA + real(ReKi) :: chi, axInduction, tanInduction ! BEMT outputs + real(ReKi) :: Rtip, Re, Vrel, fzero, phitemp + logical :: IsValidSolution !< this is set to false if k<=1 in propeller brake region or k<-1 in momentum region, indicating an invalid solution + + character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_UpdateStates' + + character(20) :: NodeTxt + + ErrStat = ErrID_None + ErrMsg = "" + + !............................................................................................................................... + ! if we haven't initialized z%phi, we want to get a better guess as to what the actual values of phi at t are: + !............................................................................................................................... + + if (.not. OtherState%nodesInitialized) then + if (p%useInduction) then + + do j = 1,p%numBlades ! Loop through all blades + do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements + NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' + + call BEMT_UnCoupledSolve(z%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u1%rlocal(i,j), p%chord(i,j), u1%theta(i,j), & + u1%Vx(i,j), u1%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & + p%maxIndIterations, p%aTol, OtherState%ValidPhi(i,j), errStat2, errMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (errStat >= AbortErrLev) return + end do + end do + + else + ! We'll simply compute a geometrical phi based on both induction factors being 0.0 + do j = 1,p%numBlades ! Loop through all blades + do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements + z%phi(i,j) = ComputePhiWithInduction(u1%Vx(i,j), u1%Vy(i,j), 0.0_ReKi, 0.0_ReKi) + end do + end do + + end if + OtherState%nodesInitialized = .true. ! state at t+1 + end if + + !............................................................................................................................... + ! compute states at t+1 + !............................................................................................................................... + + + do j = 1,p%numBlades + + ! Locate the maximum rlocal value for this time step and this blade. This is passed to the solve as Rtip + if ( p%useInduction ) then + Rtip = 0.0_ReKi + do i = 1,p%numBladeNodes + Rtip = max( Rtip, u1%rlocal(i,j) ) + end do + end if + + do i = 1,p%numBladeNodes + + NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' + + ! We only update the UnsteadyAero states if we have unsteady aero turned on for this node + if (OtherState%UA_Flag(i,j) .and. n > 0) then + + ! Set the active blade element for UnsteadyAero + m%UA%iBladeNode = i + m%UA%iBlade = j + + ! Initialize these variables + u_UA%alpha = z%phi(i,j) - u1%theta(i,j) + axInduction = 0.0_ReKi + tanInduction = 0.0_ReKi + + + if ( p%useInduction ) then + if (OtherState%ValidPhi(i,j)) then + + ! Compute Re based on zero inductions (axInduction, tanInduction), this would needed for the airfoil lookups + ! which occur within BEMTU_InductionWithResidual if we had implemented airfoil tables which are dependent on Reynold's number: Currently unused, 4-Nov-2015 + call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, u1%Vx(i,j), u1%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, Vrel, Re ) + + ! Need to get the induction factors for these conditions without skewed wake correction and without UA + ! COMPUTE: axInduction, tanInduction + fzero = BEMTU_InductionWithResidual(z%phi(i,j), u_UA%alpha, Re, p%numBlades, u1%rlocal(i,j), p%chord(i,j), AFInfo(p%AFIndx(i,j)), & + u1%Vx(i,j), u1%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & + axInduction, tanInduction, IsValidSolution, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (errStat >= AbortErrLev) return + + ! Apply the skewed wake correction to the axial induction + if ( p%skewWakeMod == SkewMod_PittPeters ) then + if ( .not.( p%useTiploss .and. EqualRealNos(p%tipLossConst(i,j),0.0_ReKi) ) .and. .not. ( p%useHubloss .and. EqualRealNos(p%hubLossConst(i,j),0.0_ReKi) ) ) then + ! Correct for skewed wake, by recomputing axInduction + call ApplySkewedWakeCorrection( u1%Vx(i,j), u1%Vy(i,j), u1%psi(j), u1%chi0, u1%rlocal(i,j)/Rtip, axInduction, tanInduction, chi, ErrStat2, ErrMsg2 ) !replaced phiOut with phitemp RRD + ! ApplySkewedWakeCorrection doesn't produce errors + end if + end if + + ! recompute phi and alpha + + ! we're recomputing phi because we may have modified axInduction or tanInduction in BEMTU_InductionWithResidual and/or ApplySkewedWakeCorrection + phitemp = ComputePhiWithInduction( u1%Vx(i,j), u1%Vy(i,j), axInduction, tanInduction ) + ! angle of attack + u_UA%alpha = phitemp - u1%theta(i,j) + + else + axInduction = 0.0_ReKi + tanInduction = 0.0_ReKi + phitemp = ComputePhiWithInduction( u1%Vx(i,j), u1%Vy(i,j), axInduction, tanInduction ) + ! angle of attack + u_UA%alpha = phitemp - u1%theta(i,j) + + end if + end if + + + ! Need to compute local velocity including both axial and tangential induction + ! COMPUTE: u_UA%U, u_UA%Re + call BEMTU_Wind( axInduction, tanInduction, u1%Vx(i,j), u1%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, u_UA%U, u_UA%Re) !replaced phiOut with phitemp RRD + + if ( abs(u_UA%alpha) >= AFInfo(p%AFIndx(i,j))%Table(1)%UA_BL%UACutout ) then ! Is the angle of attack larger than the UA cut-out for this airfoil? + OtherState%UA_Flag(i,j) = .FALSE. + call WrScr( 'Warning: Turning off Unsteady Aerodynamics due to high angle-of-attack. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) + elseif (EqualRealNos(u_UA%U, 0.0_ReKi) ) then + OtherState%UA_Flag(i,j) = .FALSE. + call WrScr( 'Warning: Turning off Unsteady Aerodynamics due to zero relative velocity. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) + + else + ! COMPUTE: xd%UA, OtherState%UA + call UA_UpdateStates( i, j, u_UA, p%UA, xd%UA, OtherState%UA, AFInfo(p%AFIndx(i,j)), m%UA, errStat2, errMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (errStat >= AbortErrLev) return + end if + + end if ! if (OtherState%UA_Flag(i,j)) then + + ! Now we need to update the inflow angle state, z%phi, independent of UnsteadyAero + if ( p%useInduction ) then + ! Solve this without any skewed wake correction and without UA + ! call BEMT_UnCoupledSolve2(i, j, u, p, z, Rtip, AFInfo, phiOut, axIndOut, tanIndOut, errStat, errMsg) + ! COMPUTE: z%phi(i,j) + call BEMT_UnCoupledSolve(z%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u2%rlocal(i,j), p%chord(i,j), u2%theta(i,j), & + u2%Vx(i,j), u2%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & + p%maxIndIterations, p%aTol, OtherState%ValidPhi(i,j), errStat2, errMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (errStat >= AbortErrLev) return + + else + ! We'll simply compute a geometrical phi based on both induction factors being 0.0 + z%phi(i,j) = ComputePhiWithInduction(u2%Vx(i,j), u2%Vy(i,j), 0.0_ReKi, 0.0_ReKi) + end if + + end do + end do + +end subroutine BEMT_UpdateStates + + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat, errMsg ) +! 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. +! NOTE: the descriptions of the output channels are not given here. Please see the included OutListParameters.xlsx sheet for +! for a complete description of each output parameter. +! NOTE: no matter how many channels are selected for output, all of the outputs are calcalated +! All of the calculated output channels are placed into the OtherState%AllOuts(:), while the channels selected for outputs are +! placed in the y%WriteOutput(:) array. +!.................................................................................................................................. + + + real(DbKi), intent(in ) :: t ! Current simulation time in seconds + type(BEMT_InputType), intent(in ) :: u ! Inputs at Time t + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_ContinuousStateType), intent(in ) :: x ! Continuous states at t + type(BEMT_DiscreteStateType), intent(in ) :: xd ! Discrete states at t + type(BEMT_ConstraintStateType), intent(in ) :: z ! Constraint states at t + type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other states at t + type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables + type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data + type(BEMT_OutputType), intent(inout) :: y ! Outputs computed at t (Input only so that mesh con- + ! nectivity information does not have to be recalculated) + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + + + ! Local variables: + + + real(ReKi) :: Re, fzero, theta, Vx, Vy + real(ReKi) :: Rtip, SigmaCavitCrit, SigmaCavit ! maximum rlocal value for node j over all blades + + integer(IntKi) :: i ! Generic index + integer(IntKi) :: j ! Loops through nodes / elements + + character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_CalcOutput' + + character(20) :: NodeTxt + + +#ifdef UA_OUTS + integer(IntKi) :: k +#endif + + logical, parameter :: UpdateValues = .TRUE. ! determines if the OtherState values need to be updated + type(BEMT_ContinuousStateType) :: dxdt ! Continuous state derivs at t + real(ReKi) :: Vrel + logical :: IsValidSolution !< this is set to false if k<=1 in propeller brake region or k<-1 in momentum region, indicating an invalid solution + ! Initialize some output values + errStat = ErrID_None + errMsg = "" + + + !............................................................................................................................... + ! if we haven't initialized z%phi, we want to get a better guess as to what the actual values of phi are: + !............................................................................................................................... + + if (OtherState%nodesInitialized) then + y%phi = z%phi + else + if (p%useInduction) then + + do j = 1,p%numBlades ! Loop through all blades + do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements + NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' + + y%phi(i,j) = z%phi(i,j) + call BEMT_UnCoupledSolve(y%phi(i,j), p%numBlades, p%airDens, p%kinVisc, AFInfo(p%AFIndx(i,j)), u%rlocal(i,j), p%chord(i,j), u%theta(i,j), & + u%Vx(i,j), u%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & + p%maxIndIterations, p%aTol, IsValidSolution, errStat2, errMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (errStat >= AbortErrLev) return + end do + end do + + else + ! We'll simply compute a geometrical phi based on both induction factors being 0.0 + do j = 1,p%numBlades ! Loop through all blades + do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements + y%phi(i,j) = ComputePhiWithInduction(u%Vx(i,j), u%Vy(i,j), 0.0_ReKi, 0.0_ReKi) + end do + end do + + end if + end if + + ! Array OtherState%AllOuts() is initialized to 0.0 in initialization, so we are not going to reinitialize it here. + + + !............................................................................................................................... + ! Calculate all of the total forces and moments using all of the partial forces and moments calculated in RtHS(). Also, + ! calculate all of the total angular and linear accelerations using all of the partial accelerations calculated in RtHS(). + ! To do this, first initialize the variables using the portions not associated with the accelerations. Then add the portions + ! associated with the accelerations one by one: + !............................................................................................................................... + + do j = 1,p%numBlades ! Loop through all blades + + ! Locate the maximum rlocal value for this time step and this blade. This is passed to the solve as Rtip + Rtip = 0.0_ReKi + do i = 1,p%numBladeNodes + Rtip = max( Rtip, u%rlocal(i,j) ) + end do + + do i = 1,p%numBladeNodes ! Loop through the blade nodes / elements + + NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' + + ! local velocities and twist angle + Vx = u%Vx(i,j) + Vy = u%Vy(i,j) + !theta = u%theta(i,j) + + + + ! Set the active blade element for UnsteadyAero + m%UA%iBladeNode = i + m%UA%iBlade = j + + ! Copy the current state to the outputs structure + !y%phi(i,j) = z%phi(i,j) ! this was done above (to take possible initializion into account) + ! angle of attack + y%AOA(i,j) = y%phi(i,j) - u%theta(i,j) + + ! initialize other outputs assuming no induction or skewed wake corrections + y%axInduction(i,j) = 0.0_ReKi + y%tanInduction(i,j) = 0.0_ReKi + y%chi(i,j) = u%chi0 ! with no induction, chi = chi0 + + if ( p%useInduction ) then + + if (m%UseFrozenWake) then + y%axInduction(i,j) = -m%AxInd_op(i,j) / u%Vx(i,j) + y%tanInduction(i,j) = m%TnInd_op(i,j) / u%Vy(i,j) + y%phi(i,j) = ComputePhiWithInduction( u%Vx(i,j), u%Vy(i,j), y%axInduction(i,j), y%tanInduction(i,j) ) + y%AOA(i,j) = y%phi(i,j) - u%theta(i,j) + else + if (OtherState%ValidPhi(i,j)) then + ! Compute Re based on zero inductions (axInduction, tanInduction), this would needed for the airfoil lookups + ! which occur within BEMTU_InductionWithResidual if we had implemented airfoil tables which are dependent on Reynold's number: Currently unused, 4-Nov-2015 + call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, Vrel, Re ) + + ! Compute inductions using steady aero. NOTE: When we use Re, we are using uninduced Re for Steady Airfoil Coef looks here + fzero = BEMTU_InductionWithResidual(y%phi(i,j), y%AOA(i,j), Re, p%numBlades, u%rlocal(i,j), p%chord(i,j), AFInfo(p%AFindx(i,j)), & + u%Vx(i,j), u%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & + y%axInduction(i,j), y%tanInduction(i,j), IsValidSolution, errStat2, errMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (errStat >= AbortErrLev) return + + ! Apply the skewed wake correction to the axial induction (y%axInduction) + if ( p%skewWakeMod == SkewMod_PittPeters ) then + if ( .not.( p%useTiploss .and. EqualRealNos(p%tipLossConst(i,j),0.0_ReKi) ) .and. .not. ( p%useHubloss .and. EqualRealNos(p%hubLossConst(i,j),0.0_ReKi) ) ) then + call ApplySkewedWakeCorrection( u%Vx(i,j), u%Vy(i,j), u%psi(j), u%chi0, u%rlocal(i,j)/Rtip, y%axInduction(i,j), y%tanInduction(i,j), y%chi(i,j), ErrStat2, ErrMsg2 ) + ! ApplySkewedWakeCorrection doesn't set errors + end if + end if + + ! recompute y%phi, y%AOA: + ! we're recomputing phi because we may have modified axInduction or tanInduction in BEMTU_InductionWithResidual and/or ApplySkewedWakeCorrection + y%phi(i,j) = ComputePhiWithInduction( u%Vx(i,j), u%Vy(i,j), y%axInduction(i,j), y%tanInduction(i,j) ) + ! angle of attack + y%AOA(i,j) = y%phi(i,j) - u%theta(i,j) + end if ! ValidPhi + + end if ! UseFrozenWake + + end if + + ! Compute Re, Vrel based on current values of axInduction, tanInduction + call BEMTU_Wind( y%axInduction(i,j), y%tanInduction(i,j), u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, y%Vrel(I,J), y%Re(i,j) ) + + ! Now depending on the option for UA get the airfoil coefs, Cl, Cd, Cm for unsteady or steady implementation + if (OtherState%UA_Flag(i,j) .and. t > 0.0_DbKi) then + call Compute_UA_AirfoilCoefs( y%AOA(i,j), y%Vrel(I,J), y%Re(i,j), AFInfo(p%AFindx(i,j)), p%UA, xd%UA, OtherState%UA, m%y_UA, m%UA, & + y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), errStat2, errMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (errStat >= AbortErrLev) return + + ! NOTE: In this version, we are disabling the UA Cm values only we have performed further validation. GJH 3/9/2016 + ! Obtain the steady state Cm value from the static tables + !call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & + ! localCl, localCd, y%Cm(i,j), errStat2, errMsg2 ) + ! call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + ! if (errStat >= AbortErrLev) return + + else + ! TODO: When we start using Re, should we use the uninduced Re since we used uninduced Re to solve for the inductions!? Probably this won't change, instead create a Re loop up above. + call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & + y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), y%Cpmin(i,j), errStat2, errMsg2 ) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) + if (errStat >= AbortErrLev) return + + + + + if ( p%CavitCheck .and. y%Cpmin(i,j)==0) then + call SetErrStat( ErrID_Fatal, 'No Cpmin data for cavitation check', ErrStat, ErrMsg, RoutineName ) + end if + + + if ( p%CavitCheck ) then ! This calculates the cavitation number for the airfoil at the node in quesiton, and compares to the critical cavitation number based on the vapour pressure and submerged depth + + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this + SigmaCavit= -1* y%Cpmin(i,j) ! Actual cavitation number on blade node j + + + if (SigmaCavitCrit < SigmaCavit) then + call WrScr( NewLine//'FAILED CAVITATION CHECK'//' Node # = '//trim(num2lstr(i)//'Blade # = '//trim(num2lstr(j)))) + + end if + + if (y%Vrel(i,j) == 0) then !if Vrel = 0 in certain cases when Prandtls tip and hub loss factors are used, use the relative verlocity without induction + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * (sqrt((Vx**2 + Vy**2)))**2) ! Critical value of Sigma, cavitation if we go over this + + end if + + y%SigmaCavit(i,j)= SigmaCavit + y%SigmaCavitCrit(i,j)=SigmaCavitCrit + + end if + + + end if + + + ! Compute Cx, Cy given Cl, Cd and phi + ! NOTE: For these calculations we force the useAIDrag and useTIDrag flags to .TRUE. + call Transform_ClCd_to_CxCy( y%phi(i,j), .TRUE., .TRUE., y%Cl(i,j), y%Cd(i,j),y%Cx(i,j), y%Cy(i,j) ) + + enddo ! I - Blade nodes / elements + + enddo ! J - All blades + +#ifdef UA_OUTS + ! if ( mod(REAL(t,ReKi),.1) < p%dt) then + WRITE (69, '(F9.4,'//trim(num2lstr(p%numBladeNodes*p%numBlades*p%UA%NumOuts))//'(:,A,ES12.3E3))') t, (' ', m%y_UA%WriteOutput(k), k=1,p%UA%NumOuts*p%numBladeNodes*p%numBlades) + ! end if + !WRITE (69, '((F8.3,'//TRIM(num2lstr(13*p%numBladeNodes*p%numBlades))//'(:,A,ES10.3E2))') + !Frmt = '(F8.3,'//TRIM(Int2LStr(p%WAMIT%NumOuts+p%Morison%NumOuts))//'(:,A,'//TRIM( p%OutFmt )//'))' + !Frmt = '('ES10.3E2,'//TRIM(13*p%numBladeNodes*p%numBlades)//'(:,A,'ES10.3E2'))' + + +#endif + + !............................................................................................................................... + ! Place the selected output channels into the WriteOutput(:) array with the proper sign: + !............................................................................................................................... + + call BEMT_MapOutputs(p, OtherState, y, errStat2, errMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (errStat >= AbortErrLev) return + + !DO I = 1,p%NumOuts ! Loop through all selected output channels + ! + ! y%WriteOutput(I) = p%OutParam(I)%SignM * OtherState%AllOuts( p%OutParam(I)%Indx ) + ! + !ENDDO ! I - All selected output channels + + + !............................................................................................................................... + ! Outputs required for AeroDyn + !............................................................................................................................... + + !........... + ! Blade elements: + !........... + + + return + + +end subroutine BEMT_CalcOutput + + +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_CalcContStateDeriv( t, u, p, x, xd, z, OtherState, m, dxdt, ErrStat, ErrMsg ) +! Tight coupling routine for computing derivatives of continuous states +!.................................................................................................................................. + + REAL(DbKi), INTENT(IN ) :: t ! Current simulation time in seconds + TYPE(BEMT_InputType), INTENT(IN ) :: u ! Inputs at t + TYPE(BEMT_ParameterType), INTENT(IN ) :: p ! Parameters + TYPE(BEMT_ContinuousStateType), INTENT(IN ) :: x ! Continuous states at t + TYPE(BEMT_DiscreteStateType), INTENT(IN ) :: xd ! Discrete states at t + TYPE(BEMT_ConstraintStateType), INTENT(IN ) :: z ! Constraint states at t + TYPE(BEMT_OtherStateType), INTENT(IN ) :: OtherState ! Other states at t + type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables + TYPE(BEMT_ContinuousStateType), INTENT( OUT) :: dxdt ! Continuous state derivatives at t + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + + + ! Initialize ErrStat + + ErrStat = ErrID_None + ErrMsg = "" - implicit none + dxdt%DummyContState = 0.0_ReKi + - integer(IntKi), public, parameter :: SkewMod_Uncoupled = 1 ! Uncoupled (no correction) [-] - integer(IntKi), public, parameter :: SkewMod_PittPeters = 2 ! Pitt/Peters [-] - integer(IntKi), public, parameter :: SkewMod_Coupled = 3 ! Coupled [-] +END SUBROUTINE BEMT_CalcContStateDeriv +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_UpdateDiscState( t, n, u, p, x, xd, z, OtherState, m, ErrStat, ErrMsg ) +! Tight coupling routine for updating discrete states +!.................................................................................................................................. + + REAL(DbKi), INTENT(IN ) :: t ! Current simulation time in seconds + INTEGER(IntKi), INTENT(IN ) :: n ! Current step of the simulation: t = n*Interval + TYPE(BEMT_InputType), INTENT(IN ) :: u ! Inputs at t + TYPE(BEMT_ParameterType), INTENT(IN ) :: p ! Parameters + TYPE(BEMT_ContinuousStateType), INTENT(IN ) :: x ! Continuous states at t + TYPE(BEMT_DiscreteStateType), INTENT(INOUT) :: xd ! Input: Discrete states at t; + ! Output: Discrete states at t + Interval + TYPE(BEMT_ConstraintStateType), INTENT(IN ) :: z ! Constraint states at t + TYPE(BEMT_OtherStateType), INTENT(IN ) :: OtherState ! Other states at t + type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + + ! Initialize ErrStat + + ErrStat = ErrID_None + ErrMsg = "" + + + ! Update discrete states here: + + ! StateData%DiscState = + +END SUBROUTINE BEMT_UpdateDiscState +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine BEMT_CalcConstrStateResidual( Time, u, p, x, xd, z, OtherState, m, z_residual, AFInfo, ErrStat, ErrMsg ) +! Tight coupling routine for solving for the residual of the constraint state equations +!.................................................................................................................................. + + real(DbKi), intent(in ) :: Time ! Current simulation time in seconds + type(BEMT_InputType), intent(in ) :: u ! Inputs at Time + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_ContinuousStateType), intent(in ) :: x ! Continuous states at Time + type(BEMT_DiscreteStateType), intent(in ) :: xd ! Discrete states at Time + type(BEMT_ConstraintStateType), intent(in ) :: z ! Constraint states at Time (possibly a guess) + type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other states at Time + type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables + type(BEMT_ConstraintStateType), intent(inout) :: z_residual ! Residual of the constraint state equations using + ! the input values described above + type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data + integer(IntKi), intent( out) :: ErrStat ! Error status of the operation + character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + + !# set epsilon + !REAL(ReKi), PARAMETER ::epsilon = 1e-6 - !1e-6 works for double precision, but not single precision - real(ReKi), public, parameter :: BEMT_epsilon2 = 10.0_ReKi*sqrt(epsilon(1.0_ReKi)) !this is the tolerance in radians for values around singularities in phi (i.e., phi=0 and phi=pi/2); must be large enough so that EqualRealNos(BEMT_epsilon2, 0.0_ReKi) is false + ! Local variables + INTEGER :: i,j + real(ReKi) axInduction, tanInduction, Vrel, Re + character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_CalcConstrStateResidual' + logical :: IsValidSolution ! placeholder for flag to determine if the residual solution is invalid + + ErrStat = ErrID_None + ErrMsg = "" - private - public :: Compute_UA_AirfoilCoefs - public :: ComputeSteadyAirfoilCoefs - public :: UncoupledErrFn - public :: BEMTU_InductionWithResidual - public :: ApplySkewedWakeCorrection - public :: Transform_ClCd_to_CxCy + if (p%useInduction) then + + if ( m%UseFrozenWake ) then ! we are linearizing with frozen wake assumption; i.e., p%FrozenWake is true and this was called from the linearization routine + do j = 1,p%numBlades + do i = 1,p%numBladeNodes + Z_residual%phi(i,j) = sin(z%phi(i,j)) * (u%Vy(i,j) + m%TnInd_op(i,j)) - cos(z%phi(i,j)) * (u%Vx(i,j) + m%AxInd_op(i,j)) + end do + end do + + else + + do j = 1,p%numBlades + do i = 1,p%numBladeNodes + + ! Need to initialize the inductions to zero for this calculation (NOTE: They are actually computed within UnCpldReFn(), but still need to be intialized to zero!) + axInduction = 0.0_ReKi + tanInduction = 0.0_ReKi + + ! Need to call BEMTU_Wind to obtain Re, even though we aren't using it in this version. + call BEMTU_Wind( axInduction, tanInduction, u%Vx(i,j), u%Vy(i,j), p%chord(i,j), p%airDens, p%kinVisc, Vrel, Re ) + + ! Solve for the constraint states here: + Z_residual%phi(i,j) = UncoupledErrFn(z%phi(i,j), u%theta(i,j), Re, p%numBlades, u%rlocal(i,j), p%chord(i,j), AFInfo(p%AFindx(i,j)), & + u%Vx(i,j), u%Vy(i,j), p%useTanInd, p%useAIDrag, p%useTIDrag, p%useHubLoss, p%useTipLoss, p%hubLossConst(i,j), p%tipLossConst(i,j), & + IsValidSolution, ErrStat2, ErrMsg2) + call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat >= AbortErrLev) return + + end do + end do + + end if ! not frozen wake + + else + + do j = 1,p%numBlades + do i = 1,p%numBladeNodes + Z_residual%Phi(i,j) = sin(z%phi(i,j)) * u%Vy(i,j) - cos(z%phi(i,j)) * u%Vx(i,j) + end do + end do + + + end if - public :: BEMTU_Wind - public :: VelocityIsZero -contains -!.................................................................................................................................. - function VelocityIsZero ( v ) +END SUBROUTINE BEMT_CalcConstrStateResidual - ! passed variables +!---------------------------------------------------------------------------------------------------------------------------------- +!> This subroutine computes the BEMT inductions that are frozen when linearizing with the FrozenWake flag. +!> It first calls BEMT_CalcOutput to compute y%tanInduction and y%axInduction at this operating point. +!SUBROUTINE computeFrozenWake( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat, errMsg ) +SUBROUTINE computeFrozenWake( u, p, y, m ) +!.................................................................................................................................. - REAL(ReKi), INTENT(IN ) :: v !< the velocity that needs to be compared with zero + + !real(DbKi), intent(in ) :: t ! Current simulation time in seconds + type(BEMT_InputType), intent(in ) :: u ! Inputs at Time t + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + !type(BEMT_ContinuousStateType), intent(in ) :: x ! Continuous states at t + !type(BEMT_DiscreteStateType), intent(in ) :: xd ! Discrete states at t + !type(BEMT_ConstraintStateType), intent(in ) :: z ! Constraint states at t + !type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other states at t + type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables + !type(AFInfoType), intent(in ) :: AFInfo(:) ! The airfoil parameter data + type(BEMT_OutputType), intent(inout) :: y ! Outputs computed at t (Input only so that mesh con- + ! nectivity information does not have to be recalculated) + !integer(IntKi), intent( out) :: errStat ! Error status of the operation + !character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - LOGICAL :: VelocityIsZero !< .true. if and only if the velocity is (almost) equal to zero + ! local variables + INTEGER(IntKi) :: j,k ! loop counters + character(*), parameter :: RoutineName = 'computeFrozenWake' + ! get a and aprime + !call BEMT_CalcOutput(t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat, errMsg) + + do k = 1,p%numBlades + do j = 1,p%numBladeNodes + + m%AxInd_op(j,k) = - u%Vx(j,k) * y%axInduction( j,k) + m%TnInd_op(j,k) = u%Vy(j,k) * y%tanInduction(j,k) + + end do + end do - VelocityIsZero = abs(v) < 0.001_ReKi ! tolerance in m/s for what we consider zero velocity for BEM computations + + +END SUBROUTINE computeFrozenWake +!---------------------------------------------------------------------------------------------------------------------------------- +!> This subroutine checks for BEMT inputs that are invalid when linearizing constraint state equations. +SUBROUTINE CheckLinearizationInput(p, u, z, m, OtherState, ErrStat, ErrMsg) + + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_InputType), intent(in ) :: u ! Inputs at the operating point + type(BEMT_ConstraintStateType), intent(in ) :: z ! Constraint states at the operating point + type(BEMT_MiscVarType), intent(in ) :: m ! Misc/optimization variables + type(BEMT_OtherStateType), intent(in ) :: OtherState ! Other state at the operating point + integer(IntKi), intent( out) :: ErrStat ! Error status of the operation + character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + ! local variables + INTEGER(IntKi) :: j,k ! loop counters + character(*), parameter :: RoutineName = 'CheckLinearizationInput' + - end function VelocityIsZero -!.................................................................................................................................. + ErrStat = ErrID_None + ErrMsg = '' - subroutine BEMTU_Wind( axInduction, tanInduction, Vx, Vy, chord, airDens, mu, W, Re ) + if (p%UseInduction) then + + do k = 1,p%numBlades + do j = 1,p%numBladeNodes + if (.not. OtherState%ValidPhi(j,k)) then + call SetErrSTat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + ": Current operating point does not contain a valid value of phi.",ErrStat,ErrMsg,RoutineName) + return + end if + + end do + end do + + - - ! in - real(ReKi), intent(in) :: axInduction, tanInduction, Vx, Vy - real(ReKi), intent(in) :: chord, airDens, mu + if ( m%UseFrozenWake ) then ! we are linearizing with frozen wake assumption (i.e., p%FrozenWake is true and this is called from linearization routine) + + do k = 1,p%numBlades + do j = 1,p%numBladeNodes + + if ( VelocityIsZero( u%Vy(j,k)+m%TnInd_op(j,k)) .and. VelocityIsZero( u%Vx(j,k)+m%AxInd_op(j,k) ) ) then + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + ": residual is undefined because u%Vy + TnInd_op = u%Vx + AxInd_op = 0.",ErrStat,ErrMsg,RoutineName) + return + end if + + end do + end do + + else + + do k = 1,p%numBlades + do j = 1,p%numBladeNodes + + if ( EqualRealNos(z%phi(j,k), 0.0_ReKi) ) then + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + ": residual is discontinuous or undefined because z%phi = 0.",ErrStat,ErrMsg,RoutineName) + return + else if ( VelocityIsZero(u%Vy(j,k)) ) then + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + ": residual is discontinuous or undefined because u%Vy = 0.",ErrStat,ErrMsg,RoutineName) + return + else if ( VelocityIsZero(u%Vx(j,k)) ) then + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + ": residual is discontinuous or undefined because u%Vx = 0.",ErrStat,ErrMsg,RoutineName) + return + end if + + end do + end do + + end if + + + + else ! .not. p%UseInduction: + + do k = 1,p%numBlades + do j = 1,p%numBladeNodes + + if ( EqualRealNos( u%Vy(j,k), 0.0_ReKi ) .and. EqualRealNos( u%Vx(j,k), 0.0_ReKi ) ) then + call SetErrStat(ErrID_Fatal,"Blade"//trim(num2lstr(k))//', node '//trim(num2lstr(k))//& + ": residual is undefined because u%Vy = u%Vx = 0.",ErrStat,ErrMsg,RoutineName) + return + end if + + end do + end do + - ! out - real(ReKi), intent(out) :: Re, W - - - + + end if + +END SUBROUTINE CheckLinearizationInput +!---------------------------------------------------------------------------------------------------------------------------------- +!> This gets the constraint-state perturbations for linearization about a given operating point. This returns two deltas (one plus +!! and one minus) such that z_op+dz_p and z_op-dz_m are in the same solution region (or that they are in adjacent regions that have +!! continuous solution regions [i.e, the pi/2 boundary is okay because it is continuous across the momentum/empirical regions]). +SUBROUTINE Get_phi_perturbations(p, m, z_op, dz_p, dz_m) - ! avoid numerical errors when angle is close to 0 or 90 deg - ! and other induction factor is at some ridiculous value - ! this only occurs when iterating on Reynolds number - ! during the phi sweep where a solution has not been found yet - !if ( abs(axInduction) > 10 ) then - ! W = Vy*(1+tanInduction)/cos(phi) - !else if ( abs(tanInduction) > 10 ) then - ! W = Vx*(1-axInduction)/sin(phi) - !else - W = sqrt((Vx*(1-axInduction))**2 + (Vy*(1+tanInduction))**2) - !end if - - Re = airDens * W * chord / mu - if ( EqualRealNos(Re, 0.0_ReKi) ) Re = 0.001 ! Do this to avoid a singularity when we take log(Re) in the airfoil lookup. - - end subroutine BEMTU_Wind - -subroutine Transform_ClCd_to_CxCy( phi, useAIDrag, useTIDrag, Cl, Cd, Cx, Cy ) - real(ReKi), intent(in ) :: phi - logical, intent(in ) :: useAIDrag - logical, intent(in ) :: useTIDrag - real(ReKi), intent(in ) :: Cl - real(ReKi), intent(in ) :: Cd - real(ReKi), intent( out) :: Cx - real(ReKi), intent( out) :: Cy + type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_MiscVarType), intent(in ) :: m ! Misc/optimization variables + + REAL(ReKi), intent(in ) :: z_op !< value of z%phi(i,j) at the operating point + REAL(ReKi), intent( out) :: dz_p !< change in z_op in the plus direction + REAL(ReKi), intent( out) :: dz_m !< change in z_op in the minus direction - real(ReKi) cphi, sphi + ! local variables + real(ReKi) :: dz ! size of perturbation + real(ReKi) :: zp ! z_op+dz + real(ReKi) :: zm ! z_op-dz - cphi = cos(phi) - sphi = sin(phi) - ! resolve into normal (x) and tangential (y) forces - if ( useAIDrag ) then - Cx = Cl*cphi + Cd*sphi - else - Cx = Cl*cphi - end if - - if ( useTIDrag ) then - Cy = Cl*sphi - Cd*cphi - else - Cy = Cl*sphi - end if + dz = 2*D2R -end subroutine Transform_ClCd_to_CxCy - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & - Cl, Cd, Cm, Cpmin, errStat, errMsg ) -! This routine is called from BEMTU_InductionWithResidual and possibly BEMT_CalcOutput. -! Determine the Cl, Cd, Cm, coeficients for a given angle of attack -!.................................................................................................................................. - real(ReKi), intent(in ) :: AOA - real(ReKi), intent(in ) :: Re ! Unused in the current version! - type(AFInfoType), intent(in ) :: AFInfo - real(ReKi), intent( out) :: Cl, Cd, Cm, Cpmin - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None + ! we'll assume a central difference unless we are on the boundaries below [default] + dz_p = dz + dz_m = dz - - real :: IntAFCoefs(4) ! The interpolated airfoil coefficients. - real(reki) :: Alpha - integer :: s1 + + if (p%UseInduction .and. .not. m%UseFrozenWake) then + + zp = z_op+dz + zm = z_op-dz + + ! check if it goes past the pi-eps upper boundary + if ( zp > pi - BEMT_epsilon2 ) then + ! 1-sided difference + dz_p = 0 + dz_m = dz - ErrStat = ErrID_None - ErrMsg = '' - IntAFCoefs = 0.0_ReKi ! initialize in case we only don't have 4 columns in the airfoil data (i.e., so cm is zero if not in the file) + ! next we care about the -pi/4-eps boundary: + else if ( zm < -pi/4 - BEMT_epsilon2) then + ! 1-sided difference + dz_p = dz + dz_m = 0 + ! next let's check the +eps boundaries: + else if ( z_op > 0.0_ReKi .and. zm < BEMT_epsilon2 ) then + ! 1-sided difference + dz_p = dz + dz_m = 0 - + ! next let's check the -eps boundaries: + else if ( z_op < 0.0_ReKi .and. zp > -BEMT_epsilon2 ) then + ! 1-sided difference + dz_p = 0 + dz_m = dz + ! else ! we don't care about the pi/2 boundary, so let's do a central difference for everything else + end if - ! NOTE: we use Table(1) because the right now we can only interpolate with AOA and not Re or other variables. If we had multiple tables stored - ! for changes in other variables (Re, Mach #, etc) then then we would need to interpolate across tables. - ! - s1 = size(AFInfo%Table(1)%Coefs,2) + end if + - Alpha = AOA - call MPi2Pi ( Alpha ) ! change AOA into range of -pi to pi - IntAFCoefs(1:s1) = CubicSplineInterpM( Alpha & - , AFInfo%Table(1)%Alpha & - , AFInfo%Table(1)%Coefs & - , AFInfo%Table(1)%SplineCoefs & - , ErrStat, ErrMsg ) +END SUBROUTINE Get_phi_perturbations +!---------------------------------------------------------------------------------------------------------------------------------- +subroutine GetSolveRegionOrdering(Vx, phiIn, test_lower, test_upper) + real(ReKi), intent(in ) :: Vx + real(ReKi), intent(in ) :: phiIn + real(ReKi), intent( out) :: test_lower(3) + real(ReKi), intent( out) :: test_upper(3) + + + if (Vx > 0) then - - Cl = IntAFCoefs(1) - Cd = IntAFCoefs(2) + test_lower(1) = BEMT_epsilon2 + test_upper(1) = PiBy2 - BEMT_epsilon2 - - IF ( AFInfo%InCol_Cm > 0 ) THEN ! If there is Cm data, it is in column 3 - Cm = IntAFCoefs(3) - - IF ( AFInfo%InCol_Cpmin > 0 ) THEN - Cpmin = IntAFCoefs(4) - END IF - - ELSE IF ( AFInfo%InCol_Cpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 - Cpmin = IntAFCoefs(3) - END IF - - - + if (phiIn < pi/4.0_ReKi .and. phiIn > -pi/4.0_ReKi) then !bjj: added the negative for those cases where the previously calculated non-BEMT phi is in the [-pi,-pi/4] range + test_lower(2) = -pi/4.0_ReKi + test_upper(2) = -BEMT_epsilon2 - + test_lower(3) = PiBy2 + BEMT_epsilon2 + test_upper(3) = pi - BEMT_epsilon2 + else + test_lower(3) = -pi/4.0_ReKi + test_upper(3) = -BEMT_epsilon2 + + test_lower(2) = PiBy2 + BEMT_epsilon2 + test_upper(2) = pi - BEMT_epsilon2 + end if - -end subroutine ComputeSteadyAirfoilCoefs - -!---------------------------------------------------------------------------------------------------------------------------------- -subroutine Compute_UA_AirfoilCoefs( AOA, U, Re, AFInfo, & - p_UA, xd_UA, OtherState_UA, y_UA, m_UA, & - Cl, Cd, Cm, errStat, errMsg ) -! This routine is called from BEMTU_InductionWithResidual and possibly BEMT_CalcOutput. -! Determine the Cl, Cd, Cm coeficients for a given angle of attack -!.................................................................................................................................. - real(ReKi), intent(in ) :: AOA - real(ReKi), intent(in ) :: U - real(ReKi), intent(in ) :: Re ! Unused in the current version! - type(AFInfoType), intent(in ) :: AFInfo - type(UA_ParameterType), intent(in ) :: p_UA ! Parameters - type(UA_DiscreteStateType), intent(in ) :: xd_UA ! Discrete states at Time - type(UA_OtherStateType), intent(in ) :: OtherState_UA ! Other states at Time - type(UA_OutputType), intent(inout) :: y_UA ! - type(UA_MiscVarType), intent(inout) :: m_UA ! misc/optimization variables - real(ReKi), intent( out) :: Cl, Cd, Cm - integer(IntKi), intent( out) :: errStat ! Error status of the operation - character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None - - integer(intKi) :: ErrStat2 ! temporary Error status - character(ErrMsgLen) :: ErrMsg2 ! temporary Error message - character(*), parameter :: RoutineName = 'Compute_UA_AirfoilCoefs' - - - type(UA_InputType) :: u_UA + else - ErrStat = ErrID_None - ErrMsg = '' - - u_UA%alpha = AOA - u_UA%Re = Re - u_UA%U = U + test_lower(1) = -BEMT_epsilon2 + test_upper(1) = -PiBy2 + BEMT_epsilon2 - call UA_CalcOutput(u_UA, p_UA, xd_UA, OtherState_UA, AFInfo, y_UA, m_UA, errStat2, errMsg2 ) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (errStat >= AbortErrLev) return + if (phiIn > -pi/4.0_ReKi .and. phiIn < pi/4.0_ReKi) then !bjj: added the negative for those cases where the previously calculated non-BEMT phi is in the [-pi,-pi/4] range + test_lower(2) = pi/4.0_ReKi + test_upper(2) = BEMT_epsilon2 - Cl = y_UA%Cl - Cd = y_UA%Cd - Cm = y_UA%Cm - - -end subroutine Compute_UA_AirfoilCoefs -!---------------------------------------------------------------------------------------------------------------------------------- -!>This is the residual calculation for the uncoupled BEM solve -real(ReKi) function BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, chord, AFInfo, & - Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - axInduction, tanInduction, IsValidSolution, ErrStat, ErrMsg) - + test_lower(3) = -PiBy2 - BEMT_epsilon2 + test_upper(3) = -pi + BEMT_epsilon2 + else + test_lower(3) = pi/4.0_ReKi + test_upper(3) = BEMT_epsilon2 + + test_lower(2) = -PiBy2 - BEMT_epsilon2 + test_upper(2) = -pi + BEMT_epsilon2 + end if + end if + + +end subroutine GetSolveRegionOrdering + +integer function TestRegion(phiLower, phiUpper, numBlades, rlocal, chord, theta, AFInfo, & + Vx, Vy, Re, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, atol, & + f1, f2, errStat, errMsg) - real(ReKi), intent(in ) :: phi - real(ReKi), intent(in ) :: AOA - real(ReKi), intent(in ) :: Re + real(ReKi), intent(in ) :: phiLower + real(ReKi), intent(in ) :: phiUpper integer, intent(in ) :: numBlades - real(ReKi), intent(in ) :: rlocal - real(ReKi), intent(in ) :: chord + !integer, intent(in ) :: numBladeNodes type(AFInfoType), intent(in ) :: AFInfo - real(ReKi), intent(in ) :: Vx - real(ReKi), intent(in ) :: Vy + real(ReKi), intent(in ) :: rlocal + real(ReKi), intent(in ) :: chord + real(ReKi), intent(in ) :: theta + real(ReKi), intent(in ) :: Vx + real(ReKi), intent(in ) :: Vy + real(ReKi), intent(in ) :: Re logical, intent(in ) :: useTanInd logical, intent(in ) :: useAIDrag logical, intent(in ) :: useTIDrag @@ -258,76 +1769,80 @@ real(ReKi) function BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, logical, intent(in ) :: useTipLoss real(ReKi), intent(in ) :: hubLossConst real(ReKi), intent(in ) :: tipLossConst - real(ReKi), intent( out) :: axInduction, tanInduction - logical, intent( out) :: IsValidSolution !< this is set to false if k<=1 in the propeller brake region or k<-1 in the momentum region, indicating an invalid solution + real(ReKi), intent(in ) :: atol + real(ReKi), intent( out) :: f1 !< value of residual at phiLower + real(ReKi), intent( out) :: f2 !< value of residual at phiUpper integer(IntKi), intent( out) :: ErrStat ! Error status of the operation character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables - - integer(intKi) :: ErrStat2 ! temporary Error status - character(ErrMsgLen) :: ErrMsg2 ! temporary Error message - character(*), parameter :: RoutineName = 'BEMTU_InductionWithResidual' - - real(ReKi) :: fzero - - real(ReKi) :: Cl, Cd, Cx, Cy, Cm, Cpmin + ! Local variables + character(errMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName='TestRegion' + logical :: IsValidSolution, IsValidSolution2 ! placeholder for flag to determine if the residual solution is invalid (we'll handle that after the brent solve) ErrStat = ErrID_None ErrMsg = "" - BEMTU_InductionWithResidual = 0.0_ReKi - IsValidSolution = .true. - ! make these return values consistent with what is returned in inductionFactors routine: - - ! Set the local version of the induction factors (use values that set the force to 0) - if ( ( useTiploss .and. EqualRealNos(tipLossConst,0.0_ReKi) ) .or. ( useHubloss .and. EqualRealNos(hubLossConst,0.0_ReKi) ) ) then - ! We are simply going to bail if we are using tiploss and tipLossConst = 0 or using hubloss and hubLossConst=0, regardless of phi! [do this before checking if Vx or Vy is zero or you'll get jumps in the induction and loads] - axInduction = 1.0_ReKi - tanInduction = 0.0_ReKi - elseif ( EqualRealNos(phi, 0.0_ReKi) .or. VelocityIsZero(Vx) .OR. VelocityIsZero(Vy) ) then - axInduction = 0.0_ReKi - tanInduction = 0.0_ReKi - else !if ( (.NOT. VelocityIsZero(Vx)) .AND. (.NOT. VelocityIsZero(Vy)) ) then - - call ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, Cl, Cd, Cm, Cpmin, errStat2, errMsg2 ) !bjj: would be nice if this could be done outside this routine (so we don't copy AFInfo so much) - call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if (ErrStat >= AbortErrLev) return - - ! Compute Cx, Cy given Cl, Cd and phi, we honor the useAIDrag and useTIDrag flag because Cx,Cy are only used for the solution of inductions - call Transform_ClCd_to_CxCy( phi, useAIDrag, useTIDrag, Cl, Cd, Cx, Cy ) - - - ! Determine axInduction, tanInduction for the current Cl, Cd, phi - call inductionFactors( rlocal, chord, phi, Cx, Cy, numBlades, & - Vx, Vy, useTanInd, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - fzero, axInduction, tanInduction, IsValidSolution) - BEMTU_InductionWithResidual = fzero ! the residual + f1 = UncoupledErrFn(phiLower, theta, Re, numBlades, rlocal, chord, AFInfo, & + Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + IsValidSolution, errStat2, errMsg2) + + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) return + + f2 = UncoupledErrFn(phiUpper, theta, Re, numBlades, rlocal, chord, AFInfo, & + Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + IsValidSolution2, errStat2, errMsg2) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) return + + + ! Look for zero-crossing + if ( EqualRealNos(f1, 0.0_ReKi) .and. EqualRealNos(f2, 0.0_ReKi) .and. IsValidSolution .and. IsValidSolution2) then + TestRegion = 0 ! all solutions yield zero -- special case + return + else + if ( abs(f1) < aTol ) then + if ( abs(f2) < abs(f1) .and. IsValidSolution2 ) then + TestRegion = 4 ! special case: upper end point is a zero (and it's smaller than the solution at the lower end point) + return + elseif ( IsValidSolution ) then + TestRegion = 3 ! special case: lower end point is a zero + return + end if + elseif ( abs(f2) < aTol .and. IsValidSolution2 ) then + TestRegion = 4 ! special case: upper end point is a zero + return + end if end if - -end function BEMTU_InductionWithResidual - - - ! This is the residual calculation for the uncoupled BEM solve - -real(ReKi) function UncoupledErrFn(phi, theta, Re, numBlades, rlocal, chord, AFInfo, & - Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - IsValidSolution, ErrStat, ErrMsg) + if ( sign(1.0_ReKi,f1) /= sign(1.0_ReKi,f2) ) then + TestRegion = 1 + else + TestRegion = 2 ! No zero + end if + +end function TestRegion +subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, chord, theta, & + Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + maxIndIterations, aTol, ValidPhi, ErrStat, ErrMsg) - - real(ReKi), intent(in ) :: phi - real(ReKi), intent(in ) :: theta - real(ReKi), intent(in ) :: Re + use fminfcn + use mod_root1dim + !use fminMod + real(ReKi), intent(inout) :: phi integer, intent(in ) :: numBlades - real(ReKi), intent(in ) :: rlocal - real(ReKi), intent(in ) :: chord - type(AFInfoType), intent(in ) :: AFInfo - real(ReKi), intent(in ) :: Vx - real(ReKi), intent(in ) :: Vy + real(ReKi), intent(in ) :: airDens + real(ReKi), intent(in ) :: mu + TYPE(AFInfoType), INTENT(IN ) :: AFInfo + real(ReKi), intent(in ) :: rlocal + real(ReKi), intent(in ) :: chord + real(ReKi), intent(in ) :: theta + real(ReKi), intent(in ) :: Vx + real(ReKi), intent(in ) :: Vy logical, intent(in ) :: useTanInd logical, intent(in ) :: useAIDrag logical, intent(in ) :: useTIDrag @@ -335,326 +1850,156 @@ real(ReKi) function UncoupledErrFn(phi, theta, Re, numBlades, rlocal, chord, AFI logical, intent(in ) :: useTipLoss real(ReKi), intent(in ) :: hubLossConst real(ReKi), intent(in ) :: tipLossConst - integer(IntKi), intent( out) :: ErrStat ! Error status of the operation - logical, intent( out) :: IsValidSolution !< this is set to false if k<=1 in the propeller brake region or k<-1 in the momentum region, indicating an invalid solution - character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None - - ! Local variables - - real(ReKi) :: axInduction, tanInduction, AoA - - ErrStat = ErrID_None - ErrMsg = "" - - AOA = phi - theta - - - UncoupledErrFn = BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, chord, AFInfo, & - Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - axInduction, tanInduction, IsValidSolution, ErrStat, ErrMsg) - + integer, intent(in ) :: maxIndIterations + real(ReKi), intent(in ) :: aTol + logical, intent(inout) :: ValidPhi + integer(IntKi), intent( out) :: errStat ! Error status of the operation + character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None -end function UncoupledErrFn - - -subroutine ApplySkewedWakeCorrection( Vx, Vy, azimuth, chi0, tipRatio, a, ap, chi, ErrStat, ErrMsg ) - real(ReKi), intent(in ) :: Vx - real(ReKi), intent(in ) :: Vy - real(ReKi), intent(in ) :: azimuth - real(ReKi), intent(in ) :: chi0 - real(ReKi), intent(in ) :: tipRatio ! r/Rtip - real(ReKi), intent(inout) :: a - real(ReKi), intent(inout) :: ap - real(ReKi), intent( out) :: chi - integer(IntKi), intent( out) :: ErrStat ! Error status of the operation - character(*), intent( out) :: ErrMsg ! Error message if ErrStat /= ErrID_None + ! Local variables + type(fmin_fcnArgs) :: fcnArgs - ! Local variables - real(ReKi) :: yawCorr, saz + character(ErrMsgLen) :: errMsg2 ! temporary Error message if ErrStat /= ErrID_None + integer(IntKi) :: errStat2 ! temporary Error status of the operation + character(*), parameter :: RoutineName = 'BEMT_UnCoupledSolve' + real(ReKi), parameter :: MsgLimit = 0.07_ReKi ! don't print a message if we're within about 4 degrees of 0 or +/- pi/2 [arbitrary number picked by bjj] + real(ReKi) :: f1, f_lower, f_upper + real(ReKi) :: phi_lower(3), phi_upper(3) ! upper and lower bounds for region of phi in which we are trying to find a solution to the BEM equations + integer :: i, TestRegionResult + logical :: IsValidSolution + real(ReKi) :: Re, Vrel, cpmin ErrStat = ErrID_None ErrMsg = "" + - ! Skewed wake correction - - saz = sin(azimuth) - chi = chi0 - - if ( abs(saz) > 0.005_ReKi ) then - chi = (0.6_ReKi*a + 1.0_ReKi)*chi0 - - !if (chi0 < 40.0*d2r .and. chi > 0.0 ) then - ! TODO: Add check on chi to make sure it is < pi/2 and (positive check should be outside solve) GJH 5/20/2015 - !yawCorr = max(0.0,chi0-0.5236) - !yawCorr = min(0.785,yawCorr) - !bjj: modified 22-Sep-2015: RRD recommends 32 instead of 64 in the denominator (like AD14) - yawCorr = (15.0_ReKi*pi/32.0_ReKi*tan(chi/2.0_ReKi) * (tipRatio) * saz) - - a = a * (1.0 + yawCorr) ! *(-yawCorr/0.785 + 1) ) - !if ((a > 1.0 .AND. ayaw < 1.0) .OR. (a < 1.0 .AND. ayaw > 1.0 )) then - ! call WrScr('Yaw correction crossed over 1.0.') - ! !a = max(1.0, ayaw) - !else if ((a < -1.0 .AND. ayaw > -1.0) .OR. (a > -1.0 .AND. ayaw < -1.0 )) then - ! call WrScr('Yaw correction crossed over -1.0.') - ! - !end if - - else - chi = chi0 + if ( VelocityIsZero(Vx) ) then + phi = 0.0_ReKi + ValidPhi = .true. + return + else if ( VelocityIsZero(Vy) ) then + if (Vx>0.0_ReKi) then + phi = PiBy2 + else + phi = -PiBy2 + end if + ValidPhi = .true. + return end if - + ! Need to call BEMTU_Wind to obtain Re, even though we aren't using it in this version. + ! inductions are set to zero! + call BEMTU_Wind( 0.0_ReKi, 0.0_ReKi, Vx, Vy, chord, airDens, mu, Vrel, Re ) -end subroutine ApplySkewedWakeCorrection -!----------------------------------------------------------------------------------------- -subroutine inductionFactors(r, chord, phi, cn, ct, B, Vx, Vy, wakerotation, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & - fzero, a, ap, IsValidSolution) - - implicit none - - ! in - real(ReKi), intent(in) :: r !< local radial position [u%rlocal] - real(ReKi), intent(in) :: chord !< chord [p%chord] - real(ReKi), intent(in) :: phi !< angle between the plane of rotation and the direction of the local wind [y%phi]; must be in range [-pi,pi] - real(ReKi), intent(in) :: cn !< normal force coefficient (normal to the plane, not chord) of the jth node in the kth blade; [y%cx] - real(ReKi), intent(in) :: ct !< tangential force coefficient (tangential to the plane, not chord) of the jth node in the kth blade; [y%cy] - integer, intent(in) :: B !< number of blades [p%numBlades] - real(ReKi), intent(in) :: Vx !< velocity component [u%Vx] - real(ReKi), intent(in) :: Vy !< velocity component [u%Vy] - real(ReKi), intent(in) :: hubLossConst !< hub loss constant [p%hubLossConst] - real(ReKi), intent(in) :: tipLossConst !< tip loss constant [p%tipLossConst] - logical, intent(in) :: useHubLoss !< hub-loss flag [p%useHubLoss] - logical, intent(in) :: useTipLoss !< tip-loss flag [p%useTipLoss] - logical, intent(in) :: wakerotation !< Include tangential induction in BEMT calculations [flag] [p%useTanInd] - - - ! out - real(ReKi), intent(out) :: fzero !< residual of BEM equations - real(ReKi), intent(out) :: a !< axial induction [y%axInduction] - real(ReKi), intent(out) :: ap !< tangential induction, i.e., a-prime [y%tanInduction] - logical, intent(out) :: IsValidSolution !< this is set to false if k<=1 in the propeller brake region or k<-1 in the momentum region, indicating an invalid solution - - ! local - - real(ReKi) :: sigma_p ! local solidity (B*chord/(TwoPi*r)) - real(ReKi) :: sphi, cphi, lambda_r - real(ReKi) :: k, kp ! non-dimensional parameters - real(ReKi) :: F ! hub/tip loss correction factor - real(ReKi) :: g1, g2, g3 - real(ReKi) :: temp ! temporary variable so we don't have to calculate 2.0_ReKi*F*k multiple times - real(ReKi), parameter :: InductionLimit = 1000000.0_ReKi - real(ReKi), parameter :: MaxTnInd = 2.0_ReKi - real(ReKi), parameter :: MaxAxInd = 2.0_ReKi - - logical :: momentumRegion - - - - IsValidSolution = .true. - - !..................................................... - ! Some special cases (bjj commented out because we have taken care of these in BEMTU_InductionWithResidual, the only routine that calls this function) - !..................................................... - !if ( ( useTiploss .and. EqualRealNos(tipLossConst,0.0_ReKi) ) .or. ( useHubloss .and. EqualRealNos(hubLossConst,0.0_ReKi) ) ) then - ! ! We are simply going to bail if we are using tiploss and tipLossConst = 0 or using hubloss and hubLossConst=0, regardless of phi! - ! fzero = 0.0_ReKi - ! a = 1.0_ReKi - ! ap = -1.0_ReKi - ! return - !else if ( EqualRealNos(phi, 0.0_ReKi) ) then - ! fzero = 0.0_ReKi - ! a = 1.0_ReKi - ! if (wakerotation) then - ! ap = -1.0_ReKi - ! else - ! ap = 0.0_ReKi - ! end if - ! - ! return - !end if - - !..................................................... - ! Temporary variables: - !..................................................... - sphi = sin(phi) - cphi = cos(phi) - - - !..................................................... - ! Prandtl's tip and hub loss factor: - !..................................................... - - F = getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLossConst, tipLossConst) ! Prandtl's tip and hub loss factor - - !..................................................... - ! compute axial induction factor: - !..................................................... - sigma_p = B*chord/(TwoPi*r) ! local solidity - k = sigma_p*cn/4.0_ReKi/F/sphi/sphi - + !# ------ BEM solution method see (Ning, doi:10.1002/we.1636) ------ - momentumRegion = (phi > 0.0_ReKi .and. Vx >= 0.0_ReKi) .or. (phi < 0.0_ReKi .and. Vx < 0.0_ReKi) - if (momentumRegion) then ! momentum/empirical - - - ! update axial induction factor - if (k <= 2.0_ReKi/3.0_ReKi) then ! momentum state for a < 0.4 - - if ( EqualRealNos(k,-1.0_ReKi) ) then - a = -sign(InductionLimit, 1.0_ReKi+k) - else - a = k/(1.0_ReKi+k) - end if - - if (k<-1.0_ReKi) then ! k < -1 cannot be a solution in momentum region (this is equivalent to a>1.0) - IsValidSolution = .false. - end if - - - ! note that we'll put a max on the magnitude of 'a' later - - else ! Glauert(Buhl) correction for 0.4 0, but just in case there are numerical issues, I will add the abs() here - end if + ! See if the previous value of phi still satisfies the residual equation. + ! (If the previous phi wasn't a valid solution to BEMT equations, skip this check and just perform the solve) + if (ValidPhi .and. .NOT. EqualRealNos(phi, 0.0_ReKi) .and. .not. EqualRealNos(abs(phi),PiBy2) ) then + f1 = UncoupledErrFn(phi, theta, Re, numBlades, rlocal, chord, AFInfo, & + Vx, Vy, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, & + IsValidSolution, errStat2, errMsg2) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) + if (errStat >= AbortErrLev) return + if ( abs(f1) < aTol .and. IsValidSolution ) then + !phiStar = phiIn + return end if - - else ! propeller brake - - - if ( EqualRealNos(k,1.0_ReKi) ) then - IsValidSolution = .false. - a = InductionLimit - else - a = k/(k-1.0_ReKi) - end if - - - if (k<=1.0_ReKi) then ! k <= 1 cannot be a solution in propeller brake region (this is equivalent to a<1.0) - IsValidSolution = .false. - else if (a > MaxAxInd) then ! propeller brake region is for induction factors > 1, but not too large; - ! note that we use k in the residual equation instead of a in the propeller brake region, so we can put the limit here - a = MaxAxInd - end if - end if + + + + ! + ValidPhi = .false. ! initialize to false while we try to find a new valid solution + + !............ + ! + + ! Set up the fcn argument settings for Brent's method - !..................................................... - ! compute tangential induction factor: - !..................................................... - - if (wakerotation) then + fcnArgs%airDens = airDens + fcnArgs%mu = mu + fcnArgs%numBlades = numBlades + fcnArgs%rlocal = rlocal + fcnArgs%chord = chord + fcnArgs%theta = theta + fcnArgs%Vx = Vx + fcnArgs%Vy = Vy + fcnArgs%Re = Re + fcnArgs%useTanInd = useTanInd + fcnArgs%useAIDrag = useAIDrag + fcnArgs%useTIDrag = useTIDrag + fcnArgs%useHubLoss = useHubLoss + fcnArgs%useTipLoss = useTipLoss + fcnArgs%hubLossConst = hubLossConst + fcnArgs%tipLossConst = tipLossConst - ! compute tangential induction factor - if ( EqualRealNos(cphi,0.0_ReKi) ) then - - ap = -1.0_ReKi - kp = sign(InductionLimit, ct*sphi)*sign(1.0_ReKi,Vx) - - else - - kp = sigma_p*ct/4.0_ReKi/F/sphi/cphi - if (Vx < 0.0_ReKi) then - kp = -kp - end if - + + call GetSolveRegionOrdering(Vx, phi, phi_lower, phi_upper) + + do i = 1,size(phi_upper) ! Need to potentially test 3 regions + TestRegionResult = TestRegion(phi_lower(i), phi_upper(i), numBlades, rlocal, chord, theta, AFInfo, & + Vx, Vy, Re, useTanInd, useAIDrag, useTIDrag, useHubLoss, useTipLoss, hubLossConst, tipLossConst, atol, & + f_lower, f_upper, errStat2, errMsg2) + call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - if ( EqualRealNos(kp,1.0_ReKi) ) then - ap = sign(InductionLimit, 1.0_ReKi-kp) + if ( TestRegionResult == 1 ) then + !............ + ! There is a zero in the solution region [phi_lower(i), phi_upper(i)] because the endpoints have residuals with different signs (SolutionRegion=1) + ! We use Brent's Method to find the zero-residual solution in this region + + call sub_brent(phi,fmin_fcn,phi_lower(i),phi_upper(i), aTol, maxIndIterations, fcnArgs, AFInfo, f_lower, f_upper) + call SetErrStat(fcnArgs%ErrStat, fcnArgs%ErrMsg, ErrStat, ErrMsg, RoutineName) + + if (fcnArgs%IsValidSolution) then ! we have a valid BEMT solution + ValidPhi = .true. + exit + end if + elseif (TestRegionResult == 3) then + phi = phi_lower(i) !this boundary is a solution + ValidPhi = .true. + exit + elseif (TestRegionResult == 4) then + phi = phi_upper(i) !this boundary is a solution + ValidPhi = .true. + exit + elseif (TestRegionResult == 0) then ! Special case where both end points return 0 residual; return value closest to 0 as the solution + if (phi_lower(i) > 0.0_ReKi) then + phi = phi_lower(i) !this boundary is a solution + ValidPhi = .true. + exit else - ap = kp/(1.0_ReKi-kp) - end if - - ! bandaid so that this doesn't blow up. Note that we're not using ap in the residual calculation, so we can modify it here. - if (abs(ap) > MaxTnInd) ap = sign(MaxTnInd, ap) - - end if - - - else + phi = phi_upper(i) !this boundary is a solution + ValidPhi = .true. + exit + end if + end if - ! we're not computing tangential induction: - ap = 0.0_ReKi - kp = 0.0_ReKi - - end if + end do + - - !..................................................... - ! error function (residual) - !..................................................... - lambda_r = Vy/Vx - - if (momentumRegion) then ! momentum/empirical - if ( EqualRealNos(a, 1.0_ReKi) ) then - fzero = - cphi/lambda_r*(1-kp) - else - fzero = sphi/(1-a) - cphi/lambda_r*(1-kp) - - ! bandaid so that axial induction doesn't blow up - a = max(a,-MaxAxInd) + if (.not. ValidPhi) then + phi = ComputePhiWithInduction(Vx, Vy, 0.0_ReKi, 0.0_ReKi) + + if (abs(phi)>MsgLimit .and. abs(abs(phi)-PiBy2) > MsgLimit ) then + call SetErrStat( ErrID_Info, 'There is no valid value of phi for these operating conditions: Vx = '//TRIM(Num2Lstr(Vx))//& + ', Vy = '//TRIM(Num2Lstr(Vy))//', rlocal = '//TRIM(Num2Lstr(rLocal))//', theta = '//TRIM(Num2Lstr(theta))//', geometric phi = '//TRIM(Num2Lstr(phi)), errStat, errMsg, RoutineName ) end if - else ! propeller brake region - fzero = sphi*(1-k) - cphi/lambda_r*(1-kp) - end if - - if (.not. IsValidSolution) then - a = 0.0_ReKi - ap = 0.0_ReKi + end if - -end subroutine inductionFactors -!----------------------------------------------------------------------------------------- -!> This function computes \f$F\f$, the hub/tip loss correction -real(reKi) function getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLossConst, tipLossConst) result(F) - - real(ReKi), intent(in) :: sphi !< sine of local inflow angle, sin(phi) - real(ReKi), intent(in) :: hubLossConst !< hub loss constant [p%hubLossConst] - real(ReKi), intent(in) :: tipLossConst !< tip loss constant [p%tipLossConst] - logical, intent(in) :: useHubLoss !< hub-loss flag [p%useHubLoss] - logical, intent(in) :: useTipLoss !< tip-loss flag [p%useTipLoss] - - - real(ReKi) :: factortip, Ftip, factorhub, Fhub - - !..................................................... - ! Prandtl's tip and hub loss factor: - !..................................................... + +end subroutine BEMT_UnCoupledSolve - Ftip = 1.0_ReKi ! default tip loss value - Fhub = 1.0_ReKi ! default hub loss value - - if (.not. EqualRealNos(sphi,0.0_ReKi)) then - if ( useTipLoss ) then - factortip = tipLossConst/abs(sphi) - Ftip = TwoByPi*acos(min(1.0_ReKi,exp(-factortip))) - ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 - end if - if ( useHubLoss ) then - factorhub = hubLossConst/abs(sphi) - Fhub = TwoByPi*acos(min(1.0_ReKi,exp(-factorhub))) - ! else Ftip = 1.0_ReKi ! TwoByPi*Pi/2 - end if - end if - - F = Ftip * Fhub - -end function getHubTipLossCorrection -!----------------------------------------------------------------------------------------- -end module BEMTUncoupled + end module BEMT + + + + From cbe05c03e083909e6c4ecde5a1a658313cbc80e4 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 11:14:25 -0600 Subject: [PATCH 26/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index a1a29ff68..95e032993 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -749,11 +749,7 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte call SetErrStat( ErrID_Fatal, 'Turn off Unsteady Aerodynamics to do a cavitation check', ErrStat, ErrMsg, RoutineName ) end if - - - - call WrScr (' p%InCol_Cpmin='//trim(num2lstr((p%InCol_Cpmin)))) - + end do end do From 7fc54e92a8924d41ba2393052a1cf018e77cfb1d Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 14 Mar 2017 12:16:29 -0600 Subject: [PATCH 27/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 95e032993..1c1179991 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -749,7 +749,8 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte call SetErrStat( ErrID_Fatal, 'Turn off Unsteady Aerodynamics to do a cavitation check', ErrStat, ErrMsg, RoutineName ) end if - + + end do end do @@ -1273,13 +1274,13 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat - + !Check to make sure there is cavitaiton data if ( p%CavitCheck .and. y%Cpmin(i,j)==0) then call SetErrStat( ErrID_Fatal, 'No Cpmin data for cavitation check', ErrStat, ErrMsg, RoutineName ) end if - - if ( p%CavitCheck ) then ! This calculates the cavitation number for the airfoil at the node in quesiton, and compares to the critical cavitation number based on the vapour pressure and submerged depth + !Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth + if ( p%CavitCheck ) then SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this SigmaCavit= -1* y%Cpmin(i,j) ! Actual cavitation number on blade node j From 2733d1bddddd0c6506d03ea6377c82fcc2e630ec Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 20 Mar 2017 08:38:16 -0600 Subject: [PATCH 28/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 1c1179991..346375ba2 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -1273,14 +1273,32 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat if (errStat >= AbortErrLev) return - + + + !Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth + if ( p%CavitCheck ) then + + !Check to make sure there is cavitaiton data - if ( p%CavitCheck .and. y%Cpmin(i,j)==0) then + if ( y%Cpmin(i,j)==0) then call SetErrStat( ErrID_Fatal, 'No Cpmin data for cavitation check', ErrStat, ErrMsg, RoutineName ) end if - !Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth - if ( p%CavitCheck ) then + !Make sure input parameters make sense + if (p%FluidDepth<0) then + call SetErrStat( ErrID_Fatal, 'Vapour pressure (FluidDepth) cannot be negative', ErrStat, ErrMsg, RoutineName ) + end if + + !Make sure input parameters make sense + if (p%Pvap<0) then + call SetErrStat( ErrID_Fatal, 'Vapour pressure (Pvap) cannot be negative', ErrStat, ErrMsg, RoutineName ) + end if + + !Make sure input parameters make sense + if (p%Patm<0) then + call SetErrStat( ErrID_Fatal, 'Atmospheric pressure (Patm) cannot be negative', ErrStat, ErrMsg, RoutineName ) + end if + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this SigmaCavit= -1* y%Cpmin(i,j) ! Actual cavitation number on blade node j From 87872f27b3931c1122a00a15380b277ca0432d1b Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 20 Mar 2017 08:41:39 -0600 Subject: [PATCH 29/58] Cavitation Updated the BEMT_CalcOutputs to include a check for cavitation. Also included some checks for the cavitation input parameters here so that we don't waste time checking these if the user isn't doing a cavitation check. --- modules-local/aerodyn/src/BEMT.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 346375ba2..2e836ae0b 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -28,7 +28,7 @@ module BEMT use BEMT_Types use BEMTUncoupled - + use UnsteadyAero !USE AeroDyn_Types use AirfoilInfo From ea6d0a152612370b871242b1ed9e54e3eb3cf73a Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 20 Mar 2017 08:43:06 -0600 Subject: [PATCH 30/58] BEMT_CalcOutputs includes cavitation check Updated the BEMT_CalcOutputs to include a check for cavitation. Also included some checks for the cavitation input parameters here so that we don't waste time checking these if the user isn't doing a cavitation check. --- modules-local/aerodyn/src/BEMT.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 2e836ae0b..6e99c6c67 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -34,7 +34,7 @@ module BEMT use AirfoilInfo - implicit none +implicit none private From aca6695a13ed631f80d2764121bc890c2aaf8bf5 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Fri, 24 Mar 2017 11:12:26 -0600 Subject: [PATCH 31/58] Update AeroDyn.f90 --- modules-local/aerodyn/src/AeroDyn.f90 | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn.f90 b/modules-local/aerodyn/src/AeroDyn.f90 index 69ff18a52..6b42bc7ba 100644 --- a/modules-local/aerodyn/src/AeroDyn.f90 +++ b/modules-local/aerodyn/src/AeroDyn.f90 @@ -866,9 +866,7 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) p%AirDens = InputFileData%AirDens p%KinVisc = InputFileData%KinVisc - p%SpdSound = InputFileData%SpdSound - p%Patm = InputFileData%Patm - p%Pvap = InputFileData%Pvap + !p%AFI ! set in call to AFI_Init() [called early because it wants to use the same echo file as AD] !p%BEMT ! set in call to BEMT_Init() @@ -1419,7 +1417,11 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) if (InputFileData%AirDens <= 0.0) call SetErrStat ( ErrID_Fatal, 'The air density (AirDens) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) if (InputFileData%KinVisc <= 0.0) call SetErrStat ( ErrID_Fatal, 'The kinesmatic viscosity (KinVisc) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) if (InputFileData%SpdSound <= 0.0) call SetErrStat ( ErrID_Fatal, 'The speed of sound (SpdSound) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) - + if (InputFileData%Pvap <= 0.0) call SetErrStat ( ErrID_Fatal, 'The vapour pressure (Pvap) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) + if (InputFileData%Patm <= 0.0) call SetErrStat ( ErrID_Fatal, 'The atmospheric pressure (Patm) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) + if (InputFileData%FluidDepth <= 0.0) call SetErrStat ( ErrID_Fatal, 'Fluid depth (FluidDepth) cannot be negative', ErrStat, ErrMsg, RoutineName ) + + ! BEMT inputs ! bjj: these checks should probably go into BEMT where they are used... @@ -1441,7 +1443,14 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) if (.not. InputFileData%FLookUp ) call SetErrStat( ErrID_Fatal, 'FLookUp must be TRUE for this version.', ErrStat, ErrMsg, RoutineName ) end if - + + if ( InputFileData%CavitCheck .and. InputFileData%AFAeroMod == 2) then + call SetErrStat( ErrID_Fatal, 'Turn off Unsteady Aerodynamics to do a cavitation check', ErrStat, ErrMsg, RoutineName ) + end if + + if (InputFileData%InCol_Cpmin == 0 .and. InputFileData%CavitCheck) call SetErrStat( ErrID_Fatal, 'InCol_Cpmin must not be 0 to do a cavitation check.', ErrStat, ErrMsg, RoutineName ) + + ! validate the AFI input data because it doesn't appear to be done in AFI if (InputFileData%NumAFfiles < 1) call SetErrStat( ErrID_Fatal, 'The number of unique airfoil tables (NumAFfiles) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) @@ -1702,10 +1711,6 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, InitInp%airDens = InputFileData%AirDens InitInp%kinVisc = InputFileData%KinVisc - InitInp%Pvap = InputFileData%Pvap - InitInp%Patm = InputFileData%Patm - InitInp%FluidDepth = InputFileData%FluidDepth - InitInp%CavitCheck = InputFileData%CavitCheck InitInp%skewWakeMod = InputFileData%SkewMod InitInp%aTol = InputFileData%IndToler InitInp%useTipLoss = InputFileData%TipLoss @@ -3759,6 +3764,7 @@ FUNCTION CheckBEMTInputPerturbations( p, m ) RESULT(ValidPerturb) end if + else ! not UseInduction do k=1,p%NumBlades From 5d9e4532ae423fe27881a0e94be26dbd6ece9ce5 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Fri, 24 Mar 2017 11:12:48 -0600 Subject: [PATCH 32/58] Update AeroDyn_IO.f90 --- modules-local/aerodyn/src/AeroDyn_IO.f90 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index 296c7aa93..cf7e21cb3 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -1687,9 +1687,9 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, indx, ErrStat, ErrMsg ) m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cl(j,k) m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cd(j,k) - m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cpmin(j,k) - m%AllOuts( BNSigCr( beta,k) ) = m%BEMT_y%SigmaCavitCrit(j,k) - m%AllOuts( BNSgCav( beta,k) ) = m%BEMT_y%SigmaCavit(j,k) + m%AllOuts( BNCpmin( beta,k) ) = m%BEMT%Cpmin(j,k) + m%AllOuts( BNSigCr( beta,k) ) = m%BEMT%SigmaCavitCrit(j,k) + m%AllOuts( BNSgCav( beta,k) ) = m%BEMT%SigmaCavit(j,k) cp=cos(m%BEMT_y%phi(j,k)) sp=sin(m%BEMT_y%phi(j,k)) @@ -2024,6 +2024,9 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadVar( UnIn, InputFile, InputFileData%CavitCheck, "CavitCheck", "Perform cavitation check? (flag)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! AddedMass - Include added mass effects? (flag): +! CALL ReadVar( UnIn, InputFile, InputFileData%AddedMass, "AddedMass", "Include added mass effects? (flag)", ErrStat2, ErrMsg2, UnEc) + ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) ! Return on error at end of section From fda73993a749db0474cf77a2b6c512931d821c1b Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Fri, 24 Mar 2017 11:13:02 -0600 Subject: [PATCH 33/58] Update AeroDyn_Registry.txt --- modules-local/aerodyn/src/AeroDyn_Registry.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn_Registry.txt b/modules-local/aerodyn/src/AeroDyn_Registry.txt index e6ba13d2a..5bb5d1401 100644 --- a/modules-local/aerodyn/src/AeroDyn_Registry.txt +++ b/modules-local/aerodyn/src/AeroDyn_Registry.txt @@ -153,9 +153,6 @@ typedef ^ ParameterType ReKi TwrDiam {:} - - "Diameter of tower at node" m typedef ^ ParameterType ReKi TwrCd {:} - - "Coefficient of drag at tower node" - typedef ^ ParameterType ReKi AirDens - - - "Air density" kg/m^3 typedef ^ ParameterType ReKi KinVisc - - - "Kinematic air viscosity" m^2/s -typedef ^ ParameterType ReKi Patm - - - "Atmospheric pressure" Pa -typedef ^ ParameterType ReKi Pvap - - - "Vapour pressure" Pa -typedef ^ ParameterType ReKi FluidDepth - - - "Depth of water to hub center" m typedef ^ ParameterType ReKi SpdSound - - - "Speed of sound" m/s typedef ^ ParameterType AFI_ParameterType AFI - - - "AirfoilInfo parameters" typedef ^ ParameterType BEMT_ParameterType BEMT - - - "Parameters for BEMT module" @@ -185,7 +182,5 @@ typedef ^ InputType ReKi InflowOnTower {:}{:} "U,V,W at nodes on the tower" m/ # Define outputs that are contained on the mesh here: typedef ^ OutputType MeshType TowerLoad - - - "loads on the tower" - typedef ^ OutputType MeshType BladeLoad {:} - - "loads on each blade" - -typedef ^ OutputType MeshType SigmaCavitCrit {:} - - "Critical cavitation number " - -typedef ^ OutputType MeshType SigmaCavit {:} - - " Cavitation number at node " - # Define outputs that are not on this mesh here: typedef ^ OutputType ReKi WriteOutput {:} - - "Data to be written to an output file: see WriteOutputHdr for names of each variable" "see WriteOutputUnt" From e25d94e90be091d95d96f1d522008b389ab936ef Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Fri, 24 Mar 2017 11:13:19 -0600 Subject: [PATCH 34/58] Update AirfoilInfo.f90 --- modules-local/aerodyn/src/AirfoilInfo.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules-local/aerodyn/src/AirfoilInfo.f90 b/modules-local/aerodyn/src/AirfoilInfo.f90 index d38f7731e..a695cdaf2 100644 --- a/modules-local/aerodyn/src/AirfoilInfo.f90 +++ b/modules-local/aerodyn/src/AirfoilInfo.f90 @@ -130,9 +130,9 @@ SUBROUTINE AFI_Init ( InitInput, p, ErrStat, ErrMsg, UnEcho ) RETURN ENDIF - p%AFInfo( :)%InCol_Cpmin=p%ColCpmin - p%AFInfo( :)%InCol_Cm=p%ColCm - + p%AFInfo( :)%ColCpmin=p%ColCpmin + p%AFInfo( :)%ColCm=p%ColCm + DO File=1,InitInput%NumAFfiles From 76a63d679daaaa36b88c54f06558405c416b58c4 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Fri, 24 Mar 2017 11:13:34 -0600 Subject: [PATCH 35/58] Update AirfoilInfo_Registry.txt --- modules-local/aerodyn/src/AirfoilInfo_Registry.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt index 7c1e3c583..03c27c0ae 100644 --- a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt +++ b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt @@ -95,9 +95,7 @@ typedef ^ ^ INTEGER NumCpminReKts - - - "The number of log(Re) knots for 2D spli typedef ^ ^ INTEGER NumTabs - - - "The number of airfoil tables in the airfoil file" - typedef ^ ^ AFI_Table_Type Table {:} - - "The tables of airfoil data for given Re and control setting" - typedef ^ ^ INTEGER ColCpmin - - - "Column number for Cpmin" - -typedef ^ ^ INTEGER ColCm - - - "Column number for Cpmin" - -typedef ^ ^ INTEGER InCol_Cm - - - "The column of the coefficient tables that holds the pitching-moment coefficient" - -typedef ^ ^ INTEGER InCol_Cpmin - - - "The column of the coefficient tables that holds the minimum pressure coefficient" - +typedef ^ ^ INTEGER ColCm - - - "Column number for Cm" - # ..... Initialization data ....................................................................................................... # The following derived type stores information that comes from the calling module (say, AeroDyn): From 10d833ff3b5b62056bcc68431480829b063884f5 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Fri, 24 Mar 2017 11:13:51 -0600 Subject: [PATCH 36/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 75 ++++++++---------------------- 1 file changed, 19 insertions(+), 56 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 6e99c6c67..1d69fe999 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -28,13 +28,13 @@ module BEMT use BEMT_Types use BEMTUncoupled - + use UnsteadyAero !USE AeroDyn_Types use AirfoilInfo -implicit none + implicit none private @@ -212,10 +212,6 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) !p%DT = InitInp%DT p%airDens = InitInp%airDens p%kinVisc = InitInp%kinVisc - p%Patm = InitInp%Patm - p%Pvap = InitInp%Pvap - p%CavitCheck = InitInp%CavitCheck - p%FluidDepth = InitInp%FluidDepth p%skewWakeMod = InitInp%skewWakeMod p%useTipLoss = InitInp%useTipLoss p%useHubLoss = InitInp%useHubLoss @@ -226,7 +222,6 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numReIterations = InitInp%numReIterations p%maxIndIterations = InitInp%maxIndIterations p%aTol = InitInp%aTol - p%InCol_Cpmin = InitInp%InCol_Cpmin end subroutine BEMT_SetParameters @@ -440,7 +435,7 @@ end subroutine BEMT_AllocInput !---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) +subroutine BEMT_AllocOutput( y, p, m, errStat, errMsg ) ! This routine is called from BEMT_Init. ! ! @@ -448,6 +443,7 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) type(BEMT_OutputType), intent( out) :: y ! output data type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables integer(IntKi), intent( out) :: errStat ! Error status of the operation character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None @@ -474,9 +470,9 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) call allocAry( y%Cm, p%numBladeNodes, p%numBlades, 'y%Cm', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cl, p%numBladeNodes, p%numBlades, 'y%Cl', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cd, p%numBladeNodes, p%numBlades, 'y%Cd', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) -call allocAry( y%Cpmin, p%numBladeNodes, p%numBlades, 'y%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%SigmaCavit, p%numBladeNodes, p%numBlades, 'y%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( y%SigmaCavitCrit, p%numBladeNodes, p%numBlades, 'y%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( m%Cpmin, p%numBladeNodes, p%numBlades, 'm%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( m%SigmaCavit, p%numBladeNodes, p%numBlades, 'm%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( m%SigmaCavitCrit, p%numBladeNodes, p%numBlades, 'm%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) if (ErrStat >= AbortErrLev) RETURN @@ -495,10 +491,8 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) y%tanInduction = 0.0_ReKi y%AOA = 0.0_ReKi y%Cl = 0.0_ReKi - y%Cd = 0.0_ReKi - y%Cpmin = 0.0_ReKi - y%SigmaCavit = 0.0_ReKi - y%SigmaCavitCrit = 0.0_ReKi + y%Cd = 0.0_ReKi + end subroutine BEMT_AllocOutput @@ -743,14 +737,7 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte call WrScr( 'Warning: Turning off Unsteady Aerodynamics because C_nalpha is 0. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) end if - - if ( p%CavitCheck .and. OtherState%UA_Flag(i,j)) then - OtherState%UA_Flag(i,j) = .false. - call SetErrStat( ErrID_Fatal, 'Turn off Unsteady Aerodynamics to do a cavitation check', ErrStat, ErrMsg, RoutineName ) - end if - - - + end do end do @@ -782,7 +769,7 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte !call BEMT_InitOut(p, InitOut, errStat2, errMsg2) !call CheckError( errStat2, errMsg2 ) - call BEMT_AllocOutput(y, p, errStat2, errMsg2) !u is sent so we can create sibling meshes + call BEMT_AllocOutput(y, p, m, errStat2, errMsg2) !u is sent so we can create sibling meshes call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) if (errStat >= AbortErrLev) then call cleanup() @@ -1268,7 +1255,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat else ! TODO: When we start using Re, should we use the uninduced Re since we used uninduced Re to solve for the inductions!? Probably this won't change, instead create a Re loop up above. call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & - y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), y%Cpmin(i,j), errStat2, errMsg2 ) + y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), m%Cpmin(i,j), errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) if (errStat >= AbortErrLev) return @@ -1277,33 +1264,10 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat !Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth if ( p%CavitCheck ) then - - - !Check to make sure there is cavitaiton data - if ( y%Cpmin(i,j)==0) then - call SetErrStat( ErrID_Fatal, 'No Cpmin data for cavitation check', ErrStat, ErrMsg, RoutineName ) - end if - - !Make sure input parameters make sense - if (p%FluidDepth<0) then - call SetErrStat( ErrID_Fatal, 'Vapour pressure (FluidDepth) cannot be negative', ErrStat, ErrMsg, RoutineName ) - end if - - !Make sure input parameters make sense - if (p%Pvap<0) then - call SetErrStat( ErrID_Fatal, 'Vapour pressure (Pvap) cannot be negative', ErrStat, ErrMsg, RoutineName ) - end if - - !Make sure input parameters make sense - if (p%Patm<0) then - call SetErrStat( ErrID_Fatal, 'Atmospheric pressure (Patm) cannot be negative', ErrStat, ErrMsg, RoutineName ) - end if - - + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this - SigmaCavit= -1* y%Cpmin(i,j) ! Actual cavitation number on blade node j - - + SigmaCavit= -1* m%Cpmin(i,j) ! Actual cavitation number on blade node j + if (SigmaCavitCrit < SigmaCavit) then call WrScr( NewLine//'FAILED CAVITATION CHECK'//' Node # = '//trim(num2lstr(i)//'Blade # = '//trim(num2lstr(j)))) @@ -1314,12 +1278,10 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat end if - y%SigmaCavit(i,j)= SigmaCavit - y%SigmaCavitCrit(i,j)=SigmaCavitCrit + m%SigmaCavit(i,j)= SigmaCavit + m%SigmaCavitCrit(i,j)=SigmaCavitCrit end if - - end if @@ -1884,7 +1846,8 @@ subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, cho real(ReKi) :: phi_lower(3), phi_upper(3) ! upper and lower bounds for region of phi in which we are trying to find a solution to the BEM equations integer :: i, TestRegionResult logical :: IsValidSolution - real(ReKi) :: Re, Vrel, cpmin + real(ReKi) :: Re, Vrel + ErrStat = ErrID_None ErrMsg = "" From 8896b79b2bf80cb41bafe170fa5f070d36fb18e6 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Fri, 24 Mar 2017 11:14:07 -0600 Subject: [PATCH 37/58] Update BEMTUncoupled.f90 --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index 24474eeca..e6baa35b4 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -171,19 +171,18 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & Cd = IntAFCoefs(2) - IF ( AFInfo%InCol_Cm > 0 ) THEN ! If there is Cm data, it is in column 3 + IF ( AFInfo%ColCm > 0 ) THEN ! If there is Cm data, it is in column 3 Cm = IntAFCoefs(3) - IF ( AFInfo%InCol_Cpmin > 0 ) THEN + IF ( AFInfo%ColCpmin > 0 ) THEN Cpmin = IntAFCoefs(4) END IF - ELSE IF ( AFInfo%InCol_Cpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 + ELSE IF ( AFInfo%ColCpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 Cpmin = IntAFCoefs(3) END IF - - + From e1ba813107b55d3ad401b5633767f0ab1641f110 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Fri, 24 Mar 2017 11:14:23 -0600 Subject: [PATCH 38/58] Update BEMT_Registry.txt --- modules-local/aerodyn/src/BEMT_Registry.txt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT_Registry.txt b/modules-local/aerodyn/src/BEMT_Registry.txt index 691228c1d..c3a47fc47 100644 --- a/modules-local/aerodyn/src/BEMT_Registry.txt +++ b/modules-local/aerodyn/src/BEMT_Registry.txt @@ -57,7 +57,6 @@ typedef ^ ^ LOGICAL typedef ^ ^ LOGICAL Flookup - - - "Use table lookup for f' and f'' " - typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to check for cavitation" - typedef ^ ^ ReKi a_s - - - "speed of sound" m/s -typedef ^ ^ INTEGER InCol_Cpmin - - - "InCol_Cpmin" - # # # Define outputs from the initialization routine here: @@ -87,7 +86,6 @@ typedef ^ OtherStateType UA_OtherSta typedef ^ ^ LOGICAL UA_Flag {:}{:} - - "logical flag indicating whether to use UnsteadyAero" - typedef ^ ^ LOGICAL ValidPhi {:}{:} - - "set to indicate when there is no valid Phi for this node at this time (temporarially turn off induction when this is false)" - typedef ^ OtherStateType Logical nodesInitialized - - - "the node states have been initialized properly" - -typedef ^ ^ LOGICAL CavitCheck {:}{:} - - "logical flag indicating whether to check for cavitation" - # ..... Misc/Optimization variables................................................................................................. @@ -99,6 +97,9 @@ typedef ^ MiscVarType UA_OutputTy typedef ^ MiscVarType ReKi TnInd_op {:}{:} - - "tangential induction at the operating point (for linearization with frozen wake assumption)" typedef ^ MiscVarType ReKi AxInd_op {:}{:} - - "axial induction at the operating point (for linearization) with frozen wake assumption" typedef ^ MiscVarType Logical UseFrozenWake - - - "flag set to determine if frozen values of TnInd_op and AxInd_op should be used for this calculation in the linearization process" +typedef ^ ^ ReKi Cpmin {:}{:} - - "min Cpressure" - +typedef ^ ^ ReKi SigmaCavitCrit {:}{:} - - "critical cavitation number- inception value (above which cavit will occur)" - +typedef ^ ^ ReKi SigmaCavit {:}{:} - - "cavitation nubmer at node " - # ..... Parameters ................................................................................................................ # Define parameters here: @@ -130,7 +131,6 @@ typedef ^ ^ ReKi typedef ^ ^ UA_ParameterType UA - - - "parameters for UnsteadyAero" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to use cavitation check" - -typedef ^ ^ INTEGER InCol_Cpmin - - - "InCol_Cpmin" - # # @@ -159,6 +159,3 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi Cl {:}{:} - - "lift coefficient" - typedef ^ ^ ReKi Cd {:}{:} - - "drag coefficient" - typedef ^ ^ ReKi chi {:}{:} - - "wake skew angle" rad -typedef ^ ^ ReKi Cpmin {:}{:} - - "min Cpressure" - -typedef ^ ^ ReKi SigmaCavitCrit {:}{:} - - "critical cavitation number- inception value (above which cavit will occur)" - -typedef ^ ^ ReKi SigmaCavit {:}{:} - - "cavitation nubmer at node " - From 49e84e21a0678b58a44ab841e9286c3cda022a48 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Tue, 28 Mar 2017 12:19:30 -0600 Subject: [PATCH 39/58] Updating files to remove redundancies --- modules-local/aerodyn/src/AeroDyn.f90 | 18 ++++++++++++------ modules-local/aerodyn/src/AeroDyn_IO.f90 | 2 ++ modules-local/aerodyn/src/BEMT.f90 | 14 +++++++++----- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn.f90 b/modules-local/aerodyn/src/AeroDyn.f90 index 6b42bc7ba..065e303fe 100644 --- a/modules-local/aerodyn/src/AeroDyn.f90 +++ b/modules-local/aerodyn/src/AeroDyn.f90 @@ -867,6 +867,7 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) p%AirDens = InputFileData%AirDens p%KinVisc = InputFileData%KinVisc + !p%AFI ! set in call to AFI_Init() [called early because it wants to use the same echo file as AD] !p%BEMT ! set in call to BEMT_Init() @@ -1445,7 +1446,7 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) end if if ( InputFileData%CavitCheck .and. InputFileData%AFAeroMod == 2) then - call SetErrStat( ErrID_Fatal, 'Turn off Unsteady Aerodynamics to do a cavitation check', ErrStat, ErrMsg, RoutineName ) + call SetErrStat( ErrID_Fatal, 'Cannot use unsteady aerodynamics module with a cavitation check', ErrStat, ErrMsg, RoutineName ) end if if (InputFileData%InCol_Cpmin == 0 .and. InputFileData%CavitCheck) call SetErrStat( ErrID_Fatal, 'InCol_Cpmin must not be 0 to do a cavitation check.', ErrStat, ErrMsg, RoutineName ) @@ -1710,7 +1711,10 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, InitInp%numBlades = p%NumBlades InitInp%airDens = InputFileData%AirDens - InitInp%kinVisc = InputFileData%KinVisc + InitInp%kinVisc = InputFileData%KinVisc + InitInp%Patm = InputFileData%Patm + InitInp%Pvap = InputFileData%Pvap + InitInp%FluidDepth = InputFileData%FluidDepth InitInp%skewWakeMod = InputFileData%SkewMod InitInp%aTol = InputFileData%IndToler InitInp%useTipLoss = InputFileData%TipLoss @@ -1759,11 +1763,13 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, end do end do - InitInp%UA_Flag = InputFileData%AFAeroMod == AFAeroMod_BL_unsteady - InitInp%UAMod = InputFileData%UAMod - InitInp%Flookup = InputFileData%Flookup - InitInp%a_s = InputFileData%SpdSound + InitInp%UA_Flag = InputFileData%AFAeroMod == AFAeroMod_BL_unsteady + InitInp%UAMod = InputFileData%UAMod + InitInp%Flookup = InputFileData%Flookup + InitInp%a_s = InputFileData%SpdSound InitInp%CavitCheck = InputFileData%CavitCheck + + if (ErrStat >= AbortErrLev) then call cleanup() diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index cf7e21cb3..bd5fe8dfa 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -2064,6 +2064,8 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadVar( UnIn, InputFile, InputFileData%FluidDepth, "FluidDepth", "Water depth above mid-hub height (MHK only, for cavitation check) (m)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Return on error at end of section IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 1d69fe999..abcbbfd87 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -208,10 +208,13 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) end do end do - - !p%DT = InitInp%DT + + !p%DT = InitInp%DT p%airDens = InitInp%airDens p%kinVisc = InitInp%kinVisc + p%Patm = InitInp%Patm + p%Pvap = InitInp%Pvap + p%FluidDepth = InitInp%FluidDepth p%skewWakeMod = InitInp%skewWakeMod p%useTipLoss = InitInp%useTipLoss p%useHubLoss = InitInp%useHubLoss @@ -222,7 +225,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numReIterations = InitInp%numReIterations p%maxIndIterations = InitInp%maxIndIterations p%aTol = InitInp%aTol - + end subroutine BEMT_SetParameters @@ -769,7 +772,7 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte !call BEMT_InitOut(p, InitOut, errStat2, errMsg2) !call CheckError( errStat2, errMsg2 ) - call BEMT_AllocOutput(y, p, m, errStat2, errMsg2) !u is sent so we can create sibling meshes + call BEMT_AllocOutput(y, p, misc, errStat2, errMsg2) !u is sent so we can create sibling meshes call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) if (errStat >= AbortErrLev) then call cleanup() @@ -1267,7 +1270,8 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this SigmaCavit= -1* m%Cpmin(i,j) ! Actual cavitation number on blade node j - + + if (SigmaCavitCrit < SigmaCavit) then call WrScr( NewLine//'FAILED CAVITATION CHECK'//' Node # = '//trim(num2lstr(i)//'Blade # = '//trim(num2lstr(j)))) From cdaf84bdcf209311c9b3b58baef06a8578227b0b Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 20 Apr 2017 14:38:48 -0600 Subject: [PATCH 40/58] Cleaned up code --- modules-local/aerodyn/src/AeroDyn_Driver.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/AeroDyn_Driver.f90 b/modules-local/aerodyn/src/AeroDyn_Driver.f90 index 42c3512bf..e6f4df8c0 100644 --- a/modules-local/aerodyn/src/AeroDyn_Driver.f90 +++ b/modules-local/aerodyn/src/AeroDyn_Driver.f90 @@ -73,7 +73,7 @@ program AeroDyn_Driver do iCase = 1, DvrData%NumCases - call WrScr( NewLine//'Running case'//trim(num2lstr(iCase))//' of '//trim(num2lstr(DvrData%NumCases))//'.' ) + call WrScr( NewLine//'Running case '//trim(num2lstr(iCase))//' of '//trim(num2lstr(DvrData%NumCases))//'.' ) !dT = TwoPi/DvrData%Cases(iCase)%RotSpeed / DvrData%NumSect ! sec From 8d15e7e1057e3c6117427aed5e32a42abd413e96 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 20 Apr 2017 14:39:39 -0600 Subject: [PATCH 41/58] Cleaned up code --- modules-local/aerodyn/src/AeroDyn_IO.f90 | 109 ++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index bd5fe8dfa..ccb548473 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -3274,7 +3274,114 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) ! ..... Developer must add checking for invalid inputs here: ..... - +!bjj: do we want to avoid outputting this if we haven't used tower aero? + + if ( p%TwrPotent == TwrPotent_none .and. .not. p%TwrShadow ) then + + ! BNClrnc is set only when we're computing the tower influence + do I = 1,MaxBl ! all blades (need to do this in a loop because we need the index of InvalidOutput to be an array of rank one) + InvalidOutput( BNClrnc(:,i) ) = .true. + end do + + end if + + + DO i = p%NTwOuts+1,9 ! Invalid tower nodes + + InvalidOutput( TwNVUnd(:,i) ) = .true. + InvalidOutput( TwNSTV( :,i) ) = .true. + InvalidOutput( TwNVRel( i) ) = .true. + InvalidOutput( TwNDynP( i) ) = .true. + InvalidOutput( TwNRe( i) ) = .true. + InvalidOutput( TwNM( i) ) = .true. + InvalidOutput( TwNFdx( i) ) = .true. + InvalidOutput( TwNFdy( i) ) = .true. + + END DO + + DO I = p%NumBlades+1,MaxBl ! Invalid blades + + InvalidOutput( BAzimuth( i) ) = .true. + InvalidOutput( BPitch( i) ) = .true. + InvalidOutput( BNVUndx(:,i) ) = .true. + InvalidOutput( BNVUndy(:,i) ) = .true. + InvalidOutput( BNVUndz(:,i) ) = .true. + InvalidOutput( BNVDisx(:,i) ) = .true. + InvalidOutput( BNVDisy(:,i) ) = .true. + InvalidOutput( BNVDisz(:,i) ) = .true. + InvalidOutput( BNSTVx( :,i) ) = .true. + InvalidOutput( BNSTVy( :,i) ) = .true. + InvalidOutput( BNSTVz( :,i) ) = .true. + InvalidOutput( BNVRel( :,i) ) = .true. + InvalidOutput( BNDynP( :,i) ) = .true. + InvalidOutput( BNRe( :,i) ) = .true. + InvalidOutput( BNM( :,i) ) = .true. + InvalidOutput( BNVIndx(:,i) ) = .true. + InvalidOutput( BNVIndy(:,i) ) = .true. + InvalidOutput( BNAxInd(:,i) ) = .true. + InvalidOutput( BNTnInd(:,i) ) = .true. + InvalidOutput( BNAlpha(:,i) ) = .true. + InvalidOutput( BNTheta(:,i) ) = .true. + InvalidOutput( BNPhi( :,i) ) = .true. + InvalidOutput( BNCurve(:,i) ) = .true. + InvalidOutput( BNCl( :,i) ) = .true. + InvalidOutput( BNCd( :,i) ) = .true. + InvalidOutput( BNCm( :,i) ) = .true. + InvalidOutput( BNCx( :,i) ) = .true. + InvalidOutput( BNCy( :,i) ) = .true. + InvalidOutput( BNCn( :,i) ) = .true. + InvalidOutput( BNCt( :,i) ) = .true. + InvalidOutput( BNFl( :,i) ) = .true. + InvalidOutput( BNFd( :,i) ) = .true. + InvalidOutput( BNMm( :,i) ) = .true. + InvalidOutput( BNFx( :,i) ) = .true. + InvalidOutput( BNFy( :,i) ) = .true. + InvalidOutput( BNFn( :,i) ) = .true. + InvalidOutput( BNFt( :,i) ) = .true. + InvalidOutput( BNClrnc(:,i) ) = .true. + + END DO + + DO I = p%NBlOuts+1,9 ! Invalid blade nodes + + InvalidOutput( BNVUndx(i,:) ) = .true. + InvalidOutput( BNVUndy(i,:) ) = .true. + InvalidOutput( BNVUndz(i,:) ) = .true. + InvalidOutput( BNVDisx(i,:) ) = .true. + InvalidOutput( BNVDisy(i,:) ) = .true. + InvalidOutput( BNVDisz(i,:) ) = .true. + InvalidOutput( BNSTVx( i,:) ) = .true. + InvalidOutput( BNSTVy( i,:) ) = .true. + InvalidOutput( BNSTVz( i,:) ) = .true. + InvalidOutput( BNVRel( i,:) ) = .true. + InvalidOutput( BNDynP( i,:) ) = .true. + InvalidOutput( BNRe( i,:) ) = .true. + InvalidOutput( BNM( i,:) ) = .true. + InvalidOutput( BNVIndx(i,:) ) = .true. + InvalidOutput( BNVIndy(i,:) ) = .true. + InvalidOutput( BNAxInd(i,:) ) = .true. + InvalidOutput( BNTnInd(i,:) ) = .true. + InvalidOutput( BNAlpha(i,:) ) = .true. + InvalidOutput( BNTheta(i,:) ) = .true. + InvalidOutput( BNPhi( i,:) ) = .true. + InvalidOutput( BNCurve(i,:) ) = .true. + InvalidOutput( BNCl( i,:) ) = .true. + InvalidOutput( BNCd( i,:) ) = .true. + InvalidOutput( BNCm( i,:) ) = .true. + InvalidOutput( BNCx( i,:) ) = .true. + InvalidOutput( BNCy( i,:) ) = .true. + InvalidOutput( BNCn( i,:) ) = .true. + InvalidOutput( BNCt( i,:) ) = .true. + InvalidOutput( BNFl( i,:) ) = .true. + InvalidOutput( BNFd( i,:) ) = .true. + InvalidOutput( BNMm( i,:) ) = .true. + InvalidOutput( BNFx( i,:) ) = .true. + InvalidOutput( BNFy( i,:) ) = .true. + InvalidOutput( BNFn( i,:) ) = .true. + InvalidOutput( BNFt( i,:) ) = .true. + InvalidOutput( BNClrnc(i,:) ) = .true. + + END DO ! ................. End of validity checking ................. From a73096c839f5bb60b95cb11ea4c4a6f2a058b5a8 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 20 Apr 2017 14:39:59 -0600 Subject: [PATCH 42/58] Cleaned up --- modules-local/aerodyn/src/AeroDyn_Registry.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/modules-local/aerodyn/src/AeroDyn_Registry.txt b/modules-local/aerodyn/src/AeroDyn_Registry.txt index 5bb5d1401..d93afecf9 100644 --- a/modules-local/aerodyn/src/AeroDyn_Registry.txt +++ b/modules-local/aerodyn/src/AeroDyn_Registry.txt @@ -71,7 +71,6 @@ typedef ^ AD_InputFile ReKi KinVisc - - - "Kinematic air viscosity" m^2/s typedef ^ AD_InputFile ReKi Patm - - - "Atmospheric pressure" Pa typedef ^ AD_InputFile ReKi Pvap - - - "Vapour pressure" Pa typedef ^ AD_InputFile ReKi FluidDepth - - - "Submerged hub depth" m -typedef ^ AD_InputFile ReKi SpdSound - - - "Speed of sound" m/s typedef ^ AD_InputFile IntKi SkewMod - - - "Type of skewed-wake correction model {1=uncoupled, 2=Pitt/Peters, 3=coupled} [used only when WakeMod=1]" - typedef ^ AD_InputFile LOGICAL TipLoss - - - "Use the Prandtl tip-loss model? [used only when WakeMod=1]" flag typedef ^ AD_InputFile LOGICAL HubLoss - - - "Use the Prandtl hub-loss model? [used only when WakeMod=1]" flag From ac114e5f644b64149e28933bb588eecd44727379 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 20 Apr 2017 14:40:18 -0600 Subject: [PATCH 43/58] Cleaned up --- modules-local/aerodyn/src/BEMT.f90 | 33 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index abcbbfd87..f53265922 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -1181,8 +1181,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat ! local velocities and twist angle Vx = u%Vx(i,j) Vy = u%Vy(i,j) - !theta = u%theta(i,j) - + ! Set the active blade element for UnsteadyAero @@ -1265,26 +1264,26 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat - !Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth + ! Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth if ( p%CavitCheck ) then - - SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this - SigmaCavit= -1* m%Cpmin(i,j) ! Actual cavitation number on blade node j - - + SigmaCavit= -1* m%Cpmin(i,j) ! Cavitation number on blade node j + + if ( EqualRealNos( y%Vrel(i,j), 0.0_ReKi ) ) then !if Vrel = 0 in certain cases when Prandtls tip and hub loss factors are used, use the relative verlocity without induction + if ( EqualRealNos( Vx, 0.0_ReKi ) .and. EqualRealNos( Vy, 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'Velocity can not be zero for cavitation check, turn off Prandtls tip loss', ErrStat, ErrMsg, RoutineName ) + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * (sqrt((Vx**2 + Vy**2)))**2) ! Critical value of Sigma, cavitation if we go over this + + else + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this + end if + + if (SigmaCavitCrit < SigmaCavit) then - call WrScr( NewLine//'FAILED CAVITATION CHECK'//' Node # = '//trim(num2lstr(i)//'Blade # = '//trim(num2lstr(j)))) - + call WrScr( NewLine//'Cavitation occured at node # = '//trim(num2lstr(i)//'and blade # = '//trim(num2lstr(j)))) end if - - if (y%Vrel(i,j) == 0) then !if Vrel = 0 in certain cases when Prandtls tip and hub loss factors are used, use the relative verlocity without induction - SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * (sqrt((Vx**2 + Vy**2)))**2) ! Critical value of Sigma, cavitation if we go over this - - end if - + m%SigmaCavit(i,j)= SigmaCavit m%SigmaCavitCrit(i,j)=SigmaCavitCrit - + end if end if From 0d06f68431942be4bdfe2bdbbca69ac138235d3a Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 20 Apr 2017 14:40:34 -0600 Subject: [PATCH 44/58] Cleaned up code --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index e6baa35b4..991a3d790 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -171,22 +171,19 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & Cd = IntAFCoefs(2) - IF ( AFInfo%ColCm > 0 ) THEN ! If there is Cm data, it is in column 3 + IF ( AFInfo%ColCm > 0 ) THEN ! If there is Cm data, it is in column 3 Cm = IntAFCoefs(3) - IF ( AFInfo%ColCpmin > 0 ) THEN - Cpmin = IntAFCoefs(4) + IF ( AFInfo%ColCpmin > 0 ) THEN + Cpmin = IntAFCoefs(4) END IF - ELSE IF ( AFInfo%ColCpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 - Cpmin = IntAFCoefs(3) - END IF - - - - + ELSE IF ( AFInfo%ColCpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 + Cpmin = IntAFCoefs(3) + END IF - + + end subroutine ComputeSteadyAirfoilCoefs !---------------------------------------------------------------------------------------------------------------------------------- From 372d825d2641aa5eaa8d28fd937b705f0bba8227 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 20 Apr 2017 14:40:58 -0600 Subject: [PATCH 45/58] Updated with cavitation outputs --- .../aerodyn/src/OutListParameters.xlsx | Bin 44503 -> 115021 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modules-local/aerodyn/src/OutListParameters.xlsx b/modules-local/aerodyn/src/OutListParameters.xlsx index 4ad9f419d995a87a671a1f4b7aaa3bc2942f4792..47003f4c916c61d4da86e8be54bbb638ecbffaf7 100644 GIT binary patch literal 115021 zcmeEt^;?$fwlyu?-5`y0cbAd^f^>ICcL+##NOwwyfHX*VcPU7hwDkA9pliGLKIbnu zpFb?T?wB#=m}B0o>rwF)BornX3>YjJ7#JB?4QBUxIye{@KO7hs1{f@arkJgbqp^*n zu8P|`V+UwZ zA#ptx)Savb*@QhjsAyG+=*r0HV&rnVk}q5BDBAGCHxmX|$g+`IQG4BVjlMZC&nO@q zpLotTq2tA#NH%=SMnw>2!6zn0%)mioUbl$)Kohc78(;LQ2y>InZ!1AYI)U6YiECS$YT!ErCXR_Za(|6R=c+@!c)E9!KmadtQ&j*gQ zy`}|z9!bv#UlgG)mxOvGI#3IVrnCey57vi$UQRIyJ9+u`VYsEc?F!e}fp3LPdRh1R zQtW!(bHYNR@7#N^y>3$6jJ#j%=FuWceAY-uV4{c5kEEoY*Q{p=YjC#1MGXH@h~{u-W-dveHdtD#Yy+ha|NTxfH^e7Xgrd zFAW#RFSbU7G*=Ec%~ePU4VdIR8)-zU*bF>oEnLeo-=Jg}keixg_Tonp>Z>iUSn0av z#its~-V{}bh2b~G-##~BCsM#fINrC44Y?s?2GxR= z!r4O|w;lPbkTL0Rr~Ip-4#InT?-?`AKK*JL;a@8Z_%3JkOTVKVMMW1#{J*<|uIu2n zBryAko`HekgTaEkS}{E}ii@qirGc%jC20EnX&P`~1OjLOZ~tjd7_{+cMwPfsxJK!_ zF(8GLDG|mlqcdJCAkjj;HJo1ppqSIN-u zE`4zbR4wd?BGwao_vZN+Fb)i8%Y5H(MBg9Ly1ECMS;h;^0Zx;KdMZ#Rc{7b|xtMN9 zM4gHkq(d^as=c3SRV6%nMoS@5#Fbu7D#0g<6Eo8R~FO7j)TN+*iDU2T@|Ci5mC78|%MW z7?UBsLk#G&51`~I0KEVf{>{H|6(!pRW>oLY&kx_;Hh+v}R}>B?#yaR3R4FU<5~pfK zEr}$W4{UE+<-xQl;yj>j_;q-5*m{)Ke^4H4gwO+D#)|La5$`*|fn$+Az8cnBLPj~m z(w#g7&)WFxm2IJJn=HQd${UR~G$=*R+~?ocZo(QYfX*{q*=V+97tVl|Og*1mR{ z5MN$O%2aR#(@|jxkcJOG=xyhq@(ek)eiCkg3mKo!ckOHoy^35vkIC}8tafiAqFs3#549)F-0@HPQIVk+rR&>|Be#pxVyXJu zP2FjApx7^R`+|%v=`d#_6eP?qdufOarantm_%)%At}FRzkhI=`RWTAdC+E%K45rV0 z^($jtu$KUTOHUnJr;xMoc58sQrh|M6YWdV})Q(1+%kVvu$%x^qgZk;W?(rId1v|Pg zaPYB%eja+$Ztm#MuF5>gI@pp9puGvP^Ae%jvL-aYi3n9)ZgYz~FkSr!g_SsLcV+#& z^d62Z7AyygZU4B1uJ5uSoyPWFhDQzBCZ6jT+a9Sfo_l;zzQpRgvH*y~#4~>POZ$en z;$23P4_zWALseKc-(0v%Pp-CK?5e|$bgb&}3cS54bC?b3O+QNi{*FBaqJV9IEr zGH}4aaQ{Um2Qy=1M+c_IAM7AaD^*{N%;iS)(lvhoKNj?b14pOCbMieK>69*+*2yqm zqbL&VgYde!VOZ4KXC0;}aWm&FUl&tNFJ?X2-Se>H)G=4x+Ay|8A7nvt?;r5;<|!X; zyI=BxlgqW47!(vp#A)OdGPCwxzP%pYEi28~!^n>SM@)3L&Pds8{CvR6H%?wwcJh)* zk0)L=hVy3)@4|U)&Q69c-ALUYcdK^ZRW~N$;4XIL$-6!_{KWZJB1{papSF3d+aIpu zb@w96`fRf4Cw8wkt|{rm=oR@lwwkZL@c<66PXbv)z@7vZ_?IOG@!UY8Kn6@^fP7b(I zNEDDT15DjeIS{-X9)iu&MP|Nl%!H4dY~XQ!t5Et;>P~9D!{^hwakKfEQ`=y8D}w~a zVbV3nsb&zb(A#q0pZn^~H*ZNDiBb7A zKQ_^6usP;RBZ}YKV$|cge_j|AB zL@jls>=yD;RaIN@#;UVSyyWJ=NMF5iA$2dTD56LHUJC_>`-!5DVhT0aT~EtXNJR#z zq=LZIxJ|U*gu$TXIV@Q@d?*y`%FHB~S%Kf0QgoqTtkRek^nqh$v{)3cA1d{}xs|kW zra~X_0QFSmc4E_M|Cbr6{UeO;yn-*yDTD=WMGHj3anQ|0?687kO2%k%%SXPcC&zma zf{rC>rN;?MGz*f0uVF+mbuIfvNr4yN$JJhv0kOnk%s}GFYex#DK{t zxggk2ttiU#bA%vk1Qa#9Jg<0oVXOMa}+4AL1d!N8eF)5JpFoRD>yHe!;nZad0%0^yXA8Bx%i~{XZzMH z4~iKK>#yl&)exA`VQGKZh#=!lyR!!3g+^@I7q%^=qfA$bH;<9uKS1|?`Rpfd0mO<$ zp(C9K-K`4otTSTQl??$or$6+ERk2_>hJmeSe4bJpYcSMJ<;&+qW4)cmLmx)z;wq0I zYT0`OQsA%NJD5R`&E{fL(&m*>oP-vm@ja+=^%nHRr)rY7lKs&C&g-zm&j6p&L_+H; zO0CHsiSI6w2KAgq7hRNnI!P1vj2j{)uEU8#ZC^}uc=|4u75Rm^Z>t44xngymD`gBz zaVlxR{^n=rVheD(t0YoB-g0y+sh0;TO;L41#U|8*`xesseIHqch|qoW(Gg%c+_by) zDWVU|0x0^3$?cp&mo*U?9j>Li5#vlMOUSAWZ#SdCUNnV|tO2(0(ctPV>1c195-?A< z$g2ErHlwFRP|f_o=Eq}_D?LzYDH~r_dx=xd^Jk;;CFe(r?^%$jDxd!n?%F{{TDsYT zW}^_9%K7mT=O!>gyr-zUD^jn2nAWEbsy&vPxcCTnv36+iMw?nVW9`os8*fD+FuJ zz`TsZ`%8kDA@X(mKBHq}emNr6-9f$05IQU|+lPy-OIy>2W*>KN*W2U6W)CMjZ|8^g z!{f=$D5j&4hpjf-`-79){i}_O-oi!OD51mE^arO0&-?nzhifL=2UpMQgR8x}yFt9N zpX*o4SF?$UnYKD@-mN$84|f+=)9a%*BxiA>Q3|WJy4ymTtVSiO;3M~70yWGFJ++1hYPH*#maBdKNxOw-` zTl4F|)U(6K%kwtE=jWxu(Fl|J^@6$WM}+%K1=Gw!q1F5QgN-)ghhLXBK}@>3G)?Oz zF{nvDh6~#+E=OG);motuAeo#le?_c~KV*3Md@B=H`*tz9u_{C?*y8Es;(cX-dmWa& zS9n^Zdz7hbL+mqZ-zZiT&)TvCon6U54)c8imUlF9Q2nN}|N}>N@>=%Wl)Fz)za`I%>cjEJj_q zNp7ZBDms(PjWBmj<>Qlbni;pe6fW~GZWa?4FKsi4AGmV~A}20yPe0nO9wIUHHRZK= zN?h_UQGOP1onYb*3)nKH@F^&}9lgY{)qRL_USBT$^$kmV_FTh}NZj#wjg_9Dqi8pau`VcDC z$krh%8l8Ciuc2&y_2v)#Wk<^4Fpq{QTALbbUAa`wk<%r_Aqn?~$U< ze&Z%JmD`D_;fDi!SAd61tQ*g!ww$q)RxLH{GG-NeLkf((KI;WP#=o9lffk|Ij)JtG zaWr-Y!+h(Gp0M4CpOI0rIC&}b&!NKyQgq-v#~{A|iZuJ5L-#KyaRkC^XF5$zc?Ah2 z#yh|I{$%ERR|(1G91&$8e6SQbkTDr|sh`|4kC9lK8F9C-may>VE?;H`yjaUwxJ!p0 zj~#QCl=`R-MVm$&G2RVkUu_y&Mg3I?e|%I@&>CwVIGqX;%m8jzMws(L^7Y2GELlR( z3EHWmmKwV-(I8sw-4KS)Ds;ko*7`;8V&KvoLfH6X6v77>nvBgu+Edb17m-@%4=Th1 zQbS@@r(D8B2r$W?(%l4)nz9!BMCnjAo^NK)jS*x;I{Ess8V|H0&_Nn!#5^lyecSd{ zHNL_~NsTsZ#T&B9pq_2Iw-uq7fu_h_k<gE7J(n;vn_6o2YVy{?qsgUxU(ivcxp-CSs zN@(1Vjttw_c;+eq7b;3xyfmmR2;Gui*B5&&Z5Z)oG;e@Biy`0e(4ZdE2_&CgSUz5X zGNunz1$^%zKZ7PW$(}1BVBNS&&l*CQzkCeIq%75mVFEsLz&JFb5q#k0W=?k@)K5tF z61uE^3%rC7GuSnOxZeGyRuxmAn1(T~gNZ~Rs8fHuzn@c(KLlEhB4!n(GXJpP1k!WDd~ejF7{%@ubvi^a`}3zh1t7=c}J2Qx>hG$sV)x}F8g=Sxopy-?8T3` zlttrd1kc)gJe1N(;lMw1zSCDn+0&r27PHMb;$qJErKnVeSYS_6UCF&+@P%1ZzwHIK zHvy$Fwqb&`UMbzV`d$rg!5bRGX!YjSk)@#}g8fSwt!wtYi!eJOB5mh_7X=EQw#ZO_07*UfU8h`Efshd*uD2+mmx>g|C#gHp%C*zL<_>j=rQu#2_XDgcol3 ztVyRn)I7E%fD90DuJiHAGQnIokz_)c1M^F3q8`W4uo`aT+_q|4gT(IJ0#=Ws$^p*m zD!`7s-LXu=ud(F8=B-SBkH4+N0ajKBZcp*UNf*Du0stv%dA?>`(Vge2x^?i?zgW=+ z;0fraW08JymzOe?0^&i2kBKquzi@|5G6>Gu_8b6i84jzJHh>x=-~!0C zvc#wxB+b@uW!_kwnH&+Zvc@eE5XpI`D|#LBD81Q(JHy7^U;Jszk_fBN&eAf3R%GS| z;oP@N7_I(87&G}h(J##X8P|I1c2=pZoDH}+!V);?7jXLoh`jG17!UPc_CS7Ya9Mrv zYP=fils0mB?eiw{+*iZ5L)Iu#zQ&QlQiB+klrx)pR8lkzZ-P7I z?=5s{a4+}{N^uiT z8XxssLaA%ie|4A{FB|NGF7 z)ZE>1E`afVLAk3fj^7~zr=5`FUm;%v{P2D@?Ci+%Cqkh!h07$I2pcoRlK0k`}wyo`ONAvzy=iLvXDKhfN&Y(Dt zSy7*k3H*j+KWZ9kfbyB$0!6dJib&1*zrx{oZ!cppq_>+x#IC9EgbTV>##;XiY?l+O zJH59<%l&Iw8o#<3Kk`5jF(^dyyP0z<-oBj7x9{&Drd~cBZOL_ef(VF-Wj_ZVVk6dH z0KKs-z+?|DYX}3xsf*s1e!7hQ$#fNjOAVt%p{vB&QeE{@%Y7XYOJAG>2hh&@*Nsm$ zFf`OWznPzuR~}Zr*gJwhg%vDiJ>T9hd%IGkH}4;i*q^CDuC&54w0Yd7`>~7^PQFEg z+yr6#T3l zm@?3F>CfDfnG++h&*68POGeSYNE}NMkcsYBds(J1q>L)K2yF ztEd5d$mEXw9m#$b62*YSGZ*1Qc#V32V^=`5C|K1qx_)_VDF1rt(aeX{EA)(q1!b?3 z?kRL@VxN40m2~{|%-QHC=hWt>zv#`I*1tuD9*oI|><`&F53 zPYIrTtnF3~)JYpv^23!?$G%u)Dr-?t`Pt!|GN*f7eMq}6<0s3onI3}^7In)H*JRb# zFGDfmOiR6a+}H-c*^(Sb8drho%FpyheK+)Wx0c3J}rZ~gEOpfFYkhL!3=p08uQ zi(StANMzm-U`T&^2!Y=!U@MdE?`MM{)kFV{VpIr8>iQ@57s!NVXh$z!498S%Rvqx5 zvU=kh88#}yn=20&H2!5P&VP39>Y=50S-;QuwKc)^*w_vEr*UeIS+DiELZ_)fq}9#m zF!8;gst34gQec)v@>dkKrWk%C&Kc17ev^Ipfe{>1TH`JX~UDY@&!&rwr{8N zQuTbEh_Z9@5maV<>M;KpEuY9!HdZ+s_ANGHh!dUgusm$cKZQL^-UQX~21Tc38` zce>f0HwCxGO%-CAX_zP0B@Ebn znMc`MG=XRR3h6&Cg(Uz65hLnWABzeUV9sfF@it*^UAXx5P^f9Ay;i2=F z2rNYo!E?`R*FO);egec-JA-Qwr`_c&5^BVjSCtZ!52`xKgR2Fq6 zh2}F%E7HISq}~-zdxvF8?EyP{42oRpKwjZ+N9eVl6od<5LhEPP!-M9rhcmwWP@5}J}eefr8{Ns~DZMU5!_`4QhEEsnizDuj(GpavtP_Xtehd8KI z7HX-5#2dIfs4Qbx!3{d*WH3(1XiX`W)^kM})8?{hz%E)Y?tffO&=3wK>}?qum+fv2g~ zf5=_mu=^5j){*Uo-m3x?0J)1X5P3Y_35ZSZ8n7d2*1>Waz#{Y&y!%-fsAaL3qB^04 z5s-)D=2=E0xwEQ$xgYIs*v&0#zB9|{VyTnh&axsUJgqDo#s&n4PKUU#>h{}8G(@k{ zz_uRs%K!|EpeH-6OR+>L)OO*Siq5{@JNKcMsUkxYd$XNV-l=%f;hhzl2XrDdt!B;Z z5PY8ZlV^Bl6>q$AvSEi`0%0SZ{Eg%Txc*kabRs3OupK$q^6zp%H8^t!w2n@zn3z2MWxl$Wwx0$A9RH1owhyjC? ze2sMPB4l~zU>!amh{6_@)9Jl!R6FI4PG zc14Mfk&j{86aUNVFmzK+WStWvTCcnG4^ZmI6Btjqv&_;nj9RE{h1WIxJs)Bi6&}^J z*g^7!^4XJ`QdHUUMFW_UOYUuifYeCRX@q8_vQ%pMHJ6%5_*P2A>4X=S0y$)0c&dbQ z*Wt3kKO=-!SLew3>$6~pGhK_ysZdyNQ59wMFMwgwH zKS*+c`una*a_M8l#Qd2`+Z^-!XJNHe%opaD|`WKv3 ztL)Fucd)u#%RP?bH$!iT&~ncKNS-ePkQBO{$gw@nVG-7=0zAcM!P)!yTzTphh-0gkjN8X#OtLmHwkvG(Ppg%rJq`ja6WQ7kj{j^pZKh^^F3FWg?PZB+>gP1f0yh7y z?Fkar>jwj%?u{;C=H*{lgK+_*H$lT67GrtuCb`$SZ+*R!4XnilsP)%0uyibTgFRAC%tXCJ>OzoX+FspH6XTvA>Qh30hA6 zA9f~0K`bDuJ5tUy1@c;OK{q(;DgTS@KO!?OKjD1-4HhAYkY$^@`UKnkL;^UxBH=r-j@i#BOqgg3iL>l1{hh=a9u0&`IGRz(!OOjMpuz! z3fS*nuAkPrgD!TU@{mpsenkIR{PBSk!}zNCbGXgibS33E``@Ab|i1&N17niRthG86YPhI~+JxJOcAIC&25M?D4hA?)p0opxhh%9{|vZo2dW2 zbqFlWr^+>2cgNF)sGpjyU~^%WF9h_^`^~<`o+G}Ydb}tbEqn3pL1YLE(9an_&>ll_ z<%knlRp_cBM(?td9XKV( zJe`jcBr(PYMUY*JPf9Sj)6a?iMBZLKfhsK-2gBE9{p9UEK}eHMSn2&oUW65oD+{UXo-{l%kU3S zYg?NO|9+Y$Tj2!zCxM33U!8A#@n>7)Ka_6~#qWvG68kGMd4CZBBt!E;_J3ad$xE3R z=zn!I{QC^QT(woEDfr_P>8+ z`|DQS9rs_q4uN{>tiXmeu%&`}cB4R{Q9P{&v&y3$*2x!l_oVC7=I+Ya-OmJfl=H+2 zv&`H1hw@du^M5$KC_}()Aa$`i{*(3aFKs zD(JL;4G8(@@74sp!a>60)Ucz>X7gK64<#f266pp;F0b8LhTvl@g>Xlj-Y0fE3hkc# zWZ}mZK=_y4{^>~x)Wi(6wlhl<+XabF4GTt^i(`fim?C2PicVgHDeGe^C`7ko!*(=f z=SoOBtCcT?>*&q5jVIzX?33zC&ft~I+2(sV&#Gf=Ds{J>V`D|H$n+jA!1yDCyCc4S zg?P$Ofv8eJikK&cOQ#3!UlRDV3Qh1;SOWH|FmFIM#3swff`w_^#`+5*kJkO0TB-W0 zk7)<=4(+_Y*^t=GvJtNvCxy-$gD#Cy+fiZYaHxFWJHq-q(%wNMavoe;Me~;N&W|t# zyte=g05-&+U+7h0%o=V}ms<;q;`Yr^FV1}6#F`*O#H#e|xX_3av4}xBp7zZrrb7HN z0}Hu>8VIl6t~XlROIq8-tm{pIXw>m%mAhkT2b;RK>s>3jhl4_03A}Z&-sN>jAhSw4 z1k9p&pX5W}rWOCE_)qe6(D25P4Qx*dVKdLk@3DYZE8z4=T_ka(gMQx-2xOh^=OiRU z{4o+|Z6TTp5AvSWtDd5#X1J|0S92g-eKeb~;64h8SOkg7s|WtP!L_?3+e2@(t_=2% zDLQRWb9e1bB;(@K5A;*|6$kSdm^^2SARnTfPo78Wz+wM8o{_qeXMc=5WdMq2zHX5e zh^NMSN8~9U01dvfUd005#e0H)j=_25>OXk=Suem3c)x_FPfGMv5gY;6s_-0lK*e-% z)t@<Wi zmbbS%#AIO6%FfV`p-;bp+87gia&TMlMUVjG!OO3@W3Yib;b2hY-!Yx9iwEVv*8WJS zKlqQ-%|ZhCW>^cs4Zwg1@Qyn2Xct8&(R<)2;@kH?#Lxe5^LMm-y#I<8pi=sbA&qjn zwFBH&;Y0pKXXMYHqLKBBe4!ERCfyN@i)#*AgmL@Q(H`vs1asDi%9eGiL&AdnhYlcq zw@>4iVqZ`b6YdoTR`&k1^0~9$&PLYT_Jt0Q(@OI|0U8CN)hjavgFc;SQw*1IW`W`l zw)3D$c*B4YH~z!c-}RA%1XkU!+p0A=N&a(h1hn^GHIn!JA2J@j!ho^gn!iBLlKb$x zfu6EH=(?sm=at3`UyB^=fMozW5T|PdHst3)P{*A;D;1mni(nr6>Hkyk z)j;sS$@NdU4q_}H%jLiSpXCy8lK&sdCDjl2Pr3eK&xHyfh&=~9_6sWi*1_|{*MN46 zJat71 z$Mlq^9@FddrToK2ffLz3>ETrd{9)r((x3FmAV2;Vr;!U^mdEtSOdiuSYDWho?NJai zxc^BHQT^+mrZ?>RQ}t+|>0i+gSs=baSgqXhxP;s<B9@H;2;2n5k-ctht;f)!3tr-0@a>9OI3(x9jd*5A%mZ|q zQGJ9;S~)*)3;ukniB*C+{cd*<%*jl--#6b11n!@`XnV-qiEg)+;@_*3h^M6anuHB( zfMjG__5E|267h(jFWuC`H{tLpXmCUGa`lLg-K2H9xQM+4ba2LewcrW%yKr#w5=_vQTq3QOK6^gxeq1*tu>9o3n0r#qJ`lX3WlA|wg zJQ6UoL2^;p5>Vw3Boj0hs<4d;6I50ygu#5%u8qGoy}CBg?E-j=zTUIeQ)%R`pf1-W z{!OPZk5||gBwd1Js*tVeh?t{5#&Y@W?3VN=$eg|^^Im#G?xF@FC-nj>9}VPG1>8y> z9B?wzX{XI%%rb;kvHOZTofC)Vz#rnCvXRDMLopz3VMO%~8>+ofU#+=AD6EjD!KsRuDTw)2BZX1ziYNI#`a z!ky1X0;R;sZ8cml0e*^0-N1cm6NkGg(n#{!fh+$MpoItWiLT{C3qb8j)LSz6U*t;mzOr6_#yX~ z0|AtlV1^7pRZfw!q63wzWzqSNnHHdFlJ8sK>ws5BizjMS4I3$4?=r*NGpsr%D~(z#UY{{IFB^lSX5f*f3jzTh`LDd0F|P(_OJxqMOe;BthcOl!Y9B zigERljd!RZCG!a+Ur`~o41Js4eA!^{l3@OO)b+!L1Z2v|Bqd`5RAlY%?)6v&lCizCDvxoU;j=p;ue&D3pW z4bBVqOCp`%&I*h3ah_+pQ=)6ii$8aDgnU}seCAhMms)*pZhxJfL?tdJ-qaM{j2?{$ zovGQ{Y}>#Keeu3M-ub@q{aEVy`?G7ZWr2$I=1W_j72q@HsKr7i6rqgK)@7f9rkgb^ z%A=j{2wbwd_YZ^XqZ<$7a(8>{gM;gr>posBZFi0jT@MnMhg-e9iR(U!h&q=fmrQLB z{2rd}S&V!2w=Y-HAM(_09dCY$qOI_Iy1U$;T`DY}#NGp+7Fv^eJUoE@3F?1;BiY*x zyASUL2Ilb^@_+kAlJ)VccQ4JFCC-!|Hw0eIx zxz*-*b$)fVM<4(5Ch=lUbqrjl04qpR8aZuU`k9vp&clTD{MY@3??3Kv#vl zye|t^+iysg50`JM_P;+!ACm|*KiuvN7V5UPirCpYNFHmc8no5s1NU&FYVlLZ>-sG5jO6}c>qti^D_m&h?*4W+ z^WhXlg&_U%dU{sD=k{_-w>2Zf=Y}ESi`(7q@=XQF{l)E3yVvElLT0P?-5Cpbpx|9- zruWtDj!=dViJ#!Z1>%e1IQX)ThG;E|Hjz-zD<84+$p=ZVRe7w)2anQQ<33-Xhuht) zE!~y7^ZJTHg|@p@6d|9x^QPHeuH{aFk+E$5X)YcV4+uQPk*Hf3v7X=7K85DaH7$8R;Z`lM% zHa5Ixp+f3*3_6%x5_aH~gD&_n)WDi&_Hek@bkuftyK_{*JVR>UN;=JA@3fjF_zR~c z(}SaM9}LeP4atlZjlq{tR^l#t0KZ%+)Vrg?=jQ(VV!h9+4umx+2}kYvPa=hgqMtwE z`qpt2)n{oV@oJ8>!f1b%SIN%A9Ct!dP-d|mk5~4{IWH0zuXU+2rQ2(o{o-u_OR$MWfgPr-39ns?S4~!9G$j06RE@}t5p)I3j?vr6s_dX>t zlC$#7sP>4n-XNJKcPegav(FrIn;J~B^m=^B3kx3fW)ylwWoW^;#Dv^wnA2lnzY`nL z(qI@^l7v+2t}DzzwA)$(Y3_I)8>!bmP4QmwF-QQ;U@vyjKqBhMlYzKHyD`l-NW zHaL;n1TVpu_pAALEKUpiTaHDqS(n$D_oQx3s7?>eX1xg+i#_aaq#GRRvQpS1ELy;c z_;z-!#CKy|rCFRT;^ZBKoSZIy{)Bn0vssp*-&-r-)Z=MI*^TA+1MbG^)!O$$Ujqoq z6)~GTBjFonglW7OPY8~Y$!s?+9z4fd9KM0$ktf)w3)p}N&8FVJ}rbF!r( z?35S{;qh!?oW`Y&6n}%UK>mPHB!4DOP7gosYZh1D4B#ttKQeH1#n0>;uV!?(j7A~n z{Ez2vE=yU6JPRFnS&OLXA!8twBGas8C>CFVmtknK;+OOn)6WwI1XXeI;iHVCLn@W) z!kb}5eSf>6K@9n2WNi3-aZ)C-_hsYmX94=McolzjbIv8i;=lwXx6E#RV=xSqasypq zCoCCrQv~vSZP_mcL5tC;Z#QGCC8ozcLRU~I?R}z0MzO{5+-b9L%ZH!O`%k+iw1~fO z?Nq?Oj=+x;@E^hM;$;HuK^FBr7ocn0W#rn);ccty<*_@J))98{4oR|?L38|32xY2? zjsjmGKW;p2Ku%p1`B|`ZPVhB@d?%YB@KqWTGElxN^RM&17vFbg$9fVWLIsFqP_i-+ zi_96ge&_@SbuQlz*WN^YZ{&UMy#G-F8k5h%Ckw5RE9l|Y z_cGG{#S}~-1pJ|vH&3sw#m1_EC8vdDT@?FV27J*WSIS#=1OpUP5zIq_U88F``c?#G znQ8JJGK-;|Za6ov+2rPBWs7w9A{#V_b8PY4o%#2~=Ikv=yyjuJicJzWRT`RJji1*| zMGGN{HGafw4g$4yaugghk0cMmHb(i^N-0HDM5cg@4`dUt6duly$X}zV8yK^llweQ(;FL|)CJ(I=SMa`=D=W8D1#j$L zMv|>8PUDU8u`_-&gXS#jd{DR1lD$S|9iB=(;$vTOK>>|?FB2$O7H5tJU8@;b`t4mw zjX{XMO&)pg_$fy#N&PAtTgGfQCa&LC&!=aF!e8~LY(6@&S}%VUdj1$Kf}w=M z;^16+!E|RVlf11#&NDClE<1{^SYsM@r_LvQFkRwU9jPN6^Fr|IlP;PNL9~n^l4&3Q zm<_U8;qiXvo3qlC1bOVmOFWghjYU>SR^U3~TS$voIT$0S(PGV=ubufKk#~arH`1v>YiJ{(~aGkR0ecln)e_@AQiDsW0-iV%!*jO1{$-UxKlY+lrs@i zgeu~(#vR*J0v=)hyhWPx{ECI=(3oz7oy(4Y7nf?@NEjFsjR|s6CGYRZ{OO3LoE86x z9t0i7TPJz~Z-)vYBSi`iM6RTKQ!Jy2N8B*6i}u(hL38MvJNwE{2wk5(KwE|t{(UPR77dgu*lBolXPi~i3NV`yPWOl1H_j}D>9vz+3fup@D_7R z27SBU*OXfIYS~*8$1Zfsp6bP_V^}YgM>ieLrK+{*Qw_e9z7eV4x~#hP3r!w3x4@0R zg5{X5K`!c&D_iL5_ba0;?|IhcHonc08_X@|Y#PLS;y#$4#jGsnrk`Y4yD-!r)gp_z zgLJI*RYiauHY_L0kETG^M57Oh_&L%`3H@R{jlSeB^OmX@Uky)$_2<-62`tjbFwchS zNZ>0-9-M-noxqs-v*wKX27d8#?sz@j6-UzO|7C#&HIsk~#Xky9HDv9l@B|NEJlY3I z_93h(lZ+uHy?aq5qY~9&OpkdH!#R>?e2~LU?y_xAN`$T-_N){oF*TqkMSIX;l;3Pg z+N)%LmyW}4*JpHX%G+ffWrv9&$k^m@ABN)~IFVs$Eec&m#*M7wzr)>E( zVt7hs;+oHi8jDVPdkLj!_xZQ@Ff`^-oK!J;L48Z`btUC@up zYg>=SVI0b6rn1Sn%ue=#zV7j4@%@YosSyE;f%36l>$g}Ilo0$R25AR!MXnU>ID%{} zo{fg&09~7$s}XaBAQAJ@@a9Y$a&?C`cTJY%o|T%`-oMK+qdZmVsaSX_VFu+U0?HI6 zPEs~SVq!K!{`PeW3V0uOWr0t5Vn^n)!fDvE$jY-eSSIsdiYa#5{D^H^h9Gnw8 zp6qJPlE#b|`2*c?gd7OETwZp58KYHoMR8B!#A`vhgu{@l z8LLDBL~L}S2Dg-2F5hsJM<<=w{@`b!G-OkjLK`XEt#4RHGhs{)58#vij+psMto$GN znr6^vjs;h_wWzwxPxcUsv7wokGl&2a0@?cIS)2~6kq9}`^k88}i6k}FB@}kwBHqYD zV^PLbbl!5l+G$@TOapj0^}J2gl|^+7#QhXPl5{#B_%|{+lH1y1l)}9RpZgbVYK@Zp*d#XRnnU+ z3!BG&DGv5bkoE)q_tMfP);2HOujRM6XqTaHV zZjSEZeXC$j=m~D@(Y35=&s_se%$IKWA35J($rY`-@^x z$*EeC0b>aj2bn?-=>mF0a(a%OH%MDbV>ul56rH<--{lmAb@b(*<16=$R+T3F05?3@ zV~=J0!Qv-`1O0$la&@{j3Aijoi`e-^Z;^f4FWV~ne132m|GPp{Rt#bZJL^3=wU5g; zqJuG6cnAD`8urdSidorEi}Ih2C_nhsEGRs>)zQoXG9<{QSi|iD@}N$DW8+DY%{kb8 zxh9w96xuZS-#y9>$vT6Dkjnn$>b;M>k-o2IvgB+1Gtb?2T`1A#cyG*&Zq4N_0c#dn z$(Wn$u}Ul)+HADN4d47bOLt8)KB3h*jKR*!n^APqNNq|%Ug<~p^F)}*O6e$BpL8lg zlS!dpsh$S&tb^TlTc(_%H$pPSt$Tv6bIe1=pkOXThl+KB&B#F~@~GW!Y%%?7=3llP0Al zwI_pfQcA>@-)TVR_lL5G9T3_FsFO*tBAzF+BSmb3Wj|8IUR(*}@A=7I^G9CZpEwof zBgyUjqOV1_wk8bNKoRxoDp}uqT6Kr9zaB{zz6lyZW^%%cz*L{=J5z3sxyEOM8MfF}-I!Z)zJV0L%#{Fpi8l*x5!;70} z4kOUN!e-e`O@trO9S;uK`IQ=!QpPc1!@WuFD98>`LZxGA9`Z9t3zh^{VjT?mW{1A*`x)F~*3EGCgHQNK{r*y3`DNaeP>4k$~;4J)V+M@-qBvo5D z;TusVhIl8dl`PnQDXh`$KQ5&0@e8JfkH2;RQ+C@nQD!OPf@WAN+rWCi8^b1lf7$Lo z#CubS4YMpbNo*-AoO;Dl5?=K4cZ)YkU%qq=?b>qb=W)ouFphn`LT%cMc%!&!c~(-0 zoHg$7Nx4J-sULq?5Ea#g>coaYO~zB0Wmtsg#0#Y#YCsFe%z%u-Q%lxR3^Vb!h}Vul;As3P1fuxh1S}@F9$37|fl^y*BMp6qgATBQPJm@Q&;L`Rs;;QK&rX zv58bI_Usg6hKWDww-k5cB2NicIwzYZekCpC!Q3ey8SgA?2>zP1b@-~~dm z?D*P}qYiNy2cwGcfvs*@Aw7?wm81;(v7Lkdx_L;1euo%q!4r1=lPS~E{`9ux$E_(h$&3`XPIEu#nq<%R%~*g zl}~Rq^qp5@AO7eIaR|2Yj7h)ues$r#i8CL$PwOKXF@BZjhcx7CK!eyRl3|+fVpR-u zi{&Zhbx9Znco4XL+lh`yYdAVo{4gZ^XY$I1|2*C|cmN|-SN+DN;O`JzgiUVZZ>cKX zX`7bxqv~qrfN(o42^@9g_Zuc@$ONPLF6{)t$XDdM_;%V@$YR!>y5Q>|Ed`VDis??% z{bRb1zjHd8dcERTn7KXAu;GetClUjaJz}odfly+^kP$EZW#Z`D5jgZ|yUgVF%WYY# z^CV6Xd$7%mgtsoarmR>wGLK=(j9(=uqDBN5na)CYVFq~ghE4UJKd~4=RLsTSzcCHx zEz9dccuKwEA_8TCW6Q4JVBD||r6=gWaQ0;E+9r7aOOYZaew4M2j{EzDZs;X`jo0RE zR8yDJ34WER2w&?NE79{jhL<^6BjKE3Vv?l3c{wUL?d@)^Rx( zbvChK<`add{Jo{}bSt13rOk#U+ZA@VNBMv9;}G zpt+=y&>t(VKQ!Y;ga3*o&hywTc!=OtXM%WxPLekzzJShZGLC6LO_~>{|L)>W_LBPDG5a2{w0SOMrFWXWkk zaAGll#1H-}aQv+=NyJ=DP*a`o54s!wCKAOTu{!j~j{L)E5zWw<>!1pbM|XtVnPi=Q z&z{T=n4Wyna}8Pz=8yLd(cJFyMKX0V%r_v(PcuZVo-7S)=L57$2KA>un~(Nxw!nNM z2K`a#*u^3*(JsYDoE#Sy(d41VtCQ>=M-;IG2u%)G$G7tVg0y<2QJszdK$N%HjpoUPv18UxsL>r7Fw_os2rOD}1>X6KVe}tSFH7 z{}MO$PF~0uF&yoOT%bBXu}_HRQ3iS?q%BFQlB77DJ%6INu-{#nScw1yqe_ErT@t6V zhb(KegUs(y@(+YBj%M$q>1eal?UeWSD+4)Xf2EhK7ki9=_~ymvK@RfFgSKR9n!UZ7 z#^ZhrMg~mvBJq_icLDrzi&?8LJ}R96Um6Mpe3|bg&Vh|XgDe^ddKjjpz@-Z%@}JQq zt~*|Z6qC8)cpwCeyXM|JDPUic!wi29gc%nkq6s>)Xo(RN`$U~_# zD=26b(|xfeNs06C{K&kYA7`GYo;VBR&l1)?@w^S3xDQ;k2MCMGqxFaid!m|!?N06R3;i!VtXn_B8MXf`XPynAo#Zl%5Ek?J zauh{1eFcvA;e>F6%0a@$7A}o$>F3FACh46lJvQzq5=?Q;5q3Umgn0m@j?Z0A*Z5T} z6!CZ$%?ea`uiomd?z<`x$s@gS(isKCNSh;xbA-dwLllsQdSz-&Rn$D(dXpQ=#i=Ye zzffg*uF3}fmGv*^rZaMhl^z@RL;Ner3E}@@K+dnIxZyv1AA}pf$-2jX^%-P~ocet2 zNzx7mlbq1pvyl;dOw_Di)NtcbLZ**olxtLf5#SN${Bs!qnM2w1BIx0InM!)k3qm6> zujQ_nQVlv%vq}HeYkXaV41{yuEK9X6idTt(@q}*999<=Z1c=%ZN#;C1;&41Q1;tSX zr17^JBuauP1C@hT@s295NMPM}>;3rVpRyAIVngyGOEAt0F)^!ikic#V6C}oY8Gb((K#X3H14mNd!u^wNg~F9-QWdPdLS4G7-ja zim-1tAFSg4w}~lbCafgM$AuU zpo09ltnf|6I?0SFuVg?^$>Xvifw;3=OXZC%;UgZ))31?npWGN!Q z^~LHB`rZ;SdeF2Y!mXf%~QJ0LUpIRDw-0I znJ$}7KWp$=H<9f0y`;>O88CXt2H>D~Nk2{tI~U1(-y@BOsYis&90#$yD||?96lBS+ z^vv9gqQK}UzR9b>w4U<=QAfTJC9sFB&?`8Im*66%6No0(U-UOujo=KH>)OxoeeWV0 zbr?m?Lc|0!ahC3cw;Iq=H#@bL?y>Azm&8uGlCEd5LCw!rKswu1rY%yGl$eGlK+NdA zL!$?XU-0g}rZ;24W1ujmc~CEo?k_GG-@pw(HlwCCE61_E-j4tx?Q9G{g zwI#GD3=Kj>(ya>#7lrS!GaOf^CqRY?d8l2)RSo;lwi6wWWOmmiWLy=} zlKMjKfh*W0mv+rqX97##(xEgu@B{#t>@rPqj{t1n0VfC&1MQ47E=O>J(AS#%1W>>d zmia+h1M(Vx_4ER2p-1*)U6!!*19Z>DK?oWEd!3HR`qLB)6F&!*OK~y45p@*txv?}H zm%=94NgW|UaL5kU_+5o%M>QENloV0c6dQhJ7;{GI$kGk|9{rv^dTRXyQ$}m2N)(QJ zApmEPa@kr7%g5EJ)Q#Bs{Ab`AV~^HWbtY6bV*OoBKHZO-FV$lu;^DB&3q<^ZNPtJp z1PKVr@BVERqm-Tm<}$I2JMKzGfDTD&BqOkY!zVTMbNH*B{C9x1$X-0RlY3XeCs|Ag z(*yAJWFG)P!b0W&A6fkl*sul+05~9r*eN` z2`VhafeMb^0r>lm7H7IZm}Gh`A*1}I4PXtm#3TDaxB)vb!W!Ugag7Q~VIy2DzJnVZ z!^D3kXy9t6qiKu!OE_OFLINI~yeLT;X_XnkEgVtqs9(`Z1MB@mOg3KvvZMON7PMw+ zqD4>Gz6-2KqA5z}(@kK7 zfqQRy&F?SLPraVCyzJ@~I`SyG=^`U~boq0QY_~^%#RBU zcwD*Hl%wS7E@1QzD)F?QP>1}3*ig6FIqh|@tak|ODD6(mq-BE5hM4JdU*gUW^}rH?ff+) zquTY^MT}-Y9kIq1e1S{567NFke}Lj#z^NyD5*iMPr42OhSn>;f=AF0dI|x1JUJ`kK z{~wrGZ(m9^3~JhacDcP#x`?txaWZZW{oVV~zsU~(=tdwipQ4#ZKII9lV{&{xkL8mC z%{kG+(Q*|1q>>dxI+>=y=~?CBQvcvYiM;m<0o9cB;GVSNiD2O`5}{viqv(mH`TrNN zfoS)hCFj;6c#Vi`nh_1Bb{AgD1;A0?A6nDv+N4G|eH^7^uIsCGkGn^iAB55WRL)^C z19*x?JC~YtdM)k1Uc|91h+mF&F9pDcL6VeoA(FkX4brx@dwrfI;=9L^_GDJaYPK5Tn$Ux}Mp&{)!XVKvX?$R8D$% zKl8z)GBLjM$XgF$OfkTP?!teNC|t2%@lni8roX~0M=3BRYyF$}WD!r~?rySM;27Tw z4d5_h7(V{mOQ{OlOLyYQH5_lBT~IDra3qhh?=f@SaprKt@wPT&qP){#=7S7eRg6hx zOXbXGGx}Cc z|Au-qbk7Mu$dga6BYNtIKv5zoTXvhe(!&0`Bn8Y{BatFk&1at&9i< zW;6bfNV48nBLGx-{%57U2hjHa59vMs8)(xx5}X5&etIiP+FaCE8kieB04K#x@cX-r zp4s|S5CGaoUj?R30;GTJm9b{6NdF4}N2u$RsJ6t3sbv3w*-lOW z0Y<%X08<;4b#ePFLPOVuLGtwP$~|7OC+hEEqXc@ma>W*s;JvJ@Wpv071z_2hj}LKA z47SgMD9tB6IxyWDCas_lO@&k?Doo7rqFJ75-4mZI^ZDD+QFTX#&HntnqJZ@r@7OID@;Ts;6^ zt32%U_)v4K`|Ome{Sj3-oFYw=NdqiMTQ-&|MEiManASuOoF|P02u2>fogt!PXU1u# zz4%`g_^-03f^An8694QPcyo?2@3KcK+_NQJq67n#ufWQARV<{{1zsD!KU_vux-;(23^h7S&AvzU zoX%mV1DGG56z zUUM!dwJip8&Cur7inB(y#vn^OBBu}kmX43VYVr! zphy#z? z|J{?Qij8X1Vi{F-pSOw`)ijj)LUpt|N;dKcV2HlJ#t2)?V`pGhIGbueY+cY{@^@i7 zC8Mjw9~P62%@wu8`gXMCFR}*&M@LIPFZ=Ctb96e|-IoKLxTPF;HO@Srcw5R4RI${? zz~Jg>jFK58?)97hmm33o9Y3UwF`jBWfBtM>TwuciNxnbfWwT)LjL8l@$3cr*$S)`Q zJw++<(>_(zlBq;V;rI-Xo`SrYqsi9isbGA!n+F|Ga}7ykOD!31WGs~l_o`kjnUFcL z1v07fHE&)3pVP8NCySAvuCa$g#g^Hn!-$D{v3M3m_{Lb~`o}NW0A`!;M7&wF#qEfu(!Z5cPPY6LYrZE6CJuozMacDFkN10pwRe1pM*0EXh$2L z@;v|QBsCeA-#DfFl)E&^L1jxspZD$)9*PLqfzAgfzfSvZ+vWclFXl%j9^I~oXd&+^H5kxyxX#BKCy@zwrXWNkP zo~ejO+jW?i>lJ{dy)^v!iH@{OOlR!or>U6MuRZmIKH6Q-?r=iCghcaV9xYTzkgwTj z1gRWRF`iw2k2#xNeiAk7A*?U6+Wz>9rl^dXVoDAxa4>_L$1KQUbsl;k*sE^Qyyh>X z5pj0GPb-2<+)G+b$I2dQGOpN>(I|6hE&|m!^E~4IebV3#eOcoCVvi#qN@JJnju(0M zOo~Sgz@)uA$PF(k=o}(xdIQjZvqx9DUQ-ji^dm_>pY}Pq#4Q&{qnFF@Xme`Xtgc>r z6ETH)J&p0x><(98gMPo0f6PxmO|oL6+^|KDsP^;gaw?-iy$$HPRCaig07-{^uas05 zvNth~F6YuCLOd6Q*iY+}{%4r8brK@zvASvl0sAZ62KFYK!=CSLj*s z1t7qO-ifNcGsr^UuJaQ*qaGdpoFHpmt|3Y^a!^3{UW*>2SvV2Ow=FKX{@vH`jEDuv zc}gxK-WN^xXa3T-HyfQ^&)G*ENAoVWUD4>9atU%5V{sO${E5EZ#vL+J%&a$ytd}38 zgsB%3MqiN;t}wVbA)~O6*b_dpeHy!oQ2aY|@YcHds)%pB?frWKza*?0^A<#w%_d&j z5-z7T`p~J1Yi5i>mE}{6T{deY4%0-a?spS4^eJwpb~hZ#S&fR3JgsN>HUkFu5i$IM z{=EViH7%&ME}HsTJKOPUXZuqL$Mj?cx@u%-Sl9U+?8*o%rSj2^n@nSPD4w$kx|}? zY5Bj;Cw}dM+d3ax7nt&DQQFtO=34s@sLkb|`Bu3?^0MgqafAVRo`xcCS^5`)P3*>Xz>44Pp23v0+3c5MXy>7vj$lTSRT_@vP>pj>Hc$~Dr?xnBz%`Rz9u zp4Ia0PipKWWj5G>6_^vze&=rG!`(#dkN||{?@!ok3$2Vfe}1$b`9#_?my;-HB{RQk z5^Sr3sgUaw&6?!%sQUnSi*^8-p5NQCOR=b{`6b?KZFIkg?_s*fl9Z|}J)wr{Lq*VY z1LcM>Ct~n>mp5OYinCwgzh;_s=odpTU%3_t&kZ3E`TXcYEoi3s*?A}57gu`sJCaq7 z{Cv%0Oe5YJ-#Tx6x8xaD9Tkxt(!`eiCcg%W;nfF6m|3fejoLs*%TN48Z-s+Rjh@of z8AX@}hb5donYqU04NSER#_UG?lwaI9^r{=(dJV1CMy!*1@7XGo3bMe#_XA*#9kc#= zBi69l+iv-`?pvuz;*4Ei?c5%f5lQT4+1y)DRCUBtD^y%@l~)L zFUdQ1H;;if_vwBSr0Jt}+5>UcugMQt-KE11PRQe#)E9(YL! zRMo0yfb1Rku+c;f_#26DSUOXS{qr`SLy^xxvmf(oaq||^Tar^grjqZrB!cy&$K-zv zLNZFv0PY`SM`cS{Lv7k`}mBskiS`~!z+DbE6fph~XLa;c-& z<^@yIc$2jo1DW+0YC3B$=cNiDb%Vm1)A%aAt5omCo!e68dxJ6xx1~)T@&(RhE9Nzh z$dq{xB6m;gtW0Kkm6yWpOIEFq>WuYGC`e52caU6`s*hV42?->C*)9Ffiz3g)x8Z_8 zd)iAlAKkhmgEX#>7h~G{h;tXKIVF4ssYiW^H>b^RSV9EVkvNBva4HSaXt6L6q3_pz z*%hUZK@99$819|P_ph$Rv1p-`gl}j_pI$zx@H%%m z?!HFC!|1k{z*N_>y6S7%E)y#44s-J3NA8gYOKAUB~l1bdGkuftOjFah@ztkBe)QG)IQfd{x?We{$EXB< zHlSMvvfqnge3oeUVLZq=_NAwq)Dfij+4ZVxPsglF49Eh*U#OEvFbp8{SNx}+&@{<@E%criGt-28Gj zK{Zm<(ASZLxlOmpO12x=OHVS}an@!rzEI0 z4cY$UKC>)3$SNy!wT(zU_HX?2_Ci|1ZV*O`|4i)hyftCOessK}7&tOCh~riCK5gdm zuCmQwMNoZS_k8is>n@LGXVQ3)gVC-E|9DRxN^*~ti?%kU4YO8;Q3U6MH`P*n{dWwAub%CXZX9jz`Mfn zsV%qnUFTS~@nwAG;KKN?o{70alQbjkx9VmFmiwp;Qo$W5Bq;we%d=$VCc0x>cTX-4 zF2(boa#Ln_WrRFt-w9nWiUHmHEh|9lbftjhEn^ODAohdwKbb+RFqReUd%F%Ijjsys z7LoIo?7gp`<7s+laE6F);f!@{I_qZjj&@N|wtXSJ&8UKZG3cgx-=HKLMStMQRoII& zPI}+QHif3dqBe4mqN(D09lZG#M^*SD?XS&i7YXp*XQw|%N)Dom^&tkwm2JozT{m8X z2*%fw`aw$#{EOq9%R0zghd@`45j+BFJtw~ucVjR%BuQMP^bZN`0*`l|0LpTCyzTq@ zJfcyoY8p^=O25~&O8#71oYxHRJuMMns<3@TM5WM+V*J@EKA-`wL~9(5iG_6)dU>ok zwkk$F`Ory@&2*K3bqn7ea6Btk?uRnpgX~fU-{?RMswOLqZ`tx%W##qj;+>_#F6O!8 zFFzLN7?jN(;ymu^L@zip&KYt*@3)ZnyRREI0^irI+DG&vITVGjPz=OvdIj*s14qb! zUHX$~Gt?7(#%SwSWq*dydUC9|FTl<&JF!oGF||=Zph{dcd_@Zaong{$znw}?pMZ7j z7K9U|zb{`TAX*E4LyN${4)C{|k0D;b351IR;5Yy)a2#L{(W~mCZ?FgZD=OUTXdWNt z<54098ZU=1R*2lRtw0x&9*LmR6eIBcYp6nYDpcV^b>6Y(8amL|xV;sfcX1t z6CG%5z*)fid7vN|0fp$o3|Q-l{^#hybU7d^8G)6YhQ06^&4+G=|9;3*>ATX3{g(ja4ij4ZaH*qTw8DoRe`f%cIC#tCR6a zmLGJJu`-VJM6RdpCwkK#$c#X;r%TmA+xpZ>Zt^eI&eLHD}@-N^eB|&&T{b~NIk8rx!&%R@uU%Hy@%}^^>A!mT)T|#WD!jY7S z$7QcNtZTrIF~@mWdzE#{6X~b>lYfC+J?5>0S~G-9Du(zXvsA`Bt7?HFB0twW&=CSf zieTKf9t7i#7Rxu9Q_M-eX3o|Npy4@v-Kt1&WN&sggt4BToUlBXnLBT$6I;b_H9Mz9 zLs=V4i#4Za(5rYe(&clp6eQk58&GSJW6I0JV7WwVpU|J3XQ64^-4++ab|#N_5FA3no4?ssy{3vEPb8uta4CnyqyEN0wHfdB*gut_RT0&3RB6E8 zR%Ps0JG5^`=T^_wGJLyNkvdvrC+=>KVpwrc#Nc9m3Cp|Zr1540iDPsy&S1`18G#2s znQtRI-eQt}J32#FxgD%NPb+i!IuZFBmiO6X8HRoZ0i!@iwMI=&mnHg@u0zCta=_FF2R88Dmy@>~U@Q zTNL%cB15)|EHpge86hu{9mgbv^BMvY%}EjdIMreW3+Pc&n4w=$fUCV$4qPAE$g)F> zVCNVO)2RubAgakj+kdt9?>OfwRsZ@Poatzrkl?~-zf7-f@>eR23^2M3yn83!i!5DN z;W3y1Ok!td zn`x25P8tF93Ai0@Nj`Znf(*XY<#$gNH#DAL0=pbHYM$}C4p?206~&Qz@7l$G^ndS| zkgW&K{MY0P^{B7!<@Nxv@!zqY4VB%P<5b^MTWSMW!v4lO4KM(o+YR6^)_@?6P#J3h zOGORxSwd&-{T%L>$jDrqr$2K}m71&cBK41NfC+Y9>i37^_$ZgB@sIb&)e2}cl1-Aufq?gO>h@x&3& zw=*>_HTkYguZA8|1+}SK1|6$Oi9Hv*;X6teWo_Mf@UT28G??Z2V54VxLiQ_~2rQzY!N5bb3S` zkTZt4!63CKvZ*`d<(847w%w)*4B3LCSM^jR8m;&;u=Q9(Vq344k5Dkng%<>*o4gmG z#Z3nF`U8k;o(sF;k=o7BY91C}Wid{b(S4Z#J7teL6>>jF;d8P#W5NiIRiHill>A&dP-~^D zd;VO6cb{&p%o9`nd&vwrvh=O0Nb9Dl!06P$)2ce;0~M@f%qJ1klY=dE|>UL}98$Uhyj?HjT zRXQVxXWrrrKmJl0l((%{Jn|h$f7nt9r~`%-XWH^>t|4JR7RmrFH>?BYud`&$QrQR zWKj8ipmsO(z_H?wp?33%=0v#`E4qHhTz4seUXZ7`qx^~DUAQL zvN70Za=*7|DT^!L~ji2`HL*-V7hM^I5+N-Ep+c z?W)2flhMOchtd3x>M^rrIW-wC1=S6DRc}=6Th$YGt?!5p{_4)Pk$3tf|F>IyvRl9# zp#l`s)LjtQo0G9)mGdF2UwVgL?_Y6Tg^_ouVgRA>+w#Okg}^O@af+@<>8&cOTfRPO zN?nRv1z;gSkuo6O7MMLOXVV5M?1Y$i!ui%X`G0r&=hQu4RBJm{Ie|2}nHlh3kuU>y z1z;8@dZ0hP;SQ8uM6#5D4mqxAX$F*cHkQAUNqPlpcui5jC$Kjv5SO9&3CobGbt~a-W)-y?)$h z9R8DsBMOB7?I=$_#QSG;(GnfeP9krW=WsWV!pt8`kaB+QpvZVcygb%vf9 z<1-1R&ub8WW*-ku8C)AHUx6eiSNa#$bMl>gK}SjHj zn}9=hR`y*Kr%IhUzgq7FK2=e@1{4ZsXbWn{dt_$_zn?mJh1 zJ*Jc)k(7e}*c(S^;oUH3==HLQ-8JSJ&$E?cl*IYGd#{Ws|D#C&nn>_7yPzc+5#n^O z4W7UyIs}g6;#R|kq}1&J+8Z^=t=a2LR6_5WOr6mc6Mv+>H%F??kfY!fmUa+kHqi3z z#l6BF3W+=O?(_>lYknf{8F`!Es+!}8-j-&^Ybc#|C+(mckqm(WV6eKv>SLLy4?OgR zV-nvtu9!Vao%%fCxgGlv;ny`1`nB;p+XW!?gYW~IhsK@ma8FNPHCC@hZ!fLEye5}( zit{Ce0kk>L7cL?V*s{N0;68rKQ_oT|N^({KN2@P)IY0EC3H)_jT(G?aMDO`lu|8(} z@x$0ecwGEz&kH%{SJ%|;4dlpi6Ni_n7G8D7vtd1S2#&`}d-mQyQ4yg$-#=EZjV}bv zwx^^3zP=t~4e+cxoZJI^9q$HY0ugn!vrz)Id{-$*)5}!YKnDogo!X5Q=%#rWePqEj zQV_KKpZ@qniZ+fL`#|fZBK-oxD;NaFz>HZPONm2MmIZvKP(-wZltzzp+M$3+l_K}=BMGkg5zw1J>8mx>n<38hU)RNS z|1o^b#(Z(=11gc_MU#ba%*0zw&LW*yjO!K0CNZ3KJ53RR?X$=)(x(*FukEF3B=hv0 z44!QDWcx_?)Qr>4?OEXNfAVsEI*~}%BiLwOEuUNZuwsIUx(t&@-|{(&RQ-S>IIFu} zeMv>ESAHJbCHKdJe8=I3$ht5Gp`om_V}mCR8IM`;A+)=L6x89MO?SGQNgaIM*UuozYGo)9&w`A6CCg@+t7L|I9aj1-kwwLSN*vq>mxfMPS_$rR%niZJZnGr zr%K4FAmPis2BC-dqsK!e^dIT0NH>hY_^BfQTQK(HU?`nky#H%N6P6QyWL+|OHB*U) zSIlP!EI}R80%0r*3Ds7uS*V}-r5yXyzw0j-i6#P8!3+*}Dc4e*Ae(m)qAnwSw^T=mk;5JPGd_^-wd4h5Mx)0gl#{k4hO}Yj7#n z{T^RaoUsIT)(4bW&FW2!NLVc&zu{t8JKv3E&CXbX*tcEmQ%eaj(kAW>_|~ENu0?uY zFTFc@#9mWi@ZRi25&kAp%nEOBwFpq}q|@c*xl+2#B>r zu^+{whWL$5(vfX<1*uU+n6{J}f-#MH5Ujvr8*^)ucdc-z=2L$Th1$A``-KwQr}kl! zJJ`@UbbfKvd}sfj{}T>@E}rwsid#$P)|Z#K^ekCFh9;j-p;b!fw%PNoD<{UNS7*Er zrERm-oxsh`uB|-IRnaxq@JXj^=f4dltDuj+vTgBV338GZc*FQUogJA)DM&Vg7^2lZ z=X<4#x%I{6QgyX0{7Fma=2JJp4P{eu4umf03Ad(C{+Zumn{$fyp67G~2x77@GM_{R z!5xjxyY#4jW-fJE zp*vLXLVscndh;`4@-6|+A!gAItR+XRiK}Cc9A^#@p?yF|Zr_rHH*rxD$F9Ko^5bj7 zMi`q^Eg+0YxFEB(8Sc+GjJUe)l$&(yCI0Y(NRWlQfz9bOc-CL|NAX>aUYj6lY|oeq z50FUIzop(9d8(Gy8lftv;Pv;zNEtE_Y+uWnmOoSD7|0~I!rhoomh2>SPb#A9L6OY5 zn@!IYm;uRjK6H(@rtvb=u0FQ-89tQWR(!d6Jfj?s%7FEhJ0>+T>0>Fhcn*T_iHUKh z>h*_$D~?ZAa*;euVC9yMajykj7kZ0?hqU}lEYT{^jp$N>lb%nm!mXJf9ahbu&uK&I z98}R>4FfV-@_RCOX%skvyVG`(f|FRTZ&63epzI9Tf=B`SW00yPTidQZlvX_qfq)J5 z%D6A`ai%5i4`pIE)G>C$-!1*pdC~xFNg3mxV%oJe%^=}^=Oe3Gd93Ns!64Q;{RHh7 z2w@OYDw-66Pvf=s^dKa}1%sXn|Bi9K@6M#mW8JLkxjvX-zBUTAhY9uJq||Ez&0pqd zXZT#bDUbV{>NNGRk@=2gu;1x}q^_H!NtNdAUuDj`|>C!-K3!5%%M}_yw*elWT9D=FWMZ;%jJfexbwkbPOr6UEY z6u#X09dc2ssoyqD&7q*Ca8N=23asZ4YlKO*4Xdww2SxbB9=wf+>5h$ykGpXo0qw1F zv6pfBom{`;Uy98)qP37-+>q~E3OJx9_wy_Lw@)<&T4(3qsfY#dyOH{w!m1_oF3LFK zHhpK4&G{)+v0gE3HcTv53zTqwltVP3tvp2mJaHsp26&?S@UvXrJ|%4h(+7c!M+i23 z1pD%y(8gad!RW84uaN@qlhnv->J!1?$iJyRnh2Txw3{lBtU2hOeplkKGKdj`{Xy!b z&p9P4;DmCzSUe<|D-d< zqKMFmKKJp*tRba4B*8m^i&u zz>cv+0v{hE^fZSRBZTBUwFsFlcyTE z#4|J3FEV5kMcAFqPVI%>IapXQ!(nF-ik|YG9-9@(d9AvAiKwcNCK6aSWpJnGHFf`( z7r}o#yJ8<@SuQX{RwE0ReWvGt@3K~nyiCQ_e<2IL64n+tzYB=e-SF|gx&V?y&-#Xn z^G5vfn)1PLcEk(_pubE$AJ0bZ&I~{D9k+khiUjU__($H#Ggcctdj24#Sd=0-=aDX7 zn}K?)bRKhT6K;rt5H-1u#O)@N3q8~*GlRBN3j73{EGB@~4+AwwM@Ua9EHo3fmAJ&a z=+4`id6EAuDZSat093JDZI+BpO#z~UpN?VpT<_3#uwJoj>Y`lKavSQ3#iQYizv9k4 z*tJtMcr^js36a7eBGlrdFv2%@qm;5$k$?ijkD)&fl1#H!Hb~xtI7`ZCfq8>>EeNxm z!E(nCb=8-1ET|ABM%8Z)d&<|&G|)oedTt1ba-ab+J)zU!PJn*dqqPtiq&mwuoC3P5 zeDVU1eg`;b4@H86CdEgVhonkT+T3)JY>|oh8PARvH z4*-1<1w=$G=TLnv2M+SzH`r5sD^Lbfwe^}U6BZ6=gJKntFsf#|UwKv0%UN?kf&0Y> zFsW`e*iLWNO8y*46& z=nM3K@mBY%YQ*?|4+hzt)#`$S(f8kcEEmh`vdz^5@Zv)gA{So=F;&Ck60O21{1}GN zO9$X)2R}5l9Li#l!EUu%rFZTL0fbx^qCvuof4W*fHSuTvXOzGQQp)p_*2E4G0Ed9H zPmuq8IFr+GHlLDhUFXDl?X-o4)j4r81mQ9G!TDXn!Y~njZKCc|thj?=N%;2-h60$@ zhk9H{_~lRHI~#Dq)ZSaxZ>;_#%76RE-GBSBd|3VZB@;agY}kH{00zP`Q|X!<2}py`{vCd(wK8qlz~>~i=9{-I z!iasoN0g`I{CeFwsRSVu^rU*HX+iNoSSqaNWQ=?cdt{Q)be5s()OW3`5##tX_LIFA~@M7Xy$i0+weZuBi|+ z2jYl<3-Z&8b^7(pAXRRmcrmvtgBfpmt~Z&Um+ksHp86Q*shr0ABINjlue4Ep$W29S z>9gEm(q1pGQ8p&4PAwxKu~@h7upsJL%Z`uIt-Jb(lr{Q&9fn^5;kou4rjn)Yx~>pk z#YSR32rjxGR{EcQk&gvU)cMjBmJv*1)Mc%Y(CL9qzwgAV^h~Cy zM>BbD2@X3uVW)=|^>`2|ulTc}FE1WnHIc;0S@Y1Ua>xDSjE5#8pY=6IX-Js3TSaRZ zUamLGS&u4cYgqdOj=;jmp?lUIe>;@MyxmusByFgA>tC*_zZ#bsAs~N zw&uu|)MA6XfOHG)0#U88*e%EKjs=_|n+4K1tun<7tE0pH@pt#;xbFc_MS4=!I@|&H zTPUP|oy4~E5QaFg{hFs)L1cH7;#M9jSa1Iu{qc*SwZ1S02!2JgbF)iL3J{)vK{=7u z%VCVv-&yqk_1!_CZr@ zHCqS9ubh2A2@J6|>9&*w(IlX@gWCud9!i8lTofibP3O2qfQe;^gNwj_4E%Qn__2RN z`nviCD?`U>EZoPFC7*YhV-|q;%daUKKmE|8tb&fPrp?ZX3&inzwtt5n%lFA>QF4Dq zCF-7d=7M7*-OH&X*(s=k;Xf62DlVsRMADVUu9&q>kokmO(V85%C^+VO zL>o_Q39&G3%9VB68(m`?8Au0S(tuH^)!4~qZRZ3ab|X=kHYme)L^(>Lj)#7NGX z;Woh4zyCzxU>j?z&%8p$IWkYnwF_X6Y;Xfmr}u;nYl_Hc@2k}LskyR--suvz0&qF- zc(yFvFx(zqM*rq;t@EcA%Eh@2p2Ln$?yq0|H4VJTG#UABU?M&P{!SQml<>AygiWlL zF?*9Jb}GMs%mmn{GJI2CF(d=bg_JYYwU7|wXLAB*z?WHYbYy_*iCk&u?eLtq5zZxoLu=O@@-?W$taO)W1b1Y4uZ8qJ{I_k`yLT^i{%bwC59Fm?&RieVs@-hF7Jf_vzOV z_Pt++@NlwF47)M&zLo8*M&B7*8Ey?c| zHjy%S@<6gzrNyJaFE?k^zb5}b*4_fDj%8~X4FrM)cXxM(;2s=;ySoK<65J9zxVt+9 z2yVgMLU4C?d%eis`;qOVT>|EVHz7KmH;3FA3DaJ~ya)C6^WQCEF->%(e6* zZ^GlE=Y;3mhr$kfjR)QUHkj~kZ&X1wzJ_iU_ek!g5!2o4VYU^{P#cfi$zRV4$7mwV znLrrgWSGKml_`VawJ5XTMaDsY0E~DL(Cvq8>nSxVvRkp}I>tv}g7q?G_ED%xDuoSc z|1pIx8r$8bR%<~+g^r^(5^C%`)84|2ME>Uvz*zn<##EC{5P&VECao&+^8ZiY`{Ha~ zDwCLy)hqpDOP^*QfARUGv#5vMt+`+Tx=3Pq{wW%V{+F*{1@#`Z@?Of_QiUVi9ktotNL?Nw~G;ri9fai zgRn(9;C+8Eo;zC&uNmEp4Thr)HuxuX+j5Fv|4NU7HmS1`yp6hJu~`{^3i#t@I5q`< zumGevs&|)l#rH5YPwTeIJ`w0w8Bc6@JIk zvK>9glaO|oo$|RF`$KkVBACg|cQN-hT%<_`g1DkP{aYH&VbAL*5**O{lox&ktyXO( z=`UySFX0U^ziLO3_o5oEatzW6qP6vLU;C$xyGLk=-k71RZ zMQWdfV{1|~ufJ0a1psxM?5=pPP5jpg{4@U@IkE{bkWs^dY$qyg9DW$vn}0y#Tw)~P zEp1AjSs&L3ANY`{WWAK>)jaHHTa3;16EWxKVzk zP)?P28Zjh7_yF<}e>uDSR#R1L6>d1r+gBizZsOnmcl9f3!aW*aN1aXoZ#HcSvJE%E z{B%x00PzB?XHP7Qvb*R-gU+Y1Hkd!-)q8>LoL;mRsd7XqaQ~P2H zWaQ=y(FaWBr3sl5)6Y!Rx-a5f6;+$x#32?{%s}yboOds{g*Z$LyE9C>95#q0b*t)Z zQqk_=@Hb_@0OtY7v<7Io)QC&~6SMqTFP@K1XqBVW%YTVsoNRgQZr04yu2aaDK^zpC z&vfc>Ax&;9-FvYomfkC|qZ-DafHsm?_~`y1-=+aE4aM2YUI2Vnz7EwHi<{H-5p2w6 zG11%r7A>$H0J1E|ng0VR%?yF||EX>x&h}R+$X0SKi^DkvijBAl7uRSQaHUZu@Y3m< z4n+v*s1AYbZKQW{_3jeFK=$f zaVua?MAUAR0K+I0XJG8KkYgQ9KRm8Xhw>orK98!2z>Kz9tFVY`JV5n zCO_CKs2T)z=NrEQ6{?!#IsO4SuW$ZXUH312PVo|k``W6Hn;>|h2=t7l`dH8q(@7QZ zX7W$So3J_E6j=X@@67?Br}uoH90Eb$1LS-EcFiD&S@RO?a9KveGQ60=4?X`v1_w&5 z!R2Qa;mTr;hBf+kdzDxwKXj!(JS}vvRlS3?Iy=W?Wz<7p&GZuWUes#7Vf%5k=c1k) z(VZWNAE%OQVd$!i6AQvOTG!WgU=P-YYPF(CEEtNa8iCzgB%AulbNKA}2UD~4-MPzy z*MIdSaj+XQPDPctiv15#jsq|$l8Kw0M^9@5|4ILPlk2iU9N-lO=Wd4?696^_gr(;f zo7yVgu2{wCwOy->$IPMei)xqvaY%Ta|BE6A6aJuLkY^5+U46X?8?Gq+x8Iinc@6kx z1O*23P?mn07taeI+DgNJFtO|YlTRU^w;0@}jYTP99uM7ztv5KC)>D|6w;5k?MuErd zC61!3FUCu~8{FHs1^G7%1E@`ph8^s`faVo-@S982!2}Bk#DUsmuSMBl4>At&E|3p? z@zJ0m0C%v)IY+|8?Wz$2lhGL_TY?9;;L^GLTi)B7hGlAsXAs_-3|&kf=+p8C1p=M~ zp`aik+7xBs3$P$AUmhFKgOMo{i>6p!$@PBRJ362DU-%vv3jxm5C>hXKg?vB2(u>DY z;|pmRfOrMrzXC!~fDQ7$_-Ch| z!qheT6;|(Vhx{fBmilpGn*e990_L`jY3}k#ekJ($*Ua;v;o1hr?aEdkQ zXZ#2)s!xHP1f|~rY)E}~fh!AHI&>+A?D)2=>pZf%4&N(e3$Cv)nfv^lpG$mt(w`mU zA-ixB@mk}P9@^DP)0?(JgFVb1_y;A?p&xq6XQ{WWjyHMPNaF53-;3sIc@OI3RciP1#(~`$fx1VJ}U_% zrCX2L*+)amJ6()4GXxX#AYm7#=4@m>id|ETVc0i;ae5klgIZVX&b_sz0_PvRZzSUJ zG4uyQ7!lW1;6ig;MUD+WDv0%Tk6&xvwUAh@WM@|i@1bF)5j=NWUUt4O9=_p3_^GCl zs>L-CZU}n@E3)iPTtUin7KRfQ9Qg#i#iY!%78pm2*F5vB!%pMVJFS2neP-Z8-f>YYaB$Eur$wggHaM zi22bumMirW05I-iZ+~`GW8Gr1wq!b1XWV`vqzgtz=N8C?N|R8;Z}-T&ZaTASNkp-n z4W(tt4*)UmB=j<&ZFkP&O$SE!9{E25Ip3^Q6hp07z%@e1Lnwb6$;x{=pY54yD)R`> zcqaL*vSe_j#O>z{>$qS46>IiT#>$3^kc8?TY)mE}2{I-JTO&Rv)m@3jdWETullqECJHsD8kZRI|($NPdsa%MWdS$Dy ziDq7^4GQiv5hi?|B(zn$b+@bhj_@<@IDkYeoC&)A8;m3OGpZbR#a>y37oG8gAF8l| zibN_CqOPGqYBmy;lDhyth6J8WqS8?4%+Q%BPpfoFV6z32?_CZeIs8F~PPw48i9~MQ z$hcnk9V)?zqJlI#;(=a(l9fOP=_dtM1z7Sy=zxhVwiq7$(jVP2;@fzC2uY?S1h_o$sQd<;3z{U&k+$2 zXvK#;+~MM}6;0O%SX$4@FaVvENIUHLK}M~}e#>?vq;de^AkQ)c zJt$qiQ$1L@Hw>F8C>)e1Nxe0@y*ReLs}Q)!^9uOBL>qL|aa=`O;4GR02X86Z7!q~?_ic;z$o2enp&MYz3HekuBuf55aWW;5bDlj+PhlcPV*d>3(PJhnO_SK9DlWuX$Q|B6w6RRF6g zzwSPV` zOxTw^>o45Ea7U`})NJ@cOooBuA_}%AKU=A4Rr*Bqdz>rBjQB>!)JG?og)>w}LcQyt zf$=Qm`zxxo>q*6rhwS6bE;^l&V%c7jkF~nn{jYAr9+nhBS$r8@4HWwjJOuGkm6QXR zjy+RmZ(A&`gsnf$f?Euf^UD7PGk_rGNt9_VZhZQ@56U>@4N=xxCZjTP0V*8A?mN!A1wNEBP|$n2Iicg83IVPl;wT)D*02n+GF&+wL^hr^$q;#@F8N zy+ZjJ6?ZS0i&!3rbJFQ-7UQm(P2U0lKGX$p*R(?Pki^c^yw5F8Tr`QTXdWo(mU5RI zQoSEro?)AmzE7AHY*cVCmGD9;0c3lM6xwFC?N*L;t-{Wy)|lI-6wp1*dIi=~2^3e# zW>@@%GSAX;cqD)2!W>}_+us4mB$R${(Ag9q0X;f!zu15j4W!CI`J#~@OaPY*%7w8M zLRG*C07l5?>kDoAhr}@B*CPN;6@c~?5dWetrQO=XQJViCrxC9+t{08?Z7yW}4*NT! z2g+WuQF8Pk{#}>h4_bR^7)0D@=nb;+%?fM;3^fY@8@qv0mO7nB9OPF3eb`jg*RwIi zCxC1+twMN!MOF{&yIfN40Bl?)?|x{(k8d&w_Bgai1hSzhDfs7yFKMozYN3}jS-$+8 zhTa$lAbXA(i0u-}=S+cZ=L##v+E^*Ce%*TU1EK!NU2)59<5LG?o*(cR-85qPJT=#z zJut5G1zwWgNh1el-g=8prq3&C#X=hF$?JF7CrwRj3eZG{Uja@aYLg@|$P#4}cF<7+VYfMD(H|KZt%N%r6?4m}7^{W$b)@u|35<*CVVqXcr2s-Iav zWZa*O(0&@pOBkL!#|m&*bbts@7B5rg7I6S}viqn|GB_`!>%ewVK-laG8;*9*ihM9;N=&8qe?K7fHjcd|CeH4$YcQ3gHq-H2!0_M z{{j~PHmP!v$avvTi|$@>U4KZ(zsiB!VMeP$`iFsKVCS}%k-#DL>+{o{U)vr30_tUlmqtD zwRj*i=MvwEiZ?Syi}KWzTWIFnG$1lMAnRfhIml8aC<~1MtJoD6OEYZxN0#Oaf#&h1)phq=azn6gFUp`C^n86M)cW;+ ztJw(&=pCRVOGEOjE*!RwWjp$Q)1MJbHzaefyO%js#%|~u8H-V8}ut~QPZFY>oN@um5gex*l z{kHM#*L!y~qGbt`y!+Wc0ZS^K$CYH;mP7um@X=Doh5Cj~UcZQ14%6o?3_qW8sxaX) z46+IE;=^CAYX&&C;Np3!1zjY^(ovf3fto3ca!_q`y$q94 z4?`rGPaPS(zD=aMo*`|7baKauJCJ6!*1?}xmIKUfOO4-$;K(*Xq0*tZVo`dVewqeK zI?puuTcISG12x^B6=z)v0C`}UM)keyo=s}qUU($fOjN`-tJ4JQ$b6zk__WqUo8a|}xvWln=9N4#H zP0V~s$Y+Hz)-vu@r2zq~JxhE-eQ1%$sir#5t%sr6JqQu%NBzPQ=Z9{>puI&y7~)8R zV&^gu3R$lKek{$w54tk9+?>DGW8N2Z1T&;=+=(PDf9yR?Q^B3`gf_WMc+`dq);JI zm(eMo3f}_bV-Vtr$;uNP!Y$r}2$~T6oQ3{v*6RrkRFs`{c>P5Lav3R2guJwlHWwmm z9)hPl;B=lXb6slA7MOd3d;{VKxmcK>CY0V_>JA09&MSBw+zVOC5R2`G)JDEO%#mW2 zx^Duzce|BXgt0`XLyu|@GZ^0IPPJ^GzbYF~iXhQK59_^HR_@r@UXSyjBq9{EzkZtviw1U zov{ZpHDG4bd-P;Sy7ga!R1)eXh=MJBhHhFeUnCDeqQ)70&n&@S-`FIT(UYEAU zN~VLg%TK&??jL3IV?{P)87uoz@S}e)WjW+M+ba`IO1G-4+W^;BP2&3$99HLojXYpf z!~@93Lnv2Rr-E@`<^2LRGqa7#QlJK=VFY31U)8=PEi==k)JR_ZJ;V9UU{H&3=PS^P zpBA>Jykzjqx%KC;ug~MdYRX7xJ!X;+k<8W!^YEeiEEum~?Vqilcohg`N3_v1h>=q} zUd7oXpl{BD3$}cvvulYo6@-ztkE}PC^mLNvg31)GUsz*1-AiUHBBBf%je@4orlKas zkAj^Cm+V_(i&Tz66+6i?o`Ar#)jQOB&xm73!LqOH8-!zHM*Lqk`X4dUw__KM6yP z1Me#t^M?-$s;yO4J`xcK!NE z#LY8yCJq}=ls;hG{u(@iyj2W}W) znpd89{-SRas^Z%FjRr%{8)Y!b(3<>OPEIPcFG?L9t}0NG>=CQWr+dEYD@;)o|JMBb zPUrf6kNa zU9dtJxtT}DexI=&j1m*Ig%ByeT6g2aJrqRDh# zY5esSnd-c6eclIPl>Z!S9+tii4NuTq<2F^D7PdCP=(p>&PyBdU`a!(dSjOa1$tX$Y zYIQ;0+(ovAbFh8?9;45lEy?#&&2l`xQqdhG z0jVJG_I^)2MK}_qg2P?U^eIe?uc34Y&aYwn3;2~PPkfpWbOnJ`uowpotb)}k8_q*o zIXTPFzC;a`msLRc#Xw-~K)oPBxj$;)Ah#Dq#^vb{{EDkH|1Gv&lW@M^OJw1;2l1U`m<1 zdPVOF@e1wFbKq!h;9z3>!O6kG*31z!@B{CChu`AWThCwSTnkOQxuw&P$YbNkt$Jr* zq|hY7&`rM1eTy_Q>H~A}C+jrNe48o8p=bSk9DA6cBB-a3M5T>WRt5DHyE#HGnsd`AAdmhWDk{8|#>X9s-B4~$(I{lk+^-)@%3S}q^0 zarpV}woJp6|>LZjWB;dS|?;XdTsUIc0gK zki%FO7}oWEj!RG4zHjsPQuev}fM#rQyP7g?6Jtt=ILWeV=W}7&%lDAx?)EW(NnT>6 zqqksuQVpEgoK9KBzi*Kf^C<^J8sfEgG#s?d-q$;<1Me% zcyfB^ZzPVL{@thTA0zy*^@1oQ@vO1C4H8brai7-~TV&~aeDK-?o_8nvTU5m5)FmPE z;on|r_}$S7d1GXX$0+BZf>}C|2)$SOLRKUmp^Q0yiB=3dP#+~Qdb16;`WSffK9A-E`@S6R7dae_g(~p+4yQdlz0|oN3oDlWwAbV1Ou$!s~+<%d)_%q zdT8(||1$M8t^^uM2#hdjYsgUnXmm2aSLDhk5B>^5B+v?8kde6WVZh@Qgo^%@*83^J`T5%k$s%P2z)I0W1Gn@k!C8VA(8{jlf`5J~xWRyc z();@kH@dn^ic0i2O(Z-oI7?7_3YJ2Gr|4c3z;*kk2?#kFq#K}FurNCz`xA8FM5-`z z%5N0ZmH*P%vJ`zGOlmpX=U7;XR!DZCPitC$V9*H)4OQJr1E?=rKxaET8Zs%M6@(%4 zFd)$MI=25m`*@>mDI}{;OI1h2_0pA>9(-D(y%7ekuQ=twq$(4g0PTXKE&sbh^dy06 z)}R)kmi>~61Ytm<1k~6TtEqs>rDFk3i4OfT=AH&XFzjE0?>PS742>}l7_yvNa{GHo z@E3Wf^w0>ce+xdzoAOI;R|S-3|I(G0DFN$Iw%>pxZiY}mDrNsPu7Q*mP@`qVo&aqp zhkBg(9g=MP8yYA1cR=tXP)o+fvrhWDW#p^S${R5ZseiS=+^7eALdaw{bmo5zs86a?D9VBos1`r4@1qfW}5*}v?0tu89UR%kGncc;vMC053w9^Re z2Dp+6$FJ9d+-QI^lgLttk zy5WYz#V@UpL0&itj&?vQ4 zKX9m{xp8l&G$0WiE%VrYbQc!^7L3rXBgS@WbnsH2BL>u{J6`@SJHq6}%L)=DjkE~` z&ddz7qNvr{4e(-p^u}1};$}zvu^8l={$F669_#UmMS`ZALGZj}PQe62`EPUqJX zcR8O^%Hz-=*o=K8GRmDgIKL5V*4Q<^Sx~Kcq5pch?9x`QvQI4e6JzprJ7+hlI7_e& z7uzX?49P+HViPHZdcixokIIjpiH|B8Exi=;N{7I4LUF61F(7-^ zFuk!oy@5Hsaa`QbIB1;HPTKG_GES@S&B5GT7wy*v>t1&}Y-J|93usQrnfu>@xlY=&-z=tC>v1WmM^jg zwpfj{CG7*;|qv)mK3beK7&k*68C1(6V zgLFbNZ6t7OdLpGQ8Eyf>ZpVHp3;u&i$MSKjX3~21a$$&{yyfpSHxj0;7||i}9#PKe zRlYSoiB)YXP*P(LKV4W@(oauz`Qpt-R=Kvflo2`}mpHc-5)@Gi_;_SrO`Bpm79RLn zG85F9@Y)XEl+v#^*kETgn0SqUJ8iCyV6^ESFRL)sU6U>HlvcsY#pY-AO2vj27^y*Y z%RE}!;PfVwa1X7ZM#h@xvs^1!CrjL|nli#04{g0se1h`+&XpgVN7Fh(w}k0MyM)fu z?3O;fm4vhGp|}xD9q;1ez)jOEjAEnW5Jkf%W5g~`tcOv8yG|0pW%dy~0YwNr;v|gI zUX}X0ZsCfiyK)a5)~E<0b(qSlhqb_tTa~!4Mzt&LSVa;Mke%j-K@wfJ zm+Px=y7k=lgw=`smGWkscd=$*GB|CDO@i+s$Ul!m+HT!l5<_sM_1D7kB){7+@>9x6 zJ9=DXmzGH$Uyaqd1%hIoWZo6S>BM|xTP`bnfX`glYQ>a%>y2kc+Ni z&(Qv!XVb9F(|g_WYyIG5*b(zb+q=E}RfOx|AD($?gKoG|H*-`dmkj8#HnS8c!QkjaxLciR&Q(G?INzv$Ihq&(TdQpt*D=H(c!fFi^`zjE+S|)R z=_&oZVkDU-QCuLKe}kx%KQU0(xYXLu4sAK7zN)*A3r{ZL4rZ^<)Wa0`ZR#clc1c$< zv(?%bEe1Jkwr*}mBY`T;4vGz#R895pA@!R<+dwPgBk9SKS85mw;e#a~HpIP~J?1^?w3Ae3&-9y1RpAoMG_INk*EQf0)H-OUSzO&EXcN@H z)&MFmLBhUwQ^UN`w`PVvf}ZetfBCD%Fzz#j)KrS^dLHwWY@De{$in?t)sfx}XUzLE zyS`%1=iZX+%Fr*z-k#IF6ckp7VpT0S4LoADQw=3;MQVfb8qV~HiVZ-s&!#}LzCg3j zs-R}C?fPh+RbQHY7Ps$h(=hLKLx^W4$Wax_s}=lot0&58$>&qk8?4h#H@X06T{2yZ zQQs_SO7HIqR)aCz{7FOlK&QPF@|HoLaWEF)wM(sRjtvwAmd!h+4)cZ2FyadcGEBc* z^!>)`U!z9U<0tCZ9=1c|@Ga&4=Y{`P=iB%evt4cP1yAZun(O1_!`kDSLDg5(MSWBQ zUyR8C4?GQN9!L&TJ;?f}qAEyIKFg3V(ej_md@Zd9O{>U@{Ii&3gm2oZRSO5$wcg%g zq%&zxA!Q6kaM#w^ns(AK9!>VqJm0Dle;9L0Ut~e5?XV0{XDOfAlbY}x9f~>n;1XjT zCYD|#>^B-|A)$V}%p*4Tj*Z&p@|zz0npi?5CC*gPryk#3vgpn0?&8KnEl#$q<- zOE!m6!hhNEpV*Zrwd_M?m7@D8K$OO3dk$RAhS!}8$%QH1I}6cMmmcs|L^SxhTee!qPH>Q5zaw# zU%Q3E`v!9H11P&+i$>pl?W8S%42eaj_)WyO@>{=1e1t>0W-9Xt%0>RN{F-{k=lrv; zBO8ybnc24wCarh(5$IB{wROKakG`U#c_nvb^@>;d)flV-wqf2K&Af#%siP{4EUr6C z0nuTyf>(H{uKIUfq+fC4EgH-yQ$($d%DP^9g=Z|EjydG~g1H8MDCC_(e6+kr(~p^G zHNVBon=@XEKEY@%*2niLM%d2SIi^L{=el z_6TM$k1IkJ&wHCw4LC$rL{o`H50;gP|5lDZzs8(->f4))A{k<%yo#e$&l_VI*39Cw zQA0D~`chQk$eI7f>s@1&@pwRuy(x0UjFb@H7dAB_Cl;cQHidy;_+=cSS}M7*U>fKe zoJ9OC*-V+Rs?;ddoJ8R@=D>~`#>5zJjFDv&^9n;TJOsplTM_h3honIGLsetEf@{>o z8q-xfCB~#lTVImUq}BLi@9kc^ z$JxAe4b^;ok0e-XN}a*fY$=D5)1E0aLmmvFP1d=IFD+G9$5C;v|04O1E`9CJcXK)~ zhd^wQRbI>)o1smt#-i{-bCE(DVTPmUb0jdHzD$~@}+@PAJUk-!&>hco=mxPyN z#$`9Zz}dSJ^c~z2xqJm>31@L3jZ^@FJ)SP?qsoLv1lnG+Muar>h+!_**07?1BRC)@TlltZ3q^OEeA6mH{);N_ zL4*4bQ9ubgND(i}*h$}mJqCIUI{t?}#$SvrSq4TK&@k7?^xEu#N*FUKwFo{AiN%V9 zVDx~j7{2>8p>v7|-Ne~|#%CL3)mUvXmNqr6DkZa5C`CF+@I^f8^21b(n11}W(G?KS z=e`+Gl3K#JA8%K$m|7R0QK#V}u{spP($=TrZ1wO`1x5$BcrYhDlxbqvR%y24KS_d% zGzc1H*e79#1XpOHXh>?FIJo0}ESuQuw%gtC%{DUr23Dd=Ilop@5go#2r_z~t=Y}^nybdhJ={eYs;EsMjdj?%5+PKe> z*8J5EG3>7F&^jii`JK7xlJ4pwVZBrKnPh>b`N+)7I*_MM`==cH~kEROw-Pl+lSTL9g0 z5s1>9^DIlb-D4tNg&(_Pd{ z)J^Zm1$`>-$s}ESFtkJ_E_!F& z;=qu+DSz3*juEbUea9L)Rz<9v=69^XTXZtcMza1xA=}C9;1lfDk7Dkq{$Z{a_Jvor z{pl4Jyov&tj0uA6t2#Y#6%#kLhUmE`(I!dZc*V5?-62|~SsN&fZq{x$m>LXs=0|@@2I$7mE;?VU4!>ANz(F=?s_)z61gQgV3PD+ zb`igU!p+Sd4<5z7Lf#Ys;9)EqF;?JbUZxn6)IU@y6B~#tyrGwNuMf zrEccr9qdkf3B7*w<+NtRF;&LviYl*}Vh@R1Jhv~KHQ)N)4Q#ht(Ph+)EGqIt=^EXZ zLhgS(<37O|G%MqEjT`+utIq!srZMj|+DR#qbHZ!7hw!?0HWz9uHiJT#ZeK1bZzjP3 zi3mS>&tRTv>;BJAxF0Nxo=H|TK2G32I)Ym3SpL5!*Kkz_?c?5D`FRY?(N?$W8GVly z9V6824d)-4)4?`1O)9X8t zplY_2e4Wp@-(p1Fp^vT6_G5|mn}{fXoSakcR+BZp5pAB8gmJ}uOiRbiwTf58x^wv3 zs|n<2i7&9ff66YoQtw;tDwF42(6+phXg=Kf8P*z5t9@^G*lZO()DKopJX=7WA7a%G z29x$G(w1EncV1s*{K5(@U{fhs*w!+8?zAC!ZAU=xVSdMA^nwTwQUWM6s>2HO1JWg4$BQrx2A|dpk z5gi;mJ>XHVFNjRh<6$lkoBS!^hYaezfnV58y$wBOCxrq|De}0zv{{VB_-RD6~I8NUTlo>Ap)(u3?cnS zo?sotGGHDVM@leGq1@{C41Ug>6?%aYgpS2q-fH3Z;%G6E__x>$@I<@e>IrLwpVA22 z8(q~{pGqE9rO3+(L*{gfwhDveUwdrFi-I4t4xpt}=UZ7!>*H75n(o35x7SA`{3M}-&+2yj(Qf0r_Q{|CTD9EXYjKw zf98sRz_=sB6j#Itr?Za>K(>^vgef|n`3jfi2O|PIF1x?&0{?>^!CRT@H2vIcqlyMH zhw2(Um^3Zxn~1;#80t|PfI12lhm^B%=zBxypt-D5}|VqjW;U01b&M! z>cm*5Sa3vRn}SpO?dzu5;|6l+u$Ne?ie<|bg5?9xK2-Au(z45HX?Cp%z2+JS9r=Xo@-`B2C-<^1{Wl*< zyC(@mpNtO-jP!-g_!Evh$=8TZNw2@ii&3j1jPG^}Tj!#EzfBg1ch=2`+iZR-t%t_0jn)j1E5?dEN#cV`(*ZR#%?7+>fPUA$N`0PH=NlBX3DYa}AHa7btvr z47Kz?&PtGJWDJt3hAPry$%mmi|N|dn6SU3zZAqZ{Cn{=0_q5HSs~s z+`%rn?Wf_nvuQUu+Pf>UFvPSlA;w!$@_nkrG)5+lVPF0g$|NRbzKI|^n}iI*d;V-| zUt$)&LI`d=rnSZEnBAPT(A*j|67}|DWTa;@q7;|r>7AWeP%7-A zQ(&6{V8pXS@fnM^lAWhtRC|a`4Df>`BhPw#jgtc6tDI5DLbP6`E4~#LSn;ng4Cos# zG-I8k8C|(&s?*Q%J;T`Y#OZ?$g6;*&+p&qNpWVU;8!s|Ot{X2#3)i3`yY`}&u4-&F zJP~S#i}Tj*Nw^h=jyfb#Yt1=Rqk7mCmXLecrw%tVX2U92&;8=oF!s&e!(a9^!686 zkr|a;R7R(HboiTc?5&U)?nF`t2EnhGHKV4l{GgNT&@A&D>)$rfW%U?pm?ilSFC8$1 zm^fmHzfW+^Hpb5rYsJBC`EhCo5RLGw!dNjMg)fYgOe`B=(%wD3+X&`|&bCVQVlF6_ z>@8iyUM*W{{1W>)s!np#wXPyuXzjiClw4ZV6qKOebhbI+-8_uwNzn1|wnTd9$P(I7G|qmN5u z2aZptM#iFNNrqb!UTeIS^35|jrM6FpyPTW5T2@9@fsxXbRo^EhX*y&hBn#{gk<7Oy zyH-oY*%-Qe=N*{v;cK~MNNtL34*ZbG4v!z;u3KQ>TM!Xy-NK35k{ZE(U>x-oP@*Hz z6=5)}!)wD@gv06V0Kcv6>8k%e=8XDVjnJt36{+kNxCP@e$=>qHa6t`Mc8A^4{^Cdl zg6-qV7RQIXz-%?T{+m5nl!9F$&WKU8@<{#7E2Rjg62y2i)))^GSl$$QII6)YFU9gnJ?-ip@lWn=|uM%yM8PpcR$&R7?|2Grqg=LVw*kU_V2FkE9%H=3AOby;qdZw;_C(cx<_8L_0u)lJ1&U4VnUL* z5>M?E4tF0E7xK{X4a%Q{VSA+J$1WvUNlErlZ4(wW;pPaVLY04XN`+v>8BBO@x3&XE z)2jf=anA?e)9!PX5wF0Wv3w(5nXnJCClmVIE&_b;r4@)yK%Y@EDkL}HQ)oy2*U2^t z8jyg5=AD9rfrTIdK6~%}KFNcC1V;oud9qVs474)JL@Rr`{i2ZIM`&BzZd5kec)=Ws zfN%@cO|IHdpr%v`RbQ4YkP=q-CCZIplMVhkc!FZ!qd6)%G;bV-;#ZNBLcx`++E53) zUx1Vsv6nAm!DW|L?B%KC+lSM6|NrX5t&dUA0Au*yH_xPy)9i{pZ?4Lbky;rAjY#*| z!y~j^L{Wa!A?k}1Fh)FHw0SBxF%BAJH>zsIZ~oTGBqs{SIdo9-g`z82KgBf=suh6> z(O;_ZjB`*v2b18MaQ_r1_j_AM@PU%y+ZwtGoAroF*5=r)p!`Hs%+Ro z9gY!OVeIr}ZRrPcxnUj^L*UzHiRMfZN`Yw_4KvQv?)*3Fiod@UvB0-?7th7MuN*oKoCvJ|*Zx)5wfJv^j13#4G#@Qz`a5q%bmw_;Y!Pr{w{Id3i=Kva~kkEiSI8Gy*=DaFIP3+9PKh+ zA3?jv9yFy<{eJ)>Pu|vD%{JKw%rkm818RF#4OGCnot@M9><^8w9!u^$pFd zRX^d6rM9dvo8gc_8#zLB3T)9S`_Cm$6CD_hbj$gg*c@D_&HMyT%0MSWpN8k>cPmn} z#s?$vR+-H#?`+CrN~_YI2Gns0er>tj(Hhwm5*SI<_hcDvUTe;MQz^l~nqg{=sDg*F z)nBJ)N_8$GmN3!T@sfKBKd4qVn@1sTqGM^OJOioaGSI!Fga`E?8_z6@BASp?*kYXY z>0pJY`)C&3P-|rv@73U;RBY$l>xB2a=;UV>%Q^axf%o-v8Xzj- zBo_(?lW0V}LsXlrYZo-dKqa)_Cmq+Ih2|@t?Yo6_bV-`6e&gZc7h$>jYcb5(O1|s5 z7+ih^HQNb`u(rF(OHLYZ@YtTq=D}P#Rr9i#II>2U{jqvlAZ}j;wNIlWnQO#@`##J8 zQu7kiB#OdYJgK2+nW{}^-Zf6o<$`c?RxM5NkY6;&e4}TOsbnOxj*K=$E`~16Vv;{k zn;fH1yp3dyZC^_?(c>}vr*2Io@~zI}&@!-k8jE~J8)AN-E754djJ zgo`;3(J0Q`K6p5jOw=cUVI3kh2y-VJV*WfT#}av?LDBO6F!mK-QMKLLC`gA&DkA1?t86g&BL?zvj=8o zf0ufDoRVs^dr4O(J=`(E50k8d5?2xPj(0eQ3x+s?TQj3qrZz$0CcWwttZ z&b@Qo1fWu{S=Iy8?JVqX%pyVASqzI?(@VqrozI+tteUgE?V4tMfdsrYBj*Xdj~tat(=TMQ<+yzP-ko@neKu#=grgb&r9Ek^ zM;m}?w!%+QR$GBu`>?#^MOSsddEIeGq~sy))hJy)dC`Y?EBGX!AP7HonA|24eYR+* z%5iotzYYn3?i{mkunR{`n6!6})H2%b3`2D$ER8sf}Eu$7?V zn({Cj?dWh(y0;3hs|rUg5=s)nz~8|= z@xB*$KJoVVri5#{xbfM{*$l5))3nTAQ^l4~%fTQL^sSzGu2czADQ+P=h$eVnsynvb z6I57Vx#1zNuA*;6T^b_1uh1P!cA334K)RhC;qQQO|ieW>1FZ142D13bmxz5V#-@li>&NmxZp1v^jxY) z81W3JcgzNn-Iu4_?3s1olUs8vhs zmPk+Sids2TLM&UMKh|AK9j6M}xgv#`;G$Y;an$FcXjY$t5@|(o&}4rS^MxWsQO?q? z{_qcgPXw#45Rjh1Y1DtwdW|{IRwna{TDAPwS@8Fy* z9e*TSgUIMmFHYW4dYT71?H0Q#jl+j__wLk<>IHLCe+Szp> zw7Zy@xU`K^9AW5zS=SUa+AP}`N9YK2>~{w|$AYct2D&BX&cdY~z1T4_)$7UJI9(fD z)F@<;J|&LsSQ`&rjnp;y>UUUm)D>I(MRcY~VKVeIiqjeL(?~y@%66tKd#BES#{HUk zy&#jeRa9?WUV+QJ-b=!<${ovQSsZG)QXie~C;WMpgjCklhOHv}`x^CG#1AvFgWan8 zw+>iCn+mf@?ej{?Z;GJL1vit6kBDVgGwWDQ-=;}xRV1o<*xHe2x)M%dOx)N+aD052nkR_}I`=n$1>~O|G-rO(drdQRA^79&o>^`;0zcU@>ESwS-@2F}(bNG8!{#Ez) zN^cQV`dirWGj)EZlOk{I9qyN~EJQnKi?AsNw6K)V2$X@i9vQUp69iDFn3P5Ndtn@& z9)zAh8*+x*!zmUjM;#jd%P6Kq1{49>_{vXS73-CwwsV&2zE$qk#`kv6_A@CD;|p`J zHYpAI<{U8Z{$MSDvGpY&pp$G6sbp%RytZYEHKBpf&uMn{G07bOReeme$558*0W5Y znwPdrRd;r6?{z8do3D+BcQk!)gY~PkrqUqi_32QfY#!_~g49dALPoU8JfcTW|6OP8 zEoHOcUuvNI*O7Gf)xNJr8tWGh6uc$2T^3Zi)2M7jH=n><#t{~M?*F+Gphi4oKE95o zSx~2Q@-)zx(1S<%dervvEY%JVc#0R(Vi&eP>hv7}c&fJiuGi)#*ES6BH0&^CodZyS zpRGB4x52yl{th?~?{IB%pf0@Yt;=W$kzQF*llkWaY&L7Wn+{lT0un9lVv}TBa?a^Hax;K--{5iO_a%HIH-4=%6>& zYeMejm1~@lX);~ABR8qmPWm|lZY|sqxKOk-t0T9N?Y)`B%}OV|=e(7|y`bao`L82+_MBT+OX&F_Bt+p^b~AS%cw*k=C&iTw`c2Tw;gPqVf;szBN}h#eM;*=nBnM3# zW17ZImp-YTk&ZXA^PAoZ*qMj9EkSETy>N#HSJMN0Lvs3wL`TkfWz(JEX7^677v3LX z{=nuNqp~_)d#}+eo)*&KrahOP^RdM<33T&d^1AsZ?I9gBr{26XdFt>^AH2|#JvFND z^XKm76Sr~0s?pNI?+!^$26vG48dy57S2$!fP*u?Wy}A%wzw`u@2j~oemsdbButNW} zyjoVpZW*`Mdx7=%_l#q=&d7`Q)8n+V!8d#Dr>y60kYj-@&5C1;*O_jeNL4XrurGy{HNwQZzoJWohBI8Jkzk^3+XP15|uy53dtq3FxmolyQ_nmhX&w)PR-a5pSoNn{VSUwb{0dc*^S zU`qt!2X(r?m+8@17D(nyulSEj{yaK%iJ2!gmxPPMW(qMwZ4J(YW0%*9Y5KO;j#3kx zcgqP#XC_ztlj<|+lL!`M-m*_f8qYJn?s!+6MsA>?n*qx{(S_ph;|!2AWNNMr0e(8} z?#l?4`b=`m0&uyBA(Zo%XRP&^4+}E!KQr1!T;|KfhEhk2aq@v(xt!-Asj( zFWxJfo@yXzlie-VKqo z)NzVzLjJNVnhS|EqY$VSiu@fwZ7!{zp|zn4(-;{@(i4LaY~!3h@(qN$HA zTFpcgGcE*E$0gXp9tnl_@T;BzEU4S)h`lF*T~9>d+s6cR!UvqmW7l*%(ER%~f@wnn z$=(z9hPr9TofeIlHk8~H$8~-iF?IiTu2N!E%v*HsFkw`)-^g2J5P7ab7jCK?jOV)_BitVJk<&LA}qoocKn8n`!va^@9*;i(ovsh4LuN={#q;oE_ z)LVRlN`bM9v)KE3S_hN2k+V4Nk`LvjXYsgO0MpH@pndmxPVO&FVuS9;x4WP2mBMG0 z*m)M1$K5{ft)KB1(HCR+XLM%4mH543(IG)@_kOJd54!*_bmajU=~h6*m8Ii(iqa~x zSxt#HVJIWat+DT$8Bu`X1r!%Q;DyS=MR2^`0o8u?QF_gOr)^G8IBUm@f2f5JYP&S< zq;UB-AV_5c1l2G6wex`*To%5o<>Q+N<_hk)Up`%ptKxWvvUWT-2mPCWGh+gbA&sj8 z?>GmH0WJ}W$=eVN(G>$aJ)jP*8PJO|pz8s8VVeSU6%gG+_5Y%)uBgE^{wZDb4O?me zeO~vc;_al6!ro*s5$w6b&}eC_a{PL~stSh|JP`d%F~^6A z`~X3*m~an$o#R8;J;P~^`iN8e@Im|L5L^fN%?#hrD%iybt?t(rQ+wrT)!+I~_g{C0 zxS;x%Gf!< zZGDf$E?pm6PU=@tgRe`X(>iXKcG{i@w`WJE?isN>`Fs-^&;5M~-aikkrLc^1eenFy;WkFp2VFLww%uMDq6tB3(~=59*c&EyRf$jb-tO?}ElDLw)VOpcQ94 z{b1W%BykTDXp4mR#_+d$p7)E?Ke%}f(jPlo9|o68ruj-X`}m8DBx_=9rnN$brj6>(Tp!^Xtqd;w6<2HMQ@AMfWPXq7?3ilZtR9y&1TlnAN%z{{t0}7 z$=k~+I*m`@aI;~jEr`re?yoxfY&sGKByTK>ATOC0v794Y|EXfbl3evRpj+#th(@GEceQ`|yVBJO@4r4OK;G+bIwM z5WYV9^dVr>N%QZ8!u2?PTiUXPrbe&vbp-(-EKkTzgbojS#@|Aq$E|%ML>nu`V6&Wa zzm0N+iyIGA>&t8nxdfqBcxVSnuFm_>T4?BVX~5W@>KH{jAftPL7gA?XLAC+qFr5jx ziVwc;cs?zO1;k8{eMU9MyrUSq&ZD}4*y~OKV+NBQah$c!{knmBWTC5!)$!G0WI(Du z6QJp_#+Z{-{r=LwUb7O=i0g5n0_EKh{#71X$kn7^vv2e-dgk#}zUXxN!RhO(&ve#R z`U`PQcpRq8HY){obTL3%j2)5F7Gv>+F0D1Ueq+_ zH)$4o`sn|L`%SEbhIdzFaZopzzEt9 z^?-Bpw0Z71u;Rw_x%Iv#!koT+#7v0;Tl>Pp;RnalU#WN2*Eyy9uduRl6gGvuiUvZS zD#hYHE2ZW_R9Eo8sNW5tw4QwTX~n$5{NVf;-w6}SjrMOc_ofN+Bxi~Qtjm2{~b>tkopx`;oeG(y* zb~z5!_iW^Hdfs*qt$em9SSn*?c3%GBS7_{*lT~qy#r~_JO}{-?wLatd8AHCShq`X@ z&aH}Jis?p|{p$zAvI!{=#r-pz@B^z_!e_R|_(fJ&Cwy=yVLxfyA4Ai9dc>@Ms;S=L zvB-N1Et9QnXS_hiyXip!6e%mCm&{l1obMKvacV7`zcbOM2`!f?2Xi9e<-tLxcb;hz z1?;r*qmKJ{fdlV8puyTE5Fl^hOyv__>4APEEln>hgS=;X+X<`J8&Cd&nvn;mPvhD-O+D|SpTUnHusfKA3Flf~H>*Jq;Y5Raq0K-WtcbVYuBnVw!ZG6mDyLPo zDTi~_QK??jM!V>!H0}oKXqT37I1?-Y1^;7z;1QW}Xd6@Eptt4}|7!YA8~-C~#^=7A zc8ffKj3%gXumrrj1#5-X6K2WMR&W3{oX%J)!#?$ zji~(TNPwJRruNs2{Et@tOt3cEK-1Uw=uN4`lp3c9CyI`omhW1viGljskNvmTVz7?O zyt2lm(5@eshDDjnPdA3$NTF|~mj(f6Z=(coT&0)#MVS-A%#u|`_|n@q9Mo}qcIp{n z$8B_w^VU0XKJ@xAC4?dAG2&zQXmiqs=qRTTOdT$-?$o-lEdK{hyZv8998;PN0uzLj zmzmx(m#=R~xspP2NiS6agRgJU{dOuK4$5z*4B{MoCIwp9SE-)-U+Vk6$sIVri{}Zh z1seO;p#Ri)TUhkvvlmsyr}N&xoTN0r4cFK1?Z-WZI1CVH{siLCK%C^?4n?>=BmV!T zK4Xr2L+W~^(GSJ{HeLUts~H<-=u&)m71t*%<~$#9^Qmg?Dm66yoP@dwy10%l3uZ!` z-z}kFHodg!Z_3nlU2||@m*1CbWqhi{!*_pi&PFQ1~(`SiimuR9eHy3k`shRq8F0(5e9^?*FR~q6@($u0Z!#PmToo z=$L^WMZr|VxqZ@@sf(ni$ImWruCxFAr#~Poc?$I5S7DTaOI^#zhGs8hpu%C@VO90N z4q+-L@cAtgob;8&pZ@-HOBH^{sFaQ!R&K8*ziwBt@QVt_L&&T zY{C9hm}ql($0y7ZY}8FqHr=6f3F=@Do(artB!amtDKJMx0WQ@R4K8)j4=x3303Ie# zb5bj>`E@8m(CqoDMs9uiD8`ykmngqG8*ah4saKw55pCa|Ftv zUWkklDO-pUm^`PY>k3&Udi_@THH;+E6JiwaT)*lFSm3EPin?a+aXve57i+h1dE6& ziwwB>L;}shRRa6`0jKA;69I8VzCxG;uw&jiX2C<78fthrI7>~;^h~>oskVX&DtWPD zSo+C~d8EY`#5Tipb2)h^wqyg`+^6NUO!M5BUxsUE{R^S?bry+7>iVgnn^-l0OsCpc zG*HQ)DiqZxGyAC)b3o>yIf)V!o2yZB6OhR@e*|PM&61Zx?Z0s`!tG=(SF2J6)3|*Q zS{@5bi&R0GUwmgvhg5t+2d*e(3aO}$)J72H6fv8&c*nw3wp?G=R+BVj)ZO&MnRWU6 znG6>3EzC77Qskl+aPI9(kRYf)X0}R?psy8|-cO%tL zbX0Bv8LrEVJ@pgZl-Ztmf8eF%dSXHj{1(56tp`{Pv0j&(!}%ry%K`eOG%xM^6DA5U zR~(Ht=*YhUl;R>f2TI{TcRv9ZNgtobOwaQeF!yo*%%N@qT*Ox}2QLCHm6HuFMJx+0 z^^OX>SR^^ei-KR!?F=n_9MpY4#f?$SJ}%?>C3hlFv2XCAR{>K}L(xiIhSo}@)<&Qr z#{ksxteZK`?=?1tq>`dBKq#ps0mOR)DRP8DrfTrHrxJ0!Fo=wLkb#~uuAsQ79voU( z^Va=3AQ6lN5R$YIq69(|M8Qnrkb=)_Dk3%t-7jO$(Sg$PSkgf0Pby51(%-tC0R-zy z2q6j~FdHb9Sbnso75892T3^^ys$g+GN4-ZN%@|i$?8wos zTwK|+3ZvIBFyN0K@{DHh6+jdh>jFe|rDG)g6vwqI*pyx^4iTm)LYHR5Dk&C+urGnM z9|Jc&=wJdBLa;)JjtKZE9Jpp}T2&P(YsH?dSXLMcoM1&o)D&=t!P>jR*dVqI0U&Cg zKnNHx(d9FZ9eqRH_OZ%o{JJ+sJtCxoS(r#nM8};Nfi%0E@x_yN0cfA1C<@^Hc3@^bt5TxunxNPFjowATSlM_pY=46H* z1E#e2!zHO6^t%Cv-Wo?fJV^y|H(<+GN<3S%rd3J20#GgS4nPeAC}0mS^Mzu^lT`Np z0=^#5A$nE%?m2ife+gV!(CQ(;f_HgeXz;%N)ElgL(+=M7Ggg2tUQ!u+B|ydqTw4Ud zf)(CAV8tp#0R_GYkPL(<#2^L9Aq6oY1%pm+#@YwFe}eerAsjV?!?dgy0L7XFtfVde^Wq5{UQCp9b`f-N@O4%{G|l<_&fcNf}QBq|1waw!9BF96@1Fj z5_bHlq)L`GtVsxSU&C_mLiKG&XA*;QL~fzwBh3iP0Qd;BQ$YG z013rC0AvvN2ar!Z48V`#aR6$GrvYdso)_FnIF(Ae-2=D6Zq#&lL*sT4ztO}2pnfwL zHz24Fg4ht$Z-Lk?9CvT7B`dXfJ?tKUN}l4dAz(y>AQl7(AV>~DdI++GbP`6jk`jL3 zRWgyXa%0j;X_`9IEuU42LeeXrm5V|E@M9DlfRa(q02Gaa22d#K34nZ2kARXZ>i(p> zNWE6eiOAM~0X`W-lE{!}c@ee&g3KHQH<}?f1UH%>HUu{sfqDIa4W3JG2+~3j4}!=L zyn{^TJ_HwjPit-A2+nR&8ed)aYE=Mf6M*5Qt=+3=yF8$!Xsmz{k0?CsfRVH)S^!(3 zxB*;>`T*cVlzM#la>~Kl(X3X~Aq0=tj^H*J`dw_U_8Iy=L(mn1ZV+^bpvU#q@HGQ! z`aRhzMlil(MD^rW0{ymu8lPEksmS@mgBirv*IAT5o3XI()8 z(k6H+Mzp9eLePZ zaQ(8PL;&}V#0TIeUNnI@F;$lcS_j`EZm~Gd6L|tsN&FYoXi>Rg6B|C}$P!>qKO4-g z$$&WoN-#GX4KDS)A6#l~11J?~2rl(f`}>~UF(~>~$`f*=s9gGgp{>jzt4i?zAea2o zU-)7ZNR>YbN9usUr~-8GpOL~$E+YGFTj$u|R1)jS;wVoyG z<9$+ZjtP?irG9}VD+6n(hk@8;phblCY^9Rnc@Ut$787|=zmL?F4Je*5%Rf)*33$bb}7fD|kN7p&yBmrK7lnZCIo z4LVEl6OPs-;=O$z7q+%*)Y``>i^qE_f)xv_K)%WjjDQi|sLed!5RNY9>0TwAj-{ti zfLW_*)mNZyedtlg3ItZ!d13v{tX8EnCV0uk7K4v>S~Fnbx9W$|fR`karp;CF27}6d z5OB!%%PRAF=(Qkq0Vc7E`u#qG3KRH*(0`%=3@kY{244D=<-n2h5T#Jdai@0@Pul=4 zMoPFer80?s;_`|q&c~hn9e^Nm6#(zaT>#{vNCd|z8o+UiS#X@eLr{MN zVna}W6k?AmhrMx;sr>o96~>`dp=Y(~lGF#lLsCxww@Fbx{?*9J7l!gBBYIrhBJuVn+ll^1x zq_B#*dTX~9a_5`Q=viY0tik!s!W_a;^MR&e>cc7e!yVX1Ijo0#kvpSJ-3OA(!&x`h zBrK$zOCgHHRi@XE+fRX}FxzfwnY$0w7*Zp}m+ z=V2S^*e)l-X3|wFv~nHCFRb=zFVH;%4eTe2CQ2K#%@2!|zPUTVElsGn#y`%zCD`s( z820=)&HEszqjVb1f&6o6nIw;>qGOM{|9u-UVf-l;81AY@QggSIqY>n>G)E4|F4 zS!Hz7w)#T!m_pe|+-cj`elT?7grc$e%AJXNsojU>dVDzeM5BSyNYABXjsv(-UC@5t zwagonY5t^I_rdahIsO!F?84$*(h2mb%A|oSY2t%URv} zDl49w%ViXVA{;3u3OWyG;S6k#g)^=+z2(!01$^5erussCjmfOt)Zqx(r9R5$_pFR4 zJP)AAF*I8%jx(QX-tSY?i6d3$5_`}GzP5;=&9W0T@eb}Sy6$OGr9nz|i6~+}>m4ql zj;G^adAh4~^Gym!YZVgZGbltL~Mbcm3{-#9bE+}Kal?0*Z2 zGNSJLhH6{rld?6&Fnb-Jz2I0xg?1U*RS1_If~^(n+-r4}(7(dY;FhtpNvw>x)q zU5xE;RY@y+Oa0sJ*&yC%X zE z7nYx6Q#3zPUp;di&!`A>4f_P$rdrlI_IXi7aK6AtPAKN(XH^7uBLs_VEDy%gn9*qo z91cli-1DP(+gx8S#SX73-`Y>;d_qbR9HSB(_Hmiml8wT*>noskvOxWx+7R`? z>L2x?S+KX0oy1(__)N`i^=)%@iG11$Ld^E=y<=LDyQOS8(#H&LB`w!dbae$@8+C=} zu+&dWsp0DjiSP=*xKikCT|f-rmmHCF62ZL5^?w8NFtCJYr1ajg7`JK)P+@gmP_Ob+Pw>J_u7zm?v-1q+&NJ-kG|J~>EYy1Tm0Ywrv0RRcShx8AL0g#lNf5={Nru-k09httA zt=!gzNIs}jA-CS$VsA==`{u-~tO1E)HMy)Z8EM%qc3Ayt>6%FgK+n;bxwslE=9k>En4D{-Gu zkQ90$VbTlEZ2X;x17t@0&b+7zEp=K?igJbS(Xha#%PLdUVrXf(Xjdvhi>17u4lgTn zhf&-UB9n0Uxw@GP(5c~-&zf+0uBCOWTs##Z5p#pOzGp@lF?l2NRd)H4oBKg_r79uy zr(LcvAk+AFW+#x@YXoF=obxm_0U_%y6^9$b!KcoE{g0Klp1 z1Ke4C;V2>b__ROIALNey!=>TRZ!*kA1{f33E;l8PAOGv}Lc*#;%=kTvHR) zX1UwT21BLFc0~etZzLdjyW%9 z)jla^bvUUXOXHUZtSLf&p?=00F*+naEMxC|;Jy~}VtQHAm(hT)Gc8)Ns1P3cnKyX} zE4!$u`_9mo%1FM2t~c9^<)wZKIa800q-~&#SLD&n%Wd2eQPYM7-X$s6+fPj0v%JY( z9&8M}D`zArhgD8qZ=lv2@K#RA#;)-gF`w~a?`jfK)%}9<@(i~5j8eIiI(b((6TQA^ z&9>d^I-NV8Zay<4UG_#SxR|%c=nK92N2PP7A_XcQywBLVF`83y+)%k^Q-W?85<76z zxsNlkW1f8yuVAPRj%H$+o%nRPi3n>ohWXPftHUZz2vSCkSZO>+a?}%7i zyn>kZ-qM)$fZ`ZH;UBI+)frF_Gvb*<`+-V1*L^`E64m(&ja97dn&Q%Dig340DbAHA zG-Q^WD2Fx#w+SaiN=t=IVAnJ7q=IHsptM;*;;WiVXYvwI6|Uh#kqSa$T>PEXjQB5P z#`WJx%ZlIR6x#Bs|A9}q8r9enG;5w*S&4-Kwa1FGW^p)f?cA=CW*whnJwiExjR7^* zJit9Cyd6lkZ-XX~16n;o_wD7)OxZ zvhHNcbDzcv7{VDW>>R-%1Rm9+%cjM>&rg~=`09ss!G)h7M$5AjTxy)A~F)rONr+3s3ZUExi-l6Un*hF=MtCTWk?OOwbvEETHW$I1`CK_A9Q3poIm#{ZRN2FdaeJpiGd-Z^*Gh1EqV=ZBCOe$@_jjtm$1y&aBGUSk z7m8wPR4n{Fb(X2gd{LGu#R_%MW~Zb+Nts($#6|_us1bL`7|DMu&|BWP z5B9UozU-<0r!!4oMgcEei=Hw&Fzc5%;90*a)vp1XTJ8n+F#ym+Eo7=-n*9@mt~Gl+spS7zcF8u;#@?b$sZj%w80t;>S=jf)eV*5e- zSs>VW!A7MaGdZ>N?2entUFICub=o7XP$~$SdZ%2=9Izx>6)d>#w_MU(d2e(Y)Oqf; z{`nq667rTB&tRaSOvIF0W2y*wKW+f@RHIe6_eCkIX#RgJ1lF%#0 ztS@v`-l~LAizlC>PnBPL4Md5&LeYM3Ukc$T#POMxIA|Bink>_5-LYg{4`(nDWK+kg z=p)BE;J{i{A?n~zlP*3C4^GY$M(nPPAR}H!H|s?LUY7H6;CjYw9r9Bs{|23Tcsec@kKHeoj=I z?$WGIh4H>@Txg2(`cwU>%L{%7m_wWye$uu!�cp&qS|XnbPMuFi*mkJ?#h9hKu7rU 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 literal 44503 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 a=d>Uz2@9MDP*5nqzi&Vnefkaj^#1^dM^VNA From 83b3cc175b3f387f8783bf6933a90908424fe698 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Wed, 8 Mar 2017 09:40:09 -0700 Subject: [PATCH 46/58] AeroDyn V15.04- Updated to include cavitation check Update AeroDyn_IO.f90 Update AeroDyn_Registry.txt Update AirfoilInfo_Registry.txt Update BEMT.f90 Update BEMTUncoupled.f90 Update BEMT_Registry.txt Update BEMTUncoupled.f90 Update AeroDyn_Registry.txt Update AeroDyn.f90 Update AeroDyn_IO.f90 Update AirfoilInfo_Registry.txt Update BEMT_Registry.txt Update BEMT.f90 Update BEMTUncoupled.f90 Update BEMTUncoupled.f90 Compute Cm and Cpmin If statement in ComputeSteadyAirfoilCoefs so that if there is no Cm data, Cpmin gets interpolated from IntAFCoefs(3) Update AirfoilInfo.f90 Update AeroDyn_IO.f90 Update BEMT.f90 Update BEMT.f90 Update BEMTUncoupled.f90 Update AirfoilInfo_Registry.txt Update AeroDyn_Driver.f90 Update BEMT.f90 Update BEMT.f90 Update BEMT.f90 Update BEMT.f90 Cavitation Updated the BEMT_CalcOutputs to include a check for cavitation. Also included some checks for the cavitation input parameters here so that we don't waste time checking these if the user isn't doing a cavitation check. BEMT_CalcOutputs includes cavitation check Updated the BEMT_CalcOutputs to include a check for cavitation. Also included some checks for the cavitation input parameters here so that we don't waste time checking these if the user isn't doing a cavitation check. Update AeroDyn.f90 Update AeroDyn_IO.f90 Update AeroDyn_Registry.txt Update AirfoilInfo.f90 Update AirfoilInfo_Registry.txt Update BEMT.f90 Update BEMTUncoupled.f90 Update BEMT_Registry.txt Updating files to remove redundancies Cleaned up code Cleaned up code Cleaned up Cleaned up Cleaned up code Updated with cavitation outputs --- modules-local/aerodyn/src/AeroDyn.f90 | 34 +- modules-local/aerodyn/src/AeroDyn_Driver.f90 | 2 +- modules-local/aerodyn/src/AeroDyn_IO.f90 | 1018 ++++++++++------- .../aerodyn/src/AeroDyn_Registry.txt | 5 +- modules-local/aerodyn/src/AirfoilInfo.f90 | 9 +- .../aerodyn/src/AirfoilInfo_Registry.txt | 2 + modules-local/aerodyn/src/BEMT.f90 | 73 +- modules-local/aerodyn/src/BEMTUncoupled.f90 | 32 +- modules-local/aerodyn/src/BEMT_Registry.txt | 12 + .../aerodyn/src/OutListParameters.xlsx | Bin 44503 -> 115021 bytes 10 files changed, 729 insertions(+), 458 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn.f90 b/modules-local/aerodyn/src/AeroDyn.f90 index 619381fdb..065e303fe 100644 --- a/modules-local/aerodyn/src/AeroDyn.f90 +++ b/modules-local/aerodyn/src/AeroDyn.f90 @@ -866,9 +866,8 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) p%AirDens = InputFileData%AirDens p%KinVisc = InputFileData%KinVisc - p%SpdSound = InputFileData%SpdSound - p%Patm = InputFileData%Patm - p%Pvap = InputFileData%Pvap + + !p%AFI ! set in call to AFI_Init() [called early because it wants to use the same echo file as AD] !p%BEMT ! set in call to BEMT_Init() @@ -1419,7 +1418,11 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) if (InputFileData%AirDens <= 0.0) call SetErrStat ( ErrID_Fatal, 'The air density (AirDens) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) if (InputFileData%KinVisc <= 0.0) call SetErrStat ( ErrID_Fatal, 'The kinesmatic viscosity (KinVisc) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) if (InputFileData%SpdSound <= 0.0) call SetErrStat ( ErrID_Fatal, 'The speed of sound (SpdSound) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) - + if (InputFileData%Pvap <= 0.0) call SetErrStat ( ErrID_Fatal, 'The vapour pressure (Pvap) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) + if (InputFileData%Patm <= 0.0) call SetErrStat ( ErrID_Fatal, 'The atmospheric pressure (Patm) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) + if (InputFileData%FluidDepth <= 0.0) call SetErrStat ( ErrID_Fatal, 'Fluid depth (FluidDepth) cannot be negative', ErrStat, ErrMsg, RoutineName ) + + ! BEMT inputs ! bjj: these checks should probably go into BEMT where they are used... @@ -1441,7 +1444,14 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) if (.not. InputFileData%FLookUp ) call SetErrStat( ErrID_Fatal, 'FLookUp must be TRUE for this version.', ErrStat, ErrMsg, RoutineName ) end if - + + if ( InputFileData%CavitCheck .and. InputFileData%AFAeroMod == 2) then + call SetErrStat( ErrID_Fatal, 'Cannot use unsteady aerodynamics module with a cavitation check', ErrStat, ErrMsg, RoutineName ) + end if + + if (InputFileData%InCol_Cpmin == 0 .and. InputFileData%CavitCheck) call SetErrStat( ErrID_Fatal, 'InCol_Cpmin must not be 0 to do a cavitation check.', ErrStat, ErrMsg, RoutineName ) + + ! validate the AFI input data because it doesn't appear to be done in AFI if (InputFileData%NumAFfiles < 1) call SetErrStat( ErrID_Fatal, 'The number of unique airfoil tables (NumAFfiles) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) @@ -1702,10 +1712,9 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, InitInp%airDens = InputFileData%AirDens InitInp%kinVisc = InputFileData%KinVisc - InitInp%Patm = InputFileData%Patm + InitInp%Patm = InputFileData%Patm InitInp%Pvap = InputFileData%Pvap InitInp%FluidDepth = InputFileData%FluidDepth - InitInp%CavitCheck = InputFileData%CavitCheck InitInp%skewWakeMod = InputFileData%SkewMod InitInp%aTol = InputFileData%IndToler InitInp%useTipLoss = InputFileData%TipLoss @@ -1754,11 +1763,13 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, end do end do - InitInp%UA_Flag = InputFileData%AFAeroMod == AFAeroMod_BL_unsteady - InitInp%UAMod = InputFileData%UAMod - InitInp%Flookup = InputFileData%Flookup - InitInp%a_s = InputFileData%SpdSound + InitInp%UA_Flag = InputFileData%AFAeroMod == AFAeroMod_BL_unsteady + InitInp%UAMod = InputFileData%UAMod + InitInp%Flookup = InputFileData%Flookup + InitInp%a_s = InputFileData%SpdSound InitInp%CavitCheck = InputFileData%CavitCheck + + if (ErrStat >= AbortErrLev) then call cleanup() @@ -3759,6 +3770,7 @@ FUNCTION CheckBEMTInputPerturbations( p, m ) RESULT(ValidPerturb) end if + else ! not UseInduction do k=1,p%NumBlades diff --git a/modules-local/aerodyn/src/AeroDyn_Driver.f90 b/modules-local/aerodyn/src/AeroDyn_Driver.f90 index a42b0fe4f..e6f4df8c0 100644 --- a/modules-local/aerodyn/src/AeroDyn_Driver.f90 +++ b/modules-local/aerodyn/src/AeroDyn_Driver.f90 @@ -197,4 +197,4 @@ subroutine Dvr_End() end subroutine Dvr_End !................................ end program AeroDyn_Driver - \ No newline at end of file + diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index d36c97d3f..ccb548473 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -2,6 +2,8 @@ ! LICENSING ! Copyright (C) 2015-2016 National Renewable Energy Laboratory ! + + ! This file is part of AeroDyn. ! ! Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,10 +37,10 @@ MODULE AeroDyn_IO ! =================================================================================================== ! NOTE: The following lines of code were generated by a Matlab script called "Write_ChckOutLst.m" -! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these +! using the parameters listed in the "OutListParameters_RMurray.xlsx" Excel file. Any changes to these ! lines should be modified in the Matlab script and/or Excel worksheet as necessary. ! =================================================================================================== -! This code was generated by Write_ChckOutLst.m at 11-Mar-2016 14:45:58. +! This code was generated by Write_ChckOutLst.m at 16-Feb-2017 15:50:51. ! Parameters related to output length (number of characters allowed in the output data headers): @@ -1148,34 +1150,116 @@ MODULE AeroDyn_IO INTEGER(IntKi), PARAMETER :: B3N7Clrnc = 1084 INTEGER(IntKi), PARAMETER :: B3N8Clrnc = 1085 INTEGER(IntKi), PARAMETER :: B3N9Clrnc = 1086 + INTEGER(IntKi), PARAMETER :: B1N1Cpmin = 1087 + INTEGER(IntKi), PARAMETER :: B1N2Cpmin = 1088 + INTEGER(IntKi), PARAMETER :: B1N3Cpmin = 1089 + INTEGER(IntKi), PARAMETER :: B1N4Cpmin = 1090 + INTEGER(IntKi), PARAMETER :: B1N5Cpmin = 1091 + INTEGER(IntKi), PARAMETER :: B1N6Cpmin = 1092 + INTEGER(IntKi), PARAMETER :: B1N7Cpmin = 1093 + INTEGER(IntKi), PARAMETER :: B1N8Cpmin = 1094 + INTEGER(IntKi), PARAMETER :: B1N9Cpmin = 1095 + INTEGER(IntKi), PARAMETER :: B2N1Cpmin = 1096 + INTEGER(IntKi), PARAMETER :: B2N2Cpmin = 1097 + INTEGER(IntKi), PARAMETER :: B2N3Cpmin = 1098 + INTEGER(IntKi), PARAMETER :: B2N4Cpmin = 1099 + INTEGER(IntKi), PARAMETER :: B2N5Cpmin = 1100 + INTEGER(IntKi), PARAMETER :: B2N6Cpmin = 1101 + INTEGER(IntKi), PARAMETER :: B2N7Cpmin = 1102 + INTEGER(IntKi), PARAMETER :: B2N8Cpmin = 1103 + INTEGER(IntKi), PARAMETER :: B2N9Cpmin = 1104 + INTEGER(IntKi), PARAMETER :: B3N1Cpmin = 1105 + INTEGER(IntKi), PARAMETER :: B3N2Cpmin = 1106 + INTEGER(IntKi), PARAMETER :: B3N3Cpmin = 1107 + INTEGER(IntKi), PARAMETER :: B3N4Cpmin = 1108 + INTEGER(IntKi), PARAMETER :: B3N5Cpmin = 1109 + INTEGER(IntKi), PARAMETER :: B3N6Cpmin = 1110 + INTEGER(IntKi), PARAMETER :: B3N7Cpmin = 1111 + INTEGER(IntKi), PARAMETER :: B3N8Cpmin = 1112 + INTEGER(IntKi), PARAMETER :: B3N9Cpmin = 1113 + INTEGER(IntKi), PARAMETER :: B1N1SigCr = 1114 + INTEGER(IntKi), PARAMETER :: B1N2SigCr = 1115 + INTEGER(IntKi), PARAMETER :: B1N3SigCr = 1116 + INTEGER(IntKi), PARAMETER :: B1N4SigCr = 1117 + INTEGER(IntKi), PARAMETER :: B1N5SigCr = 1118 + INTEGER(IntKi), PARAMETER :: B1N6SigCr = 1119 + INTEGER(IntKi), PARAMETER :: B1N7SigCr = 1120 + INTEGER(IntKi), PARAMETER :: B1N8SigCr = 1121 + INTEGER(IntKi), PARAMETER :: B1N9SigCr = 1122 + INTEGER(IntKi), PARAMETER :: B2N1SigCr = 1123 + INTEGER(IntKi), PARAMETER :: B2N2SigCr = 1124 + INTEGER(IntKi), PARAMETER :: B2N3SigCr = 1125 + INTEGER(IntKi), PARAMETER :: B2N4SigCr = 1126 + INTEGER(IntKi), PARAMETER :: B2N5SigCr = 1127 + INTEGER(IntKi), PARAMETER :: B2N6SigCr = 1128 + INTEGER(IntKi), PARAMETER :: B2N7SigCr = 1129 + INTEGER(IntKi), PARAMETER :: B2N8SigCr = 1130 + INTEGER(IntKi), PARAMETER :: B2N9SigCr = 1131 + INTEGER(IntKi), PARAMETER :: B3N1SigCr = 1132 + INTEGER(IntKi), PARAMETER :: B3N2SigCr = 1133 + INTEGER(IntKi), PARAMETER :: B3N3SigCr = 1134 + INTEGER(IntKi), PARAMETER :: B3N4SigCr = 1135 + INTEGER(IntKi), PARAMETER :: B3N5SigCr = 1136 + INTEGER(IntKi), PARAMETER :: B3N6SigCr = 1137 + INTEGER(IntKi), PARAMETER :: B3N7SigCr = 1138 + INTEGER(IntKi), PARAMETER :: B3N8SigCr = 1139 + INTEGER(IntKi), PARAMETER :: B3N9SigCr = 1140 + INTEGER(IntKi), PARAMETER :: B1N1SgCav = 1141 + INTEGER(IntKi), PARAMETER :: B1N2SgCav = 1142 + INTEGER(IntKi), PARAMETER :: B1N3SgCav = 1143 + INTEGER(IntKi), PARAMETER :: B1N4SgCav = 1144 + INTEGER(IntKi), PARAMETER :: B1N5SgCav = 1145 + INTEGER(IntKi), PARAMETER :: B1N6SgCav = 1146 + INTEGER(IntKi), PARAMETER :: B1N7SgCav = 1147 + INTEGER(IntKi), PARAMETER :: B1N8SgCav = 1148 + INTEGER(IntKi), PARAMETER :: B1N9SgCav = 1149 + INTEGER(IntKi), PARAMETER :: B2N1SgCav = 1150 + INTEGER(IntKi), PARAMETER :: B2N2SgCav = 1151 + INTEGER(IntKi), PARAMETER :: B2N3SgCav = 1152 + INTEGER(IntKi), PARAMETER :: B2N4SgCav = 1153 + INTEGER(IntKi), PARAMETER :: B2N5SgCav = 1154 + INTEGER(IntKi), PARAMETER :: B2N6SgCav = 1155 + INTEGER(IntKi), PARAMETER :: B2N7SgCav = 1156 + INTEGER(IntKi), PARAMETER :: B2N8SgCav = 1157 + INTEGER(IntKi), PARAMETER :: B2N9SgCav = 1158 + INTEGER(IntKi), PARAMETER :: B3N1SgCav = 1159 + INTEGER(IntKi), PARAMETER :: B3N2SgCav = 1160 + INTEGER(IntKi), PARAMETER :: B3N3SgCav = 1161 + INTEGER(IntKi), PARAMETER :: B3N4SgCav = 1162 + INTEGER(IntKi), PARAMETER :: B3N5SgCav = 1163 + INTEGER(IntKi), PARAMETER :: B3N6SgCav = 1164 + INTEGER(IntKi), PARAMETER :: B3N7SgCav = 1165 + INTEGER(IntKi), PARAMETER :: B3N8SgCav = 1166 + INTEGER(IntKi), PARAMETER :: B3N9SgCav = 1167 ! Rotor: - INTEGER(IntKi), PARAMETER :: RtSpeed = 1087 - INTEGER(IntKi), PARAMETER :: RtTSR = 1088 - INTEGER(IntKi), PARAMETER :: RtVAvgxh = 1089 - INTEGER(IntKi), PARAMETER :: RtVAvgyh = 1090 - INTEGER(IntKi), PARAMETER :: RtVAvgzh = 1091 - INTEGER(IntKi), PARAMETER :: RtSkew = 1092 - INTEGER(IntKi), PARAMETER :: RtAeroFxh = 1093 - INTEGER(IntKi), PARAMETER :: RtAeroFyh = 1094 - INTEGER(IntKi), PARAMETER :: RtAeroFzh = 1095 - INTEGER(IntKi), PARAMETER :: RtAeroMxh = 1096 - INTEGER(IntKi), PARAMETER :: RtAeroMyh = 1097 - INTEGER(IntKi), PARAMETER :: RtAeroMzh = 1098 - INTEGER(IntKi), PARAMETER :: RtAeroPwr = 1099 - INTEGER(IntKi), PARAMETER :: RtArea = 1100 - INTEGER(IntKi), PARAMETER :: RtAeroCp = 1101 - INTEGER(IntKi), PARAMETER :: RtAeroCq = 1102 - INTEGER(IntKi), PARAMETER :: RtAeroCt = 1103 + INTEGER(IntKi), PARAMETER :: RtSpeed = 1168 + INTEGER(IntKi), PARAMETER :: RtTSR = 1169 + INTEGER(IntKi), PARAMETER :: RtVAvgxh = 1170 + INTEGER(IntKi), PARAMETER :: RtVAvgyh = 1171 + INTEGER(IntKi), PARAMETER :: RtVAvgzh = 1172 + INTEGER(IntKi), PARAMETER :: RtSkew = 1173 + INTEGER(IntKi), PARAMETER :: RtAeroFxh = 1174 + INTEGER(IntKi), PARAMETER :: RtAeroFyh = 1175 + INTEGER(IntKi), PARAMETER :: RtAeroFzh = 1176 + INTEGER(IntKi), PARAMETER :: RtAeroMxh = 1177 + INTEGER(IntKi), PARAMETER :: RtAeroMyh = 1178 + INTEGER(IntKi), PARAMETER :: RtAeroMzh = 1179 + INTEGER(IntKi), PARAMETER :: RtAeroPwr = 1180 + INTEGER(IntKi), PARAMETER :: RtArea = 1181 + INTEGER(IntKi), PARAMETER :: RtAeroCp = 1182 + INTEGER(IntKi), PARAMETER :: RtAeroCq = 1183 + INTEGER(IntKi), PARAMETER :: RtAeroCt = 1184 ! The maximum number of output channels which can be output by the code. - INTEGER(IntKi), PARAMETER :: MaxOutPts = 1103 + INTEGER(IntKi), PARAMETER :: MaxOutPts = 1184 !End of code generated by Matlab script ! =================================================================================================== + INTEGER, PARAMETER :: TwNVUnd(3, 9) = RESHAPE( (/ & ! Undisturbed wind velocity TwN1VUndx,TwN1VUndy,TwN1VUndz, & @@ -1318,21 +1402,43 @@ MODULE AeroDyn_IO B2N1Curve,B2N2Curve,B2N3Curve,B2N4Curve,B2N5Curve,B2N6Curve,B2N7Curve,B2N8Curve,B2N9Curve, & B3N1Curve,B3N2Curve,B3N3Curve,B3N4Curve,B3N5Curve,B3N6Curve,B3N7Curve,B3N8Curve,B3N9Curve & /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCl(9, 3) = RESHAPE( (/ & ! lift force coefficient B1N1Cl,B1N2Cl,B1N3Cl,B1N4Cl,B1N5Cl,B1N6Cl,B1N7Cl,B1N8Cl,B1N9Cl, & B2N1Cl,B2N2Cl,B2N3Cl,B2N4Cl,B2N5Cl,B2N6Cl,B2N7Cl,B2N8Cl,B2N9Cl, & B3N1Cl,B3N2Cl,B3N3Cl,B3N4Cl,B3N5Cl,B3N6Cl,B3N7Cl,B3N8Cl,B3N9Cl & /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCd(9, 3) = RESHAPE( (/ & ! drag force coefficient B1N1Cd,B1N2Cd,B1N3Cd,B1N4Cd,B1N5Cd,B1N6Cd,B1N7Cd,B1N8Cd,B1N9Cd, & B2N1Cd,B2N2Cd,B2N3Cd,B2N4Cd,B2N5Cd,B2N6Cd,B2N7Cd,B2N8Cd,B2N9Cd, & B3N1Cd,B3N2Cd,B3N3Cd,B3N4Cd,B3N5Cd,B3N6Cd,B3N7Cd,B3N8Cd,B3N9Cd & /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCm(9, 3) = RESHAPE( (/ & ! pitching moment coefficient B1N1Cm,B1N2Cm,B1N3Cm,B1N4Cm,B1N5Cm,B1N6Cm,B1N7Cm,B1N8Cm,B1N9Cm, & B2N1Cm,B2N2Cm,B2N3Cm,B2N4Cm,B2N5Cm,B2N6Cm,B2N7Cm,B2N8Cm,B2N9Cm, & B3N1Cm,B3N2Cm,B3N3Cm,B3N4Cm,B3N5Cm,B3N6Cm,B3N7Cm,B3N8Cm,B3N9Cm & /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNCpmin(9, 3) = RESHAPE( (/ & ! pressure coefficient + B1N1Cpmin,B1N2Cpmin,B1N3Cpmin,B1N4Cpmin,B1N5Cpmin,B1N6Cpmin,B1N7Cpmin,B1N8Cpmin,B1N9Cpmin, & + B2N1Cpmin,B2N2Cpmin,B2N3Cpmin,B2N4Cpmin,B2N5Cpmin,B2N6Cpmin,B2N7Cpmin,B2N8Cpmin,B2N9Cpmin, & + B3N1Cpmin,B3N2Cpmin,B3N3Cpmin,B3N4Cpmin,B3N5Cpmin,B3N6Cpmin,B3N7Cpmin,B3N8Cpmin,B3N9Cpmin & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNSigCr(9, 3) = RESHAPE( (/ & ! Critical cavitation number + B1N1SigCr,B1N2SigCr,B1N3SigCr,B1N4SigCr,B1N5SigCr,B1N6SigCr,B1N7SigCr,B1N8SigCr,B1N9SigCr, & + B2N1SigCr,B2N2SigCr,B2N3SigCr,B2N4SigCr,B2N5SigCr,B2N6SigCr,B2N7SigCr,B2N8SigCr,B2N9SigCr, & + B3N1SigCr,B3N2SigCr,B3N3SigCr,B3N4SigCr,B3N5SigCr,B3N6SigCr,B3N7SigCr,B3N8SigCr,B3N9SigCr & + /), (/9, 3/) ) + + INTEGER, PARAMETER :: BNSgCav(9, 3) = RESHAPE( (/ & ! Cavitation number + B1N1SgCav,B1N2SgCav,B1N3SgCav,B1N4SgCav,B1N5SgCav,B1N6SgCav,B1N7SgCav,B1N8SgCav,B1N9SgCav, & + B2N1SgCav,B2N2SgCav,B2N3SgCav,B2N4SgCav,B2N5SgCav,B2N6SgCav,B2N7SgCav,B2N8SgCav,B2N9SgCav, & + B3N1SgCav,B3N2SgCav,B3N3SgCav,B3N4SgCav,B3N5SgCav,B3N6SgCav,B3N7SgCav,B3N8SgCav,B3N9SgCav & + /), (/9, 3/) ) + INTEGER, PARAMETER :: BNCx(9, 3) = RESHAPE( (/ & ! normal force (to plane) coefficient B1N1Cx,B1N2Cx,B1N3Cx,B1N4Cx,B1N5Cx,B1N6Cx,B1N7Cx,B1N8Cx,B1N9Cx, & B2N1Cx,B2N2Cx,B2N3Cx,B2N4Cx,B2N5Cx,B2N6Cx,B2N7Cx,B2N8Cx,B2N9Cx, & @@ -1578,11 +1684,16 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, indx, ErrStat, ErrMsg ) m%AllOuts( BNPhi( beta,k) ) = m%BEMT_y%phi(j,k)*R2D m%AllOuts( BNCurve(beta,k) ) = m%Curve(j,k)*R2D - !m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cl(j,k) - !m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cd(j,k) + m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cl(j,k) + m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cd(j,k) + + m%AllOuts( BNCpmin( beta,k) ) = m%BEMT%Cpmin(j,k) + m%AllOuts( BNSigCr( beta,k) ) = m%BEMT%SigmaCavitCrit(j,k) + m%AllOuts( BNSgCav( beta,k) ) = m%BEMT%SigmaCavit(j,k) + cp=cos(m%BEMT_y%phi(j,k)) sp=sin(m%BEMT_y%phi(j,k)) - m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cx(j,k)*cp + m%BEMT_y%Cy(j,k)*sp + m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cx(j,k)*cp + m%BEMT_y%Cy(j,k)*sp m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cx(j,k)*sp - m%BEMT_y%Cy(j,k)*cp m%AllOuts( BNCm( beta,k) ) = m%BEMT_y%Cm(j,k) m%AllOuts( BNCx( beta,k) ) = m%BEMT_y%Cx(j,k) @@ -1908,6 +2019,16 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE CALL ReadVar( UnIn, InputFile, InputFileData%FrozenWake, "FrozenWake", "Assume frozen wake during linearization? (flag)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! CavitCheck - Perform cavitation check? (flag): + CALL ReadVar( UnIn, InputFile, InputFileData%CavitCheck, "CavitCheck", "Perform cavitation check? (flag)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! AddedMass - Include added mass effects? (flag): +! CALL ReadVar( UnIn, InputFile, InputFileData%AddedMass, "AddedMass", "Include added mass effects? (flag)", ErrStat2, ErrMsg2, UnEc) + ! CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! Return on error at end of section IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -1925,11 +2046,26 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE ! KinVisc - Kinematic air viscosity (m^2/s): CALL ReadVar( UnIn, InputFile, InputFileData%KinVisc, "KinVisc", "Kinematic air viscosity (m^2/s)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) - - ! SpdSound - Speed of sound (m/s): + + ! SpdSound - Speed of sound (m/s): CALL ReadVar( UnIn, InputFile, InputFileData%SpdSound, "SpdSound", "Speed of sound (m/s)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + ! Patm - Atmospheric pressure (Pa): + CALL ReadVar( UnIn, InputFile, InputFileData%Patm, "Patm", "Atmospheric pressure (Pa)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + ! Pvap - Vapour pressure of fluid (Pa): + CALL ReadVar( UnIn, InputFile, InputFileData%Pvap, "Pvap", "Vapour pressure of fluid (Pa)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + ! FluidDepth - Water depth above mid-hub height (m) - used for caviation check: + CALL ReadVar( UnIn, InputFile, InputFileData%FluidDepth, "FluidDepth", "Water depth above mid-hub height (MHK only, for cavitation check) (m)", ErrStat2, ErrMsg2, UnEc) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + + ! Return on error at end of section IF ( ErrStat >= AbortErrLev ) THEN CALL Cleanup() @@ -2044,6 +2180,8 @@ SUBROUTINE ReadPrimaryFile( InputFile, InputFileData, ADBlFile, OutFileRoot, UnE ! InCol_Cpmin - The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-): CALL ReadVar( UnIn, InputFile, InputFileData%InCol_Cpmin, "InCol_Cpmin", "The column in the airfoil tables that contains the drag coefficient; use zero if there is no Cpmin column (-)", ErrStat2, ErrMsg2, UnEc) CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) + + IF ( ErrStat >= AbortErrLev ) RETURN ! NumAFfiles - Number of airfoil files used (-): @@ -2578,7 +2716,6 @@ END SUBROUTINE AD_PrintSum !---------------------------------------------------------------------------------------------------------------------------------- - !********************************************************************************************************************************** ! NOTE: The following lines of code were generated by a Matlab script called "Write_ChckOutLst.m" ! using the parameters listed in the "OutListParameters.xlsx" Excel file. Any changes to these @@ -2590,7 +2727,7 @@ END SUBROUTINE AD_PrintSum !! the sign is set to 0 if the channel is invalid. !! It sets assumes the value p%NumOuts has been set before this routine has been called, and it sets the values of p%OutParam here. !! -!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 11-Mar-2016 14:45:58. +!! This routine was generated by Write_ChckOutLst.m using the parameters listed in OutListParameters.xlsx at 16-Feb-2017 15:50:51. SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) !.................................................................................................................................. @@ -2607,6 +2744,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) INTEGER :: ErrStat2 ! temporary (local) error status INTEGER :: I ! Generic loop-counting index + INTEGER :: J ! Generic loop-counting index INTEGER :: INDX ! Index for valid arrays LOGICAL :: CheckOutListAgain ! Flag used to determine if output parameter starting with "M" is valid (or the negative of another parameter) @@ -2614,467 +2752,506 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) CHARACTER(ChanLen) :: OutListTmp ! A string to temporarily hold OutList(I) CHARACTER(*), PARAMETER :: RoutineName = "SetOutParam" - CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(1103) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically + CHARACTER(OutStrLenM1), PARAMETER :: ValidParamAry(1184) = (/ & ! This lists the names of the allowed parameters, which must be sorted alphabetically "B1AZIMUTH","B1N1ALPHA","B1N1AXIND","B1N1CD ","B1N1CL ","B1N1CLRNC","B1N1CM ", & - "B1N1CN ","B1N1CT ","B1N1CURVE","B1N1CX ","B1N1CY ","B1N1DYNP ","B1N1FD ", & - "B1N1FL ","B1N1FN ","B1N1FT ","B1N1FX ","B1N1FY ","B1N1M ","B1N1MM ", & - "B1N1PHI ","B1N1RE ","B1N1STVX ","B1N1STVY ","B1N1STVZ ","B1N1THETA","B1N1TNIND", & - "B1N1VDISX","B1N1VDISY","B1N1VDISZ","B1N1VINDX","B1N1VINDY","B1N1VREL ","B1N1VUNDX", & - "B1N1VUNDY","B1N1VUNDZ","B1N2ALPHA","B1N2AXIND","B1N2CD ","B1N2CL ","B1N2CLRNC", & - "B1N2CM ","B1N2CN ","B1N2CT ","B1N2CURVE","B1N2CX ","B1N2CY ","B1N2DYNP ", & - "B1N2FD ","B1N2FL ","B1N2FN ","B1N2FT ","B1N2FX ","B1N2FY ","B1N2M ", & - "B1N2MM ","B1N2PHI ","B1N2RE ","B1N2STVX ","B1N2STVY ","B1N2STVZ ","B1N2THETA", & - "B1N2TNIND","B1N2VDISX","B1N2VDISY","B1N2VDISZ","B1N2VINDX","B1N2VINDY","B1N2VREL ", & - "B1N2VUNDX","B1N2VUNDY","B1N2VUNDZ","B1N3ALPHA","B1N3AXIND","B1N3CD ","B1N3CL ", & - "B1N3CLRNC","B1N3CM ","B1N3CN ","B1N3CT ","B1N3CURVE","B1N3CX ","B1N3CY ", & + "B1N1CN ","B1N1CPMIN","B1N1CT ","B1N1CURVE","B1N1CX ","B1N1CY ","B1N1DYNP ", & + "B1N1FD ","B1N1FL ","B1N1FN ","B1N1FT ","B1N1FX ","B1N1FY ","B1N1M ", & + "B1N1MM ","B1N1PHI ","B1N1RE ","B1N1SGCAV","B1N1SIGCR","B1N1STVX ","B1N1STVY ", & + "B1N1STVZ ","B1N1THETA","B1N1TNIND","B1N1VDISX","B1N1VDISY","B1N1VDISZ","B1N1VINDX", & + "B1N1VINDY","B1N1VREL ","B1N1VUNDX","B1N1VUNDY","B1N1VUNDZ","B1N2ALPHA","B1N2AXIND", & + "B1N2CD ","B1N2CL ","B1N2CLRNC","B1N2CM ","B1N2CN ","B1N2CPMIN","B1N2CT ", & + "B1N2CURVE","B1N2CX ","B1N2CY ","B1N2DYNP ","B1N2FD ","B1N2FL ","B1N2FN ", & + "B1N2FT ","B1N2FX ","B1N2FY ","B1N2M ","B1N2MM ","B1N2PHI ","B1N2RE ", & + "B1N2SGCAV","B1N2SIGCR","B1N2STVX ","B1N2STVY ","B1N2STVZ ","B1N2THETA","B1N2TNIND", & + "B1N2VDISX","B1N2VDISY","B1N2VDISZ","B1N2VINDX","B1N2VINDY","B1N2VREL ","B1N2VUNDX", & + "B1N2VUNDY","B1N2VUNDZ","B1N3ALPHA","B1N3AXIND","B1N3CD ","B1N3CL ","B1N3CLRNC", & + "B1N3CM ","B1N3CN ","B1N3CPMIN","B1N3CT ","B1N3CURVE","B1N3CX ","B1N3CY ", & "B1N3DYNP ","B1N3FD ","B1N3FL ","B1N3FN ","B1N3FT ","B1N3FX ","B1N3FY ", & - "B1N3M ","B1N3MM ","B1N3PHI ","B1N3RE ","B1N3STVX ","B1N3STVY ","B1N3STVZ ", & - "B1N3THETA","B1N3TNIND","B1N3VDISX","B1N3VDISY","B1N3VDISZ","B1N3VINDX","B1N3VINDY", & - "B1N3VREL ","B1N3VUNDX","B1N3VUNDY","B1N3VUNDZ","B1N4ALPHA","B1N4AXIND","B1N4CD ", & - "B1N4CL ","B1N4CLRNC","B1N4CM ","B1N4CN ","B1N4CT ","B1N4CURVE","B1N4CX ", & - "B1N4CY ","B1N4DYNP ","B1N4FD ","B1N4FL ","B1N4FN ","B1N4FT ","B1N4FX ", & - "B1N4FY ","B1N4M ","B1N4MM ","B1N4PHI ","B1N4RE ","B1N4STVX ","B1N4STVY ", & - "B1N4STVZ ","B1N4THETA","B1N4TNIND","B1N4VDISX","B1N4VDISY","B1N4VDISZ","B1N4VINDX", & - "B1N4VINDY","B1N4VREL ","B1N4VUNDX","B1N4VUNDY","B1N4VUNDZ","B1N5ALPHA","B1N5AXIND", & - "B1N5CD ","B1N5CL ","B1N5CLRNC","B1N5CM ","B1N5CN ","B1N5CT ","B1N5CURVE", & - "B1N5CX ","B1N5CY ","B1N5DYNP ","B1N5FD ","B1N5FL ","B1N5FN ","B1N5FT ", & - "B1N5FX ","B1N5FY ","B1N5M ","B1N5MM ","B1N5PHI ","B1N5RE ","B1N5STVX ", & - "B1N5STVY ","B1N5STVZ ","B1N5THETA","B1N5TNIND","B1N5VDISX","B1N5VDISY","B1N5VDISZ", & - "B1N5VINDX","B1N5VINDY","B1N5VREL ","B1N5VUNDX","B1N5VUNDY","B1N5VUNDZ","B1N6ALPHA", & - "B1N6AXIND","B1N6CD ","B1N6CL ","B1N6CLRNC","B1N6CM ","B1N6CN ","B1N6CT ", & - "B1N6CURVE","B1N6CX ","B1N6CY ","B1N6DYNP ","B1N6FD ","B1N6FL ","B1N6FN ", & - "B1N6FT ","B1N6FX ","B1N6FY ","B1N6M ","B1N6MM ","B1N6PHI ","B1N6RE ", & - "B1N6STVX ","B1N6STVY ","B1N6STVZ ","B1N6THETA","B1N6TNIND","B1N6VDISX","B1N6VDISY", & - "B1N6VDISZ","B1N6VINDX","B1N6VINDY","B1N6VREL ","B1N6VUNDX","B1N6VUNDY","B1N6VUNDZ", & - "B1N7ALPHA","B1N7AXIND","B1N7CD ","B1N7CL ","B1N7CLRNC","B1N7CM ","B1N7CN ", & - "B1N7CT ","B1N7CURVE","B1N7CX ","B1N7CY ","B1N7DYNP ","B1N7FD ","B1N7FL ", & - "B1N7FN ","B1N7FT ","B1N7FX ","B1N7FY ","B1N7M ","B1N7MM ","B1N7PHI ", & - "B1N7RE ","B1N7STVX ","B1N7STVY ","B1N7STVZ ","B1N7THETA","B1N7TNIND","B1N7VDISX", & + "B1N3M ","B1N3MM ","B1N3PHI ","B1N3RE ","B1N3SGCAV","B1N3SIGCR","B1N3STVX ", & + "B1N3STVY ","B1N3STVZ ","B1N3THETA","B1N3TNIND","B1N3VDISX","B1N3VDISY","B1N3VDISZ", & + "B1N3VINDX","B1N3VINDY","B1N3VREL ","B1N3VUNDX","B1N3VUNDY","B1N3VUNDZ","B1N4ALPHA", & + "B1N4AXIND","B1N4CD ","B1N4CL ","B1N4CLRNC","B1N4CM ","B1N4CN ","B1N4CPMIN", & + "B1N4CT ","B1N4CURVE","B1N4CX ","B1N4CY ","B1N4DYNP ","B1N4FD ","B1N4FL ", & + "B1N4FN ","B1N4FT ","B1N4FX ","B1N4FY ","B1N4M ","B1N4MM ","B1N4PHI ", & + "B1N4RE ","B1N4SGCAV","B1N4SIGCR","B1N4STVX ","B1N4STVY ","B1N4STVZ ","B1N4THETA", & + "B1N4TNIND","B1N4VDISX","B1N4VDISY","B1N4VDISZ","B1N4VINDX","B1N4VINDY","B1N4VREL ", & + "B1N4VUNDX","B1N4VUNDY","B1N4VUNDZ","B1N5ALPHA","B1N5AXIND","B1N5CD ","B1N5CL ", & + "B1N5CLRNC","B1N5CM ","B1N5CN ","B1N5CPMIN","B1N5CT ","B1N5CURVE","B1N5CX ", & + "B1N5CY ","B1N5DYNP ","B1N5FD ","B1N5FL ","B1N5FN ","B1N5FT ","B1N5FX ", & + "B1N5FY ","B1N5M ","B1N5MM ","B1N5PHI ","B1N5RE ","B1N5SGCAV","B1N5SIGCR", & + "B1N5STVX ","B1N5STVY ","B1N5STVZ ","B1N5THETA","B1N5TNIND","B1N5VDISX","B1N5VDISY", & + "B1N5VDISZ","B1N5VINDX","B1N5VINDY","B1N5VREL ","B1N5VUNDX","B1N5VUNDY","B1N5VUNDZ", & + "B1N6ALPHA","B1N6AXIND","B1N6CD ","B1N6CL ","B1N6CLRNC","B1N6CM ","B1N6CN ", & + "B1N6CPMIN","B1N6CT ","B1N6CURVE","B1N6CX ","B1N6CY ","B1N6DYNP ","B1N6FD ", & + "B1N6FL ","B1N6FN ","B1N6FT ","B1N6FX ","B1N6FY ","B1N6M ","B1N6MM ", & + "B1N6PHI ","B1N6RE ","B1N6SGCAV","B1N6SIGCR","B1N6STVX ","B1N6STVY ","B1N6STVZ ", & + "B1N6THETA","B1N6TNIND","B1N6VDISX","B1N6VDISY","B1N6VDISZ","B1N6VINDX","B1N6VINDY", & + "B1N6VREL ","B1N6VUNDX","B1N6VUNDY","B1N6VUNDZ","B1N7ALPHA","B1N7AXIND","B1N7CD ", & + "B1N7CL ","B1N7CLRNC","B1N7CM ","B1N7CN ","B1N7CPMIN","B1N7CT ","B1N7CURVE", & + "B1N7CX ","B1N7CY ","B1N7DYNP ","B1N7FD ","B1N7FL ","B1N7FN ","B1N7FT ", & + "B1N7FX ","B1N7FY ","B1N7M ","B1N7MM ","B1N7PHI ","B1N7RE ","B1N7SGCAV", & + "B1N7SIGCR","B1N7STVX ","B1N7STVY ","B1N7STVZ ","B1N7THETA","B1N7TNIND","B1N7VDISX", & "B1N7VDISY","B1N7VDISZ","B1N7VINDX","B1N7VINDY","B1N7VREL ","B1N7VUNDX","B1N7VUNDY", & "B1N7VUNDZ","B1N8ALPHA","B1N8AXIND","B1N8CD ","B1N8CL ","B1N8CLRNC","B1N8CM ", & - "B1N8CN ","B1N8CT ","B1N8CURVE","B1N8CX ","B1N8CY ","B1N8DYNP ","B1N8FD ", & - "B1N8FL ","B1N8FN ","B1N8FT ","B1N8FX ","B1N8FY ","B1N8M ","B1N8MM ", & - "B1N8PHI ","B1N8RE ","B1N8STVX ","B1N8STVY ","B1N8STVZ ","B1N8THETA","B1N8TNIND", & - "B1N8VDISX","B1N8VDISY","B1N8VDISZ","B1N8VINDX","B1N8VINDY","B1N8VREL ","B1N8VUNDX", & - "B1N8VUNDY","B1N8VUNDZ","B1N9ALPHA","B1N9AXIND","B1N9CD ","B1N9CL ","B1N9CLRNC", & - "B1N9CM ","B1N9CN ","B1N9CT ","B1N9CURVE","B1N9CX ","B1N9CY ","B1N9DYNP ", & - "B1N9FD ","B1N9FL ","B1N9FN ","B1N9FT ","B1N9FX ","B1N9FY ","B1N9M ", & - "B1N9MM ","B1N9PHI ","B1N9RE ","B1N9STVX ","B1N9STVY ","B1N9STVZ ","B1N9THETA", & - "B1N9TNIND","B1N9VDISX","B1N9VDISY","B1N9VDISZ","B1N9VINDX","B1N9VINDY","B1N9VREL ", & - "B1N9VUNDX","B1N9VUNDY","B1N9VUNDZ","B1PITCH ","B2AZIMUTH","B2N1ALPHA","B2N1AXIND", & - "B2N1CD ","B2N1CL ","B2N1CLRNC","B2N1CM ","B2N1CN ","B2N1CT ","B2N1CURVE", & + "B1N8CN ","B1N8CPMIN","B1N8CT ","B1N8CURVE","B1N8CX ","B1N8CY ","B1N8DYNP ", & + "B1N8FD ","B1N8FL ","B1N8FN ","B1N8FT ","B1N8FX ","B1N8FY ","B1N8M ", & + "B1N8MM ","B1N8PHI ","B1N8RE ","B1N8SGCAV","B1N8SIGCR","B1N8STVX ","B1N8STVY ", & + "B1N8STVZ ","B1N8THETA","B1N8TNIND","B1N8VDISX","B1N8VDISY","B1N8VDISZ","B1N8VINDX", & + "B1N8VINDY","B1N8VREL ","B1N8VUNDX","B1N8VUNDY","B1N8VUNDZ","B1N9ALPHA","B1N9AXIND", & + "B1N9CD ","B1N9CL ","B1N9CLRNC","B1N9CM ","B1N9CN ","B1N9CPMIN","B1N9CT ", & + "B1N9CURVE","B1N9CX ","B1N9CY ","B1N9DYNP ","B1N9FD ","B1N9FL ","B1N9FN ", & + "B1N9FT ","B1N9FX ","B1N9FY ","B1N9M ","B1N9MM ","B1N9PHI ","B1N9RE ", & + "B1N9SGCAV","B1N9SIGCR","B1N9STVX ","B1N9STVY ","B1N9STVZ ","B1N9THETA","B1N9TNIND", & + "B1N9VDISX","B1N9VDISY","B1N9VDISZ","B1N9VINDX","B1N9VINDY","B1N9VREL ","B1N9VUNDX", & + "B1N9VUNDY","B1N9VUNDZ","B1PITCH ","B2AZIMUTH","B2N1ALPHA","B2N1AXIND","B2N1CD ", & + "B2N1CL ","B2N1CLRNC","B2N1CM ","B2N1CN ","B2N1CPMIN","B2N1CT ","B2N1CURVE", & "B2N1CX ","B2N1CY ","B2N1DYNP ","B2N1FD ","B2N1FL ","B2N1FN ","B2N1FT ", & - "B2N1FX ","B2N1FY ","B2N1M ","B2N1MM ","B2N1PHI ","B2N1RE ","B2N1STVX ", & - "B2N1STVY ","B2N1STVZ ","B2N1THETA","B2N1TNIND","B2N1VDISX","B2N1VDISY","B2N1VDISZ", & - "B2N1VINDX","B2N1VINDY","B2N1VREL ","B2N1VUNDX","B2N1VUNDY","B2N1VUNDZ","B2N2ALPHA", & - "B2N2AXIND","B2N2CD ","B2N2CL ","B2N2CLRNC","B2N2CM ","B2N2CN ","B2N2CT ", & - "B2N2CURVE","B2N2CX ","B2N2CY ","B2N2DYNP ","B2N2FD ","B2N2FL ","B2N2FN ", & - "B2N2FT ","B2N2FX ","B2N2FY ","B2N2M ","B2N2MM ","B2N2PHI ","B2N2RE ", & - "B2N2STVX ","B2N2STVY ","B2N2STVZ ","B2N2THETA","B2N2TNIND","B2N2VDISX","B2N2VDISY", & - "B2N2VDISZ","B2N2VINDX","B2N2VINDY","B2N2VREL ","B2N2VUNDX","B2N2VUNDY","B2N2VUNDZ", & - "B2N3ALPHA","B2N3AXIND","B2N3CD ","B2N3CL ","B2N3CLRNC","B2N3CM ","B2N3CN ", & - "B2N3CT ","B2N3CURVE","B2N3CX ","B2N3CY ","B2N3DYNP ","B2N3FD ","B2N3FL ", & - "B2N3FN ","B2N3FT ","B2N3FX ","B2N3FY ","B2N3M ","B2N3MM ","B2N3PHI ", & - "B2N3RE ","B2N3STVX ","B2N3STVY ","B2N3STVZ ","B2N3THETA","B2N3TNIND","B2N3VDISX", & - "B2N3VDISY","B2N3VDISZ","B2N3VINDX","B2N3VINDY","B2N3VREL ","B2N3VUNDX","B2N3VUNDY", & - "B2N3VUNDZ","B2N4ALPHA","B2N4AXIND","B2N4CD ","B2N4CL ","B2N4CLRNC","B2N4CM ", & - "B2N4CN ","B2N4CT ","B2N4CURVE","B2N4CX ","B2N4CY ","B2N4DYNP ","B2N4FD ", & - "B2N4FL ","B2N4FN ","B2N4FT ","B2N4FX ","B2N4FY ","B2N4M ","B2N4MM ", & - "B2N4PHI ","B2N4RE ","B2N4STVX ","B2N4STVY ","B2N4STVZ ","B2N4THETA","B2N4TNIND", & - "B2N4VDISX","B2N4VDISY","B2N4VDISZ","B2N4VINDX","B2N4VINDY","B2N4VREL ","B2N4VUNDX", & - "B2N4VUNDY","B2N4VUNDZ","B2N5ALPHA","B2N5AXIND","B2N5CD ","B2N5CL ","B2N5CLRNC", & - "B2N5CM ","B2N5CN ","B2N5CT ","B2N5CURVE","B2N5CX ","B2N5CY ","B2N5DYNP ", & - "B2N5FD ","B2N5FL ","B2N5FN ","B2N5FT ","B2N5FX ","B2N5FY ","B2N5M ", & - "B2N5MM ","B2N5PHI ","B2N5RE ","B2N5STVX ","B2N5STVY ","B2N5STVZ ","B2N5THETA", & + "B2N1FX ","B2N1FY ","B2N1M ","B2N1MM ","B2N1PHI ","B2N1RE ","B2N1SGCAV", & + "B2N1SIGCR","B2N1STVX ","B2N1STVY ","B2N1STVZ ","B2N1THETA","B2N1TNIND","B2N1VDISX", & + "B2N1VDISY","B2N1VDISZ","B2N1VINDX","B2N1VINDY","B2N1VREL ","B2N1VUNDX","B2N1VUNDY", & + "B2N1VUNDZ","B2N2ALPHA","B2N2AXIND","B2N2CD ","B2N2CL ","B2N2CLRNC","B2N2CM ", & + "B2N2CN ","B2N2CPMIN","B2N2CT ","B2N2CURVE","B2N2CX ","B2N2CY ","B2N2DYNP ", & + "B2N2FD ","B2N2FL ","B2N2FN ","B2N2FT ","B2N2FX ","B2N2FY ","B2N2M ", & + "B2N2MM ","B2N2PHI ","B2N2RE ","B2N2SGCAV","B2N2SIGCR","B2N2STVX ","B2N2STVY ", & + "B2N2STVZ ","B2N2THETA","B2N2TNIND","B2N2VDISX","B2N2VDISY","B2N2VDISZ","B2N2VINDX", & + "B2N2VINDY","B2N2VREL ","B2N2VUNDX","B2N2VUNDY","B2N2VUNDZ","B2N3ALPHA","B2N3AXIND", & + "B2N3CD ","B2N3CL ","B2N3CLRNC","B2N3CM ","B2N3CN ","B2N3CPMIN","B2N3CT ", & + "B2N3CURVE","B2N3CX ","B2N3CY ","B2N3DYNP ","B2N3FD ","B2N3FL ","B2N3FN ", & + "B2N3FT ","B2N3FX ","B2N3FY ","B2N3M ","B2N3MM ","B2N3PHI ","B2N3RE ", & + "B2N3SGCAV","B2N3SIGCR","B2N3STVX ","B2N3STVY ","B2N3STVZ ","B2N3THETA","B2N3TNIND", & + "B2N3VDISX","B2N3VDISY","B2N3VDISZ","B2N3VINDX","B2N3VINDY","B2N3VREL ","B2N3VUNDX", & + "B2N3VUNDY","B2N3VUNDZ","B2N4ALPHA","B2N4AXIND","B2N4CD ","B2N4CL ","B2N4CLRNC", & + "B2N4CM ","B2N4CN ","B2N4CPMIN","B2N4CT ","B2N4CURVE","B2N4CX ","B2N4CY ", & + "B2N4DYNP ","B2N4FD ","B2N4FL ","B2N4FN ","B2N4FT ","B2N4FX ","B2N4FY ", & + "B2N4M ","B2N4MM ","B2N4PHI ","B2N4RE ","B2N4SGCAV","B2N4SIGCR","B2N4STVX ", & + "B2N4STVY ","B2N4STVZ ","B2N4THETA","B2N4TNIND","B2N4VDISX","B2N4VDISY","B2N4VDISZ", & + "B2N4VINDX","B2N4VINDY","B2N4VREL ","B2N4VUNDX","B2N4VUNDY","B2N4VUNDZ","B2N5ALPHA", & + "B2N5AXIND","B2N5CD ","B2N5CL ","B2N5CLRNC","B2N5CM ","B2N5CN ","B2N5CPMIN", & + "B2N5CT ","B2N5CURVE","B2N5CX ","B2N5CY ","B2N5DYNP ","B2N5FD ","B2N5FL ", & + "B2N5FN ","B2N5FT ","B2N5FX ","B2N5FY ","B2N5M ","B2N5MM ","B2N5PHI ", & + "B2N5RE ","B2N5SGCAV","B2N5SIGCR","B2N5STVX ","B2N5STVY ","B2N5STVZ ","B2N5THETA", & "B2N5TNIND","B2N5VDISX","B2N5VDISY","B2N5VDISZ","B2N5VINDX","B2N5VINDY","B2N5VREL ", & "B2N5VUNDX","B2N5VUNDY","B2N5VUNDZ","B2N6ALPHA","B2N6AXIND","B2N6CD ","B2N6CL ", & - "B2N6CLRNC","B2N6CM ","B2N6CN ","B2N6CT ","B2N6CURVE","B2N6CX ","B2N6CY ", & - "B2N6DYNP ","B2N6FD ","B2N6FL ","B2N6FN ","B2N6FT ","B2N6FX ","B2N6FY ", & - "B2N6M ","B2N6MM ","B2N6PHI ","B2N6RE ","B2N6STVX ","B2N6STVY ","B2N6STVZ ", & - "B2N6THETA","B2N6TNIND","B2N6VDISX","B2N6VDISY","B2N6VDISZ","B2N6VINDX","B2N6VINDY", & - "B2N6VREL ","B2N6VUNDX","B2N6VUNDY","B2N6VUNDZ","B2N7ALPHA","B2N7AXIND","B2N7CD ", & - "B2N7CL ","B2N7CLRNC","B2N7CM ","B2N7CN ","B2N7CT ","B2N7CURVE","B2N7CX ", & - "B2N7CY ","B2N7DYNP ","B2N7FD ","B2N7FL ","B2N7FN ","B2N7FT ","B2N7FX ", & - "B2N7FY ","B2N7M ","B2N7MM ","B2N7PHI ","B2N7RE ","B2N7STVX ","B2N7STVY ", & - "B2N7STVZ ","B2N7THETA","B2N7TNIND","B2N7VDISX","B2N7VDISY","B2N7VDISZ","B2N7VINDX", & - "B2N7VINDY","B2N7VREL ","B2N7VUNDX","B2N7VUNDY","B2N7VUNDZ","B2N8ALPHA","B2N8AXIND", & - "B2N8CD ","B2N8CL ","B2N8CLRNC","B2N8CM ","B2N8CN ","B2N8CT ","B2N8CURVE", & + "B2N6CLRNC","B2N6CM ","B2N6CN ","B2N6CPMIN","B2N6CT ","B2N6CURVE","B2N6CX ", & + "B2N6CY ","B2N6DYNP ","B2N6FD ","B2N6FL ","B2N6FN ","B2N6FT ","B2N6FX ", & + "B2N6FY ","B2N6M ","B2N6MM ","B2N6PHI ","B2N6RE ","B2N6SGCAV","B2N6SIGCR", & + "B2N6STVX ","B2N6STVY ","B2N6STVZ ","B2N6THETA","B2N6TNIND","B2N6VDISX","B2N6VDISY", & + "B2N6VDISZ","B2N6VINDX","B2N6VINDY","B2N6VREL ","B2N6VUNDX","B2N6VUNDY","B2N6VUNDZ", & + "B2N7ALPHA","B2N7AXIND","B2N7CD ","B2N7CL ","B2N7CLRNC","B2N7CM ","B2N7CN ", & + "B2N7CPMIN","B2N7CT ","B2N7CURVE","B2N7CX ","B2N7CY ","B2N7DYNP ","B2N7FD ", & + "B2N7FL ","B2N7FN ","B2N7FT ","B2N7FX ","B2N7FY ","B2N7M ","B2N7MM ", & + "B2N7PHI ","B2N7RE ","B2N7SGCAV","B2N7SIGCR","B2N7STVX ","B2N7STVY ","B2N7STVZ ", & + "B2N7THETA","B2N7TNIND","B2N7VDISX","B2N7VDISY","B2N7VDISZ","B2N7VINDX","B2N7VINDY", & + "B2N7VREL ","B2N7VUNDX","B2N7VUNDY","B2N7VUNDZ","B2N8ALPHA","B2N8AXIND","B2N8CD ", & + "B2N8CL ","B2N8CLRNC","B2N8CM ","B2N8CN ","B2N8CPMIN","B2N8CT ","B2N8CURVE", & "B2N8CX ","B2N8CY ","B2N8DYNP ","B2N8FD ","B2N8FL ","B2N8FN ","B2N8FT ", & - "B2N8FX ","B2N8FY ","B2N8M ","B2N8MM ","B2N8PHI ","B2N8RE ","B2N8STVX ", & - "B2N8STVY ","B2N8STVZ ","B2N8THETA","B2N8TNIND","B2N8VDISX","B2N8VDISY","B2N8VDISZ", & - "B2N8VINDX","B2N8VINDY","B2N8VREL ","B2N8VUNDX","B2N8VUNDY","B2N8VUNDZ","B2N9ALPHA", & - "B2N9AXIND","B2N9CD ","B2N9CL ","B2N9CLRNC","B2N9CM ","B2N9CN ","B2N9CT ", & - "B2N9CURVE","B2N9CX ","B2N9CY ","B2N9DYNP ","B2N9FD ","B2N9FL ","B2N9FN ", & - "B2N9FT ","B2N9FX ","B2N9FY ","B2N9M ","B2N9MM ","B2N9PHI ","B2N9RE ", & - "B2N9STVX ","B2N9STVY ","B2N9STVZ ","B2N9THETA","B2N9TNIND","B2N9VDISX","B2N9VDISY", & - "B2N9VDISZ","B2N9VINDX","B2N9VINDY","B2N9VREL ","B2N9VUNDX","B2N9VUNDY","B2N9VUNDZ", & - "B2PITCH ","B3AZIMUTH","B3N1ALPHA","B3N1AXIND","B3N1CD ","B3N1CL ","B3N1CLRNC", & - "B3N1CM ","B3N1CN ","B3N1CT ","B3N1CURVE","B3N1CX ","B3N1CY ","B3N1DYNP ", & - "B3N1FD ","B3N1FL ","B3N1FN ","B3N1FT ","B3N1FX ","B3N1FY ","B3N1M ", & - "B3N1MM ","B3N1PHI ","B3N1RE ","B3N1STVX ","B3N1STVY ","B3N1STVZ ","B3N1THETA", & - "B3N1TNIND","B3N1VDISX","B3N1VDISY","B3N1VDISZ","B3N1VINDX","B3N1VINDY","B3N1VREL ", & - "B3N1VUNDX","B3N1VUNDY","B3N1VUNDZ","B3N2ALPHA","B3N2AXIND","B3N2CD ","B3N2CL ", & - "B3N2CLRNC","B3N2CM ","B3N2CN ","B3N2CT ","B3N2CURVE","B3N2CX ","B3N2CY ", & - "B3N2DYNP ","B3N2FD ","B3N2FL ","B3N2FN ","B3N2FT ","B3N2FX ","B3N2FY ", & - "B3N2M ","B3N2MM ","B3N2PHI ","B3N2RE ","B3N2STVX ","B3N2STVY ","B3N2STVZ ", & - "B3N2THETA","B3N2TNIND","B3N2VDISX","B3N2VDISY","B3N2VDISZ","B3N2VINDX","B3N2VINDY", & - "B3N2VREL ","B3N2VUNDX","B3N2VUNDY","B3N2VUNDZ","B3N3ALPHA","B3N3AXIND","B3N3CD ", & - "B3N3CL ","B3N3CLRNC","B3N3CM ","B3N3CN ","B3N3CT ","B3N3CURVE","B3N3CX ", & - "B3N3CY ","B3N3DYNP ","B3N3FD ","B3N3FL ","B3N3FN ","B3N3FT ","B3N3FX ", & - "B3N3FY ","B3N3M ","B3N3MM ","B3N3PHI ","B3N3RE ","B3N3STVX ","B3N3STVY ", & + "B2N8FX ","B2N8FY ","B2N8M ","B2N8MM ","B2N8PHI ","B2N8RE ","B2N8SGCAV", & + "B2N8SIGCR","B2N8STVX ","B2N8STVY ","B2N8STVZ ","B2N8THETA","B2N8TNIND","B2N8VDISX", & + "B2N8VDISY","B2N8VDISZ","B2N8VINDX","B2N8VINDY","B2N8VREL ","B2N8VUNDX","B2N8VUNDY", & + "B2N8VUNDZ","B2N9ALPHA","B2N9AXIND","B2N9CD ","B2N9CL ","B2N9CLRNC","B2N9CM ", & + "B2N9CN ","B2N9CPMIN","B2N9CT ","B2N9CURVE","B2N9CX ","B2N9CY ","B2N9DYNP ", & + "B2N9FD ","B2N9FL ","B2N9FN ","B2N9FT ","B2N9FX ","B2N9FY ","B2N9M ", & + "B2N9MM ","B2N9PHI ","B2N9RE ","B2N9SGCAV","B2N9SIGCR","B2N9STVX ","B2N9STVY ", & + "B2N9STVZ ","B2N9THETA","B2N9TNIND","B2N9VDISX","B2N9VDISY","B2N9VDISZ","B2N9VINDX", & + "B2N9VINDY","B2N9VREL ","B2N9VUNDX","B2N9VUNDY","B2N9VUNDZ","B2PITCH ","B3AZIMUTH", & + "B3N1ALPHA","B3N1AXIND","B3N1CD ","B3N1CL ","B3N1CLRNC","B3N1CM ","B3N1CN ", & + "B3N1CPMIN","B3N1CT ","B3N1CURVE","B3N1CX ","B3N1CY ","B3N1DYNP ","B3N1FD ", & + "B3N1FL ","B3N1FN ","B3N1FT ","B3N1FX ","B3N1FY ","B3N1M ","B3N1MM ", & + "B3N1PHI ","B3N1RE ","B3N1SGCAV","B3N1SIGCR","B3N1STVX ","B3N1STVY ","B3N1STVZ ", & + "B3N1THETA","B3N1TNIND","B3N1VDISX","B3N1VDISY","B3N1VDISZ","B3N1VINDX","B3N1VINDY", & + "B3N1VREL ","B3N1VUNDX","B3N1VUNDY","B3N1VUNDZ","B3N2ALPHA","B3N2AXIND","B3N2CD ", & + "B3N2CL ","B3N2CLRNC","B3N2CM ","B3N2CN ","B3N2CPMIN","B3N2CT ","B3N2CURVE", & + "B3N2CX ","B3N2CY ","B3N2DYNP ","B3N2FD ","B3N2FL ","B3N2FN ","B3N2FT ", & + "B3N2FX ","B3N2FY ","B3N2M ","B3N2MM ","B3N2PHI ","B3N2RE ","B3N2SGCAV", & + "B3N2SIGCR","B3N2STVX ","B3N2STVY ","B3N2STVZ ","B3N2THETA","B3N2TNIND","B3N2VDISX", & + "B3N2VDISY","B3N2VDISZ","B3N2VINDX","B3N2VINDY","B3N2VREL ","B3N2VUNDX","B3N2VUNDY", & + "B3N2VUNDZ","B3N3ALPHA","B3N3AXIND","B3N3CD ","B3N3CL ","B3N3CLRNC","B3N3CM ", & + "B3N3CN ","B3N3CPMIN","B3N3CT ","B3N3CURVE","B3N3CX ","B3N3CY ","B3N3DYNP ", & + "B3N3FD ","B3N3FL ","B3N3FN ","B3N3FT ","B3N3FX ","B3N3FY ","B3N3M ", & + "B3N3MM ","B3N3PHI ","B3N3RE ","B3N3SGCAV","B3N3SIGCR","B3N3STVX ","B3N3STVY ", & "B3N3STVZ ","B3N3THETA","B3N3TNIND","B3N3VDISX","B3N3VDISY","B3N3VDISZ","B3N3VINDX", & "B3N3VINDY","B3N3VREL ","B3N3VUNDX","B3N3VUNDY","B3N3VUNDZ","B3N4ALPHA","B3N4AXIND", & - "B3N4CD ","B3N4CL ","B3N4CLRNC","B3N4CM ","B3N4CN ","B3N4CT ","B3N4CURVE", & - "B3N4CX ","B3N4CY ","B3N4DYNP ","B3N4FD ","B3N4FL ","B3N4FN ","B3N4FT ", & - "B3N4FX ","B3N4FY ","B3N4M ","B3N4MM ","B3N4PHI ","B3N4RE ","B3N4STVX ", & - "B3N4STVY ","B3N4STVZ ","B3N4THETA","B3N4TNIND","B3N4VDISX","B3N4VDISY","B3N4VDISZ", & - "B3N4VINDX","B3N4VINDY","B3N4VREL ","B3N4VUNDX","B3N4VUNDY","B3N4VUNDZ","B3N5ALPHA", & - "B3N5AXIND","B3N5CD ","B3N5CL ","B3N5CLRNC","B3N5CM ","B3N5CN ","B3N5CT ", & - "B3N5CURVE","B3N5CX ","B3N5CY ","B3N5DYNP ","B3N5FD ","B3N5FL ","B3N5FN ", & - "B3N5FT ","B3N5FX ","B3N5FY ","B3N5M ","B3N5MM ","B3N5PHI ","B3N5RE ", & - "B3N5STVX ","B3N5STVY ","B3N5STVZ ","B3N5THETA","B3N5TNIND","B3N5VDISX","B3N5VDISY", & - "B3N5VDISZ","B3N5VINDX","B3N5VINDY","B3N5VREL ","B3N5VUNDX","B3N5VUNDY","B3N5VUNDZ", & - "B3N6ALPHA","B3N6AXIND","B3N6CD ","B3N6CL ","B3N6CLRNC","B3N6CM ","B3N6CN ", & + "B3N4CD ","B3N4CL ","B3N4CLRNC","B3N4CM ","B3N4CN ","B3N4CPMIN","B3N4CT ", & + "B3N4CURVE","B3N4CX ","B3N4CY ","B3N4DYNP ","B3N4FD ","B3N4FL ","B3N4FN ", & + "B3N4FT ","B3N4FX ","B3N4FY ","B3N4M ","B3N4MM ","B3N4PHI ","B3N4RE ", & + "B3N4SGCAV","B3N4SIGCR","B3N4STVX ","B3N4STVY ","B3N4STVZ ","B3N4THETA","B3N4TNIND", & + "B3N4VDISX","B3N4VDISY","B3N4VDISZ","B3N4VINDX","B3N4VINDY","B3N4VREL ","B3N4VUNDX", & + "B3N4VUNDY","B3N4VUNDZ","B3N5ALPHA","B3N5AXIND","B3N5CD ","B3N5CL ","B3N5CLRNC", & + "B3N5CM ","B3N5CN ","B3N5CPMIN","B3N5CT ","B3N5CURVE","B3N5CX ","B3N5CY ", & + "B3N5DYNP ","B3N5FD ","B3N5FL ","B3N5FN ","B3N5FT ","B3N5FX ","B3N5FY ", & + "B3N5M ","B3N5MM ","B3N5PHI ","B3N5RE ","B3N5SGCAV","B3N5SIGCR","B3N5STVX ", & + "B3N5STVY ","B3N5STVZ ","B3N5THETA","B3N5TNIND","B3N5VDISX","B3N5VDISY","B3N5VDISZ", & + "B3N5VINDX","B3N5VINDY","B3N5VREL ","B3N5VUNDX","B3N5VUNDY","B3N5VUNDZ","B3N6ALPHA", & + "B3N6AXIND","B3N6CD ","B3N6CL ","B3N6CLRNC","B3N6CM ","B3N6CN ","B3N6CPMIN", & "B3N6CT ","B3N6CURVE","B3N6CX ","B3N6CY ","B3N6DYNP ","B3N6FD ","B3N6FL ", & "B3N6FN ","B3N6FT ","B3N6FX ","B3N6FY ","B3N6M ","B3N6MM ","B3N6PHI ", & - "B3N6RE ","B3N6STVX ","B3N6STVY ","B3N6STVZ ","B3N6THETA","B3N6TNIND","B3N6VDISX", & - "B3N6VDISY","B3N6VDISZ","B3N6VINDX","B3N6VINDY","B3N6VREL ","B3N6VUNDX","B3N6VUNDY", & - "B3N6VUNDZ","B3N7ALPHA","B3N7AXIND","B3N7CD ","B3N7CL ","B3N7CLRNC","B3N7CM ", & - "B3N7CN ","B3N7CT ","B3N7CURVE","B3N7CX ","B3N7CY ","B3N7DYNP ","B3N7FD ", & - "B3N7FL ","B3N7FN ","B3N7FT ","B3N7FX ","B3N7FY ","B3N7M ","B3N7MM ", & - "B3N7PHI ","B3N7RE ","B3N7STVX ","B3N7STVY ","B3N7STVZ ","B3N7THETA","B3N7TNIND", & - "B3N7VDISX","B3N7VDISY","B3N7VDISZ","B3N7VINDX","B3N7VINDY","B3N7VREL ","B3N7VUNDX", & - "B3N7VUNDY","B3N7VUNDZ","B3N8ALPHA","B3N8AXIND","B3N8CD ","B3N8CL ","B3N8CLRNC", & - "B3N8CM ","B3N8CN ","B3N8CT ","B3N8CURVE","B3N8CX ","B3N8CY ","B3N8DYNP ", & - "B3N8FD ","B3N8FL ","B3N8FN ","B3N8FT ","B3N8FX ","B3N8FY ","B3N8M ", & - "B3N8MM ","B3N8PHI ","B3N8RE ","B3N8STVX ","B3N8STVY ","B3N8STVZ ","B3N8THETA", & - "B3N8TNIND","B3N8VDISX","B3N8VDISY","B3N8VDISZ","B3N8VINDX","B3N8VINDY","B3N8VREL ", & - "B3N8VUNDX","B3N8VUNDY","B3N8VUNDZ","B3N9ALPHA","B3N9AXIND","B3N9CD ","B3N9CL ", & - "B3N9CLRNC","B3N9CM ","B3N9CN ","B3N9CT ","B3N9CURVE","B3N9CX ","B3N9CY ", & - "B3N9DYNP ","B3N9FD ","B3N9FL ","B3N9FN ","B3N9FT ","B3N9FX ","B3N9FY ", & - "B3N9M ","B3N9MM ","B3N9PHI ","B3N9RE ","B3N9STVX ","B3N9STVY ","B3N9STVZ ", & - "B3N9THETA","B3N9TNIND","B3N9VDISX","B3N9VDISY","B3N9VDISZ","B3N9VINDX","B3N9VINDY", & - "B3N9VREL ","B3N9VUNDX","B3N9VUNDY","B3N9VUNDZ","B3PITCH ","RTAEROCP ","RTAEROCQ ", & - "RTAEROCT ","RTAEROFXH","RTAEROFYH","RTAEROFZH","RTAEROMXH","RTAEROMYH","RTAEROMZH", & - "RTAEROPWR","RTAREA ","RTSKEW ","RTSPEED ","RTTSR ","RTVAVGXH ","RTVAVGYH ", & - "RTVAVGZH ","TWN1DYNP ","TWN1FDX ","TWN1FDY ","TWN1M ","TWN1RE ","TWN1STVX ", & - "TWN1STVY ","TWN1STVZ ","TWN1VREL ","TWN1VUNDX","TWN1VUNDY","TWN1VUNDZ","TWN2DYNP ", & - "TWN2FDX ","TWN2FDY ","TWN2M ","TWN2RE ","TWN2STVX ","TWN2STVY ","TWN2STVZ ", & - "TWN2VREL ","TWN2VUNDX","TWN2VUNDY","TWN2VUNDZ","TWN3DYNP ","TWN3FDX ","TWN3FDY ", & - "TWN3M ","TWN3RE ","TWN3STVX ","TWN3STVY ","TWN3STVZ ","TWN3VREL ","TWN3VUNDX", & - "TWN3VUNDY","TWN3VUNDZ","TWN4DYNP ","TWN4FDX ","TWN4FDY ","TWN4M ","TWN4RE ", & - "TWN4STVX ","TWN4STVY ","TWN4STVZ ","TWN4VREL ","TWN4VUNDX","TWN4VUNDY","TWN4VUNDZ", & - "TWN5DYNP ","TWN5FDX ","TWN5FDY ","TWN5M ","TWN5RE ","TWN5STVX ","TWN5STVY ", & - "TWN5STVZ ","TWN5VREL ","TWN5VUNDX","TWN5VUNDY","TWN5VUNDZ","TWN6DYNP ","TWN6FDX ", & - "TWN6FDY ","TWN6M ","TWN6RE ","TWN6STVX ","TWN6STVY ","TWN6STVZ ","TWN6VREL ", & - "TWN6VUNDX","TWN6VUNDY","TWN6VUNDZ","TWN7DYNP ","TWN7FDX ","TWN7FDY ","TWN7M ", & - "TWN7RE ","TWN7STVX ","TWN7STVY ","TWN7STVZ ","TWN7VREL ","TWN7VUNDX","TWN7VUNDY", & - "TWN7VUNDZ","TWN8DYNP ","TWN8FDX ","TWN8FDY ","TWN8M ","TWN8RE ","TWN8STVX ", & - "TWN8STVY ","TWN8STVZ ","TWN8VREL ","TWN8VUNDX","TWN8VUNDY","TWN8VUNDZ","TWN9DYNP ", & - "TWN9FDX ","TWN9FDY ","TWN9M ","TWN9RE ","TWN9STVX ","TWN9STVY ","TWN9STVZ ", & - "TWN9VREL ","TWN9VUNDX","TWN9VUNDY","TWN9VUNDZ"/) - INTEGER(IntKi), PARAMETER :: ParamIndxAry(1103) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) + "B3N6RE ","B3N6SGCAV","B3N6SIGCR","B3N6STVX ","B3N6STVY ","B3N6STVZ ","B3N6THETA", & + "B3N6TNIND","B3N6VDISX","B3N6VDISY","B3N6VDISZ","B3N6VINDX","B3N6VINDY","B3N6VREL ", & + "B3N6VUNDX","B3N6VUNDY","B3N6VUNDZ","B3N7ALPHA","B3N7AXIND","B3N7CD ","B3N7CL ", & + "B3N7CLRNC","B3N7CM ","B3N7CN ","B3N7CPMIN","B3N7CT ","B3N7CURVE","B3N7CX ", & + "B3N7CY ","B3N7DYNP ","B3N7FD ","B3N7FL ","B3N7FN ","B3N7FT ","B3N7FX ", & + "B3N7FY ","B3N7M ","B3N7MM ","B3N7PHI ","B3N7RE ","B3N7SGCAV","B3N7SIGCR", & + "B3N7STVX ","B3N7STVY ","B3N7STVZ ","B3N7THETA","B3N7TNIND","B3N7VDISX","B3N7VDISY", & + "B3N7VDISZ","B3N7VINDX","B3N7VINDY","B3N7VREL ","B3N7VUNDX","B3N7VUNDY","B3N7VUNDZ", & + "B3N8ALPHA","B3N8AXIND","B3N8CD ","B3N8CL ","B3N8CLRNC","B3N8CM ","B3N8CN ", & + "B3N8CPMIN","B3N8CT ","B3N8CURVE","B3N8CX ","B3N8CY ","B3N8DYNP ","B3N8FD ", & + "B3N8FL ","B3N8FN ","B3N8FT ","B3N8FX ","B3N8FY ","B3N8M ","B3N8MM ", & + "B3N8PHI ","B3N8RE ","B3N8SGCAV","B3N8SIGCR","B3N8STVX ","B3N8STVY ","B3N8STVZ ", & + "B3N8THETA","B3N8TNIND","B3N8VDISX","B3N8VDISY","B3N8VDISZ","B3N8VINDX","B3N8VINDY", & + "B3N8VREL ","B3N8VUNDX","B3N8VUNDY","B3N8VUNDZ","B3N9ALPHA","B3N9AXIND","B3N9CD ", & + "B3N9CL ","B3N9CLRNC","B3N9CM ","B3N9CN ","B3N9CPMIN","B3N9CT ","B3N9CURVE", & + "B3N9CX ","B3N9CY ","B3N9DYNP ","B3N9FD ","B3N9FL ","B3N9FN ","B3N9FT ", & + "B3N9FX ","B3N9FY ","B3N9M ","B3N9MM ","B3N9PHI ","B3N9RE ","B3N9SGCAV", & + "B3N9SIGCR","B3N9STVX ","B3N9STVY ","B3N9STVZ ","B3N9THETA","B3N9TNIND","B3N9VDISX", & + "B3N9VDISY","B3N9VDISZ","B3N9VINDX","B3N9VINDY","B3N9VREL ","B3N9VUNDX","B3N9VUNDY", & + "B3N9VUNDZ","B3PITCH ","RTAEROCP ","RTAEROCQ ","RTAEROCT ","RTAEROFXH","RTAEROFYH", & + "RTAEROFZH","RTAEROMXH","RTAEROMYH","RTAEROMZH","RTAEROPWR","RTAREA ","RTSKEW ", & + "RTSPEED ","RTTSR ","RTVAVGXH ","RTVAVGYH ","RTVAVGZH ","TWN1DYNP ","TWN1FDX ", & + "TWN1FDY ","TWN1M ","TWN1RE ","TWN1STVX ","TWN1STVY ","TWN1STVZ ","TWN1VREL ", & + "TWN1VUNDX","TWN1VUNDY","TWN1VUNDZ","TWN2DYNP ","TWN2FDX ","TWN2FDY ","TWN2M ", & + "TWN2RE ","TWN2STVX ","TWN2STVY ","TWN2STVZ ","TWN2VREL ","TWN2VUNDX","TWN2VUNDY", & + "TWN2VUNDZ","TWN3DYNP ","TWN3FDX ","TWN3FDY ","TWN3M ","TWN3RE ","TWN3STVX ", & + "TWN3STVY ","TWN3STVZ ","TWN3VREL ","TWN3VUNDX","TWN3VUNDY","TWN3VUNDZ","TWN4DYNP ", & + "TWN4FDX ","TWN4FDY ","TWN4M ","TWN4RE ","TWN4STVX ","TWN4STVY ","TWN4STVZ ", & + "TWN4VREL ","TWN4VUNDX","TWN4VUNDY","TWN4VUNDZ","TWN5DYNP ","TWN5FDX ","TWN5FDY ", & + "TWN5M ","TWN5RE ","TWN5STVX ","TWN5STVY ","TWN5STVZ ","TWN5VREL ","TWN5VUNDX", & + "TWN5VUNDY","TWN5VUNDZ","TWN6DYNP ","TWN6FDX ","TWN6FDY ","TWN6M ","TWN6RE ", & + "TWN6STVX ","TWN6STVY ","TWN6STVZ ","TWN6VREL ","TWN6VUNDX","TWN6VUNDY","TWN6VUNDZ", & + "TWN7DYNP ","TWN7FDX ","TWN7FDY ","TWN7M ","TWN7RE ","TWN7STVX ","TWN7STVY ", & + "TWN7STVZ ","TWN7VREL ","TWN7VUNDX","TWN7VUNDY","TWN7VUNDZ","TWN8DYNP ","TWN8FDX ", & + "TWN8FDY ","TWN8M ","TWN8RE ","TWN8STVX ","TWN8STVY ","TWN8STVZ ","TWN8VREL ", & + "TWN8VUNDX","TWN8VUNDY","TWN8VUNDZ","TWN9DYNP ","TWN9FDX ","TWN9FDY ","TWN9M ", & + "TWN9RE ","TWN9STVX ","TWN9STVY ","TWN9STVZ ","TWN9VREL ","TWN9VUNDX","TWN9VUNDY", & + "TWN9VUNDZ"/) + INTEGER(IntKi), PARAMETER :: ParamIndxAry(1184) = (/ & ! This lists the index into AllOuts(:) of the allowed parameters ValidParamAry(:) B1Azimuth , B1N1Alpha , B1N1AxInd , B1N1Cd , B1N1Cl , B1N1Clrnc , B1N1Cm , & - B1N1Cn , B1N1Ct , B1N1Curve , B1N1Cx , B1N1Cy , B1N1DynP , B1N1Fd , & - B1N1Fl , B1N1Fn , B1N1Ft , B1N1Fx , B1N1Fy , B1N1M , B1N1Mm , & - B1N1Phi , B1N1Re , B1N1STVx , B1N1STVy , B1N1STVz , B1N1Theta , B1N1TnInd , & - B1N1VDisx , B1N1VDisy , B1N1VDisz , B1N1Vindx , B1N1Vindy , B1N1VRel , B1N1VUndx , & - B1N1VUndy , B1N1VUndz , B1N2Alpha , B1N2AxInd , B1N2Cd , B1N2Cl , B1N2Clrnc , & - B1N2Cm , B1N2Cn , B1N2Ct , B1N2Curve , B1N2Cx , B1N2Cy , B1N2DynP , & - B1N2Fd , B1N2Fl , B1N2Fn , B1N2Ft , B1N2Fx , B1N2Fy , B1N2M , & - B1N2Mm , B1N2Phi , B1N2Re , B1N2STVx , B1N2STVy , B1N2STVz , B1N2Theta , & - B1N2TnInd , B1N2VDisx , B1N2VDisy , B1N2VDisz , B1N2Vindx , B1N2Vindy , B1N2VRel , & - B1N2VUndx , B1N2VUndy , B1N2VUndz , B1N3Alpha , B1N3AxInd , B1N3Cd , B1N3Cl , & - B1N3Clrnc , B1N3Cm , B1N3Cn , B1N3Ct , B1N3Curve , B1N3Cx , B1N3Cy , & + B1N1Cn , B1N1Cpmin , B1N1Ct , B1N1Curve , B1N1Cx , B1N1Cy , B1N1DynP , & + B1N1Fd , B1N1Fl , B1N1Fn , B1N1Ft , B1N1Fx , B1N1Fy , B1N1M , & + B1N1Mm , B1N1Phi , B1N1Re , B1N1SgCav , B1N1SigCr , B1N1STVx , B1N1STVy , & + B1N1STVz , B1N1Theta , B1N1TnInd , B1N1VDisx , B1N1VDisy , B1N1VDisz , B1N1Vindx , & + B1N1Vindy , B1N1VRel , B1N1VUndx , B1N1VUndy , B1N1VUndz , B1N2Alpha , B1N2AxInd , & + B1N2Cd , B1N2Cl , B1N2Clrnc , B1N2Cm , B1N2Cn , B1N2Cpmin , B1N2Ct , & + B1N2Curve , B1N2Cx , B1N2Cy , B1N2DynP , B1N2Fd , B1N2Fl , B1N2Fn , & + B1N2Ft , B1N2Fx , B1N2Fy , B1N2M , B1N2Mm , B1N2Phi , B1N2Re , & + B1N2SgCav , B1N2SigCr , B1N2STVx , B1N2STVy , B1N2STVz , B1N2Theta , B1N2TnInd , & + B1N2VDisx , B1N2VDisy , B1N2VDisz , B1N2Vindx , B1N2Vindy , B1N2VRel , B1N2VUndx , & + B1N2VUndy , B1N2VUndz , B1N3Alpha , B1N3AxInd , B1N3Cd , B1N3Cl , B1N3Clrnc , & + B1N3Cm , B1N3Cn , B1N3Cpmin , B1N3Ct , B1N3Curve , B1N3Cx , B1N3Cy , & B1N3DynP , B1N3Fd , B1N3Fl , B1N3Fn , B1N3Ft , B1N3Fx , B1N3Fy , & - B1N3M , B1N3Mm , B1N3Phi , B1N3Re , B1N3STVx , B1N3STVy , B1N3STVz , & - B1N3Theta , B1N3TnInd , B1N3VDisx , B1N3VDisy , B1N3VDisz , B1N3Vindx , B1N3Vindy , & - B1N3VRel , B1N3VUndx , B1N3VUndy , B1N3VUndz , B1N4Alpha , B1N4AxInd , B1N4Cd , & - B1N4Cl , B1N4Clrnc , B1N4Cm , B1N4Cn , B1N4Ct , B1N4Curve , B1N4Cx , & - B1N4Cy , B1N4DynP , B1N4Fd , B1N4Fl , B1N4Fn , B1N4Ft , B1N4Fx , & - B1N4Fy , B1N4M , B1N4Mm , B1N4Phi , B1N4Re , B1N4STVx , B1N4STVy , & - B1N4STVz , B1N4Theta , B1N4TnInd , B1N4VDisx , B1N4VDisy , B1N4VDisz , B1N4Vindx , & - B1N4Vindy , B1N4VRel , B1N4VUndx , B1N4VUndy , B1N4VUndz , B1N5Alpha , B1N5AxInd , & - B1N5Cd , B1N5Cl , B1N5Clrnc , B1N5Cm , B1N5Cn , B1N5Ct , B1N5Curve , & - B1N5Cx , B1N5Cy , B1N5DynP , B1N5Fd , B1N5Fl , B1N5Fn , B1N5Ft , & - B1N5Fx , B1N5Fy , B1N5M , B1N5Mm , B1N5Phi , B1N5Re , B1N5STVx , & - B1N5STVy , B1N5STVz , B1N5Theta , B1N5TnInd , B1N5VDisx , B1N5VDisy , B1N5VDisz , & - B1N5Vindx , B1N5Vindy , B1N5VRel , B1N5VUndx , B1N5VUndy , B1N5VUndz , B1N6Alpha , & - B1N6AxInd , B1N6Cd , B1N6Cl , B1N6Clrnc , B1N6Cm , B1N6Cn , B1N6Ct , & - B1N6Curve , B1N6Cx , B1N6Cy , B1N6DynP , B1N6Fd , B1N6Fl , B1N6Fn , & - B1N6Ft , B1N6Fx , B1N6Fy , B1N6M , B1N6Mm , B1N6Phi , B1N6Re , & - B1N6STVx , B1N6STVy , B1N6STVz , B1N6Theta , B1N6TnInd , B1N6VDisx , B1N6VDisy , & - B1N6VDisz , B1N6Vindx , B1N6Vindy , B1N6VRel , B1N6VUndx , B1N6VUndy , B1N6VUndz , & - B1N7Alpha , B1N7AxInd , B1N7Cd , B1N7Cl , B1N7Clrnc , B1N7Cm , B1N7Cn , & - B1N7Ct , B1N7Curve , B1N7Cx , B1N7Cy , B1N7DynP , B1N7Fd , B1N7Fl , & - B1N7Fn , B1N7Ft , B1N7Fx , B1N7Fy , B1N7M , B1N7Mm , B1N7Phi , & - B1N7Re , B1N7STVx , B1N7STVy , B1N7STVz , B1N7Theta , B1N7TnInd , B1N7VDisx , & + B1N3M , B1N3Mm , B1N3Phi , B1N3Re , B1N3SgCav , B1N3SigCr , B1N3STVx , & + B1N3STVy , B1N3STVz , B1N3Theta , B1N3TnInd , B1N3VDisx , B1N3VDisy , B1N3VDisz , & + B1N3Vindx , B1N3Vindy , B1N3VRel , B1N3VUndx , B1N3VUndy , B1N3VUndz , B1N4Alpha , & + B1N4AxInd , B1N4Cd , B1N4Cl , B1N4Clrnc , B1N4Cm , B1N4Cn , B1N4Cpmin , & + B1N4Ct , B1N4Curve , B1N4Cx , B1N4Cy , B1N4DynP , B1N4Fd , B1N4Fl , & + B1N4Fn , B1N4Ft , B1N4Fx , B1N4Fy , B1N4M , B1N4Mm , B1N4Phi , & + B1N4Re , B1N4SgCav , B1N4SigCr , B1N4STVx , B1N4STVy , B1N4STVz , B1N4Theta , & + B1N4TnInd , B1N4VDisx , B1N4VDisy , B1N4VDisz , B1N4Vindx , B1N4Vindy , B1N4VRel , & + B1N4VUndx , B1N4VUndy , B1N4VUndz , B1N5Alpha , B1N5AxInd , B1N5Cd , B1N5Cl , & + B1N5Clrnc , B1N5Cm , B1N5Cn , B1N5Cpmin , B1N5Ct , B1N5Curve , B1N5Cx , & + B1N5Cy , B1N5DynP , B1N5Fd , B1N5Fl , B1N5Fn , B1N5Ft , B1N5Fx , & + B1N5Fy , B1N5M , B1N5Mm , B1N5Phi , B1N5Re , B1N5SgCav , B1N5SigCr , & + B1N5STVx , B1N5STVy , B1N5STVz , B1N5Theta , B1N5TnInd , B1N5VDisx , B1N5VDisy , & + B1N5VDisz , B1N5Vindx , B1N5Vindy , B1N5VRel , B1N5VUndx , B1N5VUndy , B1N5VUndz , & + B1N6Alpha , B1N6AxInd , B1N6Cd , B1N6Cl , B1N6Clrnc , B1N6Cm , B1N6Cn , & + B1N6Cpmin , B1N6Ct , B1N6Curve , B1N6Cx , B1N6Cy , B1N6DynP , B1N6Fd , & + B1N6Fl , B1N6Fn , B1N6Ft , B1N6Fx , B1N6Fy , B1N6M , B1N6Mm , & + B1N6Phi , B1N6Re , B1N6SgCav , B1N6SigCr , B1N6STVx , B1N6STVy , B1N6STVz , & + B1N6Theta , B1N6TnInd , B1N6VDisx , B1N6VDisy , B1N6VDisz , B1N6Vindx , B1N6Vindy , & + B1N6VRel , B1N6VUndx , B1N6VUndy , B1N6VUndz , B1N7Alpha , B1N7AxInd , B1N7Cd , & + B1N7Cl , B1N7Clrnc , B1N7Cm , B1N7Cn , B1N7Cpmin , B1N7Ct , B1N7Curve , & + B1N7Cx , B1N7Cy , B1N7DynP , B1N7Fd , B1N7Fl , B1N7Fn , B1N7Ft , & + B1N7Fx , B1N7Fy , B1N7M , B1N7Mm , B1N7Phi , B1N7Re , B1N7SgCav , & + B1N7SigCr , B1N7STVx , B1N7STVy , B1N7STVz , B1N7Theta , B1N7TnInd , B1N7VDisx , & B1N7VDisy , B1N7VDisz , B1N7Vindx , B1N7Vindy , B1N7VRel , B1N7VUndx , B1N7VUndy , & B1N7VUndz , B1N8Alpha , B1N8AxInd , B1N8Cd , B1N8Cl , B1N8Clrnc , B1N8Cm , & - B1N8Cn , B1N8Ct , B1N8Curve , B1N8Cx , B1N8Cy , B1N8DynP , B1N8Fd , & - B1N8Fl , B1N8Fn , B1N8Ft , B1N8Fx , B1N8Fy , B1N8M , B1N8Mm , & - B1N8Phi , B1N8Re , B1N8STVx , B1N8STVy , B1N8STVz , B1N8Theta , B1N8TnInd , & - B1N8VDisx , B1N8VDisy , B1N8VDisz , B1N8Vindx , B1N8Vindy , B1N8VRel , B1N8VUndx , & - B1N8VUndy , B1N8VUndz , B1N9Alpha , B1N9AxInd , B1N9Cd , B1N9Cl , B1N9Clrnc , & - B1N9Cm , B1N9Cn , B1N9Ct , B1N9Curve , B1N9Cx , B1N9Cy , B1N9DynP , & - B1N9Fd , B1N9Fl , B1N9Fn , B1N9Ft , B1N9Fx , B1N9Fy , B1N9M , & - B1N9Mm , B1N9Phi , B1N9Re , B1N9STVx , B1N9STVy , B1N9STVz , B1N9Theta , & - B1N9TnInd , B1N9VDisx , B1N9VDisy , B1N9VDisz , B1N9Vindx , B1N9Vindy , B1N9VRel , & - B1N9VUndx , B1N9VUndy , B1N9VUndz , B1Pitch , B2Azimuth , B2N1Alpha , B2N1AxInd , & - B2N1Cd , B2N1Cl , B2N1Clrnc , B2N1Cm , B2N1Cn , B2N1Ct , B2N1Curve , & + B1N8Cn , B1N8Cpmin , B1N8Ct , B1N8Curve , B1N8Cx , B1N8Cy , B1N8DynP , & + B1N8Fd , B1N8Fl , B1N8Fn , B1N8Ft , B1N8Fx , B1N8Fy , B1N8M , & + B1N8Mm , B1N8Phi , B1N8Re , B1N8SgCav , B1N8SigCr , B1N8STVx , B1N8STVy , & + B1N8STVz , B1N8Theta , B1N8TnInd , B1N8VDisx , B1N8VDisy , B1N8VDisz , B1N8Vindx , & + B1N8Vindy , B1N8VRel , B1N8VUndx , B1N8VUndy , B1N8VUndz , B1N9Alpha , B1N9AxInd , & + B1N9Cd , B1N9Cl , B1N9Clrnc , B1N9Cm , B1N9Cn , B1N9Cpmin , B1N9Ct , & + B1N9Curve , B1N9Cx , B1N9Cy , B1N9DynP , B1N9Fd , B1N9Fl , B1N9Fn , & + B1N9Ft , B1N9Fx , B1N9Fy , B1N9M , B1N9Mm , B1N9Phi , B1N9Re , & + B1N9SgCav , B1N9SigCr , B1N9STVx , B1N9STVy , B1N9STVz , B1N9Theta , B1N9TnInd , & + B1N9VDisx , B1N9VDisy , B1N9VDisz , B1N9Vindx , B1N9Vindy , B1N9VRel , B1N9VUndx , & + B1N9VUndy , B1N9VUndz , B1Pitch , B2Azimuth , B2N1Alpha , B2N1AxInd , B2N1Cd , & + B2N1Cl , B2N1Clrnc , B2N1Cm , B2N1Cn , B2N1Cpmin , B2N1Ct , B2N1Curve , & B2N1Cx , B2N1Cy , B2N1DynP , B2N1Fd , B2N1Fl , B2N1Fn , B2N1Ft , & - B2N1Fx , B2N1Fy , B2N1M , B2N1Mm , B2N1Phi , B2N1Re , B2N1STVx , & - B2N1STVy , B2N1STVz , B2N1Theta , B2N1TnInd , B2N1VDisx , B2N1VDisy , B2N1VDisz , & - B2N1Vindx , B2N1Vindy , B2N1VRel , B2N1VUndx , B2N1VUndy , B2N1VUndz , B2N2Alpha , & - B2N2AxInd , B2N2Cd , B2N2Cl , B2N2Clrnc , B2N2Cm , B2N2Cn , B2N2Ct , & - B2N2Curve , B2N2Cx , B2N2Cy , B2N2DynP , B2N2Fd , B2N2Fl , B2N2Fn , & - B2N2Ft , B2N2Fx , B2N2Fy , B2N2M , B2N2Mm , B2N2Phi , B2N2Re , & - B2N2STVx , B2N2STVy , B2N2STVz , B2N2Theta , B2N2TnInd , B2N2VDisx , B2N2VDisy , & - B2N2VDisz , B2N2Vindx , B2N2Vindy , B2N2VRel , B2N2VUndx , B2N2VUndy , B2N2VUndz , & - B2N3Alpha , B2N3AxInd , B2N3Cd , B2N3Cl , B2N3Clrnc , B2N3Cm , B2N3Cn , & - B2N3Ct , B2N3Curve , B2N3Cx , B2N3Cy , B2N3DynP , B2N3Fd , B2N3Fl , & - B2N3Fn , B2N3Ft , B2N3Fx , B2N3Fy , B2N3M , B2N3Mm , B2N3Phi , & - B2N3Re , B2N3STVx , B2N3STVy , B2N3STVz , B2N3Theta , B2N3TnInd , B2N3VDisx , & - B2N3VDisy , B2N3VDisz , B2N3Vindx , B2N3Vindy , B2N3VRel , B2N3VUndx , B2N3VUndy , & - B2N3VUndz , B2N4Alpha , B2N4AxInd , B2N4Cd , B2N4Cl , B2N4Clrnc , B2N4Cm , & - B2N4Cn , B2N4Ct , B2N4Curve , B2N4Cx , B2N4Cy , B2N4DynP , B2N4Fd , & - B2N4Fl , B2N4Fn , B2N4Ft , B2N4Fx , B2N4Fy , B2N4M , B2N4Mm , & - B2N4Phi , B2N4Re , B2N4STVx , B2N4STVy , B2N4STVz , B2N4Theta , B2N4TnInd , & - B2N4VDisx , B2N4VDisy , B2N4VDisz , B2N4Vindx , B2N4Vindy , B2N4VRel , B2N4VUndx , & - B2N4VUndy , B2N4VUndz , B2N5Alpha , B2N5AxInd , B2N5Cd , B2N5Cl , B2N5Clrnc , & - B2N5Cm , B2N5Cn , B2N5Ct , B2N5Curve , B2N5Cx , B2N5Cy , B2N5DynP , & - B2N5Fd , B2N5Fl , B2N5Fn , B2N5Ft , B2N5Fx , B2N5Fy , B2N5M , & - B2N5Mm , B2N5Phi , B2N5Re , B2N5STVx , B2N5STVy , B2N5STVz , B2N5Theta , & + B2N1Fx , B2N1Fy , B2N1M , B2N1Mm , B2N1Phi , B2N1Re , B2N1SgCav , & + B2N1SigCr , B2N1STVx , B2N1STVy , B2N1STVz , B2N1Theta , B2N1TnInd , B2N1VDisx , & + B2N1VDisy , B2N1VDisz , B2N1Vindx , B2N1Vindy , B2N1VRel , B2N1VUndx , B2N1VUndy , & + B2N1VUndz , B2N2Alpha , B2N2AxInd , B2N2Cd , B2N2Cl , B2N2Clrnc , B2N2Cm , & + B2N2Cn , B2N2Cpmin , B2N2Ct , B2N2Curve , B2N2Cx , B2N2Cy , B2N2DynP , & + B2N2Fd , B2N2Fl , B2N2Fn , B2N2Ft , B2N2Fx , B2N2Fy , B2N2M , & + B2N2Mm , B2N2Phi , B2N2Re , B2N2SgCav , B2N2SigCr , B2N2STVx , B2N2STVy , & + B2N2STVz , B2N2Theta , B2N2TnInd , B2N2VDisx , B2N2VDisy , B2N2VDisz , B2N2Vindx , & + B2N2Vindy , B2N2VRel , B2N2VUndx , B2N2VUndy , B2N2VUndz , B2N3Alpha , B2N3AxInd , & + B2N3Cd , B2N3Cl , B2N3Clrnc , B2N3Cm , B2N3Cn , B2N3Cpmin , B2N3Ct , & + B2N3Curve , B2N3Cx , B2N3Cy , B2N3DynP , B2N3Fd , B2N3Fl , B2N3Fn , & + B2N3Ft , B2N3Fx , B2N3Fy , B2N3M , B2N3Mm , B2N3Phi , B2N3Re , & + B2N3SgCav , B2N3SigCr , B2N3STVx , B2N3STVy , B2N3STVz , B2N3Theta , B2N3TnInd , & + B2N3VDisx , B2N3VDisy , B2N3VDisz , B2N3Vindx , B2N3Vindy , B2N3VRel , B2N3VUndx , & + B2N3VUndy , B2N3VUndz , B2N4Alpha , B2N4AxInd , B2N4Cd , B2N4Cl , B2N4Clrnc , & + B2N4Cm , B2N4Cn , B2N4Cpmin , B2N4Ct , B2N4Curve , B2N4Cx , B2N4Cy , & + B2N4DynP , B2N4Fd , B2N4Fl , B2N4Fn , B2N4Ft , B2N4Fx , B2N4Fy , & + B2N4M , B2N4Mm , B2N4Phi , B2N4Re , B2N4SgCav , B2N4SigCr , B2N4STVx , & + B2N4STVy , B2N4STVz , B2N4Theta , B2N4TnInd , B2N4VDisx , B2N4VDisy , B2N4VDisz , & + B2N4Vindx , B2N4Vindy , B2N4VRel , B2N4VUndx , B2N4VUndy , B2N4VUndz , B2N5Alpha , & + B2N5AxInd , B2N5Cd , B2N5Cl , B2N5Clrnc , B2N5Cm , B2N5Cn , B2N5Cpmin , & + B2N5Ct , B2N5Curve , B2N5Cx , B2N5Cy , B2N5DynP , B2N5Fd , B2N5Fl , & + B2N5Fn , B2N5Ft , B2N5Fx , B2N5Fy , B2N5M , B2N5Mm , B2N5Phi , & + B2N5Re , B2N5SgCav , B2N5SigCr , B2N5STVx , B2N5STVy , B2N5STVz , B2N5Theta , & B2N5TnInd , B2N5VDisx , B2N5VDisy , B2N5VDisz , B2N5Vindx , B2N5Vindy , B2N5VRel , & B2N5VUndx , B2N5VUndy , B2N5VUndz , B2N6Alpha , B2N6AxInd , B2N6Cd , B2N6Cl , & - B2N6Clrnc , B2N6Cm , B2N6Cn , B2N6Ct , B2N6Curve , B2N6Cx , B2N6Cy , & - B2N6DynP , B2N6Fd , B2N6Fl , B2N6Fn , B2N6Ft , B2N6Fx , B2N6Fy , & - B2N6M , B2N6Mm , B2N6Phi , B2N6Re , B2N6STVx , B2N6STVy , B2N6STVz , & - B2N6Theta , B2N6TnInd , B2N6VDisx , B2N6VDisy , B2N6VDisz , B2N6Vindx , B2N6Vindy , & - B2N6VRel , B2N6VUndx , B2N6VUndy , B2N6VUndz , B2N7Alpha , B2N7AxInd , B2N7Cd , & - B2N7Cl , B2N7Clrnc , B2N7Cm , B2N7Cn , B2N7Ct , B2N7Curve , B2N7Cx , & - B2N7Cy , B2N7DynP , B2N7Fd , B2N7Fl , B2N7Fn , B2N7Ft , B2N7Fx , & - B2N7Fy , B2N7M , B2N7Mm , B2N7Phi , B2N7Re , B2N7STVx , B2N7STVy , & - B2N7STVz , B2N7Theta , B2N7TnInd , B2N7VDisx , B2N7VDisy , B2N7VDisz , B2N7Vindx , & - B2N7Vindy , B2N7VRel , B2N7VUndx , B2N7VUndy , B2N7VUndz , B2N8Alpha , B2N8AxInd , & - B2N8Cd , B2N8Cl , B2N8Clrnc , B2N8Cm , B2N8Cn , B2N8Ct , B2N8Curve , & + B2N6Clrnc , B2N6Cm , B2N6Cn , B2N6Cpmin , B2N6Ct , B2N6Curve , B2N6Cx , & + B2N6Cy , B2N6DynP , B2N6Fd , B2N6Fl , B2N6Fn , B2N6Ft , B2N6Fx , & + B2N6Fy , B2N6M , B2N6Mm , B2N6Phi , B2N6Re , B2N6SgCav , B2N6SigCr , & + B2N6STVx , B2N6STVy , B2N6STVz , B2N6Theta , B2N6TnInd , B2N6VDisx , B2N6VDisy , & + B2N6VDisz , B2N6Vindx , B2N6Vindy , B2N6VRel , B2N6VUndx , B2N6VUndy , B2N6VUndz , & + B2N7Alpha , B2N7AxInd , B2N7Cd , B2N7Cl , B2N7Clrnc , B2N7Cm , B2N7Cn , & + B2N7Cpmin , B2N7Ct , B2N7Curve , B2N7Cx , B2N7Cy , B2N7DynP , B2N7Fd , & + B2N7Fl , B2N7Fn , B2N7Ft , B2N7Fx , B2N7Fy , B2N7M , B2N7Mm , & + B2N7Phi , B2N7Re , B2N7SgCav , B2N7SigCr , B2N7STVx , B2N7STVy , B2N7STVz , & + B2N7Theta , B2N7TnInd , B2N7VDisx , B2N7VDisy , B2N7VDisz , B2N7Vindx , B2N7Vindy , & + B2N7VRel , B2N7VUndx , B2N7VUndy , B2N7VUndz , B2N8Alpha , B2N8AxInd , B2N8Cd , & + B2N8Cl , B2N8Clrnc , B2N8Cm , B2N8Cn , B2N8Cpmin , B2N8Ct , B2N8Curve , & B2N8Cx , B2N8Cy , B2N8DynP , B2N8Fd , B2N8Fl , B2N8Fn , B2N8Ft , & - B2N8Fx , B2N8Fy , B2N8M , B2N8Mm , B2N8Phi , B2N8Re , B2N8STVx , & - B2N8STVy , B2N8STVz , B2N8Theta , B2N8TnInd , B2N8VDisx , B2N8VDisy , B2N8VDisz , & - B2N8Vindx , B2N8Vindy , B2N8VRel , B2N8VUndx , B2N8VUndy , B2N8VUndz , B2N9Alpha , & - B2N9AxInd , B2N9Cd , B2N9Cl , B2N9Clrnc , B2N9Cm , B2N9Cn , B2N9Ct , & - B2N9Curve , B2N9Cx , B2N9Cy , B2N9DynP , B2N9Fd , B2N9Fl , B2N9Fn , & - B2N9Ft , B2N9Fx , B2N9Fy , B2N9M , B2N9Mm , B2N9Phi , B2N9Re , & - B2N9STVx , B2N9STVy , B2N9STVz , B2N9Theta , B2N9TnInd , B2N9VDisx , B2N9VDisy , & - B2N9VDisz , B2N9Vindx , B2N9Vindy , B2N9VRel , B2N9VUndx , B2N9VUndy , B2N9VUndz , & - B2Pitch , B3Azimuth , B3N1Alpha , B3N1AxInd , B3N1Cd , B3N1Cl , B3N1Clrnc , & - B3N1Cm , B3N1Cn , B3N1Ct , B3N1Curve , B3N1Cx , B3N1Cy , B3N1DynP , & - B3N1Fd , B3N1Fl , B3N1Fn , B3N1Ft , B3N1Fx , B3N1Fy , B3N1M , & - B3N1Mm , B3N1Phi , B3N1Re , B3N1STVx , B3N1STVy , B3N1STVz , B3N1Theta , & - B3N1TnInd , B3N1VDisx , B3N1VDisy , B3N1VDisz , B3N1Vindx , B3N1Vindy , B3N1VRel , & - B3N1VUndx , B3N1VUndy , B3N1VUndz , B3N2Alpha , B3N2AxInd , B3N2Cd , B3N2Cl , & - B3N2Clrnc , B3N2Cm , B3N2Cn , B3N2Ct , B3N2Curve , B3N2Cx , B3N2Cy , & - B3N2DynP , B3N2Fd , B3N2Fl , B3N2Fn , B3N2Ft , B3N2Fx , B3N2Fy , & - B3N2M , B3N2Mm , B3N2Phi , B3N2Re , B3N2STVx , B3N2STVy , B3N2STVz , & - B3N2Theta , B3N2TnInd , B3N2VDisx , B3N2VDisy , B3N2VDisz , B3N2Vindx , B3N2Vindy , & - B3N2VRel , B3N2VUndx , B3N2VUndy , B3N2VUndz , B3N3Alpha , B3N3AxInd , B3N3Cd , & - B3N3Cl , B3N3Clrnc , B3N3Cm , B3N3Cn , B3N3Ct , B3N3Curve , B3N3Cx , & - B3N3Cy , B3N3DynP , B3N3Fd , B3N3Fl , B3N3Fn , B3N3Ft , B3N3Fx , & - B3N3Fy , B3N3M , B3N3Mm , B3N3Phi , B3N3Re , B3N3STVx , B3N3STVy , & + B2N8Fx , B2N8Fy , B2N8M , B2N8Mm , B2N8Phi , B2N8Re , B2N8SgCav , & + B2N8SigCr , B2N8STVx , B2N8STVy , B2N8STVz , B2N8Theta , B2N8TnInd , B2N8VDisx , & + B2N8VDisy , B2N8VDisz , B2N8Vindx , B2N8Vindy , B2N8VRel , B2N8VUndx , B2N8VUndy , & + B2N8VUndz , B2N9Alpha , B2N9AxInd , B2N9Cd , B2N9Cl , B2N9Clrnc , B2N9Cm , & + B2N9Cn , B2N9Cpmin , B2N9Ct , B2N9Curve , B2N9Cx , B2N9Cy , B2N9DynP , & + B2N9Fd , B2N9Fl , B2N9Fn , B2N9Ft , B2N9Fx , B2N9Fy , B2N9M , & + B2N9Mm , B2N9Phi , B2N9Re , B2N9SgCav , B2N9SigCr , B2N9STVx , B2N9STVy , & + B2N9STVz , B2N9Theta , B2N9TnInd , B2N9VDisx , B2N9VDisy , B2N9VDisz , B2N9Vindx , & + B2N9Vindy , B2N9VRel , B2N9VUndx , B2N9VUndy , B2N9VUndz , B2Pitch , B3Azimuth , & + B3N1Alpha , B3N1AxInd , B3N1Cd , B3N1Cl , B3N1Clrnc , B3N1Cm , B3N1Cn , & + B3N1Cpmin , B3N1Ct , B3N1Curve , B3N1Cx , B3N1Cy , B3N1DynP , B3N1Fd , & + B3N1Fl , B3N1Fn , B3N1Ft , B3N1Fx , B3N1Fy , B3N1M , B3N1Mm , & + B3N1Phi , B3N1Re , B3N1SgCav , B3N1SigCr , B3N1STVx , B3N1STVy , B3N1STVz , & + B3N1Theta , B3N1TnInd , B3N1VDisx , B3N1VDisy , B3N1VDisz , B3N1Vindx , B3N1Vindy , & + B3N1VRel , B3N1VUndx , B3N1VUndy , B3N1VUndz , B3N2Alpha , B3N2AxInd , B3N2Cd , & + B3N2Cl , B3N2Clrnc , B3N2Cm , B3N2Cn , B3N2Cpmin , B3N2Ct , B3N2Curve , & + B3N2Cx , B3N2Cy , B3N2DynP , B3N2Fd , B3N2Fl , B3N2Fn , B3N2Ft , & + B3N2Fx , B3N2Fy , B3N2M , B3N2Mm , B3N2Phi , B3N2Re , B3N2SgCav , & + B3N2SigCr , B3N2STVx , B3N2STVy , B3N2STVz , B3N2Theta , B3N2TnInd , B3N2VDisx , & + B3N2VDisy , B3N2VDisz , B3N2Vindx , B3N2Vindy , B3N2VRel , B3N2VUndx , B3N2VUndy , & + B3N2VUndz , B3N3Alpha , B3N3AxInd , B3N3Cd , B3N3Cl , B3N3Clrnc , B3N3Cm , & + B3N3Cn , B3N3Cpmin , B3N3Ct , B3N3Curve , B3N3Cx , B3N3Cy , B3N3DynP , & + B3N3Fd , B3N3Fl , B3N3Fn , B3N3Ft , B3N3Fx , B3N3Fy , B3N3M , & + B3N3Mm , B3N3Phi , B3N3Re , B3N3SgCav , B3N3SigCr , B3N3STVx , B3N3STVy , & B3N3STVz , B3N3Theta , B3N3TnInd , B3N3VDisx , B3N3VDisy , B3N3VDisz , B3N3Vindx , & B3N3Vindy , B3N3VRel , B3N3VUndx , B3N3VUndy , B3N3VUndz , B3N4Alpha , B3N4AxInd , & - B3N4Cd , B3N4Cl , B3N4Clrnc , B3N4Cm , B3N4Cn , B3N4Ct , B3N4Curve , & - B3N4Cx , B3N4Cy , B3N4DynP , B3N4Fd , B3N4Fl , B3N4Fn , B3N4Ft , & - B3N4Fx , B3N4Fy , B3N4M , B3N4Mm , B3N4Phi , B3N4Re , B3N4STVx , & - B3N4STVy , B3N4STVz , B3N4Theta , B3N4TnInd , B3N4VDisx , B3N4VDisy , B3N4VDisz , & - B3N4Vindx , B3N4Vindy , B3N4VRel , B3N4VUndx , B3N4VUndy , B3N4VUndz , B3N5Alpha , & - B3N5AxInd , B3N5Cd , B3N5Cl , B3N5Clrnc , B3N5Cm , B3N5Cn , B3N5Ct , & - B3N5Curve , B3N5Cx , B3N5Cy , B3N5DynP , B3N5Fd , B3N5Fl , B3N5Fn , & - B3N5Ft , B3N5Fx , B3N5Fy , B3N5M , B3N5Mm , B3N5Phi , B3N5Re , & - B3N5STVx , B3N5STVy , B3N5STVz , B3N5Theta , B3N5TnInd , B3N5VDisx , B3N5VDisy , & - B3N5VDisz , B3N5Vindx , B3N5Vindy , B3N5VRel , B3N5VUndx , B3N5VUndy , B3N5VUndz , & - B3N6Alpha , B3N6AxInd , B3N6Cd , B3N6Cl , B3N6Clrnc , B3N6Cm , B3N6Cn , & + B3N4Cd , B3N4Cl , B3N4Clrnc , B3N4Cm , B3N4Cn , B3N4Cpmin , B3N4Ct , & + B3N4Curve , B3N4Cx , B3N4Cy , B3N4DynP , B3N4Fd , B3N4Fl , B3N4Fn , & + B3N4Ft , B3N4Fx , B3N4Fy , B3N4M , B3N4Mm , B3N4Phi , B3N4Re , & + B3N4SgCav , B3N4SigCr , B3N4STVx , B3N4STVy , B3N4STVz , B3N4Theta , B3N4TnInd , & + B3N4VDisx , B3N4VDisy , B3N4VDisz , B3N4Vindx , B3N4Vindy , B3N4VRel , B3N4VUndx , & + B3N4VUndy , B3N4VUndz , B3N5Alpha , B3N5AxInd , B3N5Cd , B3N5Cl , B3N5Clrnc , & + B3N5Cm , B3N5Cn , B3N5Cpmin , B3N5Ct , B3N5Curve , B3N5Cx , B3N5Cy , & + B3N5DynP , B3N5Fd , B3N5Fl , B3N5Fn , B3N5Ft , B3N5Fx , B3N5Fy , & + B3N5M , B3N5Mm , B3N5Phi , B3N5Re , B3N5SgCav , B3N5SigCr , B3N5STVx , & + B3N5STVy , B3N5STVz , B3N5Theta , B3N5TnInd , B3N5VDisx , B3N5VDisy , B3N5VDisz , & + B3N5Vindx , B3N5Vindy , B3N5VRel , B3N5VUndx , B3N5VUndy , B3N5VUndz , B3N6Alpha , & + B3N6AxInd , B3N6Cd , B3N6Cl , B3N6Clrnc , B3N6Cm , B3N6Cn , B3N6Cpmin , & B3N6Ct , B3N6Curve , B3N6Cx , B3N6Cy , B3N6DynP , B3N6Fd , B3N6Fl , & B3N6Fn , B3N6Ft , B3N6Fx , B3N6Fy , B3N6M , B3N6Mm , B3N6Phi , & - B3N6Re , B3N6STVx , B3N6STVy , B3N6STVz , B3N6Theta , B3N6TnInd , B3N6VDisx , & - B3N6VDisy , B3N6VDisz , B3N6Vindx , B3N6Vindy , B3N6VRel , B3N6VUndx , B3N6VUndy , & - B3N6VUndz , B3N7Alpha , B3N7AxInd , B3N7Cd , B3N7Cl , B3N7Clrnc , B3N7Cm , & - B3N7Cn , B3N7Ct , B3N7Curve , B3N7Cx , B3N7Cy , B3N7DynP , B3N7Fd , & - B3N7Fl , B3N7Fn , B3N7Ft , B3N7Fx , B3N7Fy , B3N7M , B3N7Mm , & - B3N7Phi , B3N7Re , B3N7STVx , B3N7STVy , B3N7STVz , B3N7Theta , B3N7TnInd , & - B3N7VDisx , B3N7VDisy , B3N7VDisz , B3N7Vindx , B3N7Vindy , B3N7VRel , B3N7VUndx , & - B3N7VUndy , B3N7VUndz , B3N8Alpha , B3N8AxInd , B3N8Cd , B3N8Cl , B3N8Clrnc , & - B3N8Cm , B3N8Cn , B3N8Ct , B3N8Curve , B3N8Cx , B3N8Cy , B3N8DynP , & - B3N8Fd , B3N8Fl , B3N8Fn , B3N8Ft , B3N8Fx , B3N8Fy , B3N8M , & - B3N8Mm , B3N8Phi , B3N8Re , B3N8STVx , B3N8STVy , B3N8STVz , B3N8Theta , & - B3N8TnInd , B3N8VDisx , B3N8VDisy , B3N8VDisz , B3N8Vindx , B3N8Vindy , B3N8VRel , & - B3N8VUndx , B3N8VUndy , B3N8VUndz , B3N9Alpha , B3N9AxInd , B3N9Cd , B3N9Cl , & - B3N9Clrnc , B3N9Cm , B3N9Cn , B3N9Ct , B3N9Curve , B3N9Cx , B3N9Cy , & - B3N9DynP , B3N9Fd , B3N9Fl , B3N9Fn , B3N9Ft , B3N9Fx , B3N9Fy , & - B3N9M , B3N9Mm , B3N9Phi , B3N9Re , B3N9STVx , B3N9STVy , B3N9STVz , & - B3N9Theta , B3N9TnInd , B3N9VDisx , B3N9VDisy , B3N9VDisz , B3N9Vindx , B3N9Vindy , & - B3N9VRel , B3N9VUndx , B3N9VUndy , B3N9VUndz , B3Pitch , RtAeroCp , RtAeroCq , & - RtAeroCt , RtAeroFxh , RtAeroFyh , RtAeroFzh , RtAeroMxh , RtAeroMyh , RtAeroMzh , & - RtAeroPwr , RtArea , RtSkew , RtSpeed , RtTSR , RtVAvgxh , RtVAvgyh , & - RtVAvgzh , TwN1DynP , TwN1Fdx , TwN1Fdy , TwN1M , TwN1Re , TwN1STVx , & - TwN1STVy , TwN1STVz , TwN1Vrel , TwN1VUndx , TwN1VUndy , TwN1VUndz , TwN2DynP , & - TwN2Fdx , TwN2Fdy , TwN2M , TwN2Re , TwN2STVx , TwN2STVy , TwN2STVz , & - TwN2Vrel , TwN2VUndx , TwN2VUndy , TwN2VUndz , TwN3DynP , TwN3Fdx , TwN3Fdy , & - TwN3M , TwN3Re , TwN3STVx , TwN3STVy , TwN3STVz , TwN3Vrel , TwN3VUndx , & - TwN3VUndy , TwN3VUndz , TwN4DynP , TwN4Fdx , TwN4Fdy , TwN4M , TwN4Re , & - TwN4STVx , TwN4STVy , TwN4STVz , TwN4Vrel , TwN4VUndx , TwN4VUndy , TwN4VUndz , & - TwN5DynP , TwN5Fdx , TwN5Fdy , TwN5M , TwN5Re , TwN5STVx , TwN5STVy , & - TwN5STVz , TwN5Vrel , TwN5VUndx , TwN5VUndy , TwN5VUndz , TwN6DynP , TwN6Fdx , & - TwN6Fdy , TwN6M , TwN6Re , TwN6STVx , TwN6STVy , TwN6STVz , TwN6Vrel , & - TwN6VUndx , TwN6VUndy , TwN6VUndz , TwN7DynP , TwN7Fdx , TwN7Fdy , TwN7M , & - TwN7Re , TwN7STVx , TwN7STVy , TwN7STVz , TwN7Vrel , TwN7VUndx , TwN7VUndy , & - TwN7VUndz , TwN8DynP , TwN8Fdx , TwN8Fdy , TwN8M , TwN8Re , TwN8STVx , & - TwN8STVy , TwN8STVz , TwN8Vrel , TwN8VUndx , TwN8VUndy , TwN8VUndz , TwN9DynP , & - TwN9Fdx , TwN9Fdy , TwN9M , TwN9Re , TwN9STVx , TwN9STVy , TwN9STVz , & - TwN9Vrel , TwN9VUndx , TwN9VUndy , TwN9VUndz /) - CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(1103) = (/ character(ChanLen) :: & ! This lists the units corresponding to the allowed parameters + B3N6Re , B3N6SgCav , B3N6SigCr , B3N6STVx , B3N6STVy , B3N6STVz , B3N6Theta , & + B3N6TnInd , B3N6VDisx , B3N6VDisy , B3N6VDisz , B3N6Vindx , B3N6Vindy , B3N6VRel , & + B3N6VUndx , B3N6VUndy , B3N6VUndz , B3N7Alpha , B3N7AxInd , B3N7Cd , B3N7Cl , & + B3N7Clrnc , B3N7Cm , B3N7Cn , B3N7Cpmin , B3N7Ct , B3N7Curve , B3N7Cx , & + B3N7Cy , B3N7DynP , B3N7Fd , B3N7Fl , B3N7Fn , B3N7Ft , B3N7Fx , & + B3N7Fy , B3N7M , B3N7Mm , B3N7Phi , B3N7Re , B3N7SgCav , B3N7SigCr , & + B3N7STVx , B3N7STVy , B3N7STVz , B3N7Theta , B3N7TnInd , B3N7VDisx , B3N7VDisy , & + B3N7VDisz , B3N7Vindx , B3N7Vindy , B3N7VRel , B3N7VUndx , B3N7VUndy , B3N7VUndz , & + B3N8Alpha , B3N8AxInd , B3N8Cd , B3N8Cl , B3N8Clrnc , B3N8Cm , B3N8Cn , & + B3N8Cpmin , B3N8Ct , B3N8Curve , B3N8Cx , B3N8Cy , B3N8DynP , B3N8Fd , & + B3N8Fl , B3N8Fn , B3N8Ft , B3N8Fx , B3N8Fy , B3N8M , B3N8Mm , & + B3N8Phi , B3N8Re , B3N8SgCav , B3N8SigCr , B3N8STVx , B3N8STVy , B3N8STVz , & + B3N8Theta , B3N8TnInd , B3N8VDisx , B3N8VDisy , B3N8VDisz , B3N8Vindx , B3N8Vindy , & + B3N8VRel , B3N8VUndx , B3N8VUndy , B3N8VUndz , B3N9Alpha , B3N9AxInd , B3N9Cd , & + B3N9Cl , B3N9Clrnc , B3N9Cm , B3N9Cn , B3N9Cpmin , B3N9Ct , B3N9Curve , & + B3N9Cx , B3N9Cy , B3N9DynP , B3N9Fd , B3N9Fl , B3N9Fn , B3N9Ft , & + B3N9Fx , B3N9Fy , B3N9M , B3N9Mm , B3N9Phi , B3N9Re , B3N9SgCav , & + B3N9SigCr , B3N9STVx , B3N9STVy , B3N9STVz , B3N9Theta , B3N9TnInd , B3N9VDisx , & + B3N9VDisy , B3N9VDisz , B3N9Vindx , B3N9Vindy , B3N9VRel , B3N9VUndx , B3N9VUndy , & + B3N9VUndz , B3Pitch , RtAeroCp , RtAeroCq , RtAeroCt , RtAeroFxh , RtAeroFyh , & + RtAeroFzh , RtAeroMxh , RtAeroMyh , RtAeroMzh , RtAeroPwr , RtArea , RtSkew , & + RtSpeed , RtTSR , RtVAvgxh , RtVAvgyh , RtVAvgzh , TwN1DynP , TwN1Fdx , & + TwN1Fdy , TwN1M , TwN1Re , TwN1STVx , TwN1STVy , TwN1STVz , TwN1Vrel , & + TwN1VUndx , TwN1VUndy , TwN1VUndz , TwN2DynP , TwN2Fdx , TwN2Fdy , TwN2M , & + TwN2Re , TwN2STVx , TwN2STVy , TwN2STVz , TwN2Vrel , TwN2VUndx , TwN2VUndy , & + TwN2VUndz , TwN3DynP , TwN3Fdx , TwN3Fdy , TwN3M , TwN3Re , TwN3STVx , & + TwN3STVy , TwN3STVz , TwN3Vrel , TwN3VUndx , TwN3VUndy , TwN3VUndz , TwN4DynP , & + TwN4Fdx , TwN4Fdy , TwN4M , TwN4Re , TwN4STVx , TwN4STVy , TwN4STVz , & + TwN4Vrel , TwN4VUndx , TwN4VUndy , TwN4VUndz , TwN5DynP , TwN5Fdx , TwN5Fdy , & + TwN5M , TwN5Re , TwN5STVx , TwN5STVy , TwN5STVz , TwN5Vrel , TwN5VUndx , & + TwN5VUndy , TwN5VUndz , TwN6DynP , TwN6Fdx , TwN6Fdy , TwN6M , TwN6Re , & + TwN6STVx , TwN6STVy , TwN6STVz , TwN6Vrel , TwN6VUndx , TwN6VUndy , TwN6VUndz , & + TwN7DynP , TwN7Fdx , TwN7Fdy , TwN7M , TwN7Re , TwN7STVx , TwN7STVy , & + TwN7STVz , TwN7Vrel , TwN7VUndx , TwN7VUndy , TwN7VUndz , TwN8DynP , TwN8Fdx , & + TwN8Fdy , TwN8M , TwN8Re , TwN8STVx , TwN8STVy , TwN8STVz , TwN8Vrel , & + TwN8VUndx , TwN8VUndy , TwN8VUndz , TwN9DynP , TwN9Fdx , TwN9Fdy , TwN9M , & + TwN9Re , TwN9STVx , TwN9STVy , TwN9STVz , TwN9Vrel , TwN9VUndx , TwN9VUndy , & + TwN9VUndz /) + CHARACTER(ChanLen), PARAMETER :: ParamUnitsAry(1184) = (/ & ! This lists the units corresponding to the allowed parameters "(deg) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & - "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & + "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & + "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(deg) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & - "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & + "(m/s) ","(m/s) ","(deg) ","(deg) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & - "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & + "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(deg) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & - "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & - "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & - "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ", & - "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & - "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(deg) ", & - "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ", & + "(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & - "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & + "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & + "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ", & "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & - "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & - "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & + "(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & + "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(deg) ", & + "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & - "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ", & "(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ", & "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ", & - "(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(-) ","(-) ","(m) ","(-) ","(-) ","(-) ","(-) ", & + "(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ", & + "(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ","(m) ", & + "(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & + "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & + "(-) ","(-) ","(-) ","(m) ","(-) ","(-) ","(-) ", & + "(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ", & + "(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ", & "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ","(-) ", & - "(m) ","(-) ","(-) ","(-) ","(deg) ","(-) ","(-) ", & - "(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & - "(-) ","(N·m/m) ","(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & + "(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ","(-) ", & + "(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ","(-) ", & + "(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(deg) ","(-) ","(-) ","(-) ","(m) ","(-) ","(-) ", & + "(-) ","(-) ","(deg) ","(-) ","(-) ","(Pa) ","(N/m) ", & + "(N/m) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ","(-) ","(N·m/m) ", & + "(deg) ","(-) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & "(deg) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(-) ", & - "(-) ","(N) ","(N) ","(N) ","(N·m) ","(N·m) ","(N·m) ", & - "(W) ","(m^2) ","(deg) ","(rpm) ","(-) ","(m/s) ","(m/s) ", & + "(-) ","(m) ","(-) ","(-) ","(-) ","(-) ","(deg) ", & + "(-) ","(-) ","(Pa) ","(N/m) ","(N/m) ","(N/m) ","(N/m) ", & + "(N/m) ","(N/m) ","(-) ","(N·m/m) ","(deg) ","(-) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(deg) ","(-) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(deg) ","(-) ","(-) ","(-) ","(N) ","(N) ", & + "(N) ","(N·m) ","(N·m) ","(N·m) ","(W) ","(m^2) ","(deg) ", & + "(rpm) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ", & + "(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & + "(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ", & + "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ", & "(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & @@ -3087,10 +3264,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) "(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & "(m/s) ","(m/s) ","(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ", & "(-) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(Pa) ","(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(m/s) ","(Pa) ", & - "(N/m) ","(N/m) ","(-) ","(-) ","(m/s) ","(m/s) ","(m/s) ", & - "(m/s) ","(m/s) ","(m/s) ","(m/s) "/) + "(m/s) "/) ! Initialize values @@ -3100,7 +3274,7 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) ! ..... Developer must add checking for invalid inputs here: ..... - !bjj: do we want to avoid outputting this if we haven't used tower aero? +!bjj: do we want to avoid outputting this if we haven't used tower aero? if ( p%TwrPotent == TwrPotent_none .and. .not. p%TwrShadow ) then @@ -3208,7 +3382,6 @@ SUBROUTINE SetOutParam(OutList, p, ErrStat, ErrMsg ) InvalidOutput( BNClrnc(i,:) ) = .true. END DO - ! ................. End of validity checking ................. @@ -3296,5 +3469,4 @@ END SUBROUTINE SetOutParam !********************************************************************************************************************************** - END MODULE AeroDyn_IO diff --git a/modules-local/aerodyn/src/AeroDyn_Registry.txt b/modules-local/aerodyn/src/AeroDyn_Registry.txt index f9373e98e..d93afecf9 100644 --- a/modules-local/aerodyn/src/AeroDyn_Registry.txt +++ b/modules-local/aerodyn/src/AeroDyn_Registry.txt @@ -65,9 +65,12 @@ typedef ^ AD_InputFile IntKi TwrPotent - - - "Type tower influence on wind based typedef ^ AD_InputFile LOGICAL TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow?" - typedef ^ AD_InputFile LOGICAL TwrAero - - - "Calculate tower aerodynamic loads?" flag typedef ^ AD_InputFile Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - +typedef ^ AD_InputFile Logical CavitCheck - - - "Flag that tells us if we want to check for cavitation" - typedef ^ AD_InputFile ReKi AirDens - - - "Air density" kg/m^3 typedef ^ AD_InputFile ReKi KinVisc - - - "Kinematic air viscosity" m^2/s -typedef ^ AD_InputFile ReKi SpdSound - - - "Speed of sound" m/s +typedef ^ AD_InputFile ReKi Patm - - - "Atmospheric pressure" Pa +typedef ^ AD_InputFile ReKi Pvap - - - "Vapour pressure" Pa +typedef ^ AD_InputFile ReKi FluidDepth - - - "Submerged hub depth" m typedef ^ AD_InputFile IntKi SkewMod - - - "Type of skewed-wake correction model {1=uncoupled, 2=Pitt/Peters, 3=coupled} [used only when WakeMod=1]" - typedef ^ AD_InputFile LOGICAL TipLoss - - - "Use the Prandtl tip-loss model? [used only when WakeMod=1]" flag typedef ^ AD_InputFile LOGICAL HubLoss - - - "Use the Prandtl hub-loss model? [used only when WakeMod=1]" flag diff --git a/modules-local/aerodyn/src/AirfoilInfo.f90 b/modules-local/aerodyn/src/AirfoilInfo.f90 index a8ef71e0f..a695cdaf2 100644 --- a/modules-local/aerodyn/src/AirfoilInfo.f90 +++ b/modules-local/aerodyn/src/AirfoilInfo.f90 @@ -110,6 +110,7 @@ SUBROUTINE AFI_Init ( InitInput, p, ErrStat, ErrMsg, UnEcho ) p%ColCd = 2 p%ColCm = 0 ! These may or may not be used; initialize to zero in case they aren't used p%ColCpmin = 0 ! These may or may not be used; initialize to zero in case they aren't used + IF ( InitInput%InCol_Cm > 0 ) THEN p%ColCm = 3 IF ( InitInput%InCol_Cpmin > 0 ) THEN @@ -119,8 +120,8 @@ SUBROUTINE AFI_Init ( InitInput, p, ErrStat, ErrMsg, UnEcho ) p%ColCpmin = 3 END IF NumCoefs = MAX(p%ColCd, p%ColCm,p%ColCpmin) ! number of non-zero coefficient columns - + ! Process the airfoil files. ALLOCATE ( p%AFInfo( InitInput%NumAFfiles ), STAT=ErrStat2 ) @@ -129,6 +130,9 @@ SUBROUTINE AFI_Init ( InitInput, p, ErrStat, ErrMsg, UnEcho ) RETURN ENDIF + p%AFInfo( :)%ColCpmin=p%ColCpmin + p%AFInfo( :)%ColCm=p%ColCm + DO File=1,InitInput%NumAFfiles @@ -496,6 +500,7 @@ SUBROUTINE ReadAFfile ( AFfile, NumCoefs, InCol_Alfa, InCol_Cl, InCol_Cd, InCol_ TYPE (AFInfoType), INTENT(INOUT) :: AFInfo ! The derived type for holding the constant parameters for this airfoil. + ! Local declarations. REAL(ReKi) :: Coords (2) ! An array to hold data from the airfoil-shape table. @@ -805,6 +810,8 @@ SUBROUTINE ReadAFfile ( AFfile, NumCoefs, InCol_Alfa, InCol_Cl, InCol_Cd, InCol_ CALL Cleanup() RETURN ENDIF + + DO Row=1,AFInfo%Table(Table)%NumAlf diff --git a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt index 62858637e..03c27c0ae 100644 --- a/modules-local/aerodyn/src/AirfoilInfo_Registry.txt +++ b/modules-local/aerodyn/src/AirfoilInfo_Registry.txt @@ -94,6 +94,8 @@ typedef ^ ^ INTEGER NumCpminAoAkts - - - "The number of angle-of-attack knots fo typedef ^ ^ INTEGER NumCpminReKts - - - "The number of log(Re) knots for 2D splines of Cpmin" - typedef ^ ^ INTEGER NumTabs - - - "The number of airfoil tables in the airfoil file" - typedef ^ ^ AFI_Table_Type Table {:} - - "The tables of airfoil data for given Re and control setting" - +typedef ^ ^ INTEGER ColCpmin - - - "Column number for Cpmin" - +typedef ^ ^ INTEGER ColCm - - - "Column number for Cm" - # ..... Initialization data ....................................................................................................... # The following derived type stores information that comes from the calling module (say, AeroDyn): diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index caf0e3300..f53265922 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -162,6 +162,9 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numBladeNodes = InitInp%numBladeNodes p%numBlades = InitInp%numBlades p%UA_Flag = InitInp%UA_Flag + p%CavitCheck = InitInp%CavitCheck + + allocate ( p%chord(p%numBladeNodes, p%numBlades), STAT = errStat2 ) if ( errStat2 /= 0 ) then @@ -205,10 +208,13 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) end do end do - - !p%DT = InitInp%DT + + !p%DT = InitInp%DT p%airDens = InitInp%airDens - p%kinVisc = InitInp%kinVisc + p%kinVisc = InitInp%kinVisc + p%Patm = InitInp%Patm + p%Pvap = InitInp%Pvap + p%FluidDepth = InitInp%FluidDepth p%skewWakeMod = InitInp%skewWakeMod p%useTipLoss = InitInp%useTipLoss p%useHubLoss = InitInp%useHubLoss @@ -219,6 +225,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numReIterations = InitInp%numReIterations p%maxIndIterations = InitInp%maxIndIterations p%aTol = InitInp%aTol + end subroutine BEMT_SetParameters @@ -431,7 +438,7 @@ end subroutine BEMT_AllocInput !---------------------------------------------------------------------------------------------------------------------------------- -subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) +subroutine BEMT_AllocOutput( y, p, m, errStat, errMsg ) ! This routine is called from BEMT_Init. ! ! @@ -439,6 +446,7 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) type(BEMT_OutputType), intent( out) :: y ! output data type(BEMT_ParameterType), intent(in ) :: p ! Parameters + type(BEMT_MiscVarType), intent(inout) :: m ! Misc/optimization variables integer(IntKi), intent( out) :: errStat ! Error status of the operation character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None @@ -465,6 +473,10 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) call allocAry( y%Cm, p%numBladeNodes, p%numBlades, 'y%Cm', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cl, p%numBladeNodes, p%numBlades, 'y%Cl', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cd, p%numBladeNodes, p%numBlades, 'y%Cd', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( m%Cpmin, p%numBladeNodes, p%numBlades, 'm%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( m%SigmaCavit, p%numBladeNodes, p%numBlades, 'm%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( m%SigmaCavitCrit, p%numBladeNodes, p%numBlades, 'm%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + if (ErrStat >= AbortErrLev) RETURN @@ -482,7 +494,8 @@ subroutine BEMT_AllocOutput( y, p, errStat, errMsg ) y%tanInduction = 0.0_ReKi y%AOA = 0.0_ReKi y%Cl = 0.0_ReKi - y%Cd = 0.0_ReKi + y%Cd = 0.0_ReKi + end subroutine BEMT_AllocOutput @@ -705,6 +718,7 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte write (69,'(A)') ' ' #endif + do j = 1,p%numBlades do i = 1,p%numBladeNodes ! Loop over blades and nodes @@ -726,6 +740,8 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte call WrScr( 'Warning: Turning off Unsteady Aerodynamics because C_nalpha is 0. BladeNode = '//trim(num2lstr(i))//', Blade = '//trim(num2lstr(j)) ) end if + + end do end do @@ -756,7 +772,7 @@ subroutine BEMT_Init( InitInp, u, p, x, xd, z, OtherState, AFInfo, y, misc, Inte !call BEMT_InitOut(p, InitOut, errStat2, errMsg2) !call CheckError( errStat2, errMsg2 ) - call BEMT_AllocOutput(y, p, errStat2, errMsg2) !u is sent so we can create sibling meshes + call BEMT_AllocOutput(y, p, misc, errStat2, errMsg2) !u is sent so we can create sibling meshes call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) if (errStat >= AbortErrLev) then call cleanup() @@ -1081,8 +1097,8 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat ! Local variables: - real(ReKi) :: Re, fzero - real(ReKi) :: Rtip ! maximum rlocal value for node j over all blades + real(ReKi) :: Re, fzero, theta, Vx, Vy + real(ReKi) :: Rtip, SigmaCavitCrit, SigmaCavit ! maximum rlocal value for node j over all blades integer(IntKi) :: i ! Generic index integer(IntKi) :: j ! Loops through nodes / elements @@ -1162,6 +1178,12 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat NodeTxt = '(node '//trim(num2lstr(i))//', blade '//trim(num2lstr(j))//')' + ! local velocities and twist angle + Vx = u%Vx(i,j) + Vy = u%Vy(i,j) + + + ! Set the active blade element for UnsteadyAero m%UA%iBladeNode = i m%UA%iBlade = j @@ -1235,9 +1257,34 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat else ! TODO: When we start using Re, should we use the uninduced Re since we used uninduced Re to solve for the inductions!? Probably this won't change, instead create a Re loop up above. call ComputeSteadyAirfoilCoefs( y%AOA(i,j), y%Re(i,j), AFInfo(p%AFindx(i,j)), & - y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), errStat2, errMsg2 ) + y%Cl(i,j), y%Cd(i,j), y%Cm(i,j), m%Cpmin(i,j), errStat2, errMsg2 ) call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) if (errStat >= AbortErrLev) return + + + + + ! Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth + if ( p%CavitCheck ) then + SigmaCavit= -1* m%Cpmin(i,j) ! Cavitation number on blade node j + + if ( EqualRealNos( y%Vrel(i,j), 0.0_ReKi ) ) then !if Vrel = 0 in certain cases when Prandtls tip and hub loss factors are used, use the relative verlocity without induction + if ( EqualRealNos( Vx, 0.0_ReKi ) .and. EqualRealNos( Vy, 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'Velocity can not be zero for cavitation check, turn off Prandtls tip loss', ErrStat, ErrMsg, RoutineName ) + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * (sqrt((Vx**2 + Vy**2)))**2) ! Critical value of Sigma, cavitation if we go over this + + else + SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this + end if + + + if (SigmaCavitCrit < SigmaCavit) then + call WrScr( NewLine//'Cavitation occured at node # = '//trim(num2lstr(i)//'and blade # = '//trim(num2lstr(j)))) + end if + + m%SigmaCavit(i,j)= SigmaCavit + m%SigmaCavitCrit(i,j)=SigmaCavitCrit + + end if end if @@ -1803,6 +1850,7 @@ subroutine BEMT_UnCoupledSolve( phi, numBlades, airDens, mu, AFInfo, rlocal, cho integer :: i, TestRegionResult logical :: IsValidSolution real(ReKi) :: Re, Vrel + ErrStat = ErrID_None ErrMsg = "" @@ -1931,5 +1979,8 @@ end subroutine BEMT_UnCoupledSolve -end module BEMT - \ No newline at end of file + end module BEMT + + + + diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index 6daa2fc70..991a3d790 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -129,14 +129,14 @@ end subroutine Transform_ClCd_to_CxCy !---------------------------------------------------------------------------------------------------------------------------------- subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & - Cl, Cd, Cm, errStat, errMsg ) + Cl, Cd, Cm, Cpmin, errStat, errMsg ) ! This routine is called from BEMTU_InductionWithResidual and possibly BEMT_CalcOutput. ! Determine the Cl, Cd, Cm, coeficients for a given angle of attack !.................................................................................................................................. real(ReKi), intent(in ) :: AOA real(ReKi), intent(in ) :: Re ! Unused in the current version! type(AFInfoType), intent(in ) :: AFInfo - real(ReKi), intent( out) :: Cl, Cd, Cm + real(ReKi), intent( out) :: Cl, Cd, Cm, Cpmin integer(IntKi), intent( out) :: errStat ! Error status of the operation character(*), intent( out) :: errMsg ! Error message if ErrStat /= ErrID_None @@ -166,12 +166,24 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & , AFInfo%Table(1)%SplineCoefs & , ErrStat, ErrMsg ) - Cl = IntAFCoefs(1) - Cd = IntAFCoefs(2) - Cm = IntAFCoefs(3) - + + Cl = IntAFCoefs(1) + Cd = IntAFCoefs(2) - + + IF ( AFInfo%ColCm > 0 ) THEN ! If there is Cm data, it is in column 3 + Cm = IntAFCoefs(3) + + IF ( AFInfo%ColCpmin > 0 ) THEN + Cpmin = IntAFCoefs(4) + END IF + + ELSE IF ( AFInfo%ColCpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 + Cpmin = IntAFCoefs(3) + END IF + + + end subroutine ComputeSteadyAirfoilCoefs !---------------------------------------------------------------------------------------------------------------------------------- @@ -255,7 +267,7 @@ real(ReKi) function BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, real(ReKi) :: fzero - real(ReKi) :: Cl, Cd, Cx, Cy, Cm + real(ReKi) :: Cl, Cd, Cx, Cy, Cm, Cpmin ErrStat = ErrID_None @@ -275,7 +287,7 @@ real(ReKi) function BEMTU_InductionWithResidual(phi, AOA, Re, numBlades, rlocal, tanInduction = 0.0_ReKi else !if ( (.NOT. VelocityIsZero(Vx)) .AND. (.NOT. VelocityIsZero(Vy)) ) then - call ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, Cl, Cd, Cm, errStat2, errMsg2 ) !bjj: would be nice if this could be done outside this routine (so we don't copy AFInfo so much) + call ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, Cl, Cd, Cm, Cpmin, errStat2, errMsg2 ) !bjj: would be nice if this could be done outside this routine (so we don't copy AFInfo so much) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) if (ErrStat >= AbortErrLev) return @@ -641,4 +653,4 @@ real(reKi) function getHubTipLossCorrection(sphi, useHubLoss, useTipLoss, hubLos end function getHubTipLossCorrection !----------------------------------------------------------------------------------------- -end module BEMTUncoupled \ No newline at end of file +end module BEMTUncoupled diff --git a/modules-local/aerodyn/src/BEMT_Registry.txt b/modules-local/aerodyn/src/BEMT_Registry.txt index 8a791bca7..c3a47fc47 100644 --- a/modules-local/aerodyn/src/BEMT_Registry.txt +++ b/modules-local/aerodyn/src/BEMT_Registry.txt @@ -34,6 +34,9 @@ typedef BEMT/BEMT InitInputType ReKi typedef ^ ^ INTEGER numBlades - - - "Number of blades" - typedef ^ ^ ReKi airDens - - - "Air density" kg/m^3 typedef ^ ^ ReKi kinVisc - - - "Kinematic air viscosity" m^2/s +typedef ^ ^ ReKi Patm - - - "Atmospheric pressure" Pa +typedef ^ ^ ReKi Pvap - - - "Vapour pressure" Pa +typedef ^ ^ ReKi FluidDepth - - - "Submerged hub height" m typedef ^ ^ INTEGER skewWakeMod - - - "Type of skewed-wake correction model [switch] {1=uncoupled, 2=Pitt/Peters, 3=coupled}" - typedef ^ ^ ReKi aTol - - - "Tolerance for the induction solution" - typedef ^ ^ LOGICAL useTipLoss - - - "Use the Prandtl tip-loss model? [flag]" - @@ -52,6 +55,7 @@ typedef ^ ^ ReKi typedef ^ ^ INTEGER UAMod - - - "Model for the dynamic stall equations [1 = Leishman/Beddoes, 2 = Gonzalez, 3 = Minnema]" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - typedef ^ ^ LOGICAL Flookup - - - "Use table lookup for f' and f'' " - +typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to check for cavitation" - typedef ^ ^ ReKi a_s - - - "speed of sound" m/s # # @@ -83,6 +87,7 @@ typedef ^ ^ LOGICAL typedef ^ ^ LOGICAL ValidPhi {:}{:} - - "set to indicate when there is no valid Phi for this node at this time (temporarially turn off induction when this is false)" - typedef ^ OtherStateType Logical nodesInitialized - - - "the node states have been initialized properly" - + # ..... Misc/Optimization variables................................................................................................. # Define any data that are used only for efficiency purposes (these variables are not associated with time): # e.g. indices for searching in an array, large arrays that are local variables in any routine called multiple times, etc. @@ -92,6 +97,9 @@ typedef ^ MiscVarType UA_OutputTy typedef ^ MiscVarType ReKi TnInd_op {:}{:} - - "tangential induction at the operating point (for linearization with frozen wake assumption)" typedef ^ MiscVarType ReKi AxInd_op {:}{:} - - "axial induction at the operating point (for linearization) with frozen wake assumption" typedef ^ MiscVarType Logical UseFrozenWake - - - "flag set to determine if frozen values of TnInd_op and AxInd_op should be used for this calculation in the linearization process" +typedef ^ ^ ReKi Cpmin {:}{:} - - "min Cpressure" - +typedef ^ ^ ReKi SigmaCavitCrit {:}{:} - - "critical cavitation number- inception value (above which cavit will occur)" - +typedef ^ ^ ReKi SigmaCavit {:}{:} - - "cavitation nubmer at node " - # ..... Parameters ................................................................................................................ # Define parameters here: @@ -102,6 +110,9 @@ typedef ^ ^ ReKi typedef ^ ^ INTEGER numBlades - - - "Number of blades" - typedef ^ ^ ReKi airDens - - - "Air density" kg/m^3 typedef ^ ^ ReKi kinVisc - - - "Kinematic air viscosity" m^2/s +typedef ^ ^ ReKi Patm - - - "Atmospheric pressure" Pa +typedef ^ ^ ReKi Pvap - - - "Vapour pressure" Pa +typedef ^ ^ ReKi FluidDepth - - - "Submerged hub height" m typedef ^ ^ INTEGER skewWakeMod - - - "Type of skewed-wake correction model [switch] {1=uncoupled, 2=Pitt/Peters, 3=coupled}" - typedef ^ ^ ReKi aTol - - - "Tolerance for the induction solution" - typedef ^ ^ LOGICAL useTipLoss - - - "Use the Prandtl tip-loss model? [flag]" - @@ -119,6 +130,7 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi zHub {:} - - "Distance to hub for each blade" m typedef ^ ^ UA_ParameterType UA - - - "parameters for UnsteadyAero" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - +typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to use cavitation check" - # # diff --git a/modules-local/aerodyn/src/OutListParameters.xlsx b/modules-local/aerodyn/src/OutListParameters.xlsx index 4ad9f419d995a87a671a1f4b7aaa3bc2942f4792..47003f4c916c61d4da86e8be54bbb638ecbffaf7 100644 GIT binary patch literal 115021 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�cp&qS|XnbPMuFi*mkJ?#h9hKu7rU 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 literal 44503 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 a=d>Uz2@9MDP*5nqzi&Vnefkaj^#1^dM^VNA From 23911d02d71439efff6077449b44cdabb4e89f4f Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 20 Apr 2017 15:38:31 -0600 Subject: [PATCH 47/58] Added Spd sound back in --- modules-local/aerodyn/src/AeroDyn_Registry.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/modules-local/aerodyn/src/AeroDyn_Registry.txt b/modules-local/aerodyn/src/AeroDyn_Registry.txt index d93afecf9..5bb5d1401 100644 --- a/modules-local/aerodyn/src/AeroDyn_Registry.txt +++ b/modules-local/aerodyn/src/AeroDyn_Registry.txt @@ -71,6 +71,7 @@ typedef ^ AD_InputFile ReKi KinVisc - - - "Kinematic air viscosity" m^2/s typedef ^ AD_InputFile ReKi Patm - - - "Atmospheric pressure" Pa typedef ^ AD_InputFile ReKi Pvap - - - "Vapour pressure" Pa typedef ^ AD_InputFile ReKi FluidDepth - - - "Submerged hub depth" m +typedef ^ AD_InputFile ReKi SpdSound - - - "Speed of sound" m/s typedef ^ AD_InputFile IntKi SkewMod - - - "Type of skewed-wake correction model {1=uncoupled, 2=Pitt/Peters, 3=coupled} [used only when WakeMod=1]" - typedef ^ AD_InputFile LOGICAL TipLoss - - - "Use the Prandtl tip-loss model? [used only when WakeMod=1]" flag typedef ^ AD_InputFile LOGICAL HubLoss - - - "Use the Prandtl hub-loss model? [used only when WakeMod=1]" flag From 470771f8d68ac291b6832dcb27835ca65c16a007 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 24 Apr 2017 12:46:07 -0600 Subject: [PATCH 48/58] Update AeroDyn.f90 --- modules-local/aerodyn/src/AeroDyn.f90 | 80 ++++++++++++++++++++------- 1 file changed, 59 insertions(+), 21 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn.f90 b/modules-local/aerodyn/src/AeroDyn.f90 index 065e303fe..8eea1751a 100644 --- a/modules-local/aerodyn/src/AeroDyn.f90 +++ b/modules-local/aerodyn/src/AeroDyn.f90 @@ -93,7 +93,7 @@ subroutine AD_SetInitOut(p, InputFileData, InitOut, errStat, errMsg) errMsg = "" InitOut%AirDens = p%AirDens - + call AllocAry( InitOut%WriteOutputHdr, p%numOuts, 'WriteOutputHdr', errStat2, errMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) @@ -102,7 +102,7 @@ subroutine AD_SetInitOut(p, InputFileData, InitOut, errStat, errMsg) if (ErrStat >= AbortErrLev) return - + #ifdef DBG_OUTS ! Loop over blades and nodes to populate the output channel names and units @@ -220,7 +220,7 @@ subroutine AD_SetInitOut(p, InputFileData, InitOut, errStat, errMsg) end if - + end subroutine AD_SetInitOut @@ -278,11 +278,16 @@ subroutine AD_Init( InitInp, u, p, x, xd, z, OtherState, y, m, Interval, InitOut call DispNVD( AD_Ver ) - + p%NumBlades = InitInp%NumBlades ! need this before reading the AD input file so that we know how many blade files to read !bjj: note that we haven't validated p%NumBlades before using it below! p%RootName = TRIM(InitInp%RootName)//'.AD' + + + + + ! Read the primary AeroDyn input file call ReadInputFiles( InitInp%InputFile, InputFileData, interval, p%RootName, p%NumBlades, UnEcho, ErrStat2, ErrMsg2 ) call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName ) @@ -442,7 +447,14 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) call AllocAry( m%WithoutSweepPitchTwist, 3_IntKi, 3_IntKi, p%NumBlNds, p%numBlades, 'OtherState%WithoutSweepPitchTwist', ErrStat2, ErrMsg2 ) call SetErrStat( errStat2, errMsg2, errStat, errMsg, RoutineName ) - + + call allocAry( m%SigmaCavit, p%NumBlNds, p%numBlades, 'm%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( m%SigmaCavitCrit, p%NumBlNds, p%numBlades, 'm%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + call allocAry( m%Cpmin, p%NumBlNds, p%numBlades, 'm%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) + + m%SigmaCavit=0.0_ReKi !Init to zero for output files in case a cavit check isnt done but output is requested + m%SigmaCavitCrit=0.0_ReKi + ! arrays for output #ifdef DBG_OUTS allocate( m%AllOuts(0:p%NumOuts), STAT=ErrStat2 ) ! allocate starting at zero to account for invalid output channels @@ -507,8 +519,7 @@ subroutine Init_MiscVars(m, p, u, y, errStat, errMsg) m%X_Twr = 0.0_ReKi m%Y_Twr = 0.0_ReKi end if - - + end subroutine Init_MiscVars !---------------------------------------------------------------------------------------------------------------------------------- @@ -845,6 +856,9 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) p%TwrPotent = InputFileData%TwrPotent p%TwrShadow = InputFileData%TwrShadow p%TwrAero = InputFileData%TwrAero + p%CavitCheck = InputFileData%CavitCheck + + if (InitInp%Linearize) then p%FrozenWake = InputFileData%FrozenWake @@ -866,6 +880,10 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) p%AirDens = InputFileData%AirDens p%KinVisc = InputFileData%KinVisc + p%Patm = InputFileData%Patm + p%Pvap = InputFileData%Pvap + p%FluidDepth = InputFileData%FluidDepth + p%SpdSound = InputFileData%SpdSound @@ -1029,7 +1047,7 @@ end subroutine AD_UpdateStates !! The descriptions of the output channels are not given here. Please see the included OutListParameters.xlsx sheet for !! for a complete description of each output parameter. subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) -! NOTE: no matter how many channels are selected for output, all of the outputs are calcalated +! NOTE: no matter how many channels are selected for output, all of the outputs are calculated ! All of the calculated output channels are placed into the m%AllOuts(:), while the channels selected for outputs are ! placed in the y%WriteOutput(:) array. !.................................................................................................................................. @@ -1050,15 +1068,18 @@ subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) integer, parameter :: indx = 1 ! m%BEMT_u(1) is at t; m%BEMT_u(2) is t+dt integer(intKi) :: i + integer(intKi) :: j + integer(intKi) :: ErrStat2 character(ErrMsgLen) :: ErrMsg2 character(*), parameter :: RoutineName = 'AD_CalcOutput' - - + real(ReKi) :: SigmaCavitCrit, SigmaCavit + ErrStat = ErrID_None ErrMsg = "" + call SetInputs(p, u, m, indx, errStat2, errMsg2) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) @@ -1069,12 +1090,33 @@ subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) call SetOutputsFromBEMT(p, m, y ) - + if ( p%TwrAero ) then call ADTwr_CalcOutput(p, u, m, y, ErrStat2, ErrMsg2 ) call SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) end if - + + if ( p%CavitCheck ) then ! Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth + do j = 1,p%numBlades ! Loop through all blades + do i = 1,p%NumBlNds ! Loop through all nodes + + if ( EqualRealNos( m%BEMT_y%Vrel(i,j), 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'Vrel cannot be zero to do a cavitaition check', ErrStat, ErrMsg, RoutineName) + + SigmaCavit= -1* m%BEMT%Cpmin(i,j) ! Local cavitation number on node j + SigmaCavitCrit= ( ( p%Patm + ( p%Gravity * (p%FluidDepth - ( u%BladeMotion(j)%Position(3,i) + u%BladeMotion(j)%TranslationDisp(3,i) - u%HubMotion%Position(3,1))) * p%airDens) - p%Pvap ) / ( 0.5_ReKi * p%airDens * m%BEMT_y%Vrel(i,j)**2)) ! Critical value of Sigma, cavitation occurs if local cavitation number is greater than this + + if (SigmaCavitCrit < SigmaCavit) then + call WrScr( NewLine//'Cavitation occured at blade '//trim(num2lstr(j))//' and node '//trim(num2lstr(i))//'.' ) + end if + + m%SigmaCavit(i,j)= SigmaCavit + m%SigmaCavitCrit(i,j)=SigmaCavitCrit + + end do ! p%NumBlNds + end do ! p%numBlades + end if ! Cavitation check + + !------------------------------------------------------- ! get values to output to file: !------------------------------------------------------- @@ -1100,9 +1142,10 @@ subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) end do ! i - All selected output channels end if + - - + + end subroutine AD_CalcOutput !---------------------------------------------------------------------------------------------------------------------------------- !> Tight coupling routine for solving for the residual of the constraint state equations @@ -1709,12 +1752,8 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, ! set initialization data here: Interval = p%DT InitInp%numBlades = p%NumBlades - InitInp%airDens = InputFileData%AirDens InitInp%kinVisc = InputFileData%KinVisc - InitInp%Patm = InputFileData%Patm - InitInp%Pvap = InputFileData%Pvap - InitInp%FluidDepth = InputFileData%FluidDepth InitInp%skewWakeMod = InputFileData%SkewMod InitInp%aTol = InputFileData%IndToler InitInp%useTipLoss = InputFileData%TipLoss @@ -1767,10 +1806,9 @@ SUBROUTINE Init_BEMTmodule( InputFileData, u_AD, u, p, x, xd, z, OtherState, y, InitInp%UAMod = InputFileData%UAMod InitInp%Flookup = InputFileData%Flookup InitInp%a_s = InputFileData%SpdSound - InitInp%CavitCheck = InputFileData%CavitCheck - - + + if (ErrStat >= AbortErrLev) then call cleanup() return From 363af0ea2f34a2e79dec544e1c0a21b25fd69d6a Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 24 Apr 2017 12:47:09 -0600 Subject: [PATCH 49/58] Update AeroDyn_IO.f90 --- modules-local/aerodyn/src/AeroDyn_IO.f90 | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index ccb548473..3fa8ad8bc 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -1684,16 +1684,16 @@ SUBROUTINE Calc_WriteOutput( p, u, m, y, indx, ErrStat, ErrMsg ) m%AllOuts( BNPhi( beta,k) ) = m%BEMT_y%phi(j,k)*R2D m%AllOuts( BNCurve(beta,k) ) = m%Curve(j,k)*R2D - m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cl(j,k) - m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cd(j,k) + !m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cl(j,k) + !m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cd(j,k) m%AllOuts( BNCpmin( beta,k) ) = m%BEMT%Cpmin(j,k) - m%AllOuts( BNSigCr( beta,k) ) = m%BEMT%SigmaCavitCrit(j,k) - m%AllOuts( BNSgCav( beta,k) ) = m%BEMT%SigmaCavit(j,k) + m%AllOuts( BNSigCr( beta,k) ) = m%SigmaCavitCrit(j,k) + m%AllOuts( BNSgCav( beta,k) ) = m%SigmaCavit(j,k) cp=cos(m%BEMT_y%phi(j,k)) sp=sin(m%BEMT_y%phi(j,k)) - m%AllOuts( BNCpmin( beta,k) ) = m%BEMT_y%Cx(j,k)*cp + m%BEMT_y%Cy(j,k)*sp + m%AllOuts( BNCl( beta,k) ) = m%BEMT_y%Cx(j,k)*cp + m%BEMT_y%Cy(j,k)*sp m%AllOuts( BNCd( beta,k) ) = m%BEMT_y%Cx(j,k)*sp - m%BEMT_y%Cy(j,k)*cp m%AllOuts( BNCm( beta,k) ) = m%BEMT_y%Cm(j,k) m%AllOuts( BNCx( beta,k) ) = m%BEMT_y%Cx(j,k) @@ -1826,7 +1826,6 @@ SUBROUTINE ReadInputFiles( InputFileName, InputFileData, Default_DT, OutFileRoot RETURN END IF - ! get the blade input-file data ALLOCATE( InputFileData%BladeProps( NumBlades ), STAT = ErrStat2 ) From 046a48c427fc1947514fc70cafae6d6a7fa3a9ad Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 24 Apr 2017 12:47:55 -0600 Subject: [PATCH 50/58] Update AeroDyn_Registry.txt --- modules-local/aerodyn/src/AeroDyn_Registry.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules-local/aerodyn/src/AeroDyn_Registry.txt b/modules-local/aerodyn/src/AeroDyn_Registry.txt index 5bb5d1401..7fea59ebd 100644 --- a/modules-local/aerodyn/src/AeroDyn_Registry.txt +++ b/modules-local/aerodyn/src/AeroDyn_Registry.txt @@ -136,6 +136,10 @@ typedef ^ MiscVarType ReKi V_DiskAvg {3} - - "disk-average relative wind speed" typedef ^ MiscVarType ReKi V_dot_x - - - typedef ^ MiscVarType MeshType HubLoad - - - "mesh at hub; used to compute an integral for mapping the output blade loads to a single point (for writing to file only)" - typedef ^ MiscVarType MeshMapType B_L_2_H_P {:} - - "mapping data structure to map each bladeLoad output mesh to the MiscVar%HubLoad mesh" +typedef ^ MiscVarType ReKi SigmaCavitCrit {:}{:} - - "critical cavitation number- inception value (above which cavit will occur)" - +typedef ^ MiscVarType ReKi SigmaCavit {:}{:} - - "cavitation nubmer at node " - +typedef ^ MiscVarType ReKi Cpmin {:}{:} - - "min Cpressure" - + # ..... Parameters ................................................................................................................ # Define parameters here: @@ -146,6 +150,7 @@ typedef ^ ParameterType IntKi TwrPotent - - - "Type tower influence on wind base typedef ^ ParameterType LOGICAL TwrShadow - - - "Calculate tower influence on wind based on downstream tower shadow?" - typedef ^ ParameterType LOGICAL TwrAero - - - "Calculate tower aerodynamic loads?" flag typedef ^ ParameterType Logical FrozenWake - - - "Flag that tells this module it should assume a frozen wake during linearization." - +typedef ^ ParameterType Logical CavitCheck - - - "Flag that tells us if we want to check for cavitation" - typedef ^ ParameterType IntKi NumBlades - - - "Number of blades on the turbine" - typedef ^ ParameterType IntKi NumBlNds - - - "Number of nodes on each blade" - typedef ^ ParameterType IntKi NumTwrNds - - - "Number of nodes on the tower" - @@ -154,6 +159,10 @@ typedef ^ ParameterType ReKi TwrCd {:} - - "Coefficient of drag at tower node" - typedef ^ ParameterType ReKi AirDens - - - "Air density" kg/m^3 typedef ^ ParameterType ReKi KinVisc - - - "Kinematic air viscosity" m^2/s typedef ^ ParameterType ReKi SpdSound - - - "Speed of sound" m/s +typedef ^ ParameterType ReKi Gravity - - - "Gravitational acceleration" m/s^2 +typedef ^ ParameterType ReKi Patm - - - "Atmospheric pressure" Pa +typedef ^ ParameterType ReKi Pvap - - - "Vapour pressure" Pa +typedef ^ ParameterType ReKi FluidDepth - - - "Submerged hub height" m typedef ^ ParameterType AFI_ParameterType AFI - - - "AirfoilInfo parameters" typedef ^ ParameterType BEMT_ParameterType BEMT - - - "Parameters for BEMT module" # parameters for output From 4cc8c7d229b189e5740d7a33035bb9941de5f6c5 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 24 Apr 2017 12:48:26 -0600 Subject: [PATCH 51/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 37 ++++-------------------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index f53265922..37226eb6c 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -162,7 +162,6 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numBladeNodes = InitInp%numBladeNodes p%numBlades = InitInp%numBlades p%UA_Flag = InitInp%UA_Flag - p%CavitCheck = InitInp%CavitCheck @@ -212,9 +211,6 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) !p%DT = InitInp%DT p%airDens = InitInp%airDens p%kinVisc = InitInp%kinVisc - p%Patm = InitInp%Patm - p%Pvap = InitInp%Pvap - p%FluidDepth = InitInp%FluidDepth p%skewWakeMod = InitInp%skewWakeMod p%useTipLoss = InitInp%useTipLoss p%useHubLoss = InitInp%useHubLoss @@ -225,6 +221,7 @@ subroutine BEMT_SetParameters( InitInp, p, errStat, errMsg ) p%numReIterations = InitInp%numReIterations p%maxIndIterations = InitInp%maxIndIterations p%aTol = InitInp%aTol + end subroutine BEMT_SetParameters @@ -474,9 +471,7 @@ subroutine BEMT_AllocOutput( y, p, m, errStat, errMsg ) call allocAry( y%Cl, p%numBladeNodes, p%numBlades, 'y%Cl', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( y%Cd, p%numBladeNodes, p%numBlades, 'y%Cd', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) call allocAry( m%Cpmin, p%numBladeNodes, p%numBlades, 'm%Cpmin', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( m%SigmaCavit, p%numBladeNodes, p%numBlades, 'm%SigmaCavit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - call allocAry( m%SigmaCavitCrit, p%numBladeNodes, p%numBlades, 'm%SigmaCavitCrit', errStat2, errMsg2); call setErrStat(errStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName) - + if (ErrStat >= AbortErrLev) RETURN @@ -495,6 +490,7 @@ subroutine BEMT_AllocOutput( y, p, m, errStat, errMsg ) y%AOA = 0.0_ReKi y%Cl = 0.0_ReKi y%Cd = 0.0_ReKi + end subroutine BEMT_AllocOutput @@ -1098,7 +1094,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat real(ReKi) :: Re, fzero, theta, Vx, Vy - real(ReKi) :: Rtip, SigmaCavitCrit, SigmaCavit ! maximum rlocal value for node j over all blades + real(ReKi) :: Rtip! maximum rlocal value for node j over all blades integer(IntKi) :: i ! Generic index integer(IntKi) :: j ! Loops through nodes / elements @@ -1261,30 +1257,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName//trim(NodeTxt)) if (errStat >= AbortErrLev) return - - - - ! Calculate the cavitation number for the airfoil at the node in quesiton, and compare to the critical cavitation number based on the vapour pressure and submerged depth - if ( p%CavitCheck ) then - SigmaCavit= -1* m%Cpmin(i,j) ! Cavitation number on blade node j - - if ( EqualRealNos( y%Vrel(i,j), 0.0_ReKi ) ) then !if Vrel = 0 in certain cases when Prandtls tip and hub loss factors are used, use the relative verlocity without induction - if ( EqualRealNos( Vx, 0.0_ReKi ) .and. EqualRealNos( Vy, 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'Velocity can not be zero for cavitation check, turn off Prandtls tip loss', ErrStat, ErrMsg, RoutineName ) - SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * (sqrt((Vx**2 + Vy**2)))**2) ! Critical value of Sigma, cavitation if we go over this - - else - SigmaCavitCrit= ( ( p%Patm + ( 9.81_ReKi * (p%FluidDepth - ( u%rlocal(i,j))* cos(u%psi(j) )) * p%airDens)) - p%Pvap ) / ( 0.5_ReKi * p%airDens * y%Vrel(i,j)**2) ! Critical value of Sigma, cavitation if we go over this - end if - - - if (SigmaCavitCrit < SigmaCavit) then - call WrScr( NewLine//'Cavitation occured at node # = '//trim(num2lstr(i)//'and blade # = '//trim(num2lstr(j)))) - end if - - m%SigmaCavit(i,j)= SigmaCavit - m%SigmaCavitCrit(i,j)=SigmaCavitCrit - - end if + end if From eac219d2d4f48e4f163169a9cf0af9ba7a7d8d41 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 24 Apr 2017 12:48:47 -0600 Subject: [PATCH 52/58] Update BEMTUncoupled.f90 --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index 991a3d790..1df25a28b 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -176,13 +176,12 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & IF ( AFInfo%ColCpmin > 0 ) THEN Cpmin = IntAFCoefs(4) - END IF + END IF ELSE IF ( AFInfo%ColCpmin > 0 ) THEN ! If there is Cpmin data and no Cm data, Cpmin is in column 3 Cpmin = IntAFCoefs(3) END IF - end subroutine ComputeSteadyAirfoilCoefs From ac43abc298fa2c6a841b88bc26a375366f82688b Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Mon, 24 Apr 2017 12:49:10 -0600 Subject: [PATCH 53/58] Update BEMT_Registry.txt --- modules-local/aerodyn/src/BEMT_Registry.txt | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/modules-local/aerodyn/src/BEMT_Registry.txt b/modules-local/aerodyn/src/BEMT_Registry.txt index c3a47fc47..224db4b2c 100644 --- a/modules-local/aerodyn/src/BEMT_Registry.txt +++ b/modules-local/aerodyn/src/BEMT_Registry.txt @@ -34,9 +34,6 @@ typedef BEMT/BEMT InitInputType ReKi typedef ^ ^ INTEGER numBlades - - - "Number of blades" - typedef ^ ^ ReKi airDens - - - "Air density" kg/m^3 typedef ^ ^ ReKi kinVisc - - - "Kinematic air viscosity" m^2/s -typedef ^ ^ ReKi Patm - - - "Atmospheric pressure" Pa -typedef ^ ^ ReKi Pvap - - - "Vapour pressure" Pa -typedef ^ ^ ReKi FluidDepth - - - "Submerged hub height" m typedef ^ ^ INTEGER skewWakeMod - - - "Type of skewed-wake correction model [switch] {1=uncoupled, 2=Pitt/Peters, 3=coupled}" - typedef ^ ^ ReKi aTol - - - "Tolerance for the induction solution" - typedef ^ ^ LOGICAL useTipLoss - - - "Use the Prandtl tip-loss model? [flag]" - @@ -55,7 +52,6 @@ typedef ^ ^ ReKi typedef ^ ^ INTEGER UAMod - - - "Model for the dynamic stall equations [1 = Leishman/Beddoes, 2 = Gonzalez, 3 = Minnema]" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - typedef ^ ^ LOGICAL Flookup - - - "Use table lookup for f' and f'' " - -typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to check for cavitation" - typedef ^ ^ ReKi a_s - - - "speed of sound" m/s # # @@ -98,9 +94,7 @@ typedef ^ MiscVarType ReKi typedef ^ MiscVarType ReKi AxInd_op {:}{:} - - "axial induction at the operating point (for linearization) with frozen wake assumption" typedef ^ MiscVarType Logical UseFrozenWake - - - "flag set to determine if frozen values of TnInd_op and AxInd_op should be used for this calculation in the linearization process" typedef ^ ^ ReKi Cpmin {:}{:} - - "min Cpressure" - -typedef ^ ^ ReKi SigmaCavitCrit {:}{:} - - "critical cavitation number- inception value (above which cavit will occur)" - -typedef ^ ^ ReKi SigmaCavit {:}{:} - - "cavitation nubmer at node " - - + # ..... Parameters ................................................................................................................ # Define parameters here: # Time step for integration of continuous states (if a fixed-step integrator is used) and update of discrete states: @@ -110,9 +104,6 @@ typedef ^ ^ ReKi typedef ^ ^ INTEGER numBlades - - - "Number of blades" - typedef ^ ^ ReKi airDens - - - "Air density" kg/m^3 typedef ^ ^ ReKi kinVisc - - - "Kinematic air viscosity" m^2/s -typedef ^ ^ ReKi Patm - - - "Atmospheric pressure" Pa -typedef ^ ^ ReKi Pvap - - - "Vapour pressure" Pa -typedef ^ ^ ReKi FluidDepth - - - "Submerged hub height" m typedef ^ ^ INTEGER skewWakeMod - - - "Type of skewed-wake correction model [switch] {1=uncoupled, 2=Pitt/Peters, 3=coupled}" - typedef ^ ^ ReKi aTol - - - "Tolerance for the induction solution" - typedef ^ ^ LOGICAL useTipLoss - - - "Use the Prandtl tip-loss model? [flag]" - From 5a5190a4de6671fc0dae75e1a6d9bb17ab3752b3 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 27 Apr 2017 08:26:39 -0600 Subject: [PATCH 54/58] Update AeroDyn.f90 --- modules-local/aerodyn/src/AeroDyn.f90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules-local/aerodyn/src/AeroDyn.f90 b/modules-local/aerodyn/src/AeroDyn.f90 index 8eea1751a..166e84cb5 100644 --- a/modules-local/aerodyn/src/AeroDyn.f90 +++ b/modules-local/aerodyn/src/AeroDyn.f90 @@ -857,6 +857,7 @@ subroutine SetParameters( InitInp, InputFileData, p, ErrStat, ErrMsg ) p%TwrShadow = InputFileData%TwrShadow p%TwrAero = InputFileData%TwrAero p%CavitCheck = InputFileData%CavitCheck + p%Gravity = 9.81_Reki @@ -1100,7 +1101,8 @@ subroutine AD_CalcOutput( t, u, p, x, xd, z, OtherState, y, m, ErrStat, ErrMsg ) do j = 1,p%numBlades ! Loop through all blades do i = 1,p%NumBlNds ! Loop through all nodes - if ( EqualRealNos( m%BEMT_y%Vrel(i,j), 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'Vrel cannot be zero to do a cavitaition check', ErrStat, ErrMsg, RoutineName) + if ( EqualRealNos( m%BEMT_y%Vrel(i,j), 0.0_ReKi ) ) call SetErrStat( ErrID_Fatal, 'Vrel cannot be zero to do a cavitation check', ErrStat, ErrMsg, RoutineName) + if (ErrStat >= AbortErrLev) return SigmaCavit= -1* m%BEMT%Cpmin(i,j) ! Local cavitation number on node j SigmaCavitCrit= ( ( p%Patm + ( p%Gravity * (p%FluidDepth - ( u%BladeMotion(j)%Position(3,i) + u%BladeMotion(j)%TranslationDisp(3,i) - u%HubMotion%Position(3,1))) * p%airDens) - p%Pvap ) / ( 0.5_ReKi * p%airDens * m%BEMT_y%Vrel(i,j)**2)) ! Critical value of Sigma, cavitation occurs if local cavitation number is greater than this @@ -1463,7 +1465,7 @@ SUBROUTINE ValidateInputData( InitInp, InputFileData, NumBl, ErrStat, ErrMsg ) if (InputFileData%SpdSound <= 0.0) call SetErrStat ( ErrID_Fatal, 'The speed of sound (SpdSound) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) if (InputFileData%Pvap <= 0.0) call SetErrStat ( ErrID_Fatal, 'The vapour pressure (Pvap) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) if (InputFileData%Patm <= 0.0) call SetErrStat ( ErrID_Fatal, 'The atmospheric pressure (Patm) must be greater than zero.', ErrStat, ErrMsg, RoutineName ) - if (InputFileData%FluidDepth <= 0.0) call SetErrStat ( ErrID_Fatal, 'Fluid depth (FluidDepth) cannot be negative', ErrStat, ErrMsg, RoutineName ) + if (InputFileData%FluidDepth <= 0.0) call SetErrStat ( ErrID_Fatal, 'Fluid depth (FluidDepth) must be greater than zero', ErrStat, ErrMsg, RoutineName ) From 3ac62e65f324647d81c7618a2dc434ab367246da Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 27 Apr 2017 08:27:22 -0600 Subject: [PATCH 55/58] Update AeroDyn_IO.f90 --- modules-local/aerodyn/src/AeroDyn_IO.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/AeroDyn_IO.f90 b/modules-local/aerodyn/src/AeroDyn_IO.f90 index 3fa8ad8bc..fce661728 100644 --- a/modules-local/aerodyn/src/AeroDyn_IO.f90 +++ b/modules-local/aerodyn/src/AeroDyn_IO.f90 @@ -32,7 +32,7 @@ MODULE AeroDyn_IO implicit none - type(ProgDesc), parameter :: AD_Ver = ProgDesc( 'AeroDyn', 'v15.04.00', '29-Oct-2016' ) + type(ProgDesc), parameter :: AD_Ver = ProgDesc( 'AeroDyn', 'v15.04.00', '25-Apr-2017' ) character(*), parameter :: AD_Nickname = 'AD' ! =================================================================================================== From d12b7da1a72ccf6a1f38ad2f7ee2821d73bc4e25 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 27 Apr 2017 08:28:18 -0600 Subject: [PATCH 56/58] Update BEMT_Registry.txt --- modules-local/aerodyn/src/BEMT_Registry.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/modules-local/aerodyn/src/BEMT_Registry.txt b/modules-local/aerodyn/src/BEMT_Registry.txt index 224db4b2c..8dc1258d6 100644 --- a/modules-local/aerodyn/src/BEMT_Registry.txt +++ b/modules-local/aerodyn/src/BEMT_Registry.txt @@ -121,7 +121,6 @@ typedef ^ ^ ReKi typedef ^ ^ ReKi zHub {:} - - "Distance to hub for each blade" m typedef ^ ^ UA_ParameterType UA - - - "parameters for UnsteadyAero" - typedef ^ ^ LOGICAL UA_Flag - - - "logical flag indicating whether to use UnsteadyAero" - -typedef ^ ^ LOGICAL CavitCheck - - - "logical flag indicating whether to use cavitation check" - # # From 6cfc6e24df303b544e34220069ec2a7492e38a85 Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 27 Apr 2017 08:28:59 -0600 Subject: [PATCH 57/58] Update BEMTUncoupled.f90 --- modules-local/aerodyn/src/BEMTUncoupled.f90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/BEMTUncoupled.f90 b/modules-local/aerodyn/src/BEMTUncoupled.f90 index 1df25a28b..09ace3b01 100644 --- a/modules-local/aerodyn/src/BEMTUncoupled.f90 +++ b/modules-local/aerodyn/src/BEMTUncoupled.f90 @@ -169,7 +169,8 @@ subroutine ComputeSteadyAirfoilCoefs( AOA, Re, AFInfo, & Cl = IntAFCoefs(1) Cd = IntAFCoefs(2) - + Cm = 0.0_Reki !Set these to zero unless there is data to be read in + Cpmin = 0.0_Reki IF ( AFInfo%ColCm > 0 ) THEN ! If there is Cm data, it is in column 3 Cm = IntAFCoefs(3) From 53d01f580aa0498a66330b637e08256b944c00ef Mon Sep 17 00:00:00 2001 From: robynnemurrayNREL Date: Thu, 27 Apr 2017 08:31:26 -0600 Subject: [PATCH 58/58] Update BEMT.f90 --- modules-local/aerodyn/src/BEMT.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules-local/aerodyn/src/BEMT.f90 b/modules-local/aerodyn/src/BEMT.f90 index 37226eb6c..2bc4280c9 100644 --- a/modules-local/aerodyn/src/BEMT.f90 +++ b/modules-local/aerodyn/src/BEMT.f90 @@ -1093,7 +1093,7 @@ subroutine BEMT_CalcOutput( t, u, p, x, xd, z, OtherState, AFInfo, y, m, errStat ! Local variables: - real(ReKi) :: Re, fzero, theta, Vx, Vy + real(ReKi) :: Re, fzero real(ReKi) :: Rtip! maximum rlocal value for node j over all blades integer(IntKi) :: i ! Generic index