|
| 1 | + |
| 2 | +MODULE WaveTankTesting |
| 3 | + |
| 4 | + USE ISO_C_BINDING |
| 5 | + USE NWTC_Library |
| 6 | + ! USE Precision |
| 7 | + USE MoorDyn_C |
| 8 | + USE SeaState_C_Binding |
| 9 | + USE NWTC_C_Binding, ONLY: IntfStrLen, SetErr |
| 10 | + |
| 11 | + IMPLICIT NONE |
| 12 | + SAVE |
| 13 | + |
| 14 | + PUBLIC :: WaveTank_Init |
| 15 | + |
| 16 | + REAL(C_DOUBLE) :: dt_c = 0.01_C_DOUBLE ! 100 hertz |
| 17 | + REAL(C_FLOAT) :: g_c = 9.8065_C_FLOAT |
| 18 | + REAL(C_FLOAT) :: rho_c = 1025.0_C_FLOAT |
| 19 | + REAL(C_FLOAT) :: depth_c = 200.0_C_FLOAT |
| 20 | + REAL(C_FLOAT), DIMENSION(6) :: ptfminit_c = 0.0_C_FLOAT |
| 21 | + INTEGER(C_INT) :: interporder_c = 2 ! 1: linear (uses two time steps) or 2: quadratic (uses three time steps) |
| 22 | + |
| 23 | + INTEGER(C_INT) :: N_CAMERA_POINTS |
| 24 | + |
| 25 | + INTEGER(C_INT) :: load_period = 20 ! seconds |
| 26 | + |
| 27 | +CONTAINS |
| 28 | + |
| 29 | +SUBROUTINE SetErrStat_C(ErrStatLocal, ErrMessLocal, ErrStatGlobal, ErrMessGlobal, RoutineName) |
| 30 | + |
| 31 | +INTEGER(C_INT), INTENT(IN ) :: ErrStatLocal ! Error status of the operation |
| 32 | +CHARACTER(*, KIND=C_CHAR), INTENT(IN ) :: ErrMessLocal ! Error message if ErrStat /= ErrID_None |
| 33 | +INTEGER(C_INT), INTENT(INOUT) :: ErrStatGlobal ! Error status of the operation |
| 34 | +CHARACTER(KIND=C_CHAR), INTENT(INOUT) :: ErrMessGlobal ! Error message if ErrStat /= ErrID_None |
| 35 | +CHARACTER(*), INTENT(IN ) :: RoutineName ! Name of the routine error occurred in |
| 36 | + |
| 37 | +IF ( ErrStatLocal == ErrID_None ) RETURN |
| 38 | + |
| 39 | +IF (ErrStatGlobal /= ErrID_None) ErrMessGlobal = TRIM(ErrMessGlobal)//new_line('a') |
| 40 | +ErrMessGlobal = TRIM(ErrMessGlobal)//TRIM(RoutineName)//':'//TRIM(ErrMessLocal) |
| 41 | +ErrStatGlobal = MAX(ErrStatGlobal,ErrStatLocal) |
| 42 | + |
| 43 | +END SUBROUTINE |
| 44 | + |
| 45 | +SUBROUTINE WaveTank_Init( & |
| 46 | + MD_InputFile_c, & |
| 47 | + SS_InputFile_c, & |
| 48 | + AD_InputFile_c, & |
| 49 | + IfW_InputFile_c, & |
| 50 | + n_camera_points_c, & |
| 51 | + ErrStat_c, & |
| 52 | + ErrMsg_c & |
| 53 | +) BIND (C, NAME='WaveTank_Init') |
| 54 | +#ifndef IMPLICIT_DLLEXPORT |
| 55 | +!DEC$ ATTRIBUTES DLLEXPORT :: WaveTank_Init |
| 56 | +!GCC$ ATTRIBUTES DLLEXPORT :: WaveTank_Init |
| 57 | +#endif |
| 58 | + |
| 59 | +IMPLICIT NONE |
| 60 | + |
| 61 | +CHARACTER(KIND=C_CHAR), INTENT(IN ), TARGET :: MD_InputFile_c(IntfStrLen) |
| 62 | +CHARACTER(KIND=C_CHAR), INTENT(IN ), TARGET :: SS_InputFile_c(IntfStrLen) |
| 63 | +CHARACTER(KIND=C_CHAR), INTENT(IN ), TARGET :: AD_InputFile_c(IntfStrLen) |
| 64 | +CHARACTER(KIND=C_CHAR), INTENT(IN ), TARGET :: IfW_InputFile_c(IntfStrLen) |
| 65 | +INTEGER(C_INT), INTENT(IN ) :: n_camera_points_c |
| 66 | +INTEGER(C_INT), INTENT( OUT) :: ErrStat_C |
| 67 | +CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) |
| 68 | + |
| 69 | +! Local variables |
| 70 | +integer(c_int) :: numchannels_c |
| 71 | +character(kind=c_char) :: outputchannelnames_c(100000) |
| 72 | +character(kind=c_char) :: outputchannelunits_c(100000) |
| 73 | +integer(c_int) :: input_file_passed = 0 ! We're passing paths to input files rather than input strings for all modules |
| 74 | +! character(kind=c_char), pointer :: filestring_c(IntfStrLen) ! Point to input file path input argument |
| 75 | + |
| 76 | +print *, MD_InputFile_c |
| 77 | +print *, SS_InputFile_c |
| 78 | +print *, AD_InputFile_c |
| 79 | +print *, IfW_InputFile_c |
| 80 | + |
| 81 | +N_CAMERA_POINTS = n_camera_points_c |
| 82 | + |
| 83 | +! filestring_c => MD_InputFile_c |
| 84 | +! call MD_C_Init( & |
| 85 | +! input_file_passed, & |
| 86 | +! filestring_c, & |
| 87 | +! IntfStrLen, & |
| 88 | +! dt_c, & |
| 89 | +! g_c, & |
| 90 | +! rho_c, & |
| 91 | +! depth_c, & |
| 92 | +! ptfminit_c, & |
| 93 | +! interporder_c, & |
| 94 | +! numchannels_c, & |
| 95 | +! outputchannelnames_c, & |
| 96 | +! outputchannelunits_c, & |
| 97 | +! ErrStat_C, ErrMsg_C & |
| 98 | +! ) |
| 99 | + |
| 100 | +! call ADI_C_Init( & |
| 101 | +! ADinputFilePassed, & ! integer(c_int), intent(in ) :: ADinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] |
| 102 | +! ADinputFileString_C, & ! type(c_ptr), intent(in ) :: ADinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR |
| 103 | +! ADinputFileStringLength_C, & ! integer(c_int), intent(in ) :: ADinputFileStringLength_C !< lenght of the input file string |
| 104 | +! IfWinputFilePassed, & ! integer(c_int), intent(in ) :: IfWinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] |
| 105 | +! IfWinputFileString_C, & ! type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR |
| 106 | +! IfWinputFileStringLength_C, & ! integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string |
| 107 | +! OutRootName_C, & ! character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other |
| 108 | +! OutVTKDir_C, & ! character(kind=c_char), intent(in ) :: OutVTKDir_C(IntfStrLen) !< Directory to put all vtk output |
| 109 | +! gravity_C, & ! real(c_float), intent(in ) :: gravity_C !< Gravitational acceleration (m/s^2) |
| 110 | +! defFldDens_C, & ! real(c_float), intent(in ) :: defFldDens_C !< Air density (kg/m^3) |
| 111 | +! defKinVisc_C, & ! real(c_float), intent(in ) :: defKinVisc_C !< Kinematic viscosity of working fluid (m^2/s) |
| 112 | +! defSpdSound_C, & ! real(c_float), intent(in ) :: defSpdSound_C !< Speed of sound in working fluid (m/s) |
| 113 | +! defPatm_C, & ! real(c_float), intent(in ) :: defPatm_C !< Atmospheric pressure (Pa) [used only for an MHK turbine cavitation check] |
| 114 | +! defPvap_C, & ! real(c_float), intent(in ) :: defPvap_C !< Vapour pressure of working fluid (Pa) [used only for an MHK turbine cavitation check] |
| 115 | +! WtrDpth_C, & ! real(c_float), intent(in ) :: WtrDpth_C !< Water depth (m) |
| 116 | +! MSL2SWL_C, & ! real(c_float), intent(in ) :: MSL2SWL_C !< Offset between still-water level and mean sea level (m) [positive upward] |
| 117 | +! InterpOrder_C, & ! integer(c_int), intent(in ) :: InterpOrder_C !< Interpolation order to use (must be 1 or 2) |
| 118 | +! DT_C, & ! real(c_double), intent(in ) :: DT_C !< Timestep used with AD for stepping forward from t to t+dt. Must be constant. |
| 119 | +! TMax_C, & ! real(c_double), intent(in ) :: TMax_C !< Maximum time for simulation |
| 120 | +! storeHHVel, & ! integer(c_int), intent(in ) :: storeHHVel !< Store hub height time series from IfW |
| 121 | +! WrVTK_in, & ! integer(c_int), intent(in ) :: WrVTK_in !< Write VTK outputs [0: none, 1: init only, 2: animation] |
| 122 | +! WrVTK_inType, & ! integer(c_int), intent(in ) :: WrVTK_inType !< Write VTK outputs as [1: surface, 2: lines, 3: both] |
| 123 | +! WrVTK_inDT, & ! real(c_double), intent(in ) :: WrVTK_inDT !< Timestep between VTK writes |
| 124 | +! VTKNacDim_in, & ! real(c_float), intent(in ) :: VTKNacDim_in(6) !< Nacelle dimension passed in for VTK surface rendering [0,y0,z0,Lx,Ly,Lz] (m) |
| 125 | +! VTKHubRad_in, & ! real(c_float), intent(in ) :: VTKHubrad_in !< Hub radius for VTK surface rendering |
| 126 | +! wrOuts_C, & |
| 127 | +! DT_Outs_C, & |
| 128 | +! NumChannels_C, & |
| 129 | +! OutputChannelNames_C, & |
| 130 | +! OutputChannelUnits_C, & |
| 131 | +! ErrStat_C, ErrMsg_C & |
| 132 | +! ) |
| 133 | + |
| 134 | + |
| 135 | +! ! Input file info |
| 136 | +! integer(c_int), intent(in ) :: ADinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] |
| 137 | +! type(c_ptr), intent(in ) :: ADinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR |
| 138 | +! integer(c_int), intent(in ) :: ADinputFileStringLength_C !< lenght of the input file string |
| 139 | +! integer(c_int), intent(in ) :: IfWinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] |
| 140 | +! type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR |
| 141 | +! integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string |
| 142 | +! character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other |
| 143 | +! character(kind=c_char), intent(in ) :: OutVTKDir_C(IntfStrLen) !< Directory to put all vtk output |
| 144 | +! ! Environmental |
| 145 | +! real(c_float), intent(in ) :: gravity_C !< Gravitational acceleration (m/s^2) |
| 146 | +! real(c_float), intent(in ) :: defFldDens_C !< Air density (kg/m^3) |
| 147 | +! real(c_float), intent(in ) :: defKinVisc_C !< Kinematic viscosity of working fluid (m^2/s) |
| 148 | +! real(c_float), intent(in ) :: defSpdSound_C !< Speed of sound in working fluid (m/s) |
| 149 | +! real(c_float), intent(in ) :: defPatm_C !< Atmospheric pressure (Pa) [used only for an MHK turbine cavitation check] |
| 150 | +! real(c_float), intent(in ) :: defPvap_C !< Vapour pressure of working fluid (Pa) [used only for an MHK turbine cavitation check] |
| 151 | +! real(c_float), intent(in ) :: WtrDpth_C !< Water depth (m) |
| 152 | +! real(c_float), intent(in ) :: MSL2SWL_C !< Offset between still-water level and mean sea level (m) [positive upward] |
| 153 | +! ! Interpolation |
| 154 | +! integer(c_int), intent(in ) :: InterpOrder_C !< Interpolation order to use (must be 1 or 2) |
| 155 | +! ! Time |
| 156 | +! real(c_double), intent(in ) :: DT_C !< Timestep used with AD for stepping forward from t to t+dt. Must be constant. |
| 157 | +! real(c_double), intent(in ) :: TMax_C !< Maximum time for simulation |
| 158 | +! ! Flags |
| 159 | +! integer(c_int), intent(in ) :: storeHHVel !< Store hub height time series from IfW |
| 160 | +! ! VTK |
| 161 | +! integer(c_int), intent(in ) :: WrVTK_in !< Write VTK outputs [0: none, 1: init only, 2: animation] |
| 162 | +! integer(c_int), intent(in ) :: WrVTK_inType !< Write VTK outputs as [1: surface, 2: lines, 3: both] |
| 163 | +! real(c_double), intent(in ) :: WrVTK_inDT !< Timestep between VTK writes |
| 164 | +! real(c_float), intent(in ) :: VTKNacDim_in(6) !< Nacelle dimension passed in for VTK surface rendering [0,y0,z0,Lx,Ly,Lz] (m) |
| 165 | +! real(c_float), intent(in ) :: VTKHubrad_in !< Hub radius for VTK surface rendering |
| 166 | +! integer(c_int), intent(in ) :: wrOuts_C !< Write ADI output file |
| 167 | +! real(c_double), intent(in ) :: DT_Outs_C !< Timestep to write output file from ADI |
| 168 | +! ! Output |
| 169 | +! integer(c_int), intent( out) :: NumChannels_C !< Number of output channels requested from the input file |
| 170 | +! character(kind=c_char), intent( out) :: OutputChannelNames_C(ChanLen*MaxADIOutputs+1) !< NOTE: if MaxADIOutputs is sufficiently large, we may overrun the buffer on the Python side. |
| 171 | +! character(kind=c_char), intent( out) :: OutputChannelUnits_C(ChanLen*MaxADIOutputs+1) |
| 172 | +! integer(c_int), intent( out) :: ErrStat_C !< Error status |
| 173 | +! character(kind=c_char), intent( out) :: ErrMsg_C(ErrMsgLen_C) !< Error message (C_NULL_CHAR terminated) |
| 174 | + |
| 175 | +! Set compiler flag for Labview |
| 176 | +! Cmpl4LV = .TRUE. |
| 177 | + |
| 178 | +END SUBROUTINE WaveTank_Init |
| 179 | + |
| 180 | +! delta_time, & |
| 181 | +SUBROUTINE WaveTank_CalcOutput( & |
| 182 | + frame_number, & |
| 183 | + positions_x, & |
| 184 | + positions_y, & |
| 185 | + positions_z, & |
| 186 | + rotation_matrix, & |
| 187 | + loads, & |
| 188 | + ErrStat_c, & |
| 189 | + ErrMsg_c & |
| 190 | +) BIND (C, NAME='WaveTank_CalcOutput') |
| 191 | +#ifndef IMPLICIT_DLLEXPORT |
| 192 | +!DEC$ ATTRIBUTES DLLEXPORT :: WaveTank_CalcOutput |
| 193 | +!GCC$ ATTRIBUTES DLLEXPORT :: WaveTank_CalcOutput |
| 194 | +#endif |
| 195 | + |
| 196 | +IMPLICIT NONE |
| 197 | + |
| 198 | +! INTEGER(C_INT) :: delta_time |
| 199 | +INTEGER(C_INT) :: frame_number |
| 200 | +REAL(C_FLOAT), INTENT(IN ) :: positions_x(N_CAMERA_POINTS) |
| 201 | +REAL(C_FLOAT), INTENT(IN ) :: positions_y(N_CAMERA_POINTS) |
| 202 | +REAL(C_FLOAT), INTENT(IN ) :: positions_z(N_CAMERA_POINTS) |
| 203 | +REAL(C_FLOAT), INTENT(IN ) :: rotation_matrix(9) |
| 204 | +REAL(C_FLOAT), INTENT( OUT) :: loads(N_CAMERA_POINTS) |
| 205 | +INTEGER(C_INT), INTENT( OUT) :: ErrStat_C |
| 206 | +CHARACTER(KIND=C_CHAR), INTENT( OUT) :: ErrMsg_C(ErrMsgLen_C) |
| 207 | + |
| 208 | +INTEGER :: i |
| 209 | + |
| 210 | +IF ( MOD(frame_number / load_period, 2) == 0 ) THEN |
| 211 | + loads = -1.0 |
| 212 | +ELSE |
| 213 | + loads = 1.0 |
| 214 | +ENDIF |
| 215 | + |
| 216 | +END SUBROUTINE |
| 217 | + |
| 218 | +SUBROUTINE WaveTank_End() bind (C, NAME="WaveTank_End") |
| 219 | + |
| 220 | + |
| 221 | +IMPLICIT NONE |
| 222 | + |
| 223 | + |
| 224 | + |
| 225 | + |
| 226 | +END SUBROUTINE |
| 227 | + |
| 228 | +end module WaveTankTesting |
0 commit comments