Skip to content
Snippets Groups Projects
lfiz.f90 6.69 KiB
Newer Older
PROGRAM LFIZ
#ifdef NAGf95
  USE F90_UNIX
#endif

IMPLICIT NONE 

#ifndef NAGf95
INTEGER :: IARGC
! CRAY specific
INTEGER :: arglen
!!!!!!!!!!!!!!!!!
#endif
INTEGER :: inarg
CHARACTER(LEN=50) :: yexe

LOGICAL(KIND=LFI_INT),PARAMETER :: GTRUE  = .TRUE.
LOGICAL(KIND=LFI_INT),PARAMETER :: GFALSE = .FALSE.

INTEGER, PARAMETER :: FM_FIELD_SIZE = 16
INTEGER(KIND=LFI_INT), PARAMETER :: ISRCLU  = 11
INTEGER(KIND=LFI_INT), PARAMETER :: IDESTLU = 12
INTEGER :: JPHEXT
INTEGER(KIND=LFI_INT) :: iverb
INTEGER(KIND=LFI_INT) :: inap ! nb d'articles prevus (utile a la creation)
INTEGER(KIND=LFI_INT) :: inaf ! nb d'articles presents dans un fichier existant
INTEGER(KIND=LFI_INT) :: inafdest

CHARACTER(LEN=128) :: filename,DESTFNAME
INTEGER :: JI,JJ
CHARACTER(LEN=FM_FIELD_SIZE),DIMENSION(:),ALLOCATABLE :: yrecfm
INTEGER(KIND=LFI_INT),       DIMENSION(:),ALLOCATABLE :: ileng
INTEGER(KIND=8),             DIMENSION(:),ALLOCATABLE :: iwork

INTEGER(KIND=LFI_INT) :: ilengs
INTEGER(KIND=LFI_INT) :: ipos
INTEGER :: sizemax

INTEGER            :: IGRID
INTEGER            :: ICOMLEN,ICH
CHARACTER(LEN=100) :: COMMENT
INTEGER :: I2DSIZE,I3DSIZE,DATASIZE
INTEGER :: IDIMX,IDIMY,IDIMZ
LOGICAL :: GUSEDIM
INTEGER :: CPT
INTEGER :: LFICOMP
INTEGER :: NEWSIZE
INTEGER :: searchndx
INTEGER :: INDDATIM

!OLD: INARG = IARGC()
INARG = COMMAND_ARGUMENT_COUNT()

#if defined(F90HP)
#define HPINCR 1
#else
#define HPINCR 0
#endif

#if defined(FUJI) || defined(NAGf95) || defined(NEC) || defined(HP) || defined(pgf) || defined(G95) || defined(GFORTRAN)
  CALL GETARG(0+HPINCR,yexe)
  IF (LEN_TRIM(yexe) == 0) THEN
    PRINT *, 'FATAL ERROR : Activer la macro -DF90HP dans le Makefile et recompiler'
    STOP
  END IF
#else
  CALL PXFGETARG(0,yexe,arglen,iresp)
#endif
!  PRINT *,yexe, ' avec ',INARG,' arguments.'
  IF (INARG == 1) THEN 
     CALL GET_COMMAND_ARGUMENT(1,filename)
#if 0
!OLD:
#if defined(FUJI) || defined(NAGf95) || defined(NEC) || defined(HP) || defined(pgf) || defined(G95)|| defined(GFORTRAN)
     CALL GETARG(1+HPINCR,filename)
#else
     CALL PXFGETARG(1,filename,arglen,iresp)
#endif
  ELSE 
     PRINT *,'Usage : ', TRIM(yexe), ' [fichier lfi]'
     STOP
  END IF

searchndx = INDEX(TRIM(filename),".lfi",.TRUE.)
IF (searchndx /= 0 .AND. (LEN_TRIM(filename)-searchndx) == 3) THEN
  DESTFNAME=filename(1:searchndx)//'Z.lfi'
ELSE
  PRINT *,'ERROR : extension invalide'
  STOP
END IF

iverb = 0 ! verbosity level


IDIMX = 0
IDIMY = 0
IDIMZ = 0
GUSEDIM = .FALSE.

CALL LFIOUV(IRESP,ISRCLU,GTRUE,filename,'OLD',GFALSE&
            & ,GFALSE,iverb,inap,inaf)

CALL FMREADLFIN1(ISRCLU,'LFI_COMPRESSED',LFICOMP,iresp)
IF (iresp == 0) THEN
  SELECT CASE (LFICOMP)
    CASE(1)
      PRINT *,TRIM(filename),' : already compressed'
    CASE(0)
      PRINT *,'Data are in 32bits real format'
    CASE default
      PRINT *,'File in an unknown compression mode'
    END SELECT
    CALL LFIFER(IRESP,ISRCLU,'KEEP')
    STOP 9
END IF

CALL FMREADLFIN1(ISRCLU,'JPHEXT',JPHEXT,iresp)
IF (iresp /= 0) JPHEXT = 1

! First check if IMAX,JMAX,KMAX exist in LFI file
! to handle 3D, 2D variables -> update IDIMX,IDIMY,IDIMZ
CALL FMREADLFIN1(ISRCLU,'IMAX',IDIMX,iresp)
IF (iresp == 0) IDIMX = IDIMX+2*JPHEXT  ! IMAX + 2*JPHEXT
!
CALL FMREADLFIN1(ISRCLU,'JMAX',IDIMY,iresp)
IF (iresp == 0) IDIMY = IDIMY+2*JPHEXT  ! JMAX + 2*JPHEXT
!
CALL FMREADLFIN1(ISRCLU,'KMAX',IDIMZ,iresp)
IF (iresp == 0) IDIMZ = IDIMZ+2  ! KMAX + 2*JPVEXT

