MODULE NFUTIL
!
!   NAME:       NFUTIL                                      
!   STATUS:     Ver. 1.0                                              
!   PURPOSE:    utility routines              
!   LIBRARY:    MATH                                                  
!   TYPE:       SINGLE, DOUBLE PRECISION                              
!   AUTHOR:     Shigeru Inagaki                                       
!               National Institute for Fusion Science                 
!               +81-572-58-2143                                       
!               inagaki@LHD.nifs.ac.jp                                
!                                                                     
!   DESCRIPTION:                                                      
!     Utility routines are packaged  
!                                                                     
!   SEE ALSO:                                           
!   CALLED:                                                            
!   REVISION HISTORY:                                                 
!     14-MAY-2004 (CREATION)
!     14-SEP-2004 REALLOCATE, INDMASK added                    
!   COMMENTS:                                                         
!              
  USE NFNUM_KINDS, ONLY : i4b, sp, dp, lgt
!
  IMPLICIT NONE
!
  PRIVATE
!
  INTERFACE IMINLOC
    MODULE PROCEDURE IMINLOC_I4B, IMINLOC_SP, IMINLOC_DP
  END INTERFACE
!
  INTERFACE IMAXLOC
    MODULE PROCEDURE IMAXLOC_I4B, IMAXLOC_SP, IMAXLOC_DP
  END INTERFACE
!
  INTERFACE INTERPOL
    MODULE PROCEDURE INTERPOL_SP, INTERPOL_DP
  END INTERFACE
!
  INTERFACE REALLOCATE
    MODULE PROCEDURE REALLOCATE_VEC_STR, REALLOCATE_VEC_I4B, &
                   & REALLOCATE_VEC_SP,  REALLOCATE_VEC_DP,  &
                   & REALLOCATE_MAT_I4B, REALLOCATE_MAT_SP,  &
                   & REALLOCATE_MAT_DP
  END INTERFACE
!
  INTERFACE RESIZE
    MODULE PROCEDURE RESIZE_VEC_STR, RESIZE_VEC_I4B, &
                   & RESIZE_VEC_SP,  RESIZE_VEC_DP
  END INTERFACE
!
  INTERFACE CLEAR
    MODULE PROCEDURE CLEAR_VEC_STR, CLEAR_VEC_I4B, &
                   & CLEAR_VEC_SP,  CLEAR_VEC_DP,  &
                   & CLEAR_MAT_I4B, CLEAR_MAT_SP,  &
                   & CLEAR_MAT_DP
  END INTERFACE
!
  PUBLIC :: LGT_TO_INT, INT_TO_LGT
  PUBLIC :: DATENOW, IFIRSTLOC, INDMASK, IMINLOC, IMAXLOC, INTERPOL
  PUBLIC :: REALLOCATE, CLEAR, RESIZE
!
CONTAINS
!
!-------------------------------------------------------
!
ELEMENTAL FUNCTION LGT_TO_INT(bool) RESULT(i)
  LOGICAL(lgt), INTENT(IN) :: bool
  INTEGER(i4b) :: i
!
  IF (bool) THEN
    i = 1
  ELSE
    i = 0
  ENDIF
  RETURN
END FUNCTION LGT_TO_INT
!
!-------------------------------------------------------
!
ELEMENTAL FUNCTION INT_TO_LGT(i) RESULT(bool)
  INTEGER(i4b), INTENT(IN) :: i
  LOGICAL(lgt) :: bool
!
  IF (i > 0) THEN
    bool = .TRUE.
  ELSE
    bool = .FALSE.
  ENDIF
  RETURN
END FUNCTION INT_TO_LGT
!
!-------------------------------------------------------
!
FUNCTION DATENOW()
!
! Make and set date as MM/DD/YYYY HH:MM
!
  CHARACTER(LEN=16) :: DATENOW
!
  INTEGER(i4b)     :: date_time(8)
  CHARACTER(LEN=2) :: month, day, hour, minute
  CHARACTER(LEN=4) :: year
