!STARTOFREGISTRYGENERATEDFILE 'WAMIT2_Types.f90'
!
! WARNING This file is generated automatically by the FAST registry.
! Do not edit.  Your changes to this file will be lost.
!
! FAST Registry (v3.02.00, 22-Jun-2016)
!*********************************************************************************************************************************
! WAMIT2_Types
!.................................................................................................................................
! This file is part of WAMIT2.
!
! Copyright (C) 2012-2016 National Renewable Energy Laboratory
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
!     http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!
!
! W A R N I N G : This file was automatically generated from the FAST registry.  Changes made to this file may be lost.
!
!*********************************************************************************************************************************
!> This module contains the user-defined types needed in WAMIT2. It also contains copy, destroy, pack, and
!! unpack routines associated with each defined data type. This code is automatically generated by the FAST Registry.
MODULE WAMIT2_Types
!---------------------------------------------------------------------------------------------------------------------------------
USE NWTC_Library
IMPLICIT NONE
    INTEGER(IntKi), PUBLIC, PARAMETER  :: MaxWAMIT2Outputs = 6      !  [-]
! =========  WAMIT2_InitInputType  =======
  TYPE, PUBLIC :: WAMIT2_InitInputType
    LOGICAL  :: HasWAMIT      !< .TRUE. if using WAMIT model, .FALSE. otherwise [-]
    CHARACTER(1024)  :: WAMITFile      !< Root of the filename for WAMIT2 outputs [-]
    INTEGER(IntKi)  :: UnSum      !< The unit number for the HydroDyn summary file [-]
    REAL(ReKi)  :: WAMITULEN      !< WAMIT unit length scale [-]
    REAL(ReKi)  :: RhoXg      !< Density * Gravity -- from the Waves module. [-]
    INTEGER(IntKi)  :: NStepWave      !< Total number of frequency components = total number of time steps in the incident wave [-]
    INTEGER(IntKi)  :: NStepWave2      !< NStepWave / 2 [-]
    REAL(ReKi)  :: WaveDOmega      !< Frequency step for incident wave calculations [(rad/s)]
    REAL(ReKi)  :: WtrDens      !< Water density [(kg/m^3)]
    REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE  :: WaveElevC0      !< Discrete Fourier transform of the instantaneous elevation of incident waves at the platform reference point.  First column is real part, second column is imaginary part [(meters)]
    REAL(SiKi)  :: WaveDir      !< Mean incident wave propagation heading direction [(degrees)]
    LOGICAL  :: WaveMultiDir      !< Indicates the waves are multidirectional -- set by HydroDyn_Input [-]
    REAL(SiKi) , DIMENSION(:), ALLOCATABLE  :: WaveDirArr      !< Wave direction assigned to each frequency [(degrees)]
    REAL(SiKi)  :: WaveDirMin      !< Minimum wave direction from Waves module [-]
    REAL(SiKi)  :: WaveDirMax      !< Maximum wave direction from Waves module [-]
    REAL(SiKi) , DIMENSION(:), ALLOCATABLE  :: WaveTime      !< Simulation times at which the instantaneous second order loads associated with the incident waves are determined [sec]
    CHARACTER(10) , DIMENSION(1:27)  :: OutList      !< This should really be dimensioned with MaxOutPts [-]
    LOGICAL  :: OutAll      !<  [-]
    INTEGER(IntKi)  :: NumOuts      !<  [-]
    INTEGER(IntKi)  :: NumOutAll      !<  [-]
    INTEGER(IntKi)  :: WaveMod      !< The wave model to use.  This is for error checking -- ideally this would be done in the main calling routine, not here. [-]
    LOGICAL  :: PtfmSgF2      !< Supplied by Driver:  Platform horizontal surge translation force (flag) [-]
    LOGICAL  :: PtfmSwF2      !< Supplied by Driver:  Platform horizontal sway  translation force (flag) [-]
    LOGICAL  :: PtfmHvF2      !< Supplied by Driver:  Platform vertical   heave translation force (flag) [-]
    LOGICAL  :: PtfmRF2      !< Supplied by Driver:  Platform roll  tilt rotation force (flag) [-]
    LOGICAL  :: PtfmPF2      !< Supplied by Driver:  Platform pitch tilt rotation force (flag) [-]
    LOGICAL  :: PtfmYF2      !< Supplied by Driver:  Platform yaw        rotation force (flag) [-]
    INTEGER(IntKi)  :: MnDrift      !< Calculate the mean drift force {0: no mean drift; [7,8,9,10,11, or 12]: WAMIT file to use} [-]
    INTEGER(IntKi)  :: NewmanApp      !< Slow drift forces computed with Newman approximation from WAMIT file:{0: No slow drift; [7,8,9,10,11, or 12]: WAMIT file to use} [-]
    INTEGER(IntKi)  :: DiffQTF      !< Full Difference-Frequency forces computed with full QTF's from WAMIT file: {0: No diff-QTF; [10,11, or 12]: WAMIT file to use} [-]
    INTEGER(IntKi)  :: SumQTF      !< Full Sum-Frequency forces computed with full QTF's from WAMIT file: {0: No sum-QTF; [10,11, or 12]: WAMIT file to use} [-]
    LOGICAL  :: MnDriftF      !< Flag indicating mean drift force should be calculated [-]
    LOGICAL  :: NewmanAppF      !< Flag indicating Newman approximation should be calculated [-]
    LOGICAL  :: DiffQTFF      !< Flag indicating the full difference QTF should be calculated [-]
    LOGICAL  :: SumQTFF      !< Flag indicating the full    sum     QTF should be calculated [-]
    REAL(ReKi)  :: WvLowCOff      !< Low cut-off frequency or lower frequency limit of the wave spectrum beyond which the wave spectrum is zeroed.  [used only when WaveMod=2,3,4] [(rad/s)]
    REAL(ReKi)  :: WvHiCOff      !< High cut-off frequency or upper frequency limit of the wave spectrum beyond which the wave spectrum is zeroed.  [used only when WaveMod=2,3,4] [(rad/s)]
    REAL(ReKi)  :: WvLowCOffD      !< Minimum frequency used in the difference methods [Ignored if all difference methods = 0] [(rad/s)]
    REAL(ReKi)  :: WvHiCOffD      !< Maximum frequency used in the difference methods [Ignored if all difference methods = 0] [(rad/s)]
    REAL(ReKi)  :: WvLowCOffS      !< Minimum frequency used in the sum-QTF method     [Ignored if SumQTF = 0] [(rad/s)]
    REAL(ReKi)  :: WvHiCOffS      !< Maximum frequency used in the sum-QTF method     [Ignored if SumQTF = 0] [(rad/s)]
  END TYPE WAMIT2_InitInputType
! =======================
! =========  WAMIT2_InitOutputType  =======
  TYPE, PUBLIC :: WAMIT2_InitOutputType
    CHARACTER(10) , DIMENSION(:), ALLOCATABLE  :: WriteOutputHdr      !<  [-]
    CHARACTER(10) , DIMENSION(:), ALLOCATABLE  :: WriteOutputUnt      !<  [-]
  END TYPE WAMIT2_InitOutputType
! =======================
! =========  WAMIT2_ContinuousStateType  =======
  TYPE, PUBLIC :: WAMIT2_ContinuousStateType
    REAL(SiKi)  :: DummyContState      !< Remove this variable if you have continuous states [-]
  END TYPE WAMIT2_ContinuousStateType
! =======================
! =========  WAMIT2_DiscreteStateType  =======
  TYPE, PUBLIC :: WAMIT2_DiscreteStateType
    REAL(SiKi)  :: DummyDiscState      !< Remove this variable if you have discrete states [-]
  END TYPE WAMIT2_DiscreteStateType
! =======================
! =========  WAMIT2_ConstraintStateType  =======
  TYPE, PUBLIC :: WAMIT2_ConstraintStateType
    REAL(SiKi)  :: DummyConstrState      !< Remove this variable if you have constraint states [-]
  END TYPE WAMIT2_ConstraintStateType
! =======================
! =========  WAMIT2_OtherStateType  =======
  TYPE, PUBLIC :: WAMIT2_OtherStateType
    INTEGER(IntKi)  :: DummyOtherState      !< Remove this variable if you have other states [-]
  END TYPE WAMIT2_OtherStateType
! =======================
! =========  WAMIT2_MiscVarType  =======
  TYPE, PUBLIC :: WAMIT2_MiscVarType
    INTEGER(IntKi)  :: LastIndWave      !< Index for last interpolation step of 2nd order forces [-]
    REAL(ReKi) , DIMENSION(1:6)  :: F_Waves2      !< 2nd order force from this timestep [-]
  END TYPE WAMIT2_MiscVarType
! =======================
! =========  WAMIT2_ParameterType  =======
  TYPE, PUBLIC :: WAMIT2_ParameterType
    REAL(SiKi) , DIMENSION(:), ALLOCATABLE  :: WaveTime      !< Simulation times at which the instantaneous second order loads associated with the incident waves are determined [sec]
    INTEGER(IntKi)  :: NStepWave      !< Number of wave time steps [-]
    REAL(DbKi)  :: DT      !<  [-]
    REAL(SiKi) , DIMENSION(:,:), ALLOCATABLE  :: WaveExctn2      !< Time series of the resulting 2nd order force (first index is timestep, second index is load component) [(N)]
    LOGICAL , DIMENSION(1:6)  :: MnDriftDims      !< Flags for which dimensions to calculate in MnDrift   calculations [-]
    LOGICAL , DIMENSION(1:6)  :: NewmanAppDims      !< Flags for which dimensions to calculate in NewmanApp calculations [-]
    LOGICAL , DIMENSION(1:6)  :: DiffQTFDims      !< Flags for which dimensions to calculate in DiffQTF   calculations [-]
    LOGICAL , DIMENSION(1:6)  :: SumQTFDims      !< Flags for which dimensions to calculate in SumQTF    calculations [-]
    LOGICAL  :: MnDriftF      !< Flag indicating mean drift force should be calculated [-]
    LOGICAL  :: NewmanAppF      !< Flag indicating Newman approximation should be calculated [-]
    LOGICAL  :: DiffQTFF      !< Flag indicating the full difference QTF should be calculated [-]
    LOGICAL  :: SumQTFF      !< Flag indicating the full    sum     QTF should be calculated [-]
    TYPE(OutParmType) , DIMENSION(:), ALLOCATABLE  :: OutParam      !<  [-]
    INTEGER(IntKi)  :: NumOuts      !<  [-]
    INTEGER(IntKi)  :: NumOutAll      !<  [-]
    CHARACTER(20)  :: OutFmt      !<  [-]
    CHARACTER(20)  :: OutSFmt      !<  [-]
    CHARACTER(10)  :: Delim      !<  [-]
    INTEGER(IntKi)  :: UnOutFile      !<  [-]
  END TYPE WAMIT2_ParameterType
! =======================
! =========  WAMIT2_InputType  =======
  TYPE, PUBLIC :: WAMIT2_InputType
    TYPE(MeshType)  :: Mesh      !< Displacements at the platform reference point in the inertial frame [-]
  END TYPE WAMIT2_InputType
! =======================
! =========  WAMIT2_OutputType  =======
  TYPE, PUBLIC :: WAMIT2_OutputType
    TYPE(MeshType)  :: Mesh      !< Loads at the platform reference point in the inertial frame [-]
    REAL(ReKi) , DIMENSION(:), ALLOCATABLE  :: WriteOutput      !<  [-]
  END TYPE WAMIT2_OutputType