I2DSIZE = IDIMX*IDIMY 
I3DSIZE = IDIMX*IDIMY*IDIMZ
 
GUSEDIM = (I2DSIZE > 0)
IF (GUSEDIM) THEN
  PRINT *,'MESONH 3D, 2D articles DIMENSIONS used :'
  PRINT *,'DIMX =',IDIMX
  PRINT *,'DIMY =',IDIMY
  PRINT *,'DIMZ =',IDIMZ ! IDIMZ may be equal to 0 (PGD files)
ELSE
  PRINT *,'Can''t find IMAX or JMAX variables in the file : Compression ABORTED'
  CALL LFIFER(IRESP,ISRCLU,'KEEP')
  STOP 
END IF


PRINT *,'compressed file : ',DESTFNAME
CALL LFIOUV(IRESP,IDESTLU,GTRUE,DESTFNAME,'NEW'&
     & ,GFALSE,GFALSE,iverb,inaf+1,inafdest)

CALL LFIPOS(IRESP,ISRCLU)
ALLOCATE(yrecfm(inaf))
ALLOCATE(ileng(inaf))
yrecfm(:) = ''
sizemax=0
DO ji=1,inaf
  CALL LFICAS(IRESP,ISRCLU,yrecfm(ji),ileng(ji),ipos,GTRUE)
  IF (ileng(ji) > sizemax) sizemax=ileng(ji)
END DO
PRINT *,' Nombre total d''articles dans fichier source :', inaf
PRINT *,'sizemax =',sizemax
ALLOCATE(IWORK(sizemax))

CPT=0
DO JI=1,inaf
  CALL LFILEC(IRESP,ISRCLU,yrecfm(JI),iwork,ileng(JI))
  IGRID = IWORK(1)
  ICOMLEN = IWORK(2)
  IF (ICOMLEN > LEN(COMMENT)) THEN
    PRINT *,'ERROR : COMMENT string is too small'
    STOP
  END IF
  
  COMMENT = ''
  DO JJ=1,ICOMLEN
    ICH = iwork(2+JJ)
    COMMENT(JJ:JJ) = CHAR(ICH)
  END DO
  DATASIZE=ileng(JI)-ICOMLEN-2

!  IF (DATASIZE == I2DSIZE .OR. DATASIZE == I3DSIZE) THEN
  !IF (MODULO(DATASIZE,I2DSIZE) == 0) THEN

  INDDATIM=INDEX(yrecfm(JI),'.DATIM')
  IF ((MODULO(DATASIZE,I2DSIZE) == 0).AND. (TRIM(yrecfm(ji))/='ZS').AND.&
  (INDDATIM == 0))THEN
    CPT=CPT+1

!    PRINT *,'GRID=',IGRID
!    PRINT *,'COMMENT = ',TRIM(COMMENT)
!    PRINT *,'Taille data = ',DATASIZE
    PRINT *,'***** compression de ',JI,': ',TRIM(yrecfm(JI))
    CALL COMPRESS_FIELD(IWORK(3+ICOMLEN),IDIMX,IDIMY,DATASIZE,NEWSIZE)
!    NEWSIZE=DATASIZE
    PRINT *,'***** ARTICLE compress ',JI,': ',TRIM(yrecfm(JI)),', taille=',DATASIZE,',comp=',NEWSIZE
    ileng(JI) = NEWSIZE+ICOMLEN+2
  ELSE
    PRINT *,'ARTICLE ',JI,': ',TRIM(yrecfm(JI)),', taille =',ileng(JI)
  END IF
  CALL LFIECR(iresp,IDESTLU,yrecfm(JI),iwork,ileng(JI))  
END DO

IF (CPT > 0) THEN
  ! ADD a new article to TAG the compressed file
  IWORK(1) = 0
  COMMENT = "Compressed articles"
  ICOMLEN = LEN_TRIM(COMMENT)
  IWORK(2) = ICOMLEN
  DO JJ=1,ICOMLEN
    IWORK(2+JJ)=ICHAR(COMMENT(JJ:JJ))
  END DO
  ILENGS = 3+ICOMLEN
  IWORK(ILENGS) = 1
  CALL LFIECR(iresp,IDESTLU,'LFI_COMPRESSED',iwork,ilengs) 
END IF


PRINT *,' Nombre total d''articles      :', inaf
PRINT *,' Nombre d''articles compresses :', CPT
PRINT *,'sizemax =',sizemax
CALL LFIFER(IRESP,ISRCLU,'KEEP')
CALL LFIFER(IRESP,IDESTLU,'KEEP')

CONTAINS 

SUBROUTINE FMREADLFIN1(klu,hrecfm,kval,kresp)
INTEGER(KIND=LFI_INT), INTENT(IN)  :: klu ! logical fortran unit au lfi file
CHARACTER(LEN=*),      INTENT(IN)  :: hrecfm ! article name to be read
INTEGER,               INTENT(OUT) :: kval ! integer value for hrecfm article
INTEGER(KIND=LFI_INT), INTENT(OUT) :: kresp! return code null if OK
INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: iwork
INTEGER(KIND=LFI_INT)                    :: iresp,ilenga,iposex,icomlen
!
CALL LFINFO(iresp,klu,hrecfm,ilenga,iposex)
IF (iresp /=0 .OR. ilenga == 0) THEN
  kresp = -1
  kval = 0
ELSE
  ALLOCATE(IWORK(ilenga))
  CALL LFILEC(iresp,klu,hrecfm,iwork,ilenga)
  icomlen = iwork(2)
  kval = iwork(3+icomlen)
  kresp = iresp
  DEALLOCATE(IWORK)
END IF
END SUBROUTINE FMREADLFIN1

END PROGRAM LFIZ