diff --git a/glue-codes/python/pyOpenFAST/hydrodyn.py b/glue-codes/python/pyOpenFAST/hydrodyn.py index cb0f2522e1..df9da2334a 100644 --- a/glue-codes/python/pyOpenFAST/hydrodyn.py +++ b/glue-codes/python/pyOpenFAST/hydrodyn.py @@ -103,6 +103,9 @@ def __init__(self, library_path): self._initialize_routines() self.ended = False # For error handling at end + # Input file handling configuration + self.seastate_inputs_passed_as_string: bool = True # Pass input file as string + self.hydrodyn_inputs_passed_as_string: bool = True # Pass input file as string # Create buffers for class data self.abort_error_level = 4 @@ -161,11 +164,13 @@ def __init__(self, library_path): # _initialize_routines() ------------------------------------------------------------------------------------------------------------ def _initialize_routines(self): self.HydroDyn_C_Init.argtypes = [ - POINTER(c_char), # OutRootName + POINTER(c_int), # SeaState input file passed as string POINTER(c_char_p), # SeaState input file string POINTER(c_int), # SeaState input file string length + POINTER(c_int), # HydroDyn input file passed as string POINTER(c_char_p), # HydroDyn input file string POINTER(c_int), # HydroDyn input file string length + POINTER(c_char), # OutRootName POINTER(c_float), # gravity POINTER(c_float), # defWtrDens POINTER(c_float), # defWtrDpth @@ -281,28 +286,30 @@ def hydrodyn_init(self, seast_input_string_array, hd_input_string_array): # call HydroDyn_C_Init self.HydroDyn_C_Init( - _outRootName_c, # IN: rootname for HD file writing - c_char_p(seast_input_string), # IN: SeaState input file string - byref(c_int(seast_input_string_length)),# IN: SeaState input file string length - c_char_p(hd_input_string), # IN: HydroDyn input file string - byref(c_int(hd_input_string_length)), # IN: HydroDyn input file string length - byref(c_float(self.gravity)), # IN: gravity - byref(c_float(self.defWtrDens)), # IN: default water density - byref(c_float(self.defWtrDpth)), # IN: default water depth - byref(c_float(self.defMSL2SWL)), # IN: default offset between still-water level and mean sea level - byref(c_float(self.ptfmRefPt_x)), # IN: Platform initial position (X) - byref(c_float(self.ptfmRefPt_y)), # IN: Platform initial position (Y) - byref(c_int(self.numNodePts)), # IN: number of attachment points expected (where motions are transferred into HD) - nodeInitLoc_flat_c, # IN: initNodePos -- initial node positions in flat array of 6*numNodePts - byref(c_int(self.InterpOrder)), # IN: InterpOrder (1: linear, 2: quadratic) - byref(c_double(self.t_start)), # IN: time initial - byref(c_double(self.dt)), # IN: time step (dt) - byref(c_double(self.tmax)), # IN: tmax - byref(self._numChannels_c), # OUT: number of channels - self._channel_names_c, # OUT: output channel names - self._channel_units_c, # OUT: output channel units - byref(self.error_status_c), # OUT: ErrStat_C - self.error_message_c # OUT: ErrMsg_C + byref(c_int(self.seastate_inputs_passed_as_string)), # IN: SeaState input file is passed as string + c_char_p(seast_input_string), # IN: SeaState input file string + byref(c_int(seast_input_string_length)), # IN: SeaState input file string length + byref(c_int(self.hydrodyn_inputs_passed_as_string)), # IN: HydroDyn input file is passed as string + c_char_p(hd_input_string), # IN: HydroDyn input file string + byref(c_int(hd_input_string_length)), # IN: HydroDyn input file string length + _outRootName_c, # IN: rootname for HD file writing + byref(c_float(self.gravity)), # IN: gravity + byref(c_float(self.defWtrDens)), # IN: default water density + byref(c_float(self.defWtrDpth)), # IN: default water depth + byref(c_float(self.defMSL2SWL)), # IN: default offset between still-water level and mean sea level + byref(c_float(self.ptfmRefPt_x)), # IN: Platform initial position (X) + byref(c_float(self.ptfmRefPt_y)), # IN: Platform initial position (Y) + byref(c_int(self.numNodePts)), # IN: number of attachment points expected (where motions are transferred into HD) + nodeInitLoc_flat_c, # IN: initNodePos -- initial node positions in flat array of 6*numNodePts + byref(c_int(self.InterpOrder)), # IN: InterpOrder (1: linear, 2: quadratic) + byref(c_double(self.t_start)), # IN: time initial + byref(c_double(self.dt)), # IN: time step (dt) + byref(c_double(self.tmax)), # IN: tmax + byref(self._numChannels_c), # OUT: number of channels + self._channel_names_c, # OUT: output channel names + self._channel_units_c, # OUT: output channel units + byref(self.error_status_c), # OUT: ErrStat_C + self.error_message_c # OUT: ErrMsg_C ) self.check_error() diff --git a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 index 9cda0d19c6..2a2c2e869b 100644 --- a/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 +++ b/modules/aerodyn/src/AeroDyn_Inflow_C_Binding.f90 @@ -420,10 +420,10 @@ SUBROUTINE ADI_C_Init( ADinputFilePassed, ADinputFileString_C, ADinputFileString !GCC$ ATTRIBUTES DLLEXPORT :: ADI_C_Init #endif ! Input file info - integer(c_int), intent(in ) :: ADinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] + integer(c_int), intent(in ) :: ADinputFilePassed !< 0: pass the input file name; 1: pass the input file content type(c_ptr), intent(in ) :: ADinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR integer(c_int), intent(in ) :: ADinputFileStringLength_C !< lenght of the input file string - integer(c_int), intent(in ) :: IfWinputFilePassed !< Write VTK outputs [0: none, 1: init only, 2: animation] + integer(c_int), intent(in ) :: IfWinputFilePassed !< 0: pass the input file name; 1: pass the input file content type(c_ptr), intent(in ) :: IfWinputFileString_C !< Input file as a single string with lines deliniated by C_NULL_CHAR integer(c_int), intent(in ) :: IfWinputFileStringLength_C !< lenght of the input file string character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other diff --git a/modules/hydrodyn/src/HydroDyn_C_Binding.f90 b/modules/hydrodyn/src/HydroDyn_C_Binding.f90 index e70caa6f2c..083ed430f3 100644 --- a/modules/hydrodyn/src/HydroDyn_C_Binding.f90 +++ b/modules/hydrodyn/src/HydroDyn_C_Binding.f90 @@ -202,9 +202,12 @@ end subroutine SetErr !=============================================================================================================== !--------------------------------------------- HydroDyn Init---------------------------------------------------- !=============================================================================================================== -SUBROUTINE HydroDyn_C_Init( OutRootName_C, & +SUBROUTINE HydroDyn_C_Init( & + SeaSt_InputFilePassed, & SeaSt_InputFileString_C, SeaSt_InputFileStringLength_C, & + HD_InputFilePassed, & HD_InputFileString_C, HD_InputFileStringLength_C, & + OutRootName_C, & Gravity_C, defWtrDens_C, defWtrDpth_C, defMSL2SWL_C, & PtfmRefPtPositionX_C, PtfmRefPtPositionY_C, & NumNodePts_C, InitNodePositions_C, & @@ -218,11 +221,13 @@ SUBROUTINE HydroDyn_C_Init( OutRootName_C, !GCC$ ATTRIBUTES DLLEXPORT :: HydroDyn_C_Init #endif - character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other + integer(c_int), intent(in ) :: SeaSt_InputFilePassed !< 0: pass the input file name; 1: pass the input file content type(c_ptr), intent(in ) :: SeaSt_InputFileString_C !< SeaSt input file as a single string with lines deliniated by C_NULL_CHAR integer(c_int), intent(in ) :: SeaSt_InputFileStringLength_C !< SeaSt length of the input file string + integer(c_int), intent(in ) :: HD_InputFilePassed !< 0: pass the input file name; 1: pass the input file content type(c_ptr), intent(in ) :: HD_InputFileString_C !< HD input file as a single string with lines deliniated by C_NULL_CHAR integer(c_int), intent(in ) :: HD_InputFileStringLength_C !< HD length of the input file string + character(kind=c_char), intent(in ) :: OutRootName_C(IntfStrLen) !< Root name to use for echo files and other real(c_float), intent(in ) :: Gravity_C !< Gravitational constant (set by calling code) real(c_float), intent(in ) :: defWtrDens_C !< Default value for water density (may be overridden by input file) real(c_float), intent(in ) :: defWtrDpth_C !< Default value for water density (may be overridden by input file) @@ -248,6 +253,7 @@ SUBROUTINE HydroDyn_C_Init( OutRootName_C, character(IntfStrLen) :: OutRootName !< Root name to use for echo files and other character(kind=C_char, len=SeaSt_InputFileStringLength_C), pointer :: SeaSt_InputFileString !< Input file as a single string with NULL chracter separating lines character(kind=C_char, len=HD_InputFileStringLength_C), pointer :: HD_InputFileString !< Input file as a single string with NULL chracter separating lines + character(IntfStrLen) :: TmpFileName !< Temporary file name if not passing HD or SS input file contents directly real(DbKi) :: TimeInterval !< timestep for HD integer(IntKi) :: ErrStat !< aggregated error message @@ -327,8 +333,21 @@ SUBROUTINE HydroDyn_C_Init( OutRootName_C, ! Get fortran pointer to C_NULL_CHAR deliniated input file as a string call C_F_pointer(SeaSt_InputFileString_C, SeaSt_InputFileString) - ! Get the data to pass to SeaSt%Init - call InitFileInfo(SeaSt_InputFileString, SeaSt%InitInp%PassedFileData, ErrStat2, ErrMsg2); if (Failed()) return + ! Format SeaSt input file contents + if (SeaSt_InputFilePassed==1_c_int) then + ! Get the data to pass to SeaSt%Init + SeaSt%InitInp%InputFile = "passed_SeaSt_file" ! dummy + SeaSt%InitInp%UseInputFile = .FALSE. ! this probably should be passed in + call InitFileInfo(SeaSt_InputFileString, SeaSt%InitInp%PassedFileData, ErrStat2, ErrMsg2); if (Failed()) return + else + i = min(IntfStrLen,SeaSt_InputFileStringLength_C) + TmpFileName = '' + TmpFileName(1:i) = SeaSt_InputFileString(1:i) + i = INDEX(TmpFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + if ( i > 0 ) TmpFileName = TmpFileName(1:I) ! remove it + SeaSt%InitInp%InputFile = TmpFileName + SeaSt%InitInp%UseInputFile = .TRUE. + endif ! For diagnostic purposes, the following can be used to display the contents ! of the InFileInfo data structure. @@ -337,8 +356,7 @@ SUBROUTINE HydroDyn_C_Init( OutRootName_C, ! Set other inputs for calling SeaState_Init SeaSt%InitInp%hasIce = .FALSE. ! Always keep at false unless interfacing to ice modules - SeaSt%InitInp%InputFile = "passed_SeaSt_file" ! dummy - SeaSt%InitInp%UseInputFile = .FALSE. ! this probably should be passed in + ! Linearization ! for now, set linearization to false. Pass this in later when interface supports it ! Note: we may want to linearize at T=0 for added mass effects, but that might be @@ -384,8 +402,21 @@ SUBROUTINE HydroDyn_C_Init( OutRootName_C, ! Get fortran pointer to C_NULL_CHAR deliniated input file as a string call C_F_pointer(HD_InputFileString_C, HD_InputFileString) - ! Get the data to pass to HD%Init - call InitFileInfo(HD_InputFileString, HD%InitInp%PassedFileData, ErrStat2, ErrMsg2); if (Failed()) return + ! Format HD input file contents + if (HD_InputFilePassed==1_c_int) then + ! Get the data to pass to HD%InitInp + HD%InitInp%InputFile = "passed_hd_file" ! dummy + HD%InitInp%UseInputFile = .FALSE. ! this probably should be passed in + call InitFileInfo(HD_InputFileString, HD%InitInp%PassedFileData, ErrStat2, ErrMsg2); if (Failed()) return + else + i = min(IntfStrLen, HD_InputFileStringLength_C) + TmpFileName = '' + TmpFileName(1:i) = HD_InputFileString(1:i) + i = INDEX(TmpFileName,C_NULL_CHAR) - 1 ! if this has a c null character at the end... + if ( i > 0 ) TmpFileName = TmpFileName(1:I) ! remove it + HD%InitInp%InputFile = TmpFileName + HD%InitInp%UseInputFile = .TRUE. + endif ! For diagnostic purposes, the following can be used to display the contents ! of the InFileInfo data structure. @@ -393,8 +424,6 @@ SUBROUTINE HydroDyn_C_Init( OutRootName_C, !call Print_FileInfo_Struct( CU, HD%InitInp%PassedFileData ) ! Set other inputs for calling HydroDyn_Init - HD%InitInp%InputFile = "passed_hd_file" ! dummy - HD%InitInp%UseInputFile = .FALSE. ! this probably should be passed in ! Linearization ! for now, set linearization to false. Pass this in later when interface supports it ! Note: we may want to linearize at T=0 for added mass effects, but that might be