! =======================
CONTAINS
 SUBROUTINE WAMIT2_CopyInitInput( SrcInitInputData, DstInitInputData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_InitInputType), INTENT(IN) :: SrcInitInputData
   TYPE(WAMIT2_InitInputType), INTENT(INOUT) :: DstInitInputData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
   INTEGER(IntKi)                 :: i2, i2_l, i2_u  !  bounds (upper/lower) for an array dimension 2
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyInitInput'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
    DstInitInputData%HasWAMIT = SrcInitInputData%HasWAMIT
    DstInitInputData%WAMITFile = SrcInitInputData%WAMITFile
    DstInitInputData%UnSum = SrcInitInputData%UnSum
    DstInitInputData%WAMITULEN = SrcInitInputData%WAMITULEN
    DstInitInputData%RhoXg = SrcInitInputData%RhoXg
    DstInitInputData%NStepWave = SrcInitInputData%NStepWave
    DstInitInputData%NStepWave2 = SrcInitInputData%NStepWave2
    DstInitInputData%WaveDOmega = SrcInitInputData%WaveDOmega
    DstInitInputData%WtrDens = SrcInitInputData%WtrDens
IF (ALLOCATED(SrcInitInputData%WaveElevC0)) THEN
  i1_l = LBOUND(SrcInitInputData%WaveElevC0,1)
  i1_u = UBOUND(SrcInitInputData%WaveElevC0,1)
  i2_l = LBOUND(SrcInitInputData%WaveElevC0,2)
  i2_u = UBOUND(SrcInitInputData%WaveElevC0,2)
  IF (.NOT. ALLOCATED(DstInitInputData%WaveElevC0)) THEN
    ALLOCATE(DstInitInputData%WaveElevC0(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%WaveElevC0.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DstInitInputData%WaveElevC0 = SrcInitInputData%WaveElevC0
ENDIF
    DstInitInputData%WaveDir = SrcInitInputData%WaveDir
    DstInitInputData%WaveMultiDir = SrcInitInputData%WaveMultiDir
IF (ALLOCATED(SrcInitInputData%WaveDirArr)) THEN
  i1_l = LBOUND(SrcInitInputData%WaveDirArr,1)
  i1_u = UBOUND(SrcInitInputData%WaveDirArr,1)
  IF (.NOT. ALLOCATED(DstInitInputData%WaveDirArr)) THEN
    ALLOCATE(DstInitInputData%WaveDirArr(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%WaveDirArr.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DstInitInputData%WaveDirArr = SrcInitInputData%WaveDirArr
ENDIF
    DstInitInputData%WaveDirMin = SrcInitInputData%WaveDirMin
    DstInitInputData%WaveDirMax = SrcInitInputData%WaveDirMax
IF (ALLOCATED(SrcInitInputData%WaveTime)) THEN
  i1_l = LBOUND(SrcInitInputData%WaveTime,1)
  i1_u = UBOUND(SrcInitInputData%WaveTime,1)
  IF (.NOT. ALLOCATED(DstInitInputData%WaveTime)) THEN
    ALLOCATE(DstInitInputData%WaveTime(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitInputData%WaveTime.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DstInitInputData%WaveTime = SrcInitInputData%WaveTime
ENDIF
    DstInitInputData%OutList = SrcInitInputData%OutList
    DstInitInputData%OutAll = SrcInitInputData%OutAll
    DstInitInputData%NumOuts = SrcInitInputData%NumOuts
    DstInitInputData%NumOutAll = SrcInitInputData%NumOutAll
    DstInitInputData%WaveMod = SrcInitInputData%WaveMod
    DstInitInputData%PtfmSgF2 = SrcInitInputData%PtfmSgF2
    DstInitInputData%PtfmSwF2 = SrcInitInputData%PtfmSwF2
    DstInitInputData%PtfmHvF2 = SrcInitInputData%PtfmHvF2
    DstInitInputData%PtfmRF2 = SrcInitInputData%PtfmRF2
    DstInitInputData%PtfmPF2 = SrcInitInputData%PtfmPF2
    DstInitInputData%PtfmYF2 = SrcInitInputData%PtfmYF2
    DstInitInputData%MnDrift = SrcInitInputData%MnDrift
    DstInitInputData%NewmanApp = SrcInitInputData%NewmanApp
    DstInitInputData%DiffQTF = SrcInitInputData%DiffQTF
    DstInitInputData%SumQTF = SrcInitInputData%SumQTF
    DstInitInputData%MnDriftF = SrcInitInputData%MnDriftF
    DstInitInputData%NewmanAppF = SrcInitInputData%NewmanAppF
    DstInitInputData%DiffQTFF = SrcInitInputData%DiffQTFF
    DstInitInputData%SumQTFF = SrcInitInputData%SumQTFF
    DstInitInputData%WvLowCOff = SrcInitInputData%WvLowCOff
    DstInitInputData%WvHiCOff = SrcInitInputData%WvHiCOff
    DstInitInputData%WvLowCOffD = SrcInitInputData%WvLowCOffD
    DstInitInputData%WvHiCOffD = SrcInitInputData%WvHiCOffD
    DstInitInputData%WvLowCOffS = SrcInitInputData%WvLowCOffS
    DstInitInputData%WvHiCOffS = SrcInitInputData%WvHiCOffS
 END SUBROUTINE WAMIT2_CopyInitInput

 SUBROUTINE WAMIT2_DestroyInitInput( InitInputData, ErrStat, ErrMsg )
  TYPE(WAMIT2_InitInputType), INTENT(INOUT) :: InitInputData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyInitInput'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
IF (ALLOCATED(InitInputData%WaveElevC0)) THEN
  DEALLOCATE(InitInputData%WaveElevC0)
ENDIF
IF (ALLOCATED(InitInputData%WaveDirArr)) THEN
  DEALLOCATE(InitInputData%WaveDirArr)
ENDIF
IF (ALLOCATED(InitInputData%WaveTime)) THEN
  DEALLOCATE(InitInputData%WaveTime)
ENDIF
 END SUBROUTINE WAMIT2_DestroyInitInput

 SUBROUTINE WAMIT2_PackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_InitInputType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackInitInput'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
      Int_BufSz  = Int_BufSz  + 1  ! HasWAMIT
      Int_BufSz  = Int_BufSz  + 1*LEN(InData%WAMITFile)  ! WAMITFile
      Int_BufSz  = Int_BufSz  + 1  ! UnSum
      Re_BufSz   = Re_BufSz   + 1  ! WAMITULEN
      Re_BufSz   = Re_BufSz   + 1  ! RhoXg
      Int_BufSz  = Int_BufSz  + 1  ! NStepWave
      Int_BufSz  = Int_BufSz  + 1  ! NStepWave2
      Re_BufSz   = Re_BufSz   + 1  ! WaveDOmega
      Re_BufSz   = Re_BufSz   + 1  ! WtrDens
  Int_BufSz   = Int_BufSz   + 1     ! WaveElevC0 allocated yes/no
  IF ( ALLOCATED(InData%WaveElevC0) ) THEN
    Int_BufSz   = Int_BufSz   + 2*2  ! WaveElevC0 upper/lower bounds for each dimension
      Re_BufSz   = Re_BufSz   + SIZE(InData%WaveElevC0)  ! WaveElevC0
  END IF
      Re_BufSz   = Re_BufSz   + 1  ! WaveDir
      Int_BufSz  = Int_BufSz  + 1  ! WaveMultiDir
  Int_BufSz   = Int_BufSz   + 1     ! WaveDirArr allocated yes/no
  IF ( ALLOCATED(InData%WaveDirArr) ) THEN
    Int_BufSz   = Int_BufSz   + 2*1  ! WaveDirArr upper/lower bounds for each dimension
      Re_BufSz   = Re_BufSz   + SIZE(InData%WaveDirArr)  ! WaveDirArr
  END IF
      Re_BufSz   = Re_BufSz   + 1  ! WaveDirMin
      Re_BufSz   = Re_BufSz   + 1  ! WaveDirMax
  Int_BufSz   = Int_BufSz   + 1     ! WaveTime allocated yes/no
  IF ( ALLOCATED(InData%WaveTime) ) THEN
    Int_BufSz   = Int_BufSz   + 2*1  ! WaveTime upper/lower bounds for each dimension
      Re_BufSz   = Re_BufSz   + SIZE(InData%WaveTime)  ! WaveTime
  END IF
      Int_BufSz  = Int_BufSz  + SIZE(InData%OutList)*LEN(InData%OutList)  ! OutList
      Int_BufSz  = Int_BufSz  + 1  ! OutAll
      Int_BufSz  = Int_BufSz  + 1  ! NumOuts
      Int_BufSz  = Int_BufSz  + 1  ! NumOutAll
      Int_BufSz  = Int_BufSz  + 1  ! WaveMod
      Int_BufSz  = Int_BufSz  + 1  ! PtfmSgF2
      Int_BufSz  = Int_BufSz  + 1  ! PtfmSwF2
      Int_BufSz  = Int_BufSz  + 1  ! PtfmHvF2
      Int_BufSz  = Int_BufSz  + 1  ! PtfmRF2
      Int_BufSz  = Int_BufSz  + 1  ! PtfmPF2
      Int_BufSz  = Int_BufSz  + 1  ! PtfmYF2
      Int_BufSz  = Int_BufSz  + 1  ! MnDrift
      Int_BufSz  = Int_BufSz  + 1  ! NewmanApp
      Int_BufSz  = Int_BufSz  + 1  ! DiffQTF
      Int_BufSz  = Int_BufSz  + 1  ! SumQTF
      Int_BufSz  = Int_BufSz  + 1  ! MnDriftF
      Int_BufSz  = Int_BufSz  + 1  ! NewmanAppF
      Int_BufSz  = Int_BufSz  + 1  ! DiffQTFF
      Int_BufSz  = Int_BufSz  + 1  ! SumQTFF
      Re_BufSz   = Re_BufSz   + 1  ! WvLowCOff
      Re_BufSz   = Re_BufSz   + 1  ! WvHiCOff
      Re_BufSz   = Re_BufSz   + 1  ! WvLowCOffD
      Re_BufSz   = Re_BufSz   + 1  ! WvHiCOffD
      Re_BufSz   = Re_BufSz   + 1  ! WvLowCOffS
      Re_BufSz   = Re_BufSz   + 1  ! WvHiCOffS
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%HasWAMIT , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
        DO I = 1, LEN(InData%WAMITFile)
          IntKiBuf(Int_Xferred) = ICHAR(InData%WAMITFile(I:I), IntKi)
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%UnSum
      Int_Xferred   = Int_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WAMITULEN
      Re_Xferred   = Re_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%RhoXg
      Re_Xferred   = Re_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%NStepWave
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%NStepWave2
      Int_Xferred   = Int_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WaveDOmega
      Re_Xferred   = Re_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WtrDens
      Re_Xferred   = Re_Xferred   + 1
  IF ( .NOT. ALLOCATED(InData%WaveElevC0) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WaveElevC0,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElevC0,1)
    Int_Xferred = Int_Xferred + 2
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WaveElevC0,2)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveElevC0,2)
    Int_Xferred = Int_Xferred + 2

      IF (SIZE(InData%WaveElevC0)>0) ReKiBuf ( Re_Xferred:Re_Xferred+(SIZE(InData%WaveElevC0))-1 ) = PACK(InData%WaveElevC0,.TRUE.)
      Re_Xferred   = Re_Xferred   + SIZE(InData%WaveElevC0)
  END IF
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WaveDir
      Re_Xferred   = Re_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%WaveMultiDir , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
  IF ( .NOT. ALLOCATED(InData%WaveDirArr) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WaveDirArr,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveDirArr,1)
    Int_Xferred = Int_Xferred + 2

      IF (SIZE(InData%WaveDirArr)>0) ReKiBuf ( Re_Xferred:Re_Xferred+(SIZE(InData%WaveDirArr))-1 ) = PACK(InData%WaveDirArr,.TRUE.)
      Re_Xferred   = Re_Xferred   + SIZE(InData%WaveDirArr)
  END IF
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WaveDirMin
      Re_Xferred   = Re_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WaveDirMax
      Re_Xferred   = Re_Xferred   + 1
  IF ( .NOT. ALLOCATED(InData%WaveTime) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WaveTime,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveTime,1)
    Int_Xferred = Int_Xferred + 2

      IF (SIZE(InData%WaveTime)>0) ReKiBuf ( Re_Xferred:Re_Xferred+(SIZE(InData%WaveTime))-1 ) = PACK(InData%WaveTime,.TRUE.)
      Re_Xferred   = Re_Xferred   + SIZE(InData%WaveTime)
  END IF
    DO i1 = LBOUND(InData%OutList,1), UBOUND(InData%OutList,1)
        DO I = 1, LEN(InData%OutList)
          IntKiBuf(Int_Xferred) = ICHAR(InData%OutList(i1)(I:I), IntKi)
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
    END DO !i1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%OutAll , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%NumOuts
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%NumOutAll
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%WaveMod
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%PtfmSgF2 , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%PtfmSwF2 , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%PtfmHvF2 , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%PtfmRF2 , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%PtfmPF2 , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%PtfmYF2 , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%MnDrift
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%NewmanApp
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%DiffQTF
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%SumQTF
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%MnDriftF , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%NewmanAppF , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%DiffQTFF , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%SumQTFF , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WvLowCOff
      Re_Xferred   = Re_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WvHiCOff
      Re_Xferred   = Re_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WvLowCOffD
      Re_Xferred   = Re_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WvHiCOffD
      Re_Xferred   = Re_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WvLowCOffS
      Re_Xferred   = Re_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%WvHiCOffS
      Re_Xferred   = Re_Xferred   + 1
 END SUBROUTINE WAMIT2_PackInitInput

 SUBROUTINE WAMIT2_UnPackInitInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_InitInputType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
  INTEGER(IntKi)                 :: i2, i2_l, i2_u  !  bounds (upper/lower) for an array dimension 2
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackInitInput'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
      OutData%HasWAMIT = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      DO I = 1, LEN(OutData%WAMITFile)
        OutData%WAMITFile(I:I) = CHAR(IntKiBuf(Int_Xferred))
        Int_Xferred = Int_Xferred   + 1
      END DO ! I
      OutData%UnSum = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%WAMITULEN = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
      OutData%RhoXg = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
      OutData%NStepWave = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%NStepWave2 = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%WaveDOmega = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
      OutData%WtrDens = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! WaveElevC0 not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    i2_l = IntKiBuf( Int_Xferred    )
    i2_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%WaveElevC0)) DEALLOCATE(OutData%WaveElevC0)
    ALLOCATE(OutData%WaveElevC0(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveElevC0.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    ALLOCATE(mask2(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask2.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask2 = .TRUE.
      IF (SIZE(OutData%WaveElevC0)>0) OutData%WaveElevC0 = REAL( UNPACK(ReKiBuf( Re_Xferred:Re_Xferred+(SIZE(OutData%WaveElevC0))-1 ), mask2, 0.0_ReKi ), SiKi)
      Re_Xferred   = Re_Xferred   + SIZE(OutData%WaveElevC0)
    DEALLOCATE(mask2)
  END IF
      OutData%WaveDir = REAL( ReKiBuf( Re_Xferred ), SiKi)
      Re_Xferred   = Re_Xferred + 1
      OutData%WaveMultiDir = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! WaveDirArr not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%WaveDirArr)) DEALLOCATE(OutData%WaveDirArr)
    ALLOCATE(OutData%WaveDirArr(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveDirArr.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      IF (SIZE(OutData%WaveDirArr)>0) OutData%WaveDirArr = REAL( UNPACK(ReKiBuf( Re_Xferred:Re_Xferred+(SIZE(OutData%WaveDirArr))-1 ), mask1, 0.0_ReKi ), SiKi)
      Re_Xferred   = Re_Xferred   + SIZE(OutData%WaveDirArr)
    DEALLOCATE(mask1)
  END IF
      OutData%WaveDirMin = REAL( ReKiBuf( Re_Xferred ), SiKi)
      Re_Xferred   = Re_Xferred + 1
      OutData%WaveDirMax = REAL( ReKiBuf( Re_Xferred ), SiKi)
      Re_Xferred   = Re_Xferred + 1
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! WaveTime not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%WaveTime)) DEALLOCATE(OutData%WaveTime)
    ALLOCATE(OutData%WaveTime(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveTime.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      IF (SIZE(OutData%WaveTime)>0) OutData%WaveTime = REAL( UNPACK(ReKiBuf( Re_Xferred:Re_Xferred+(SIZE(OutData%WaveTime))-1 ), mask1, 0.0_ReKi ), SiKi)
      Re_Xferred   = Re_Xferred   + SIZE(OutData%WaveTime)
    DEALLOCATE(mask1)
  END IF
    i1_l = LBOUND(OutData%OutList,1)
    i1_u = UBOUND(OutData%OutList,1)
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
    DO i1 = LBOUND(OutData%OutList,1), UBOUND(OutData%OutList,1)
        DO I = 1, LEN(OutData%OutList)
          OutData%OutList(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred))
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
    END DO !i1
    DEALLOCATE(mask1)
      OutData%OutAll = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%NumOuts = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%NumOutAll = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%WaveMod = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%PtfmSgF2 = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%PtfmSwF2 = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%PtfmHvF2 = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%PtfmRF2 = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%PtfmPF2 = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%PtfmYF2 = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%MnDrift = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%NewmanApp = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%DiffQTF = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%SumQTF = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%MnDriftF = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%NewmanAppF = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%DiffQTFF = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%SumQTFF = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%WvLowCOff = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
      OutData%WvHiCOff = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
      OutData%WvLowCOffD = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
      OutData%WvHiCOffD = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
      OutData%WvLowCOffS = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
      OutData%WvHiCOffS = ReKiBuf( Re_Xferred )
      Re_Xferred   = Re_Xferred + 1
 END SUBROUTINE WAMIT2_UnPackInitInput

 SUBROUTINE WAMIT2_CopyInitOutput( SrcInitOutputData, DstInitOutputData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_InitOutputType), INTENT(IN) :: SrcInitOutputData
   TYPE(WAMIT2_InitOutputType), INTENT(INOUT) :: DstInitOutputData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyInitOutput'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
IF (ALLOCATED(SrcInitOutputData%WriteOutputHdr)) THEN
  i1_l = LBOUND(SrcInitOutputData%WriteOutputHdr,1)
  i1_u = UBOUND(SrcInitOutputData%WriteOutputHdr,1)
  IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputHdr)) THEN
    ALLOCATE(DstInitOutputData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DstInitOutputData%WriteOutputHdr = SrcInitOutputData%WriteOutputHdr
ENDIF
IF (ALLOCATED(SrcInitOutputData%WriteOutputUnt)) THEN
  i1_l = LBOUND(SrcInitOutputData%WriteOutputUnt,1)
  i1_u = UBOUND(SrcInitOutputData%WriteOutputUnt,1)
  IF (.NOT. ALLOCATED(DstInitOutputData%WriteOutputUnt)) THEN
    ALLOCATE(DstInitOutputData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstInitOutputData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DstInitOutputData%WriteOutputUnt = SrcInitOutputData%WriteOutputUnt
ENDIF
 END SUBROUTINE WAMIT2_CopyInitOutput

 SUBROUTINE WAMIT2_DestroyInitOutput( InitOutputData, ErrStat, ErrMsg )
  TYPE(WAMIT2_InitOutputType), INTENT(INOUT) :: InitOutputData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyInitOutput'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
IF (ALLOCATED(InitOutputData%WriteOutputHdr)) THEN
  DEALLOCATE(InitOutputData%WriteOutputHdr)
ENDIF
IF (ALLOCATED(InitOutputData%WriteOutputUnt)) THEN
  DEALLOCATE(InitOutputData%WriteOutputUnt)
ENDIF
 END SUBROUTINE WAMIT2_DestroyInitOutput

 SUBROUTINE WAMIT2_PackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_InitOutputType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackInitOutput'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
  Int_BufSz   = Int_BufSz   + 1     ! WriteOutputHdr allocated yes/no
  IF ( ALLOCATED(InData%WriteOutputHdr) ) THEN
    Int_BufSz   = Int_BufSz   + 2*1  ! WriteOutputHdr upper/lower bounds for each dimension
      Int_BufSz  = Int_BufSz  + SIZE(InData%WriteOutputHdr)*LEN(InData%WriteOutputHdr)  ! WriteOutputHdr
  END IF
  Int_BufSz   = Int_BufSz   + 1     ! WriteOutputUnt allocated yes/no
  IF ( ALLOCATED(InData%WriteOutputUnt) ) THEN
    Int_BufSz   = Int_BufSz   + 2*1  ! WriteOutputUnt upper/lower bounds for each dimension
      Int_BufSz  = Int_BufSz  + SIZE(InData%WriteOutputUnt)*LEN(InData%WriteOutputUnt)  ! WriteOutputUnt
  END IF
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

  IF ( .NOT. ALLOCATED(InData%WriteOutputHdr) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WriteOutputHdr,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputHdr,1)
    Int_Xferred = Int_Xferred + 2

    DO i1 = LBOUND(InData%WriteOutputHdr,1), UBOUND(InData%WriteOutputHdr,1)
        DO I = 1, LEN(InData%WriteOutputHdr)
          IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputHdr(i1)(I:I), IntKi)
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
    END DO !i1
  END IF
  IF ( .NOT. ALLOCATED(InData%WriteOutputUnt) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WriteOutputUnt,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutputUnt,1)
    Int_Xferred = Int_Xferred + 2

    DO i1 = LBOUND(InData%WriteOutputUnt,1), UBOUND(InData%WriteOutputUnt,1)
        DO I = 1, LEN(InData%WriteOutputUnt)
          IntKiBuf(Int_Xferred) = ICHAR(InData%WriteOutputUnt(i1)(I:I), IntKi)
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
    END DO !i1
  END IF
 END SUBROUTINE WAMIT2_PackInitOutput

 SUBROUTINE WAMIT2_UnPackInitOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_InitOutputType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackInitOutput'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! WriteOutputHdr not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%WriteOutputHdr)) DEALLOCATE(OutData%WriteOutputHdr)
    ALLOCATE(OutData%WriteOutputHdr(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputHdr.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
    DO i1 = LBOUND(OutData%WriteOutputHdr,1), UBOUND(OutData%WriteOutputHdr,1)
        DO I = 1, LEN(OutData%WriteOutputHdr)
          OutData%WriteOutputHdr(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred))
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
    END DO !i1
    DEALLOCATE(mask1)
  END IF
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! WriteOutputUnt not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%WriteOutputUnt)) DEALLOCATE(OutData%WriteOutputUnt)
    ALLOCATE(OutData%WriteOutputUnt(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutputUnt.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
    DO i1 = LBOUND(OutData%WriteOutputUnt,1), UBOUND(OutData%WriteOutputUnt,1)
        DO I = 1, LEN(OutData%WriteOutputUnt)
          OutData%WriteOutputUnt(i1)(I:I) = CHAR(IntKiBuf(Int_Xferred))
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
    END DO !i1
    DEALLOCATE(mask1)
  END IF
 END SUBROUTINE WAMIT2_UnPackInitOutput

 SUBROUTINE WAMIT2_CopyContState( SrcContStateData, DstContStateData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_ContinuousStateType), INTENT(IN) :: SrcContStateData
   TYPE(WAMIT2_ContinuousStateType), INTENT(INOUT) :: DstContStateData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyContState'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
    DstContStateData%DummyContState = SrcContStateData%DummyContState
 END SUBROUTINE WAMIT2_CopyContState

 SUBROUTINE WAMIT2_DestroyContState( ContStateData, ErrStat, ErrMsg )
  TYPE(WAMIT2_ContinuousStateType), INTENT(INOUT) :: ContStateData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyContState'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
 END SUBROUTINE WAMIT2_DestroyContState

 SUBROUTINE WAMIT2_PackContState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_ContinuousStateType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackContState'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
      Re_BufSz   = Re_BufSz   + 1  ! DummyContState
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%DummyContState
      Re_Xferred   = Re_Xferred   + 1
 END SUBROUTINE WAMIT2_PackContState

 SUBROUTINE WAMIT2_UnPackContState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_ContinuousStateType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackContState'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
      OutData%DummyContState = REAL( ReKiBuf( Re_Xferred ), SiKi)
      Re_Xferred   = Re_Xferred + 1
 END SUBROUTINE WAMIT2_UnPackContState

 SUBROUTINE WAMIT2_CopyDiscState( SrcDiscStateData, DstDiscStateData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_DiscreteStateType), INTENT(IN) :: SrcDiscStateData
   TYPE(WAMIT2_DiscreteStateType), INTENT(INOUT) :: DstDiscStateData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyDiscState'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
    DstDiscStateData%DummyDiscState = SrcDiscStateData%DummyDiscState
 END SUBROUTINE WAMIT2_CopyDiscState

 SUBROUTINE WAMIT2_DestroyDiscState( DiscStateData, ErrStat, ErrMsg )
  TYPE(WAMIT2_DiscreteStateType), INTENT(INOUT) :: DiscStateData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyDiscState'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
 END SUBROUTINE WAMIT2_DestroyDiscState

 SUBROUTINE WAMIT2_PackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_DiscreteStateType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackDiscState'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
      Re_BufSz   = Re_BufSz   + 1  ! DummyDiscState
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%DummyDiscState
      Re_Xferred   = Re_Xferred   + 1
 END SUBROUTINE WAMIT2_PackDiscState

 SUBROUTINE WAMIT2_UnPackDiscState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_DiscreteStateType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackDiscState'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
      OutData%DummyDiscState = REAL( ReKiBuf( Re_Xferred ), SiKi)
      Re_Xferred   = Re_Xferred + 1
 END SUBROUTINE WAMIT2_UnPackDiscState

 SUBROUTINE WAMIT2_CopyConstrState( SrcConstrStateData, DstConstrStateData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_ConstraintStateType), INTENT(IN) :: SrcConstrStateData
   TYPE(WAMIT2_ConstraintStateType), INTENT(INOUT) :: DstConstrStateData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyConstrState'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
    DstConstrStateData%DummyConstrState = SrcConstrStateData%DummyConstrState
 END SUBROUTINE WAMIT2_CopyConstrState

 SUBROUTINE WAMIT2_DestroyConstrState( ConstrStateData, ErrStat, ErrMsg )
  TYPE(WAMIT2_ConstraintStateType), INTENT(INOUT) :: ConstrStateData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyConstrState'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
 END SUBROUTINE WAMIT2_DestroyConstrState

 SUBROUTINE WAMIT2_PackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_ConstraintStateType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackConstrState'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
      Re_BufSz   = Re_BufSz   + 1  ! DummyConstrState
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

      ReKiBuf ( Re_Xferred:Re_Xferred+(1)-1 ) = InData%DummyConstrState
      Re_Xferred   = Re_Xferred   + 1
 END SUBROUTINE WAMIT2_PackConstrState

 SUBROUTINE WAMIT2_UnPackConstrState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_ConstraintStateType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackConstrState'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
      OutData%DummyConstrState = REAL( ReKiBuf( Re_Xferred ), SiKi)
      Re_Xferred   = Re_Xferred + 1
 END SUBROUTINE WAMIT2_UnPackConstrState

 SUBROUTINE WAMIT2_CopyOtherState( SrcOtherStateData, DstOtherStateData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_OtherStateType), INTENT(IN) :: SrcOtherStateData
   TYPE(WAMIT2_OtherStateType), INTENT(INOUT) :: DstOtherStateData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyOtherState'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
    DstOtherStateData%DummyOtherState = SrcOtherStateData%DummyOtherState
 END SUBROUTINE WAMIT2_CopyOtherState

 SUBROUTINE WAMIT2_DestroyOtherState( OtherStateData, ErrStat, ErrMsg )
  TYPE(WAMIT2_OtherStateType), INTENT(INOUT) :: OtherStateData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyOtherState'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
 END SUBROUTINE WAMIT2_DestroyOtherState

 SUBROUTINE WAMIT2_PackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_OtherStateType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackOtherState'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
      Int_BufSz  = Int_BufSz  + 1  ! DummyOtherState
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%DummyOtherState
      Int_Xferred   = Int_Xferred   + 1
 END SUBROUTINE WAMIT2_PackOtherState

 SUBROUTINE WAMIT2_UnPackOtherState( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_OtherStateType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackOtherState'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
      OutData%DummyOtherState = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
 END SUBROUTINE WAMIT2_UnPackOtherState

 SUBROUTINE WAMIT2_CopyMisc( SrcMiscData, DstMiscData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_MiscVarType), INTENT(IN) :: SrcMiscData
   TYPE(WAMIT2_MiscVarType), INTENT(INOUT) :: DstMiscData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyMisc'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
    DstMiscData%LastIndWave = SrcMiscData%LastIndWave
    DstMiscData%F_Waves2 = SrcMiscData%F_Waves2
 END SUBROUTINE WAMIT2_CopyMisc

 SUBROUTINE WAMIT2_DestroyMisc( MiscData, ErrStat, ErrMsg )
  TYPE(WAMIT2_MiscVarType), INTENT(INOUT) :: MiscData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyMisc'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
 END SUBROUTINE WAMIT2_DestroyMisc

 SUBROUTINE WAMIT2_PackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_MiscVarType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackMisc'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
      Int_BufSz  = Int_BufSz  + 1  ! LastIndWave
      Re_BufSz   = Re_BufSz   + SIZE(InData%F_Waves2)  ! F_Waves2
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%LastIndWave
      Int_Xferred   = Int_Xferred   + 1
      ReKiBuf ( Re_Xferred:Re_Xferred+(SIZE(InData%F_Waves2))-1 ) = PACK(InData%F_Waves2,.TRUE.)
      Re_Xferred   = Re_Xferred   + SIZE(InData%F_Waves2)
 END SUBROUTINE WAMIT2_PackMisc

 SUBROUTINE WAMIT2_UnPackMisc( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_MiscVarType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackMisc'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
      OutData%LastIndWave = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
    i1_l = LBOUND(OutData%F_Waves2,1)
    i1_u = UBOUND(OutData%F_Waves2,1)
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      OutData%F_Waves2 = UNPACK(ReKiBuf( Re_Xferred:Re_Xferred+(SIZE(OutData%F_Waves2))-1 ), mask1, 0.0_ReKi )
      Re_Xferred   = Re_Xferred   + SIZE(OutData%F_Waves2)
    DEALLOCATE(mask1)
 END SUBROUTINE WAMIT2_UnPackMisc

 SUBROUTINE WAMIT2_CopyParam( SrcParamData, DstParamData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_ParameterType), INTENT(IN) :: SrcParamData
   TYPE(WAMIT2_ParameterType), INTENT(INOUT) :: DstParamData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
   INTEGER(IntKi)                 :: i2, i2_l, i2_u  !  bounds (upper/lower) for an array dimension 2
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyParam'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
IF (ALLOCATED(SrcParamData%WaveTime)) THEN
  i1_l = LBOUND(SrcParamData%WaveTime,1)
  i1_u = UBOUND(SrcParamData%WaveTime,1)
  IF (.NOT. ALLOCATED(DstParamData%WaveTime)) THEN
    ALLOCATE(DstParamData%WaveTime(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WaveTime.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DstParamData%WaveTime = SrcParamData%WaveTime
ENDIF
    DstParamData%NStepWave = SrcParamData%NStepWave
    DstParamData%DT = SrcParamData%DT
IF (ALLOCATED(SrcParamData%WaveExctn2)) THEN
  i1_l = LBOUND(SrcParamData%WaveExctn2,1)
  i1_u = UBOUND(SrcParamData%WaveExctn2,1)
  i2_l = LBOUND(SrcParamData%WaveExctn2,2)
  i2_u = UBOUND(SrcParamData%WaveExctn2,2)
  IF (.NOT. ALLOCATED(DstParamData%WaveExctn2)) THEN
    ALLOCATE(DstParamData%WaveExctn2(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%WaveExctn2.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DstParamData%WaveExctn2 = SrcParamData%WaveExctn2
ENDIF
    DstParamData%MnDriftDims = SrcParamData%MnDriftDims
    DstParamData%NewmanAppDims = SrcParamData%NewmanAppDims
    DstParamData%DiffQTFDims = SrcParamData%DiffQTFDims
    DstParamData%SumQTFDims = SrcParamData%SumQTFDims
    DstParamData%MnDriftF = SrcParamData%MnDriftF
    DstParamData%NewmanAppF = SrcParamData%NewmanAppF
    DstParamData%DiffQTFF = SrcParamData%DiffQTFF
    DstParamData%SumQTFF = SrcParamData%SumQTFF
IF (ALLOCATED(SrcParamData%OutParam)) THEN
  i1_l = LBOUND(SrcParamData%OutParam,1)
  i1_u = UBOUND(SrcParamData%OutParam,1)
  IF (.NOT. ALLOCATED(DstParamData%OutParam)) THEN
    ALLOCATE(DstParamData%OutParam(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstParamData%OutParam.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DO i1 = LBOUND(SrcParamData%OutParam,1), UBOUND(SrcParamData%OutParam,1)
      CALL NWTC_Library_Copyoutparmtype( SrcParamData%OutParam(i1), DstParamData%OutParam(i1), CtrlCode, ErrStat2, ErrMsg2 )
         CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
         IF (ErrStat>=AbortErrLev) RETURN
    ENDDO
ENDIF
    DstParamData%NumOuts = SrcParamData%NumOuts
    DstParamData%NumOutAll = SrcParamData%NumOutAll
    DstParamData%OutFmt = SrcParamData%OutFmt
    DstParamData%OutSFmt = SrcParamData%OutSFmt
    DstParamData%Delim = SrcParamData%Delim
    DstParamData%UnOutFile = SrcParamData%UnOutFile
 END SUBROUTINE WAMIT2_CopyParam

 SUBROUTINE WAMIT2_DestroyParam( ParamData, ErrStat, ErrMsg )
  TYPE(WAMIT2_ParameterType), INTENT(INOUT) :: ParamData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyParam'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
IF (ALLOCATED(ParamData%WaveTime)) THEN
  DEALLOCATE(ParamData%WaveTime)
ENDIF
IF (ALLOCATED(ParamData%WaveExctn2)) THEN
  DEALLOCATE(ParamData%WaveExctn2)
ENDIF
IF (ALLOCATED(ParamData%OutParam)) THEN
DO i1 = LBOUND(ParamData%OutParam,1), UBOUND(ParamData%OutParam,1)
  CALL NWTC_Library_Destroyoutparmtype( ParamData%OutParam(i1), ErrStat, ErrMsg )
ENDDO
  DEALLOCATE(ParamData%OutParam)
ENDIF
 END SUBROUTINE WAMIT2_DestroyParam

 SUBROUTINE WAMIT2_PackParam( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_ParameterType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackParam'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
  Int_BufSz   = Int_BufSz   + 1     ! WaveTime allocated yes/no
  IF ( ALLOCATED(InData%WaveTime) ) THEN
    Int_BufSz   = Int_BufSz   + 2*1  ! WaveTime upper/lower bounds for each dimension
      Re_BufSz   = Re_BufSz   + SIZE(InData%WaveTime)  ! WaveTime
  END IF
      Int_BufSz  = Int_BufSz  + 1  ! NStepWave
      Db_BufSz   = Db_BufSz   + 1  ! DT
  Int_BufSz   = Int_BufSz   + 1     ! WaveExctn2 allocated yes/no
  IF ( ALLOCATED(InData%WaveExctn2) ) THEN
    Int_BufSz   = Int_BufSz   + 2*2  ! WaveExctn2 upper/lower bounds for each dimension
      Re_BufSz   = Re_BufSz   + SIZE(InData%WaveExctn2)  ! WaveExctn2
  END IF
      Int_BufSz  = Int_BufSz  + SIZE(InData%MnDriftDims)  ! MnDriftDims
      Int_BufSz  = Int_BufSz  + SIZE(InData%NewmanAppDims)  ! NewmanAppDims
      Int_BufSz  = Int_BufSz  + SIZE(InData%DiffQTFDims)  ! DiffQTFDims
      Int_BufSz  = Int_BufSz  + SIZE(InData%SumQTFDims)  ! SumQTFDims
      Int_BufSz  = Int_BufSz  + 1  ! MnDriftF
      Int_BufSz  = Int_BufSz  + 1  ! NewmanAppF
      Int_BufSz  = Int_BufSz  + 1  ! DiffQTFF
      Int_BufSz  = Int_BufSz  + 1  ! SumQTFF
  Int_BufSz   = Int_BufSz   + 1     ! OutParam allocated yes/no
  IF ( ALLOCATED(InData%OutParam) ) THEN
    Int_BufSz   = Int_BufSz   + 2*1  ! OutParam upper/lower bounds for each dimension
   ! Allocate buffers for subtypes, if any (we'll get sizes from these)
    DO i1 = LBOUND(InData%OutParam,1), UBOUND(InData%OutParam,1)
      Int_BufSz   = Int_BufSz + 3  ! OutParam: size of buffers for each call to pack subtype
      CALL NWTC_Library_Packoutparmtype( Re_Buf, Db_Buf, Int_Buf, InData%OutParam(i1), ErrStat2, ErrMsg2, .TRUE. ) ! OutParam
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf)) THEN ! OutParam
         Re_BufSz  = Re_BufSz  + SIZE( Re_Buf  )
         DEALLOCATE(Re_Buf)
      END IF
      IF(ALLOCATED(Db_Buf)) THEN ! OutParam
         Db_BufSz  = Db_BufSz  + SIZE( Db_Buf  )
         DEALLOCATE(Db_Buf)
      END IF
      IF(ALLOCATED(Int_Buf)) THEN ! OutParam
         Int_BufSz = Int_BufSz + SIZE( Int_Buf )
         DEALLOCATE(Int_Buf)
      END IF
    END DO
  END IF
      Int_BufSz  = Int_BufSz  + 1  ! NumOuts
      Int_BufSz  = Int_BufSz  + 1  ! NumOutAll
      Int_BufSz  = Int_BufSz  + 1*LEN(InData%OutFmt)  ! OutFmt
      Int_BufSz  = Int_BufSz  + 1*LEN(InData%OutSFmt)  ! OutSFmt
      Int_BufSz  = Int_BufSz  + 1*LEN(InData%Delim)  ! Delim
      Int_BufSz  = Int_BufSz  + 1  ! UnOutFile
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

  IF ( .NOT. ALLOCATED(InData%WaveTime) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WaveTime,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveTime,1)
    Int_Xferred = Int_Xferred + 2

      IF (SIZE(InData%WaveTime)>0) ReKiBuf ( Re_Xferred:Re_Xferred+(SIZE(InData%WaveTime))-1 ) = PACK(InData%WaveTime,.TRUE.)
      Re_Xferred   = Re_Xferred   + SIZE(InData%WaveTime)
  END IF
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%NStepWave
      Int_Xferred   = Int_Xferred   + 1
      DbKiBuf ( Db_Xferred:Db_Xferred+(1)-1 ) = InData%DT
      Db_Xferred   = Db_Xferred   + 1
  IF ( .NOT. ALLOCATED(InData%WaveExctn2) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WaveExctn2,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveExctn2,1)
    Int_Xferred = Int_Xferred + 2
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WaveExctn2,2)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WaveExctn2,2)
    Int_Xferred = Int_Xferred + 2

      IF (SIZE(InData%WaveExctn2)>0) ReKiBuf ( Re_Xferred:Re_Xferred+(SIZE(InData%WaveExctn2))-1 ) = PACK(InData%WaveExctn2,.TRUE.)
      Re_Xferred   = Re_Xferred   + SIZE(InData%WaveExctn2)
  END IF
      IntKiBuf ( Int_Xferred:Int_Xferred+SIZE(InData%MnDriftDims)-1 ) = TRANSFER(PACK( InData%MnDriftDims ,.TRUE.), IntKiBuf(1), SIZE(InData%MnDriftDims))
      Int_Xferred   = Int_Xferred   + SIZE(InData%MnDriftDims)
      IntKiBuf ( Int_Xferred:Int_Xferred+SIZE(InData%NewmanAppDims)-1 ) = TRANSFER(PACK( InData%NewmanAppDims ,.TRUE.), IntKiBuf(1), SIZE(InData%NewmanAppDims))
      Int_Xferred   = Int_Xferred   + SIZE(InData%NewmanAppDims)
      IntKiBuf ( Int_Xferred:Int_Xferred+SIZE(InData%DiffQTFDims)-1 ) = TRANSFER(PACK( InData%DiffQTFDims ,.TRUE.), IntKiBuf(1), SIZE(InData%DiffQTFDims))
      Int_Xferred   = Int_Xferred   + SIZE(InData%DiffQTFDims)
      IntKiBuf ( Int_Xferred:Int_Xferred+SIZE(InData%SumQTFDims)-1 ) = TRANSFER(PACK( InData%SumQTFDims ,.TRUE.), IntKiBuf(1), SIZE(InData%SumQTFDims))
      Int_Xferred   = Int_Xferred   + SIZE(InData%SumQTFDims)
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%MnDriftF , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%NewmanAppF , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%DiffQTFF , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+1-1 ) = TRANSFER( InData%SumQTFF , IntKiBuf(1), 1)
      Int_Xferred   = Int_Xferred   + 1
  IF ( .NOT. ALLOCATED(InData%OutParam) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%OutParam,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%OutParam,1)
    Int_Xferred = Int_Xferred + 2

    DO i1 = LBOUND(InData%OutParam,1), UBOUND(InData%OutParam,1)
      CALL NWTC_Library_Packoutparmtype( Re_Buf, Db_Buf, Int_Buf, InData%OutParam(i1), ErrStat2, ErrMsg2, OnlySize ) ! OutParam
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf
        Re_Xferred = Re_Xferred + SIZE(Re_Buf)
        DEALLOCATE(Re_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
      IF(ALLOCATED(Db_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf
        Db_Xferred = Db_Xferred + SIZE(Db_Buf)
        DEALLOCATE(Db_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
      IF(ALLOCATED(Int_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf
        Int_Xferred = Int_Xferred + SIZE(Int_Buf)
        DEALLOCATE(Int_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
    END DO
  END IF
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%NumOuts
      Int_Xferred   = Int_Xferred   + 1
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%NumOutAll
      Int_Xferred   = Int_Xferred   + 1
        DO I = 1, LEN(InData%OutFmt)
          IntKiBuf(Int_Xferred) = ICHAR(InData%OutFmt(I:I), IntKi)
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
        DO I = 1, LEN(InData%OutSFmt)
          IntKiBuf(Int_Xferred) = ICHAR(InData%OutSFmt(I:I), IntKi)
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
        DO I = 1, LEN(InData%Delim)
          IntKiBuf(Int_Xferred) = ICHAR(InData%Delim(I:I), IntKi)
          Int_Xferred = Int_Xferred   + 1
        END DO ! I
      IntKiBuf ( Int_Xferred:Int_Xferred+(1)-1 ) = InData%UnOutFile
      Int_Xferred   = Int_Xferred   + 1
 END SUBROUTINE WAMIT2_PackParam

 SUBROUTINE WAMIT2_UnPackParam( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_ParameterType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
  INTEGER(IntKi)                 :: i2, i2_l, i2_u  !  bounds (upper/lower) for an array dimension 2
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackParam'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! WaveTime not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%WaveTime)) DEALLOCATE(OutData%WaveTime)
    ALLOCATE(OutData%WaveTime(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveTime.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      IF (SIZE(OutData%WaveTime)>0) OutData%WaveTime = REAL( UNPACK(ReKiBuf( Re_Xferred:Re_Xferred+(SIZE(OutData%WaveTime))-1 ), mask1, 0.0_ReKi ), SiKi)
      Re_Xferred   = Re_Xferred   + SIZE(OutData%WaveTime)
    DEALLOCATE(mask1)
  END IF
      OutData%NStepWave = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%DT = DbKiBuf( Db_Xferred )
      Db_Xferred   = Db_Xferred + 1
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! WaveExctn2 not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    i2_l = IntKiBuf( Int_Xferred    )
    i2_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%WaveExctn2)) DEALLOCATE(OutData%WaveExctn2)
    ALLOCATE(OutData%WaveExctn2(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WaveExctn2.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    ALLOCATE(mask2(i1_l:i1_u,i2_l:i2_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask2.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask2 = .TRUE.
      IF (SIZE(OutData%WaveExctn2)>0) OutData%WaveExctn2 = REAL( UNPACK(ReKiBuf( Re_Xferred:Re_Xferred+(SIZE(OutData%WaveExctn2))-1 ), mask2, 0.0_ReKi ), SiKi)
      Re_Xferred   = Re_Xferred   + SIZE(OutData%WaveExctn2)
    DEALLOCATE(mask2)
  END IF
    i1_l = LBOUND(OutData%MnDriftDims,1)
    i1_u = UBOUND(OutData%MnDriftDims,1)
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      OutData%MnDriftDims = UNPACK( TRANSFER( IntKiBuf ( Int_Xferred:Int_Xferred+(SIZE(OutData%MnDriftDims))-1 ), OutData%MnDriftDims), mask1,.TRUE.)
      Int_Xferred   = Int_Xferred   + SIZE(OutData%MnDriftDims)
    DEALLOCATE(mask1)
    i1_l = LBOUND(OutData%NewmanAppDims,1)
    i1_u = UBOUND(OutData%NewmanAppDims,1)
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      OutData%NewmanAppDims = UNPACK( TRANSFER( IntKiBuf ( Int_Xferred:Int_Xferred+(SIZE(OutData%NewmanAppDims))-1 ), OutData%NewmanAppDims), mask1,.TRUE.)
      Int_Xferred   = Int_Xferred   + SIZE(OutData%NewmanAppDims)
    DEALLOCATE(mask1)
    i1_l = LBOUND(OutData%DiffQTFDims,1)
    i1_u = UBOUND(OutData%DiffQTFDims,1)
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      OutData%DiffQTFDims = UNPACK( TRANSFER( IntKiBuf ( Int_Xferred:Int_Xferred+(SIZE(OutData%DiffQTFDims))-1 ), OutData%DiffQTFDims), mask1,.TRUE.)
      Int_Xferred   = Int_Xferred   + SIZE(OutData%DiffQTFDims)
    DEALLOCATE(mask1)
    i1_l = LBOUND(OutData%SumQTFDims,1)
    i1_u = UBOUND(OutData%SumQTFDims,1)
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      OutData%SumQTFDims = UNPACK( TRANSFER( IntKiBuf ( Int_Xferred:Int_Xferred+(SIZE(OutData%SumQTFDims))-1 ), OutData%SumQTFDims), mask1,.TRUE.)
      Int_Xferred   = Int_Xferred   + SIZE(OutData%SumQTFDims)
    DEALLOCATE(mask1)
      OutData%MnDriftF = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%NewmanAppF = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%DiffQTFF = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
      OutData%SumQTFF = TRANSFER( IntKiBuf( Int_Xferred ), mask0 )
      Int_Xferred   = Int_Xferred + 1
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! OutParam not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%OutParam)) DEALLOCATE(OutData%OutParam)
    ALLOCATE(OutData%OutParam(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%OutParam.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    DO i1 = LBOUND(OutData%OutParam,1), UBOUND(OutData%OutParam,1)
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 )
        Re_Xferred = Re_Xferred + Buf_size
      END IF
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 )
        Db_Xferred = Db_Xferred + Buf_size
      END IF
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 )
        Int_Xferred = Int_Xferred + Buf_size
      END IF
      CALL NWTC_Library_Unpackoutparmtype( Re_Buf, Db_Buf, Int_Buf, OutData%OutParam(i1), ErrStat2, ErrMsg2 ) ! OutParam
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf )
      IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf )
      IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf)
    END DO
  END IF
      OutData%NumOuts = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      OutData%NumOutAll = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
      DO I = 1, LEN(OutData%OutFmt)
        OutData%OutFmt(I:I) = CHAR(IntKiBuf(Int_Xferred))
        Int_Xferred = Int_Xferred   + 1
      END DO ! I
      DO I = 1, LEN(OutData%OutSFmt)
        OutData%OutSFmt(I:I) = CHAR(IntKiBuf(Int_Xferred))
        Int_Xferred = Int_Xferred   + 1
      END DO ! I
      DO I = 1, LEN(OutData%Delim)
        OutData%Delim(I:I) = CHAR(IntKiBuf(Int_Xferred))
        Int_Xferred = Int_Xferred   + 1
      END DO ! I
      OutData%UnOutFile = IntKiBuf( Int_Xferred )
      Int_Xferred   = Int_Xferred + 1
 END SUBROUTINE WAMIT2_UnPackParam

 SUBROUTINE WAMIT2_CopyInput( SrcInputData, DstInputData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_InputType), INTENT(INOUT) :: SrcInputData
   TYPE(WAMIT2_InputType), INTENT(INOUT) :: DstInputData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyInput'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
      CALL MeshCopy( SrcInputData%Mesh, DstInputData%Mesh, CtrlCode, ErrStat2, ErrMsg2 )
         CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
         IF (ErrStat>=AbortErrLev) RETURN
 END SUBROUTINE WAMIT2_CopyInput

 SUBROUTINE WAMIT2_DestroyInput( InputData, ErrStat, ErrMsg )
  TYPE(WAMIT2_InputType), INTENT(INOUT) :: InputData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyInput'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
  CALL MeshDestroy( InputData%Mesh, ErrStat, ErrMsg )
 END SUBROUTINE WAMIT2_DestroyInput

 SUBROUTINE WAMIT2_PackInput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_InputType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackInput'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
   ! Allocate buffers for subtypes, if any (we'll get sizes from these)
      Int_BufSz   = Int_BufSz + 3  ! Mesh: size of buffers for each call to pack subtype
      CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! Mesh
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf)) THEN ! Mesh
         Re_BufSz  = Re_BufSz  + SIZE( Re_Buf  )
         DEALLOCATE(Re_Buf)
      END IF
      IF(ALLOCATED(Db_Buf)) THEN ! Mesh
         Db_BufSz  = Db_BufSz  + SIZE( Db_Buf  )
         DEALLOCATE(Db_Buf)
      END IF
      IF(ALLOCATED(Int_Buf)) THEN ! Mesh
         Int_BufSz = Int_BufSz + SIZE( Int_Buf )
         DEALLOCATE(Int_Buf)
      END IF
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

      CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! Mesh
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf
        Re_Xferred = Re_Xferred + SIZE(Re_Buf)
        DEALLOCATE(Re_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
      IF(ALLOCATED(Db_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf
        Db_Xferred = Db_Xferred + SIZE(Db_Buf)
        DEALLOCATE(Db_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
      IF(ALLOCATED(Int_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf
        Int_Xferred = Int_Xferred + SIZE(Int_Buf)
        DEALLOCATE(Int_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
 END SUBROUTINE WAMIT2_PackInput

 SUBROUTINE WAMIT2_UnPackInput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_InputType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackInput'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 )
        Re_Xferred = Re_Xferred + Buf_size
      END IF
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 )
        Db_Xferred = Db_Xferred + Buf_size
      END IF
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 )
        Int_Xferred = Int_Xferred + Buf_size
      END IF
      CALL MeshUnpack( OutData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! Mesh
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf )
      IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf )
      IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf)
 END SUBROUTINE WAMIT2_UnPackInput

 SUBROUTINE WAMIT2_CopyOutput( SrcOutputData, DstOutputData, CtrlCode, ErrStat, ErrMsg )
   TYPE(WAMIT2_OutputType), INTENT(INOUT) :: SrcOutputData
   TYPE(WAMIT2_OutputType), INTENT(INOUT) :: DstOutputData
   INTEGER(IntKi),  INTENT(IN   ) :: CtrlCode
   INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
   CHARACTER(*),    INTENT(  OUT) :: ErrMsg
! Local
   INTEGER(IntKi)                 :: i,j,k
   INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
   INTEGER(IntKi)                 :: ErrStat2
   CHARACTER(ErrMsgLen)           :: ErrMsg2
   CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_CopyOutput'
!
   ErrStat = ErrID_None
   ErrMsg  = ""
      CALL MeshCopy( SrcOutputData%Mesh, DstOutputData%Mesh, CtrlCode, ErrStat2, ErrMsg2 )
         CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
         IF (ErrStat>=AbortErrLev) RETURN
IF (ALLOCATED(SrcOutputData%WriteOutput)) THEN
  i1_l = LBOUND(SrcOutputData%WriteOutput,1)
  i1_u = UBOUND(SrcOutputData%WriteOutput,1)
  IF (.NOT. ALLOCATED(DstOutputData%WriteOutput)) THEN
    ALLOCATE(DstOutputData%WriteOutput(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
      CALL SetErrStat(ErrID_Fatal, 'Error allocating DstOutputData%WriteOutput.', ErrStat, ErrMsg,RoutineName)
      RETURN
    END IF
  END IF
    DstOutputData%WriteOutput = SrcOutputData%WriteOutput
ENDIF
 END SUBROUTINE WAMIT2_CopyOutput

 SUBROUTINE WAMIT2_DestroyOutput( OutputData, ErrStat, ErrMsg )
  TYPE(WAMIT2_OutputType), INTENT(INOUT) :: OutputData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
  CHARACTER(*),    PARAMETER :: RoutineName = 'WAMIT2_DestroyOutput'
  INTEGER(IntKi)                 :: i, i1, i2, i3, i4, i5
!
  ErrStat = ErrID_None
  ErrMsg  = ""
  CALL MeshDestroy( OutputData%Mesh, ErrStat, ErrMsg )
IF (ALLOCATED(OutputData%WriteOutput)) THEN
  DEALLOCATE(OutputData%WriteOutput)
ENDIF
 END SUBROUTINE WAMIT2_DestroyOutput

 SUBROUTINE WAMIT2_PackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Indata, ErrStat, ErrMsg, SizeOnly )
  REAL(ReKi),       ALLOCATABLE, INTENT(  OUT) :: ReKiBuf(:)
  REAL(DbKi),       ALLOCATABLE, INTENT(  OUT) :: DbKiBuf(:)
  INTEGER(IntKi),   ALLOCATABLE, INTENT(  OUT) :: IntKiBuf(:)
  TYPE(WAMIT2_OutputType),  INTENT(IN) :: InData
  INTEGER(IntKi),   INTENT(  OUT) :: ErrStat
  CHARACTER(*),     INTENT(  OUT) :: ErrMsg
  LOGICAL,OPTIONAL, INTENT(IN   ) :: SizeOnly
    ! Local variables
  INTEGER(IntKi)                 :: Re_BufSz
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_BufSz
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_BufSz
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i,i1,i2,i3,i4,i5
  LOGICAL                        :: OnlySize ! if present and true, do not pack, just allocate buffers
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_PackOutput'
 ! buffers to store subtypes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)

  OnlySize = .FALSE.
  IF ( PRESENT(SizeOnly) ) THEN
    OnlySize = SizeOnly
  ENDIF
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_BufSz  = 0
  Db_BufSz  = 0
  Int_BufSz  = 0
   ! Allocate buffers for subtypes, if any (we'll get sizes from these)
      Int_BufSz   = Int_BufSz + 3  ! Mesh: size of buffers for each call to pack subtype
      CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, .TRUE. ) ! Mesh
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf)) THEN ! Mesh
         Re_BufSz  = Re_BufSz  + SIZE( Re_Buf  )
         DEALLOCATE(Re_Buf)
      END IF
      IF(ALLOCATED(Db_Buf)) THEN ! Mesh
         Db_BufSz  = Db_BufSz  + SIZE( Db_Buf  )
         DEALLOCATE(Db_Buf)
      END IF
      IF(ALLOCATED(Int_Buf)) THEN ! Mesh
         Int_BufSz = Int_BufSz + SIZE( Int_Buf )
         DEALLOCATE(Int_Buf)
      END IF
  Int_BufSz   = Int_BufSz   + 1     ! WriteOutput allocated yes/no
  IF ( ALLOCATED(InData%WriteOutput) ) THEN
    Int_BufSz   = Int_BufSz   + 2*1  ! WriteOutput upper/lower bounds for each dimension
      Re_BufSz   = Re_BufSz   + SIZE(InData%WriteOutput)  ! WriteOutput
  END IF
  IF ( Re_BufSz  .GT. 0 ) THEN
     ALLOCATE( ReKiBuf(  Re_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating ReKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Db_BufSz  .GT. 0 ) THEN
     ALLOCATE( DbKiBuf(  Db_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating DbKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF ( Int_BufSz  .GT. 0 ) THEN
     ALLOCATE( IntKiBuf(  Int_BufSz  ), STAT=ErrStat2 )
     IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating IntKiBuf.', ErrStat, ErrMsg,RoutineName)
       RETURN
     END IF
  END IF
  IF(OnlySize) RETURN ! return early if only trying to allocate buffers (not pack them)

  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred = 1

      CALL MeshPack( InData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2, OnlySize ) ! Mesh
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Re_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Re_Buf) > 0) ReKiBuf( Re_Xferred:Re_Xferred+SIZE(Re_Buf)-1 ) = Re_Buf
        Re_Xferred = Re_Xferred + SIZE(Re_Buf)
        DEALLOCATE(Re_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
      IF(ALLOCATED(Db_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Db_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Db_Buf) > 0) DbKiBuf( Db_Xferred:Db_Xferred+SIZE(Db_Buf)-1 ) = Db_Buf
        Db_Xferred = Db_Xferred + SIZE(Db_Buf)
        DEALLOCATE(Db_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
      IF(ALLOCATED(Int_Buf)) THEN
        IntKiBuf( Int_Xferred ) = SIZE(Int_Buf); Int_Xferred = Int_Xferred + 1
        IF (SIZE(Int_Buf) > 0) IntKiBuf( Int_Xferred:Int_Xferred+SIZE(Int_Buf)-1 ) = Int_Buf
        Int_Xferred = Int_Xferred + SIZE(Int_Buf)
        DEALLOCATE(Int_Buf)
      ELSE
        IntKiBuf( Int_Xferred ) = 0; Int_Xferred = Int_Xferred + 1
      ENDIF
  IF ( .NOT. ALLOCATED(InData%WriteOutput) ) THEN
    IntKiBuf( Int_Xferred ) = 0
    Int_Xferred = Int_Xferred + 1
  ELSE
    IntKiBuf( Int_Xferred ) = 1
    Int_Xferred = Int_Xferred + 1
    IntKiBuf( Int_Xferred    ) = LBOUND(InData%WriteOutput,1)
    IntKiBuf( Int_Xferred + 1) = UBOUND(InData%WriteOutput,1)
    Int_Xferred = Int_Xferred + 2

      IF (SIZE(InData%WriteOutput)>0) ReKiBuf ( Re_Xferred:Re_Xferred+(SIZE(InData%WriteOutput))-1 ) = PACK(InData%WriteOutput,.TRUE.)
      Re_Xferred   = Re_Xferred   + SIZE(InData%WriteOutput)
  END IF
 END SUBROUTINE WAMIT2_PackOutput

 SUBROUTINE WAMIT2_UnPackOutput( ReKiBuf, DbKiBuf, IntKiBuf, Outdata, ErrStat, ErrMsg )
  REAL(ReKi),      ALLOCATABLE, INTENT(IN   ) :: ReKiBuf(:)
  REAL(DbKi),      ALLOCATABLE, INTENT(IN   ) :: DbKiBuf(:)
  INTEGER(IntKi),  ALLOCATABLE, INTENT(IN   ) :: IntKiBuf(:)
  TYPE(WAMIT2_OutputType), INTENT(INOUT) :: OutData
  INTEGER(IntKi),  INTENT(  OUT) :: ErrStat
  CHARACTER(*),    INTENT(  OUT) :: ErrMsg
    ! Local variables
  INTEGER(IntKi)                 :: Buf_size
  INTEGER(IntKi)                 :: Re_Xferred
  INTEGER(IntKi)                 :: Db_Xferred
  INTEGER(IntKi)                 :: Int_Xferred
  INTEGER(IntKi)                 :: i
  LOGICAL                        :: mask0
  LOGICAL, ALLOCATABLE           :: mask1(:)
  LOGICAL, ALLOCATABLE           :: mask2(:,:)
  LOGICAL, ALLOCATABLE           :: mask3(:,:,:)
  LOGICAL, ALLOCATABLE           :: mask4(:,:,:,:)
  LOGICAL, ALLOCATABLE           :: mask5(:,:,:,:,:)
  INTEGER(IntKi)                 :: i1, i1_l, i1_u  !  bounds (upper/lower) for an array dimension 1
  INTEGER(IntKi)                 :: ErrStat2
  CHARACTER(ErrMsgLen)           :: ErrMsg2
  CHARACTER(*), PARAMETER        :: RoutineName = 'WAMIT2_UnPackOutput'
 ! buffers to store meshes, if any
  REAL(ReKi),      ALLOCATABLE   :: Re_Buf(:)
  REAL(DbKi),      ALLOCATABLE   :: Db_Buf(:)
  INTEGER(IntKi),  ALLOCATABLE   :: Int_Buf(:)
    !
  ErrStat = ErrID_None
  ErrMsg  = ""
  Re_Xferred  = 1
  Db_Xferred  = 1
  Int_Xferred  = 1
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Re_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Re_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Re_Buf = ReKiBuf( Re_Xferred:Re_Xferred+Buf_size-1 )
        Re_Xferred = Re_Xferred + Buf_size
      END IF
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Db_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Db_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Db_Buf = DbKiBuf( Db_Xferred:Db_Xferred+Buf_size-1 )
        Db_Xferred = Db_Xferred + Buf_size
      END IF
      Buf_size=IntKiBuf( Int_Xferred )
      Int_Xferred = Int_Xferred + 1
      IF(Buf_size > 0) THEN
        ALLOCATE(Int_Buf(Buf_size),STAT=ErrStat2)
        IF (ErrStat2 /= 0) THEN
           CALL SetErrStat(ErrID_Fatal, 'Error allocating Int_Buf.', ErrStat, ErrMsg,RoutineName)
           RETURN
        END IF
        Int_Buf = IntKiBuf( Int_Xferred:Int_Xferred+Buf_size-1 )
        Int_Xferred = Int_Xferred + Buf_size
      END IF
      CALL MeshUnpack( OutData%Mesh, Re_Buf, Db_Buf, Int_Buf, ErrStat2, ErrMsg2 ) ! Mesh
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName)
        IF (ErrStat >= AbortErrLev) RETURN

      IF(ALLOCATED(Re_Buf )) DEALLOCATE(Re_Buf )
      IF(ALLOCATED(Db_Buf )) DEALLOCATE(Db_Buf )
      IF(ALLOCATED(Int_Buf)) DEALLOCATE(Int_Buf)
  IF ( IntKiBuf( Int_Xferred ) == 0 ) THEN  ! WriteOutput not allocated
    Int_Xferred = Int_Xferred + 1
  ELSE
    Int_Xferred = Int_Xferred + 1
    i1_l = IntKiBuf( Int_Xferred    )
    i1_u = IntKiBuf( Int_Xferred + 1)
    Int_Xferred = Int_Xferred + 2
    IF (ALLOCATED(OutData%WriteOutput)) DEALLOCATE(OutData%WriteOutput)
    ALLOCATE(OutData%WriteOutput(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating OutData%WriteOutput.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    ALLOCATE(mask1(i1_l:i1_u),STAT=ErrStat2)
    IF (ErrStat2 /= 0) THEN
       CALL SetErrStat(ErrID_Fatal, 'Error allocating mask1.', ErrStat, ErrMsg,RoutineName)
       RETURN
    END IF
    mask1 = .TRUE.
      IF (SIZE(OutData%WriteOutput)>0) OutData%WriteOutput = UNPACK(ReKiBuf( Re_Xferred:Re_Xferred+(SIZE(OutData%WriteOutput))-1 ), mask1, 0.0_ReKi )
      Re_Xferred   = Re_Xferred   + SIZE(OutData%WriteOutput)
    DEALLOCATE(mask1)
  END IF
 END SUBROUTINE WAMIT2_UnPackOutput

 SUBROUTINE WAMIT2_Input_ExtrapInterp(u, t, u_out, t_out, ErrStat, ErrMsg )
!
! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time
! values of u (which has values associated with times in t).  Order of the interpolation is given by the size of u
!
!  expressions below based on either
!
!  f(t) = a
!  f(t) = a + b * t, or
!  f(t) = a + b * t + c * t**2
!
!  where a, b and c are determined as the solution to
!  f(t1) = u1, f(t2) = u2, f(t3) = u3  (as appropriate)
!
!..................................................................................................................................

 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u(:) ! Input at t1 > t2 > t3
 REAL(DbKi),                 INTENT(IN   )  :: t(:)           ! Times associated with the Inputs
 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u_out ! Input at tin_out
 REAL(DbKi),                 INTENT(IN   )  :: t_out           ! time to be extrap/interp'd to
 INTEGER(IntKi),             INTENT(  OUT)  :: ErrStat         ! Error status of the operation
 CHARACTER(*),               INTENT(  OUT)  :: ErrMsg          ! Error message if ErrStat /= ErrID_None
   ! local variables
 INTEGER(IntKi)                             :: order           ! order of polynomial fit (max 2)
 INTEGER(IntKi)                             :: ErrStat2        ! local errors
 CHARACTER(ErrMsgLen)                       :: ErrMsg2         ! local errors
 CHARACTER(*),    PARAMETER                 :: RoutineName = 'WAMIT2_Input_ExtrapInterp'
    ! Initialize ErrStat
 ErrStat = ErrID_None
 ErrMsg  = ""
 if ( size(t) .ne. size(u)) then
    CALL SetErrStat(ErrID_Fatal,'size(t) must equal size(u)',ErrStat,ErrMsg,RoutineName)
    RETURN
 endif
 order = SIZE(u) - 1
 IF ( order .eq. 0 ) THEN
   CALL WAMIT2_CopyInput(u(1), u_out, MESH_UPDATECOPY, ErrStat2, ErrMsg2 )
     CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
 ELSE IF ( order .eq. 1 ) THEN
   CALL WAMIT2_Input_ExtrapInterp1(u(1), u(2), t, u_out, t_out, ErrStat2, ErrMsg2 )
     CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
 ELSE IF ( order .eq. 2 ) THEN
   CALL WAMIT2_Input_ExtrapInterp2(u(1), u(2), u(3), t, u_out, t_out, ErrStat2, ErrMsg2 )
     CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
 ELSE
   CALL SetErrStat(ErrID_Fatal,'size(u) must be less than 4 (order must be less than 3).',ErrStat,ErrMsg,RoutineName)
   RETURN
 ENDIF
 END SUBROUTINE WAMIT2_Input_ExtrapInterp

 SUBROUTINE WAMIT2_Input_ExtrapInterp1(u1, u2, tin, u_out, tin_out, ErrStat, ErrMsg )
!
! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time
! values of u (which has values associated with times in t).  Order of the interpolation is 1.
!
!  f(t) = a + b * t, or
!
!  where a and b are determined as the solution to
!  f(t1) = u1, f(t2) = u2
!
!..................................................................................................................................

 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u1    ! Input at t1 > t2
 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u2    ! Input at t2
 REAL(DbKi),         INTENT(IN   )          :: tin(2)   ! Times associated with the Inputs
 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u_out ! Input at tin_out
 REAL(DbKi),         INTENT(IN   )          :: tin_out  ! time to be extrap/interp'd to
 INTEGER(IntKi),     INTENT(  OUT)          :: ErrStat  ! Error status of the operation
 CHARACTER(*),       INTENT(  OUT)          :: ErrMsg   ! Error message if ErrStat /= ErrID_None
   ! local variables
 REAL(DbKi)                                 :: t(2)     ! Times associated with the Inputs
 REAL(DbKi)                                 :: t_out    ! Time to which to be extrap/interpd
 CHARACTER(*),                    PARAMETER :: RoutineName = 'WAMIT2_Input_ExtrapInterp1'
 REAL(DbKi)                                 :: b0       ! temporary for extrapolation/interpolation
 REAL(DbKi)                                 :: c0       ! temporary for extrapolation/interpolation
 INTEGER(IntKi)                             :: ErrStat2 ! local errors
 CHARACTER(ErrMsgLen)                       :: ErrMsg2  ! local errors
    ! Initialize ErrStat
 ErrStat = ErrID_None
 ErrMsg  = ""
    ! we'll subtract a constant from the times to resolve some
    ! numerical issues when t gets large (and to simplify the equations)
 t = tin - tin(1)
 t_out = tin_out - tin(1)

   IF ( EqualRealNos( t(1), t(2) ) ) THEN
     CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName)
     RETURN
   END IF
      CALL MeshExtrapInterp1(u1%Mesh, u2%Mesh, tin, u_out%Mesh, tin_out, ErrStat2, ErrMsg2 )
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
 END SUBROUTINE WAMIT2_Input_ExtrapInterp1

 SUBROUTINE WAMIT2_Input_ExtrapInterp2(u1, u2, u3, tin, u_out, tin_out, ErrStat, ErrMsg )
!
! This subroutine calculates a extrapolated (or interpolated) Input u_out at time t_out, from previous/future time
! values of u (which has values associated with times in t).  Order of the interpolation is 2.
!
!  expressions below based on either
!
!  f(t) = a + b * t + c * t**2
!
!  where a, b and c are determined as the solution to
!  f(t1) = u1, f(t2) = u2, f(t3) = u3
!
!..................................................................................................................................

 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u1      ! Input at t1 > t2 > t3
 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u2      ! Input at t2 > t3
 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u3      ! Input at t3
 REAL(DbKi),                 INTENT(IN   )  :: tin(3)    ! Times associated with the Inputs
 TYPE(WAMIT2_InputType), INTENT(INOUT)  :: u_out     ! Input at tin_out
 REAL(DbKi),                 INTENT(IN   )  :: tin_out   ! time to be extrap/interp'd to
 INTEGER(IntKi),             INTENT(  OUT)  :: ErrStat   ! Error status of the operation
 CHARACTER(*),               INTENT(  OUT)  :: ErrMsg    ! Error message if ErrStat /= ErrID_None
   ! local variables
 REAL(DbKi)                                 :: t(3)      ! Times associated with the Inputs
 REAL(DbKi)                                 :: t_out     ! Time to which to be extrap/interpd
 INTEGER(IntKi)                             :: order     ! order of polynomial fit (max 2)
 REAL(DbKi)                                 :: b0       ! temporary for extrapolation/interpolation
 REAL(DbKi)                                 :: c0       ! temporary for extrapolation/interpolation
 INTEGER(IntKi)                             :: ErrStat2 ! local errors
 CHARACTER(ErrMsgLen)                       :: ErrMsg2  ! local errors
 CHARACTER(*),            PARAMETER         :: RoutineName = 'WAMIT2_Input_ExtrapInterp2'
    ! Initialize ErrStat
 ErrStat = ErrID_None
 ErrMsg  = ""
    ! we'll subtract a constant from the times to resolve some
    ! numerical issues when t gets large (and to simplify the equations)
 t = tin - tin(1)
 t_out = tin_out - tin(1)

   IF ( EqualRealNos( t(1), t(2) ) ) THEN
     CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName)
     RETURN
   ELSE IF ( EqualRealNos( t(2), t(3) ) ) THEN
     CALL SetErrStat(ErrID_Fatal, 't(2) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName)
     RETURN
   ELSE IF ( EqualRealNos( t(1), t(3) ) ) THEN
     CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName)
     RETURN
   END IF
      CALL MeshExtrapInterp2(u1%Mesh, u2%Mesh, u3%Mesh, tin, u_out%Mesh, tin_out, ErrStat2, ErrMsg2 )
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
 END SUBROUTINE WAMIT2_Input_ExtrapInterp2

 SUBROUTINE WAMIT2_Output_ExtrapInterp(y, t, y_out, t_out, ErrStat, ErrMsg )
!
! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time
! values of y (which has values associated with times in t).  Order of the interpolation is given by the size of y
!
!  expressions below based on either
!
!  f(t) = a
!  f(t) = a + b * t, or
!  f(t) = a + b * t + c * t**2
!
!  where a, b and c are determined as the solution to
!  f(t1) = y1, f(t2) = y2, f(t3) = y3  (as appropriate)
!
!..................................................................................................................................

 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y(:) ! Output at t1 > t2 > t3
 REAL(DbKi),                 INTENT(IN   )  :: t(:)           ! Times associated with the Outputs
 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y_out ! Output at tin_out
 REAL(DbKi),                 INTENT(IN   )  :: t_out           ! time to be extrap/interp'd to
 INTEGER(IntKi),             INTENT(  OUT)  :: ErrStat         ! Error status of the operation
 CHARACTER(*),               INTENT(  OUT)  :: ErrMsg          ! Error message if ErrStat /= ErrID_None
   ! local variables
 INTEGER(IntKi)                             :: order           ! order of polynomial fit (max 2)
 INTEGER(IntKi)                             :: ErrStat2        ! local errors
 CHARACTER(ErrMsgLen)                       :: ErrMsg2         ! local errors
 CHARACTER(*),    PARAMETER                 :: RoutineName = 'WAMIT2_Output_ExtrapInterp'
    ! Initialize ErrStat
 ErrStat = ErrID_None
 ErrMsg  = ""
 if ( size(t) .ne. size(y)) then
    CALL SetErrStat(ErrID_Fatal,'size(t) must equal size(y)',ErrStat,ErrMsg,RoutineName)
    RETURN
 endif
 order = SIZE(y) - 1
 IF ( order .eq. 0 ) THEN
   CALL WAMIT2_CopyOutput(y(1), y_out, MESH_UPDATECOPY, ErrStat2, ErrMsg2 )
     CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
 ELSE IF ( order .eq. 1 ) THEN
   CALL WAMIT2_Output_ExtrapInterp1(y(1), y(2), t, y_out, t_out, ErrStat2, ErrMsg2 )
     CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
 ELSE IF ( order .eq. 2 ) THEN
   CALL WAMIT2_Output_ExtrapInterp2(y(1), y(2), y(3), t, y_out, t_out, ErrStat2, ErrMsg2 )
     CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
 ELSE
   CALL SetErrStat(ErrID_Fatal,'size(y) must be less than 4 (order must be less than 3).',ErrStat,ErrMsg,RoutineName)
   RETURN
 ENDIF
 END SUBROUTINE WAMIT2_Output_ExtrapInterp

 SUBROUTINE WAMIT2_Output_ExtrapInterp1(y1, y2, tin, y_out, tin_out, ErrStat, ErrMsg )
!
! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time
! values of y (which has values associated with times in t).  Order of the interpolation is 1.
!
!  f(t) = a + b * t, or
!
!  where a and b are determined as the solution to
!  f(t1) = y1, f(t2) = y2
!
!..................................................................................................................................

 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y1    ! Output at t1 > t2
 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y2    ! Output at t2
 REAL(DbKi),         INTENT(IN   )          :: tin(2)   ! Times associated with the Outputs
 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y_out ! Output at tin_out
 REAL(DbKi),         INTENT(IN   )          :: tin_out  ! time to be extrap/interp'd to
 INTEGER(IntKi),     INTENT(  OUT)          :: ErrStat  ! Error status of the operation
 CHARACTER(*),       INTENT(  OUT)          :: ErrMsg   ! Error message if ErrStat /= ErrID_None
   ! local variables
 REAL(DbKi)                                 :: t(2)     ! Times associated with the Outputs
 REAL(DbKi)                                 :: t_out    ! Time to which to be extrap/interpd
 CHARACTER(*),                    PARAMETER :: RoutineName = 'WAMIT2_Output_ExtrapInterp1'
 REAL(DbKi)                                 :: b0       ! temporary for extrapolation/interpolation
 REAL(DbKi)                                 :: c0       ! temporary for extrapolation/interpolation
 REAL(DbKi),ALLOCATABLE,DIMENSION(:)        :: b1       ! temporary for extrapolation/interpolation
 REAL(DbKi),ALLOCATABLE,DIMENSION(:)        :: c1       ! temporary for extrapolation/interpolation
 INTEGER(IntKi)                             :: ErrStat2 ! local errors
 CHARACTER(ErrMsgLen)                       :: ErrMsg2  ! local errors
    ! Initialize ErrStat
 ErrStat = ErrID_None
 ErrMsg  = ""
    ! we'll subtract a constant from the times to resolve some
    ! numerical issues when t gets large (and to simplify the equations)
 t = tin - tin(1)
 t_out = tin_out - tin(1)

   IF ( EqualRealNos( t(1), t(2) ) ) THEN
     CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName)
     RETURN
   END IF
      CALL MeshExtrapInterp1(y1%Mesh, y2%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 )
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN
  ALLOCATE(b1(SIZE(y_out%WriteOutput,1)))
  ALLOCATE(c1(SIZE(y_out%WriteOutput,1)))
  b1 = -(y1%WriteOutput - y2%WriteOutput)/t(2)
  y_out%WriteOutput = y1%WriteOutput + b1 * t_out
  DEALLOCATE(b1)
  DEALLOCATE(c1)
END IF ! check if allocated
 END SUBROUTINE WAMIT2_Output_ExtrapInterp1

 SUBROUTINE WAMIT2_Output_ExtrapInterp2(y1, y2, y3, tin, y_out, tin_out, ErrStat, ErrMsg )
!
! This subroutine calculates a extrapolated (or interpolated) Output y_out at time t_out, from previous/future time
! values of y (which has values associated with times in t).  Order of the interpolation is 2.
!
!  expressions below based on either
!
!  f(t) = a + b * t + c * t**2
!
!  where a, b and c are determined as the solution to
!  f(t1) = y1, f(t2) = y2, f(t3) = y3
!
!..................................................................................................................................

 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y1      ! Output at t1 > t2 > t3
 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y2      ! Output at t2 > t3
 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y3      ! Output at t3
 REAL(DbKi),                 INTENT(IN   )  :: tin(3)    ! Times associated with the Outputs
 TYPE(WAMIT2_OutputType), INTENT(INOUT)  :: y_out     ! Output at tin_out
 REAL(DbKi),                 INTENT(IN   )  :: tin_out   ! time to be extrap/interp'd to
 INTEGER(IntKi),             INTENT(  OUT)  :: ErrStat   ! Error status of the operation
 CHARACTER(*),               INTENT(  OUT)  :: ErrMsg    ! Error message if ErrStat /= ErrID_None
   ! local variables
 REAL(DbKi)                                 :: t(3)      ! Times associated with the Outputs
 REAL(DbKi)                                 :: t_out     ! Time to which to be extrap/interpd
 INTEGER(IntKi)                             :: order     ! order of polynomial fit (max 2)
 REAL(DbKi)                                 :: b0       ! temporary for extrapolation/interpolation
 REAL(DbKi)                                 :: c0       ! temporary for extrapolation/interpolation
 REAL(DbKi),ALLOCATABLE,DIMENSION(:)        :: b1       ! temporary for extrapolation/interpolation
 REAL(DbKi),ALLOCATABLE,DIMENSION(:)        :: c1       ! temporary for extrapolation/interpolation
 INTEGER(IntKi)                             :: ErrStat2 ! local errors
 CHARACTER(ErrMsgLen)                       :: ErrMsg2  ! local errors
 CHARACTER(*),            PARAMETER         :: RoutineName = 'WAMIT2_Output_ExtrapInterp2'
    ! Initialize ErrStat
 ErrStat = ErrID_None
 ErrMsg  = ""
    ! we'll subtract a constant from the times to resolve some
    ! numerical issues when t gets large (and to simplify the equations)
 t = tin - tin(1)
 t_out = tin_out - tin(1)

   IF ( EqualRealNos( t(1), t(2) ) ) THEN
     CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(2) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName)
     RETURN
   ELSE IF ( EqualRealNos( t(2), t(3) ) ) THEN
     CALL SetErrStat(ErrID_Fatal, 't(2) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName)
     RETURN
   ELSE IF ( EqualRealNos( t(1), t(3) ) ) THEN
     CALL SetErrStat(ErrID_Fatal, 't(1) must not equal t(3) to avoid a division-by-zero error.', ErrStat, ErrMsg,RoutineName)
     RETURN
   END IF
      CALL MeshExtrapInterp2(y1%Mesh, y2%Mesh, y3%Mesh, tin, y_out%Mesh, tin_out, ErrStat2, ErrMsg2 )
        CALL SetErrStat(ErrStat2, ErrMsg2, ErrStat, ErrMsg,RoutineName)
IF (ALLOCATED(y_out%WriteOutput) .AND. ALLOCATED(y1%WriteOutput)) THEN
  ALLOCATE(b1(SIZE(y_out%WriteOutput,1)))
  ALLOCATE(c1(SIZE(y_out%WriteOutput,1)))
  b1 = (t(3)**2*(y1%WriteOutput - y2%WriteOutput) + t(2)**2*(-y1%WriteOutput + y3%WriteOutput))/(t(2)*t(3)*(t(2) - t(3)))
  c1 = ( (t(2)-t(3))*y1%WriteOutput + t(3)*y2%WriteOutput - t(2)*y3%WriteOutput ) / (t(2)*t(3)*(t(2) - t(3)))
  y_out%WriteOutput = y1%WriteOutput + b1 * t_out + c1 * t_out**2
  DEALLOCATE(b1)
  DEALLOCATE(c1)
END IF ! check if allocated
 END SUBROUTINE WAMIT2_Output_ExtrapInterp2

END MODULE WAMIT2_Types
!ENDOFREGISTRYGENERATEDFILE