!
  CALL DATE_AND_TIME(VALUES = date_time)
  WRITE(year, '(I4.4)')   date_time(1)
  WRITE(month, '(I2.2)')  date_time(2)
  WRITE(day, '(I2.2)')    date_time(3)
  WRITE(hour, '(I2.2)')   date_time(5)
  WRITE(minute, '(I2.2)') date_time(6) 
  DATENOW = month//'/'//day//'/'//year//' '//hour//':'//minute
  RETURN
END FUNCTION DATENOW
!
!-------------------------------------------------------
!
FUNCTION INDMASK(mask) RESULT(indx)
  LOGICAL(lgt), INTENT(IN) :: mask(:)
  INTEGER(i4b), POINTER    :: indx(:)
!
  INTEGER(i4b) :: n, m, i, istat
  INTEGER(i4b) :: series(SIZE(mask))
!
  n = COUNT(mask)
  m = SIZE(mask)
  ALLOCATE(indx(n), STAT=istat)
  IF (istat /= 0) THEN
    indx => NULL()
    RETURN
  ENDIF
!
  FORALL(i=1:m) series(i) = i
  indx = PACK(series, mask)
  RETURN
END FUNCTION INDMASK
!
!-------------------------------------------------------
!
FUNCTION IFIRSTLOC(mask) RESULT(iloc)
!
! Return the location of the first true element of mask.             
!
  LOGICAL(lgt), INTENT(in) :: mask(:)
  INTEGER(i4b) :: iloc
!
  INTEGER(i4b) :: loc(1)
!
  loc = MAXLOC(MERGE(1,0,mask))
  iloc = loc(1)
  IF (.NOT. mask(iloc)) THEN
     iloc = SIZE(mask) + 1
  ENDIF
  RETURN
END FUNCTION IFIRSTLOC
!
!-------------------------------------------------------
!
FUNCTION IMINLOC_I4B(vec, mask) RESULT(iloc)
!
! Return the location of the minimum element of vec.             
! 
  INTEGER(i4b),           INTENT(IN) :: vec(:)
  LOGICAL(lgt), OPTIONAL, INTENT(IN) :: mask(:)
  INTEGER(i4b) :: iloc
!
  INTEGER(i4b) :: loc(1)
!
  IF (.NOT. PRESENT(mask)) THEN
    loc = MINLOC(vec)
  ELSE
    loc = MINLOC(vec, MASK=mask)
  ENDIF
  iloc = loc(1)
  RETURN
END FUNCTION IMINLOC_I4B
!
!-------------------------------------------------------
!
FUNCTION IMINLOC_SP(vec, mask) RESULT(iloc)
!
! Return the location of the minimum element of vec.             
! 
  REAL(sp),               INTENT(IN) :: vec(:)
  LOGICAL(lgt), OPTIONAL, INTENT(IN) :: mask(:)
  INTEGER(i4b) :: iloc
!
  INTEGER(i4b) :: loc(1)
!
  IF (.NOT. PRESENT(mask)) THEN
    loc = MINLOC(vec)
  ELSE
    loc = MINLOC(vec, MASK=mask)
  ENDIF
  iloc = loc(1)
  RETURN
END FUNCTION IMINLOC_SP
!
!-------------------------------------------------------
!
FUNCTION IMINLOC_DP(vec, mask) RESULT(iloc)
!
! Return the location of the minimum element of vec.             
! 
  REAL(dp),               INTENT(IN) :: vec(:)
  LOGICAL(lgt), OPTIONAL, INTENT(IN) :: mask(:)
  INTEGER(i4b) :: iloc
!
  INTEGER(i4b) :: loc(1)
!
  IF (.NOT. PRESENT(mask)) THEN
    loc = MINLOC(vec)
  ELSE
    loc = MINLOC(vec, MASK=mask)
  ENDIF
  iloc = loc(1)
  RETURN
END FUNCTION IMINLOC_DP
!
!-------------------------------------------------------
!
FUNCTION IMAXLOC_I4B(vec, mask) RESULT(iloc)
!
! Return the location of the maximum element of vec.             
! 
  INTEGER(i4b),           INTENT(IN) :: vec(:)
  LOGICAL(lgt), OPTIONAL, INTENT(IN) :: mask(:)
  INTEGER(i4b) :: iloc
