Skip to content
Snippets Groups Projects
mode_util.f90 51.9 KiB
Newer Older
  • Learn to ignore specific revisions
  •     TYPE(TFILE_ELT),DIMENSION(:),INTENT(OUT) :: infiles
        TYPE(TFILE_ELT),DIMENSION(:),INTENT(OUT) :: outfiles
        INTEGER,                     INTENT(OUT) :: KNFILES_OUT
        CHARACTER(LEN=*),            INTENT(IN)  :: hinfile
        CHARACTER(LEN=*),            INTENT(IN)  :: houtfile
        INTEGER,                     INTENT(OUT) :: nbvar_infile
        TYPE(option),DIMENSION(:),   INTENT(IN)  :: options
        INTEGER,                     INTENT(IN)  :: runmode
    
    
        INTEGER(KIND=IDCDF_KIND)    :: omode
        INTEGER(KIND=IDCDF_KIND)    :: status
        INTEGER(KIND=LFI_INT)       :: ilu,iresp
    
    
        KNFILES_OUT = 0
    
        !
        ! Infiles
        !
        IF (runmode == MODECDF2CDF .OR. runmode == MODECDF2LFI) THEN
           !
           ! NetCDF
           !
    
           CALL IO_FILE_ADD2LIST(INFILES(1)%TFILE,HINFILE,'UNKNOWN','READ',HFORMAT='NETCDF4')
           CALL IO_FILE_OPEN_ll(INFILES(1)%TFILE)
    
           nbvar_infile = INFILES(1)%TFILE%NNCNAR
    
           CALL IO_FILE_ADD2LIST(INFILES(1)%TFILE,HINFILE,'UNKNOWN','READ', &
    
           CALL IO_FILE_OPEN_ll(INFILES(1)%TFILE)
    
           ilu = INFILES(1)%TFILE%NLFIFLU
    
           nbvar_infile = INFILES(1)%TFILE%NLFININAR
    
              CALL LFILAF(iresp,ilu,lfalse)
              CALL IO_FILE_CLOSE_ll(INFILES(1)%TFILE)
    
       !Read problem dimensions and some grid variables (needed to determine domain size and also by IO_FILE_OPEN_ll to create netCDF files)
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'JPHEXT',JPHEXT)
    
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'IMAX',NIMAX_ll)
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'JMAX',NJMAX_ll)
    
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'KMAX',NKMAX,IRESP2)
       IF (IRESP2/=0) NKMAX = 0
    
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'PROGRAM',CPROGRAM_ORIG)
    
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'STORAGE_TYPE',CSTORAGE_TYPE)
    
       ALLOCATE(XXHAT(NIMAX_ll+2*JPHEXT))
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'XHAT',XXHAT)
       ALLOCATE(XYHAT(NJMAX_ll+2*JPHEXT))
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'YHAT',XYHAT)
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'CARTESIAN',LCARTESIAN)
       !
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'LAT0',XLAT0)
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'LON0',XLON0)
       CALL IO_READ_FIELD(INFILES(1)%TFILE,'BETA',XBETA)
    
       IF (.NOT.LCARTESIAN) THEN
         CALL IO_READ_FIELD(INFILES(1)%TFILE,'RPK',   XRPK)
         CALL IO_READ_FIELD(INFILES(1)%TFILE,'LATORI',XLATORI)
         CALL IO_READ_FIELD(INFILES(1)%TFILE,'LONORI',XLONORI)
       ENDIF
       !
       IF (TRIM(CPROGRAM_ORIG)/='PGD' .AND. TRIM(CPROGRAM_ORIG)/='NESPGD' .AND. TRIM(CPROGRAM_ORIG)/='ZOOMPG' &
           .AND. .NOT.(TRIM(CPROGRAM_ORIG)=='REAL' .AND. CSTORAGE_TYPE=='SU') ) THEN !condition to detect PREP_SURFEX
         ALLOCATE(XZHAT(NKMAX+2*JPVEXT))
         CALL IO_READ_FIELD(INFILES(1)%TFILE,'ZHAT',XZHAT)
         ALLOCATE(LSLEVE)
         CALL IO_READ_FIELD(INFILES(1)%TFILE,'SLEVE',LSLEVE)
         ALLOCATE(TDTMOD)
    
         CALL IO_READ_FIELD(INFILES(1)%TFILE,'DTMOD',TDTMOD,IRESP2)
         IF(IRESP2/=0) DEALLOCATE(TDTMOD)
         ALLOCATE(TDTCUR)
         CALL IO_READ_FIELD(INFILES(1)%TFILE,'DTCUR',TDTCUR,IRESP2)
         IF(IRESP2/=0) DEALLOCATE(TDTCUR)
    
       ! Outfiles
       !
       IF (runmode == MODELFI2CDF .OR. runmode == MODECDF2CDF) THEN
    
             KNFILES_OUT = KNFILES_OUT + 1
    
             idx = KNFILES_OUT
             CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,HOUTFILE,'UNKNOWN','WRITE', &
    
             CALL IO_FILE_OPEN_ll(outfiles(idx)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)
    
               outfiles(idx)%tfile%LNCCOMPRESS       = .TRUE.
               outfiles(idx)%tfile%NNCCOMPRESS_LEVEL = options(OPTCOMPRESS)%ivalue
    
               outfiles(idx)%tfile%LNCREDUCE_FLOAT_PRECISION = .TRUE.
    
             status = NF90_SET_FILL(outfiles(idx)%TFILE%NNCID,NF90_NOFILL,omode)
    
             IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
           END IF ! .NOT.osplit
    
           KNFILES_OUT = KNFILES_OUT + 1
           idx = KNFILES_OUT
           CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,houtfile,'UNKNOWN','WRITE', &
    
           LIOCDF4 = .FALSE. !Necessary to open correctly the LFI file
    
           CALL IO_FILE_OPEN_ll(outfiles(idx)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)
    
       END IF
       !
       ! Create a dummy netCDF file necessary to manage correctly the netCDF dims
       IF (runmode == MODECDF2LFI) THEN
    
         KNFILES_OUT = KNFILES_OUT + 1
    
         idx = KNFILES_OUT
         CALL IO_FILE_ADD2LIST(outfiles(idx)%TFILE,'dummy_file','UNKNOWN','WRITE', &
    
                               HFORMAT='NETCDF4',OOLD=.TRUE.)
    
         CALL IO_FILE_OPEN_ll(outfiles(idx)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)
    
       PRINT *,'--> Converted to file: ', TRIM(houtfile)
    
    
      END SUBROUTINE OPEN_FILES
    
      SUBROUTINE OPEN_SPLIT_NCFILES_OUT(outfiles,KNFILES_OUT,houtfile,nbvar,options)
    
        USE MODE_FM,               ONLY: IO_FILE_OPEN_ll
        USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_ADD2LIST
    
    
        TYPE(TFILE_ELT),DIMENSION(:),  INTENT(INOUT) :: outfiles
        INTEGER,                       INTENT(OUT)   :: KNFILES_OUT
    
        CHARACTER(LEN=*),              INTENT(IN)    :: houtfile
        INTEGER,                       INTENT(IN)    :: nbvar
    
        TYPE(option),DIMENSION(:),     INTENT(IN)    :: options
    
        CHARACTER(LEN=:),ALLOCATABLE                   :: filename
        CHARACTER(LEN=:),ALLOCATABLE                   :: YLIST
    
        CHARACTER(LEN=NMNHNAMELGTMAX),DIMENSION(nbvar) :: YVARS
    
        INTEGER                  :: ji
        INTEGER                  :: idx1, idx2
        INTEGER(KIND=IDCDF_KIND) :: status
        INTEGER(KIND=IDCDF_KIND) :: omode
    
        YLIST = TRIM(options(OPTVAR)%cvalue)
    
        DO ji = 1,nbvar-1
          idx1 = INDEX(YLIST,',')
          idx2 = INDEX(YLIST,'=')
          IF (idx1/=0) THEN
            IF (idx2/=0 .AND. idx2<idx1) THEN
              YVARS(ji) = YLIST(1:idx2-1)
            ELSE
              YVARS(ji) = YLIST(1:idx1-1)
            END IF
            YLIST = YLIST(idx1+1:)
          ELSE
            CALL PRINT_MSG(NVERB_FATAL,'IO','OPEN_SPLIT_NCFILES_OUT','problem separating variable names')
          END IF
    
        idx2 = INDEX(YLIST,'=')
        IF (idx2>0) THEN
          YVARS(nbvar) = YLIST(1:idx2-1)
        ELSE
          YVARS(nbvar) = YLIST
        END IF
    
          filename = trim(houtfile)//'.'//TRIM(YVARS(ji))
    
          CALL IO_FILE_ADD2LIST(outfiles(ji)%TFILE,filename,'UNKNOWN','WRITE', &
    
          CALL IO_FILE_OPEN_ll(outfiles(ji)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)
    
            outfiles(ji)%tfile%LNCCOMPRESS       = .TRUE.
            outfiles(ji)%tfile%NNCCOMPRESS_LEVEL = options(OPTCOMPRESS)%ivalue
    
            outfiles(ji)%tfile%LNCREDUCE_FLOAT_PRECISION = .TRUE.
    
          status = NF90_SET_FILL(outfiles(ji)%TFILE%NNCID,NF90_NOFILL,omode)
    
          IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__)
        END DO
    
    
      END SUBROUTINE OPEN_SPLIT_NCFILES_OUT
    
      SUBROUTINE CLOSE_FILES(filelist,KNFILES)
    
        TYPE(TFILE_ELT),DIMENSION(:),INTENT(INOUT) :: filelist
        INTEGER,                     INTENT(IN)    :: KNFILES
    
          IF (filelist(ji)%TFILE%LOPENED) CALL IO_FILE_CLOSE_ll(filelist(ji)%TFILE,HPROGRAM_ORIG=CPROGRAM_ORIG)
    
      END SUBROUTINE CLOSE_FILES
    
      SUBROUTINE IO_FILL_DIMS_NC4(TPFILE,TPREC,KRESP)
        USE MODD_IO_ll,  ONLY: TFILEDATA
        USE MODE_NETCDF, ONLY: GETDIMCDF, IO_FIND_DIM_BYNAME_NC4
    
        TYPE(TFILEDATA),INTENT(IN)    :: TPFILE
        TYPE(workfield),INTENT(INOUT) :: TPREC
        INTEGER,        INTENT(OUT)   :: KRESP
    
        INTEGER              :: JJ
        TYPE(DIMCDF),POINTER :: TZDIMPTR
    
        KRESP = 0
    
        ALLOCATE(TPREC%TDIMS(TPREC%TFIELD%NDIMS))
    
        DO JJ=1,TPREC%TFIELD%NDIMS
        !DO JJ=1,TPREC%NDIMS_FILE !NDIMS_FILE can be bigger than NDIMS due to time dimension (it can be ignored here)
          CALL IO_FIND_DIM_BYNAME_NC4(TPFILE,TPREC%CDIMNAMES_FILE(JJ),TPREC%TDIMS(JJ),KRESP)
          !If dimension not found => create it
          IF (KRESP/=0)  THEN
            TZDIMPTR => GETDIMCDF(TPFILE,TPREC%NDIMSIZES_FILE(JJ))
            TPREC%TDIMS(JJ) = TZDIMPTR
            KRESP = 0
          END IF
          IF (TRIM(TPREC%TDIMS(JJ)%name)/='time' .AND. &
            TPREC%TDIMS(JJ)%len /= TPREC%NDIMSIZES_FILE(JJ)) THEN
            CALL PRINT_MSG(NVERB_WARNING,'IO','parse_infiles','problem with dimensions for '//TPREC%TFIELD%CMNHNAME)
            KRESP = -3
            EXIT
          END IF
        END DO
    
      END SUBROUTINE IO_FILL_DIMS_NC4
    
    
    END MODULE mode_util