!
  INTEGER(i4b) :: loc(1)
!
  IF (.NOT. PRESENT(mask)) THEN
    loc = MAXLOC(vec)
  ELSE
    loc = MAXLOC(vec, MASK=mask)
  ENDIF
  iloc = loc(1)
  RETURN
END FUNCTION IMAXLOC_I4B
!
!-------------------------------------------------------
!
FUNCTION IMAXLOC_SP(vec, mask) RESULT(iloc)
!
! Return the location of the maximum element of vec.             
! 
  REAL(sp),               INTENT(IN) :: vec(:)
  LOGICAL(lgt), OPTIONAL, INTENT(IN) :: mask(:)
  INTEGER(i4b) :: iloc
!
  INTEGER(i4b) :: loc(1)
!
  IF (.NOT. PRESENT(mask)) THEN
    loc = MAXLOC(vec)
  ELSE
    loc = MAXLOC(vec, MASK=mask)
  ENDIF
  iloc = loc(1)
  RETURN
END FUNCTION IMAXLOC_SP
!
!-------------------------------------------------------
!
FUNCTION IMAXLOC_DP(vec, mask) RESULT(iloc)
!
! Return the location of the maximum element of vec.             
! 
  REAL(dp),               INTENT(IN) :: vec(:)
  LOGICAL(lgt), OPTIONAL, INTENT(IN) :: mask(:)
  INTEGER(i4b) :: iloc
!
  INTEGER(i4b) :: loc(1)
!
  IF (.NOT. PRESENT(mask)) THEN
    loc = MAXLOC(vec)
  ELSE
    loc = MAXLOC(vec, MASK=mask)
  ENDIF
  iloc = loc(1)
  RETURN
END FUNCTION IMAXLOC_DP
!
!-------------------------------------------------------
!
SUBROUTINE INTERPOL_SP(xa,ya,x,y,errid)
!
!   Given arrays xa and ya of length N, and given a value x, this 
!   routine returns a value y
!
  USE NFERR, ONLY : ERRSTAT, DANGER
!
  REAL(sp), INTENT(IN)  :: xa(:), ya(:)
  REAL(sp), INTENT(IN)  :: x
  REAL(sp), INTENT(OUT) :: y
  TYPE(ERRSTAT), OPTIONAL, INTENT(OUT) :: errid
!
  INTEGER(i4b) :: n, ns
  REAL(sp) :: a
!
  IF (PRESENT(errid)) THEN
    errid%routine_name = "INTERPOL"
  ENDIF
  n = SIZE(xa)
  IF (n > SIZE(ya) .OR. x > MAXVAL(xa) .OR. x < MINVAL(xa)) THEN
    IF (PRESENT(errid)) THEN
      errid%message = "n > SIZE(ya) .OR. x > MAXVAL(xa) .OR. x < MINVAL(xa)"
      errid%level = DANGER
    ENDIF
    RETURN
  ENDIF
!  Find index ns of closest table entry.
  ns = IMINLOC(ABS(x-xa))
  IF (xa(ns) > x) THEN
    IF (xa(ns) == xa(ns-1)) GOTO 10
    a = (ya(ns) - ya(ns-1))/(xa(ns) - xa(ns-1))
    y = ya(ns-1) + a*(x - xa(ns-1))
  ELSE
    IF (xa(ns+1) == xa(ns)) GOTO 20
    a = (ya(ns+1) - ya(ns))/(xa(ns+1) - xa(ns))
    y = ya(ns) + a*(x - xa(ns))
  ENDIF            
  RETURN
!
 10 CONTINUE
  IF (PRESENT(errid)) THEN
    errid%message = "xa(ns) == xa(ns-1)"
    errid%level = DANGER
  ENDIF
  RETURN
!
 20 CONTINUE
  IF (PRESENT(errid)) THEN
    errid%message = "xa(ns+1) == xa(ns)"
    errid%level = DANGER
  ENDIF
  RETURN
END SUBROUTINE INTERPOL_SP
!
!-------------------------------------------------------
!
SUBROUTINE INTERPOL_DP(xa,ya,x,y,errid)
!
!   Given arrays xa and ya of length N, and given a value x, this 
!   routine returns a value y
!
  USE NFERR, ONLY : ERRSTAT, DANGER
!
  REAL(dp), INTENT(IN)  :: xa(:), ya(:)
  REAL(dp), INTENT(IN)  :: x
  REAL(dp), INTENT(OUT) :: y
  TYPE(ERRSTAT), OPTIONAL, INTENT(OUT) :: errid
!
  INTEGER(i4b) :: n, ns
  REAL(dp) :: a
!
  IF (PRESENT(errid)) THEN
    errid%routine_name = "INTERPOL"
  ENDIF
  n = SIZE(xa)
  IF (n > SIZE(ya) .OR. x > MAXVAL(xa) .OR. x < MINVAL(xa)) THEN
    IF (PRESENT(errid)) THEN
      errid%message = "n > SIZE(ya) .OR. x > MAXVAL(xa) .OR. x < MINVAL(xa)"
      errid%level = DANGER
    ENDIF
    RETURN
  ENDIF
!  Find index ns of closest table entry.
  ns = IMINLOC(ABS(x-xa))
  IF (xa(ns) > x) THEN
    IF (xa(ns) == xa(ns-1)) GOTO 10
    a = (ya(ns) - ya(ns-1))/(xa(ns) - xa(ns-1))
    y = ya(ns-1) + a*(x - xa(ns-1))
  ELSE
    IF (xa(ns+1) == xa(ns)) GOTO 20
    a = (ya(ns+1) - ya(ns))/(xa(ns+1) - xa(ns))
    y = ya(ns) + a*(x - xa(ns))
  ENDIF            
  RETURN
!
 10 CONTINUE
  IF (PRESENT(errid)) THEN
    errid%message = "xa(ns) == xa(ns-1)"
    errid%level = DANGER
  ENDIF
  RETURN
!
 20 CONTINUE
  IF (PRESENT(errid)) THEN
    errid%message = "xa(ns+1) == xa(ns)"
    errid%level = DANGER
  ENDIF
  RETURN
END SUBROUTINE INTERPOL_DP 
!
!-------------------------------------------------------
!
FUNCTION REALLOCATE_VEC_STR(vec, n, strlen) RESULT(istat)
  INTEGER(i4b),          INTENT(IN) :: strlen
  CHARACTER(LEN=strlen), POINTER    :: vec(:)
  INTEGER(i4b),          INTENT(IN) :: n
  INTEGER(i4b) :: istat
!
  istat = 0
  IF (ASSOCIATED(vec)) THEN
    IF (SIZE(vec) /= n) THEN
      DEALLOCATE(vec)
      ALLOCATE(vec(n), STAT=istat)
    ENDIF
  ELSE
    ALLOCATE(vec(n), STAT=istat)
  ENDIF
  IF (istat /= 0) THEN
    vec => NULL()
    RETURN
  ENDIF
  vec(1:n) = ''
  RETURN
END FUNCTION REALLOCATE_VEC_STR
!
!-------------------------------------------------------
!
FUNCTION REALLOCATE_VEC_I4B(vec, n) RESULT(istat)
  INTEGER(i4b), POINTER    :: vec(:)
  INTEGER(i4b), INTENT(IN) :: n
  INTEGER(i4b) :: istat
!
  istat = 0
  IF (ASSOCIATED(vec)) THEN
    IF (SIZE(vec) /= n) THEN
      DEALLOCATE(vec, STAT=istat)
      ALLOCATE(vec(n), STAT=istat)
    ENDIF
  ELSE
    ALLOCATE(vec(n), STAT=istat)
  ENDIF
  IF (istat /= 0) THEN
     vec => NULL()
     RETURN
  ENDIF
  vec(1:n) = 0
  RETURN
END FUNCTION REALLOCATE_VEC_I4B           
!
!-------------------------------------------------------
!
FUNCTION REALLOCATE_VEC_SP(vec, n) RESULT(istat)
  REAL(sp),     POINTER    :: vec(:)
  INTEGER(i4b), INTENT(IN) :: n
  INTEGER(i4b) :: istat
!
  istat = 0
  IF (ASSOCIATED(vec)) THEN
    IF (SIZE(vec) /= n) THEN
      DEALLOCATE(vec)
      ALLOCATE(vec(n), STAT=istat)
    ENDIF
  ELSE
    ALLOCATE(vec(n), STAT=istat)
  ENDIF
  IF (istat /= 0) THEN
    vec => NULL()
    RETURN
  ENDIF
  vec(1:n) = 0.0_sp
  RETURN
END FUNCTION REALLOCATE_VEC_SP           
!
!-------------------------------------------------------
!
FUNCTION REALLOCATE_VEC_DP(vec, n) RESULT(istat)
  REAL(dp),     POINTER    :: vec(:)
  INTEGER(i4b), INTENT(IN) :: n
  INTEGER(i4b) :: istat
!
  istat = 0
  IF (ASSOCIATED(vec)) THEN
    IF (SIZE(vec) /= n) THEN
      DEALLOCATE(vec)
      ALLOCATE(vec(n), STAT=istat)
    ENDIF
  ELSE
    ALLOCATE(vec(n), STAT=istat)
  ENDIF
  IF (istat /= 0) THEN
    vec => NULL()
    RETURN
  ENDIF
  vec(1:n) = 0.0_dp
  RETURN
END FUNCTION REALLOCATE_VEC_DP  
!
!-------------------------------------------------------
!
FUNCTION REALLOCATE_MAT_I4B(mat, n, m) RESULT(istat)
  INTEGER(i4b), POINTER    :: mat(:,:)
  INTEGER(i4b), INTENT(IN) :: n, m
  INTEGER(i4b) :: istat
!
  istat = 0
  IF (ASSOCIATED(mat)) THEN
    IF (SIZE(mat, DIM=1) /= n .OR. SIZE(mat, DIM=2) /= m) THEN
      DEALLOCATE(mat)
      ALLOCATE(mat(n,m), STAT=istat)
    ENDIF
  ELSE
    ALLOCATE(mat(n,m), STAT=istat)
  ENDIF
  IF (istat /= 0) THEN
    mat => NULL()
    RETURN
  ENDIF
  mat(1:n, 1:m) = 0
  RETURN
END FUNCTION REALLOCATE_MAT_I4B           
!
!-------------------------------------------------------
!
FUNCTION REALLOCATE_MAT_SP(mat, n, m) RESULT(istat)
  REAL(sp),     POINTER    :: mat(:,:)
  INTEGER(i4b), INTENT(IN) :: n, m
  INTEGER(i4b) :: istat
!
  istat = 0
  IF (ASSOCIATED(mat)) THEN
    IF (SIZE(mat, DIM=1) /= n .OR. SIZE(mat, DIM=2) /= m) THEN
      DEALLOCATE(mat)
      ALLOCATE(mat(n,m), STAT=istat)
    ENDIF
  ELSE
    ALLOCATE(mat(n,m), STAT=istat)
  ENDIF
  IF (istat /= 0) THEN
    mat => NULL()
    RETURN
  ENDIF
  mat(1:n, 1:m) = 0.0_sp
  RETURN
END FUNCTION REALLOCATE_MAT_SP           
!
!-------------------------------------------------------
!
FUNCTION REALLOCATE_MAT_DP(mat, n, m) RESULT(istat)
  REAL(dp),     POINTER    :: mat(:, :)
  INTEGER(i4b), INTENT(IN) :: n, m
  INTEGER(i4b) :: istat
!
  istat = 0
  IF (ASSOCIATED(mat)) THEN
    IF (SIZE(mat, DIM=1) /= n .OR. SIZE(mat, DIM=2) /= m) THEN
      DEALLOCATE(mat)
      ALLOCATE(mat(n,m), STAT=istat)
    ENDIF
  ELSE
    ALLOCATE(mat(n,m), STAT=istat)
  ENDIF
  IF (istat /= 0) THEN
    mat => NULL()
    RETURN
  ENDIF
  mat(1:n, 1:m) = 0.0_dp
  RETURN
END FUNCTION REALLOCATE_MAT_DP
!
!-------------------------------------------------------
!
FUNCTION RESIZE_VEC_STR(vec, n, strlen) RESULT(istat)
  INTEGER(i4b),          INTENT(IN) :: strlen
  CHARACTER(LEN=strlen), POINTER    :: vec(:)
  INTEGER(i4b),          INTENT(IN) :: n
  INTEGER(i4b) :: istat
!
  INTEGER(i4b) :: nold
  CHARACTER(LEN=strlen), ALLOCATABLE :: tmp(:)
!
  IF (n <= 0) THEN
    istat = 2
    RETURN
  ENDIF
!
  IF (.NOT. ASSOCIATED(vec)) THEN
    ALLOCATE(vec(n), STAT=istat)
    RETURN
  ENDIF
!
  nold = SIZE(vec)
  IF (nold == 0) THEN
    istat = 1
    RETURN
  ENDIF
!
  ALLOCATE(tmp(nold), STAT = istat)
  IF (istat /= 0) RETURN
  tmp(1:nold) = vec(1:nold)
  istat = REALLOCATE(vec, n, strlen)
  IF (istat /= 0) GOTO 10
  IF (n > nold) THEN
    vec(1:nold) = tmp(1:nold)
    vec(nold+1:n) = ''
  ELSE
    vec(1:n) = tmp(1:n)
  ENDIF
 10 CONTINUE
  DEALLOCATE(tmp)
  RETURN
END FUNCTION RESIZE_VEC_STR
!
!-------------------------------------------------------
!
FUNCTION RESIZE_VEC_I4B(vec, n) RESULT(istat)
  INTEGER(i4b), POINTER    :: vec(:)
  INTEGER(i4b), INTENT(IN) :: n
  INTEGER(i4b) :: istat
!
  INTEGER(i4b) :: nold
  INTEGER(i4b), ALLOCATABLE :: tmp(:)
!
  IF (n <= 0) THEN
    istat = 2
    RETURN
  ENDIF
!
  IF (.NOT. ASSOCIATED(vec)) THEN
    istat = REALLOCATE(vec, n)
    RETURN
  ENDIF
!
  nold = SIZE(vec)
  IF (nold == 0) THEN
    istat = 1
    RETURN
  ENDIF
!
  ALLOCATE(tmp(nold), STAT = istat)
  IF (istat /= 0) RETURN
  tmp(1:nold) = vec(1:nold)
  istat = REALLOCATE(vec, n)
  IF (istat /= 0) GOTO 10
  IF (n > nold) THEN
    vec(1:nold) = tmp(1:nold)
    vec(nold+1:n) = 0
  ELSE
    vec(1:n) = tmp(1:n)
  ENDIF
  10 CONTINUE
  DEALLOCATE(tmp)
  RETURN
END FUNCTION RESIZE_VEC_I4B
!
!-------------------------------------------------------
!
FUNCTION RESIZE_VEC_SP(vec, n) RESULT(istat)
  REAL(sp),     POINTER    :: vec(:)
  INTEGER(i4b), INTENT(IN) :: n
  INTEGER(i4b) :: istat
!
  INTEGER(i4b) :: nold
  REAL(sp), ALLOCATABLE :: tmp(:)
!
  IF (n <= 0) THEN
    istat = 2
    RETURN
  ENDIF
!
  IF (.NOT. ASSOCIATED(vec)) THEN
    istat = REALLOCATE(vec, n)
    RETURN
  ENDIF
!
  nold = SIZE(vec)
  IF (nold == 0) THEN
    istat = 1
    RETURN
  ENDIF
!
  ALLOCATE(tmp(nold), STAT = istat)
  IF (istat /= 0) RETURN
  tmp(1:nold) = vec(1:nold)
  istat = REALLOCATE(vec, n)
  IF (istat /= 0) GOTO 10
  IF (n > nold) THEN
    vec(1:nold) = tmp(1:nold)
    vec(nold+1:n) = 0.0_sp
  ELSE
    vec(1:n) = tmp(1:n)
  ENDIF
  10 CONTINUE
  DEALLOCATE(tmp)
  RETURN
END FUNCTION RESIZE_VEC_SP
!
!-------------------------------------------------------
!
FUNCTION RESIZE_VEC_DP(vec, n) RESULT(istat)
  REAL(dp),     POINTER    :: vec(:)
  INTEGER(i4b), INTENT(IN) :: n
  INTEGER(i4b) :: istat
!
  INTEGER(i4b) :: nold
  REAL(dp), ALLOCATABLE :: tmp(:)
!
  IF (n <= 0) THEN
    istat = 2
    RETURN
  ENDIF
!
  IF (.NOT. ASSOCIATED(vec)) THEN
    istat = REALLOCATE(vec, n)
    RETURN
  ENDIF
!
  nold = SIZE(vec)
  IF (nold == 0) THEN
    istat = 1
    RETURN
  ENDIF
!
  ALLOCATE(tmp(nold), STAT = istat)
  IF (istat /= 0) RETURN
  tmp(1:nold) = vec(1:nold)
  istat = REALLOCATE(vec, n)
  IF (istat /= 0) GOTO 10
  IF (n > nold) THEN
    vec(1:nold) = tmp(1:nold)
    vec(nold+1:n) = 0.0_dp
  ELSE
    vec(1:n) = tmp(1:n)
  ENDIF
  10 CONTINUE
  DEALLOCATE(tmp)
  RETURN
END FUNCTION RESIZE_VEC_DP
!
!-------------------------------------------------------
!
SUBROUTINE CLEAR_VEC_STR(vec)
  CHARACTER(LEN=*), POINTER :: vec(:)
!
  IF (ASSOCIATED(vec)) THEN
    DEALLOCATE(vec)
    vec => NULL()
  ENDIF
  RETURN
END SUBROUTINE CLEAR_VEC_STR
!
!-------------------------------------------------------
!
SUBROUTINE CLEAR_VEC_I4B(vec)
  INTEGER(i4b), POINTER :: vec(:)
!
  IF (ASSOCIATED(vec)) THEN
    DEALLOCATE(vec)
    vec => NULL()
  ENDIF
  RETURN
END SUBROUTINE CLEAR_VEC_I4B
!
!-------------------------------------------------------
!
SUBROUTINE CLEAR_VEC_SP(vec)
  REAL(sp), POINTER :: vec(:)
!
  IF (ASSOCIATED(vec)) THEN
    DEALLOCATE(vec)
    vec => NULL()
  ENDIF
  RETURN
END SUBROUTINE CLEAR_VEC_SP 
!
!-------------------------------------------------------
!
SUBROUTINE CLEAR_VEC_DP(vec)
  REAL(dp), POINTER :: vec(:)
!
  IF (ASSOCIATED(vec)) THEN
    DEALLOCATE(vec)
    vec => NULL()
  ENDIF
  RETURN
END SUBROUTINE CLEAR_VEC_DP
!
!-------------------------------------------------------
!
SUBROUTINE CLEAR_MAT_I4B(mat)
  INTEGER(i4b), POINTER :: mat(:,:)
!
  IF (ASSOCIATED(mat)) THEN
    DEALLOCATE(mat)
    mat => NULL()
  ENDIF
  RETURN
END SUBROUTINE CLEAR_MAT_I4B
!
!-------------------------------------------------------
!
SUBROUTINE CLEAR_MAT_SP(mat)
  REAL(sp), POINTER :: mat(:,:)
!
  IF (ASSOCIATED(mat)) THEN
    DEALLOCATE(mat)
    mat => NULL()
  ENDIF
  RETURN
END SUBROUTINE CLEAR_MAT_SP 
!
!-------------------------------------------------------
!
SUBROUTINE CLEAR_MAT_DP(mat)
  REAL(dp), POINTER :: mat(:,:)
!
  IF (ASSOCIATED(mat)) THEN
    DEALLOCATE(mat)
    mat => NULL()
  ENDIF
  RETURN
END SUBROUTINE CLEAR_MAT_DP
 
END MODULE NFUTIL
