From f0c66a4329e7ca64623aeeccb7229d9927d6cd99 Mon Sep 17 00:00:00 2001 From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr> Date: Wed, 6 Jun 2018 12:39:17 +0200 Subject: [PATCH] Philippe 06/06/2018: lfi2cdf: improved management of "unknown" variables --- LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90 | 4 +- LIBTOOLS/tools/lfi2cdf/src/mode_util.f90 | 289 ++++++++++++++++++++--- src/LIB/SURCOUCHE/src/fmreadwrit.f90 | 4 + src/LIB/SURCOUCHE/src/mode_field.f90 | 2 +- src/LIB/SURCOUCHE/src/mode_netcdf.f90 | 84 +++++-- src/MNH/modd_parameters.f90 | 2 + 6 files changed, 337 insertions(+), 48 deletions(-) diff --git a/LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90 b/LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90 index 44354d56b..38125a23e 100644 --- a/LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90 +++ b/LIBTOOLS/tools/lfi2cdf/src/lfi2cdf.f90 @@ -7,7 +7,7 @@ program LFI2CDF USE MODD_CONF, ONLY: CPROGRAM USE MODD_CONFZ, ONLY: NB_PROCIO_R USE MODD_DIM_n, ONLY: NIMAX_ll, NJMAX_ll, NKMAX - USE MODD_IO_ll, ONLY: NIO_VERB, NGEN_VERB, LVERB_OUTLST, LVERB_STDOUT, NVERB_DEBUG + USE MODD_IO_ll, ONLY: LVERB_OUTLST, LVERB_STDOUT, NIO_ABORT_LEVEL, NIO_VERB, NGEN_ABORT_LEVEL, NGEN_VERB USE MODD_PARAMETERS, ONLY: JPHEXT, JPVEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -51,6 +51,8 @@ program LFI2CDF NIO_VERB = NVERB_WARNING NGEN_VERB = NVERB_WARNING + NIO_ABORT_LEVEL = NVERB_FATAL + NGEN_ABORT_LEVEL = NVERB_FATAL LVERB_OUTLST = .FALSE. LVERB_STDOUT = .TRUE. diff --git a/LIBTOOLS/tools/lfi2cdf/src/mode_util.f90 b/LIBTOOLS/tools/lfi2cdf/src/mode_util.f90 index f7b2482a3..22523cdf2 100644 --- a/LIBTOOLS/tools/lfi2cdf/src/mode_util.f90 +++ b/LIBTOOLS/tools/lfi2cdf/src/mode_util.f90 @@ -33,6 +33,12 @@ MODULE mode_util LOGICAL :: LSPLIT = .FALSE. ! TRUE if variable is split by vertical level INTEGER :: NSIZE = 0 ! Size of the variable (in number of elements) INTEGER :: NSRC = 0 ! Number of variables used to compute the variable (needed only if calc=.true.) + INTEGER :: NDIMS_FILE ! Number of dims (as present in input file) + INTEGER,DIMENSION(:),ALLOCATABLE :: NDIMSIZES_FILE ! Dimensions sizes (as present in input file) + CHARACTER(LEN=NF90_MAX_NAME),DIMENSION(:),ALLOCATABLE :: CDIMNAMES_FILE ! Dimensions names (as present in input file) + CHARACTER(LEN=40) :: CUNITS_FILE = '' ! Units (as present in input file) + INTEGER :: NGRID_FILE ! Grid number (as present in input file) + INTEGER :: NTYPE_FILE ! netCDF datatype (NF90_CHAR, NF90_INT...) (as present in input file) INTEGER,DIMENSION(MAXRAW) :: src ! List of variables used to compute the variable (needed only if calc=.true.) INTEGER :: tgt ! Target: id of the variable that use it (calc variable) TYPE(TFIELDDATA) :: TFIELD ! Metadata about the field @@ -48,7 +54,7 @@ CONTAINS SUBROUTINE parse_infiles(infiles, outfiles, KNFILES_OUT, nbvar_infile, nbvar_tbr, nbvar_calc, nbvar_tbw, & tpreclist, options, runmode) USE MODD_DIM_n, ONLY: NIMAX_ll, NJMAX_ll, NKMAX - USE MODD_PARAMETERS, ONLY: JPHEXT, JPVEXT + USE MODD_PARAMETERS, ONLY: JPHEXT, JPVEXT, NGRIDUNKNOWN USE MODE_NETCDF, ONLY: IO_GUESS_DIMIDS_NC4 @@ -69,6 +75,8 @@ CONTAINS CHARACTER(LEN=FM_FIELD_SIZE) :: yrecfm, YDATENAME CHARACTER(LEN=FM_FIELD_SIZE) :: var_calc CHARACTER(LEN=FM_FIELD_SIZE),dimension(MAXRAW) :: var_raw + CHARACTER(LEN=1) :: YNDIMS + CHARACTER(LEN=32) :: YTYPE INTEGER :: ji,jj INTEGER :: ndb, nde, ndey, idx, idx_out, idx_var, maxvar INTEGER :: leng @@ -78,8 +86,7 @@ CONTAINS INTEGER(KIND=LFI_INT) :: iresp2,ilu,ileng,ipos INTEGER(KIND=IDCDF_KIND) :: kcdf_id, kcdf_id2, var_id INTEGER(KIND=IDCDF_KIND) :: jdim, status - INTEGER(KIND=IDCDF_KIND) :: idims, idimtmp - INTEGER(KIND=IDCDF_KIND),DIMENSION(NF90_MAX_VAR_DIMS) :: idim_id + INTEGER(KIND=IDCDF_KIND),DIMENSION(NF90_MAX_VAR_DIMS) :: idims_id LOGICAL :: ladvan LOGICAL :: GOK TYPE(TLFIDATE),DIMENSION(MAXDATES) :: TLFIDATES @@ -234,28 +241,66 @@ CONTAINS ! IF (status == NF90_NOERR) THEN tpreclist(ji)%found = .true. - status = NF90_INQUIRE_VARIABLE(kcdf_id2,var_id,ndims = idims,dimids = idim_id) + status = NF90_INQUIRE_VARIABLE(kcdf_id2,var_id,ndims = tpreclist(ji)%NDIMS_FILE, & + xtype=tpreclist(ji)%NTYPE_FILE, dimids = idims_id) IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__) - IF (idims == 0) THEN + IF (.NOT.tpreclist(ji)%LSPLIT) THEN + ALLOCATE(tpreclist(ji)%NDIMSIZES_FILE(tpreclist(ji)%NDIMS_FILE)) + ALLOCATE(tpreclist(ji)%CDIMNAMES_FILE(tpreclist(ji)%NDIMS_FILE)) + ELSE + ALLOCATE(tpreclist(ji)%NDIMSIZES_FILE(tpreclist(ji)%NDIMS_FILE+1)) + ALLOCATE(tpreclist(ji)%CDIMNAMES_FILE(tpreclist(ji)%NDIMS_FILE+1)) + END IF + + IF (tpreclist(ji)%NDIMS_FILE == 0) THEN ! variable scalaire leng = 1 ELSE ! infos sur dimensions leng = 1 - DO jdim=1,idims - status = NF90_INQUIRE_DIMENSION(kcdf_id2,idim_id(jdim),len = idimtmp) + DO jdim=1,tpreclist(ji)%NDIMS_FILE + status = NF90_INQUIRE_DIMENSION(kcdf_id2,idims_id(jdim), & + len = tpreclist(ji)%NDIMSIZES_FILE(jdim), & + name = tpreclist(ji)%CDIMNAMES_FILE(jdim) ) IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__) - leng = leng*idimtmp + leng = leng*tpreclist(ji)%NDIMSIZES_FILE(jdim) END DO + + IF (tpreclist(ji)%NDIMS_FILE>0) THEN + IF (tpreclist(ji)%CDIMNAMES_FILE(tpreclist(ji)%NDIMS_FILE)=='time') THEN + tpreclist(ji)%TFIELD%LTIMEDEP = .TRUE. + ELSE + tpreclist(ji)%TFIELD%LTIMEDEP = .FALSE. + END IF + ELSE + tpreclist(ji)%TFIELD%LTIMEDEP = .FALSE. + END IF + IF (tpreclist(ji)%LSPLIT) THEN - IF(idims/=2) CALL PRINT_MSG(NVERB_FATAL,'IO','parse_infiles','split variables can only be 3D') + IF( (.NOT.tpreclist(ji)%TFIELD%LTIMEDEP .AND. tpreclist(ji)%NDIMS_FILE/=2) & + .OR. ( tpreclist(ji)%TFIELD%LTIMEDEP .AND. tpreclist(ji)%NDIMS_FILE/=3) ) & + CALL PRINT_MSG(NVERB_FATAL,'IO','parse_infiles','split variables can only be 3D') !Split variables are Z-split leng = leng * (NKMAX+2*JPVEXT) + !Move time dimension to last (4th) position + IF (tpreclist(ji)%TFIELD%LTIMEDEP) THEN + tpreclist(ji)%NDIMSIZES_FILE(4) = tpreclist(ji)%NDIMSIZES_FILE(3) + tpreclist(ji)%CDIMNAMES_FILE(4) = tpreclist(ji)%CDIMNAMES_FILE(3) + END IF + !Add vertical dimension + tpreclist(ji)%NDIMSIZES_FILE(3) = NKMAX+2*JPVEXT + tpreclist(ji)%CDIMNAMES_FILE(3) = 'level' !Could also be 'level_w' END IF END IF END IF tpreclist(ji)%NSIZE = leng + + STATUS = NF90_GET_ATT(kcdf_id,var_id,'grid',tpreclist(ji)%NGRID_FILE) + IF (status /= NF90_NOERR) tpreclist(ji)%NGRID_FILE = 0 + + STATUS = NF90_GET_ATT(kcdf_id,var_id,'units',tpreclist(ji)%CUNITS_FILE) + !Add maximum comment size (necessary when writing LFI files because the comment is stored with the field) leng = leng + NLFIMAXCOMMENTLENGTH END IF @@ -348,25 +393,35 @@ END DO ELSE IF (INFILES(1)%TFILE%CFORMAT == 'NETCDF4') THEN DO ji=1,nbvar_infile var_id = ji - status = NF90_INQUIRE_VARIABLE(kcdf_id,var_id, name = tpreclist(ji)%name, ndims = idims, & - dimids = idim_id) + status = NF90_INQUIRE_VARIABLE(kcdf_id,var_id, name = tpreclist(ji)%name, ndims = tpreclist(ji)%NDIMS_FILE, & + xtype=tpreclist(ji)%NTYPE_FILE, dimids = idims_id) IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__) tpreclist(ji)%found = .TRUE. - IF (idims == 0) THEN + ALLOCATE(tpreclist(ji)%NDIMSIZES_FILE(tpreclist(ji)%NDIMS_FILE)) + ALLOCATE(tpreclist(ji)%CDIMNAMES_FILE(tpreclist(ji)%NDIMS_FILE)) + + IF (tpreclist(ji)%NDIMS_FILE == 0) THEN ! variable scalaire leng = 1 ELSE ! infos sur dimensions leng = 1 - DO jdim=1,idims - status = NF90_INQUIRE_DIMENSION(kcdf_id,idim_id(jdim),len = idimtmp) + DO jdim=1,tpreclist(ji)%NDIMS_FILE + status = NF90_INQUIRE_DIMENSION(kcdf_id,idims_id(jdim), & + len = tpreclist(ji)%NDIMSIZES_FILE(jdim), & + name = tpreclist(ji)%CDIMNAMES_FILE(jdim) ) IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__) - leng = leng*idimtmp + leng = leng*tpreclist(ji)%NDIMSIZES_FILE(jdim) END DO END IF tpreclist(ji)%NSIZE = leng IF (leng > sizemax) sizemax = leng + + STATUS = NF90_GET_ATT(kcdf_id,var_id,'grid',tpreclist(ji)%NGRID_FILE) + IF (status /= NF90_NOERR) tpreclist(ji)%NGRID_FILE = 0 + + STATUS = NF90_GET_ATT(kcdf_id,var_id,'units',tpreclist(ji)%CUNITS_FILE) END DO !Add maximum comment size (necessary when writing LFI files because the comment is stored with the field) sizemax = sizemax + NLFIMAXCOMMENTLENGTH @@ -397,18 +452,23 @@ END DO .OR. tpreclist(ji)%name == 'latitude_f' & .OR. tpreclist(ji)%name == 'longitude_f' & .OR. tpreclist(ji)%name == 'level' & - .OR. tpreclist(ji)%name == 'level_w' ) THEN + .OR. tpreclist(ji)%name == 'level_w' & + .OR. tpreclist(ji)%name == 'time' ) THEN tpreclist(ji)%tbw = .FALSE. tpreclist(ji)%tbr = .FALSE. tpreclist(ji)%found = .FALSE. ELSE - CALL FIND_FIELD_ID_FROM_MNHNAME(tpreclist(ji)%name,IID,IRESP) + CALL FIND_FIELD_ID_FROM_MNHNAME(tpreclist(ji)%name,IID,IRESP,ONOWARNING=.TRUE.) IF (IRESP==0) THEN tpreclist(ji)%TFIELD = TFIELDLIST(IID) - ALLOCATE(tpreclist(ji)%TDIMS(tpreclist(ji)%TFIELD%NDIMS)) ! Determine TDIMS - CALL IO_GUESS_DIMIDS_NC4(outfiles(idx_out)%TFILE,tpreclist(ji)%TFIELD,& - tpreclist(ji)%NSIZE,tpreclist(ji)%TDIMS,IRESP) + IF (runmode==MODELFI2CDF) THEN + ALLOCATE(tpreclist(ji)%TDIMS(tpreclist(ji)%TFIELD%NDIMS)) + CALL IO_GUESS_DIMIDS_NC4(outfiles(idx_out)%TFILE,tpreclist(ji)%TFIELD,& + tpreclist(ji)%NSIZE,tpreclist(ji)%TDIMS,IRESP) + ELSE !If we read netCDF4, we already have all necessary data + CALL IO_FILL_DIMS_NC4(outfiles(idx_out)%TFILE,tpreclist(ji),IRESP) + ENDIF IF (IRESP/=0) THEN CALL PRINT_MSG(NVERB_WARNING,'IO','parse_infiles','can not guess dimensions for '//tpreclist(ji)%TFIELD%CMNHNAME// & ' => ignored') @@ -417,11 +477,135 @@ END DO tpreclist(ji)%found = .FALSE. CYCLE END IF - ELSE !Field not found in list - CALL PRINT_MSG(NVERB_WARNING,'IO','parse_infiles','variable '//TRIM(tpreclist(ji)%name)//' is not known => ignored') - tpreclist(ji)%tbw = .FALSE. - tpreclist(ji)%tbr = .FALSE. - tpreclist(ji)%found = .FALSE. + ELSE !Field not found in list, try to determine characteristics + tpreclist(ji)%TFIELD%CMNHNAME = TRIM(tpreclist(ji)%name) + tpreclist(ji)%TFIELD%CSTDNAME = '' + tpreclist(ji)%TFIELD%CLONGNAME = TRIM(tpreclist(ji)%name) + tpreclist(ji)%TFIELD%CUNITS = '' + tpreclist(ji)%TFIELD%CDIR = 'XY' !Assumption... + tpreclist(ji)%TFIELD%CLBTYPE = 'NONE' + tpreclist(ji)%TFIELD%CCOMMENT = '' + ! + IF (runmode==MODELFI2CDF) THEN + tpreclist(ji)%TFIELD%NGRID = 1 !Assumption + tpreclist(ji)%TFIELD%NTYPE = TYPEREAL !Assumption + WRITE(YTYPE,'( A )') 'REAL (forced)' + IF (tpreclist(ji)%NSIZE>1) THEN + ALLOCATE(tpreclist(ji)%TDIMS(3)) + ! Determine TDIMS + CALL PRINT_MSG(NVERB_DEBUG,'IO','parse_infiles',tpreclist(ji)%TFIELD%CMNHNAME//': try 3D') + tpreclist(ji)%TFIELD%NDIMS = 3 !Try with 3D + CALL IO_GUESS_DIMIDS_NC4(outfiles(idx_out)%TFILE,tpreclist(ji)%TFIELD,& + tpreclist(ji)%NSIZE,tpreclist(ji)%TDIMS,IRESP) + ! + IF (IRESP/=0 .OR. tpreclist(ji)%TDIMS(3)%LEN==1) THEN + CALL PRINT_MSG(NVERB_DEBUG,'IO','parse_infiles',tpreclist(ji)%TFIELD%CMNHNAME//': try 2D') + !Try again with 2D + tpreclist(ji)%TFIELD%NDIMS = 2 + CALL IO_GUESS_DIMIDS_NC4(outfiles(idx_out)%TFILE,tpreclist(ji)%TFIELD,& + tpreclist(ji)%NSIZE,tpreclist(ji)%TDIMS,IRESP) + END IF + ! + IF (IRESP/=0 .OR. tpreclist(ji)%TDIMS(2)%LEN==1) THEN + CALL PRINT_MSG(NVERB_DEBUG,'IO','parse_infiles',tpreclist(ji)%TFIELD%CMNHNAME//': try 1D') + !Try again with 1D + tpreclist(ji)%TFIELD%NDIMS = 1 + tpreclist(ji)%TFIELD%CDIR = '--' !Assumption... + CALL IO_GUESS_DIMIDS_NC4(outfiles(idx_out)%TFILE,tpreclist(ji)%TFIELD,& + tpreclist(ji)%NSIZE,tpreclist(ji)%TDIMS,IRESP) + END IF + ! + IF (IRESP/=0) THEN !Could not find valid characteristics + tpreclist(ji)%tbw = .FALSE. + tpreclist(ji)%tbr = .FALSE. + tpreclist(ji)%found = .FALSE. + CYCLE + END IF + ELSE !NSIZE==0 + tpreclist(ji)%TFIELD%CDIR = '--' + tpreclist(ji)%TFIELD%NDIMS = 0 + tpreclist(ji)%TFIELD%NGRID = 0 + END IF + tpreclist(ji)%TFIELD%LTIMEDEP = .FALSE. !Assumption + ELSE ! Input file is netCDF + tpreclist(ji)%TFIELD%NGRID = tpreclist(ji)%NGRID_FILE + SELECT CASE(tpreclist(ji)%NTYPE_FILE) + CASE (NF90_INT1) !NF90_INT1=NF90_BYTE + tpreclist(ji)%TFIELD%NTYPE = TYPELOG + tpreclist(ji)%TFIELD%NDIMS = tpreclist(ji)%NDIMS_FILE + WRITE(YTYPE,'( A )') 'LOGICAL' + CASE (NF90_CHAR) + tpreclist(ji)%TFIELD%NTYPE = TYPECHAR + tpreclist(ji)%TFIELD%NDIMS = tpreclist(ji)%NDIMS_FILE-1 + WRITE(YTYPE,'( A )') 'CHARACTER' + CASE (NF90_INT,NF90_INT64) + tpreclist(ji)%TFIELD%NTYPE = TYPEINT + tpreclist(ji)%TFIELD%NDIMS = tpreclist(ji)%NDIMS_FILE + WRITE(YTYPE,'( A )') 'INTEGER' + CASE (NF90_FLOAT,NF90_DOUBLE) + tpreclist(ji)%TFIELD%NTYPE = TYPEREAL + tpreclist(ji)%TFIELD%NDIMS = tpreclist(ji)%NDIMS_FILE + WRITE(YTYPE,'( A )') 'REAL' + CASE DEFAULT + tpreclist(ji)%TFIELD%NTYPE = TYPEUNDEF + tpreclist(ji)%TFIELD%NDIMS = tpreclist(ji)%NDIMS_FILE + WRITE(YTYPE,'( A )') 'UNKNOWN' + END SELECT + + tpreclist(ji)%TFIELD%CUNITS = tpreclist(ji)%CUNITS_FILE + + IF (tpreclist(ji)%TFIELD%NDIMS<2) THEN + tpreclist(ji)%TFIELD%CDIR = '--' !Assumption + ELSE + tpreclist(ji)%TFIELD%CDIR = 'XY' !Assumption + END IF + + CALL IO_FILL_DIMS_NC4(outfiles(idx_out)%TFILE,tpreclist(ji),IRESP) + + IF (tpreclist(ji)%NDIMS_FILE>0) THEN + IF (tpreclist(ji)%CDIMNAMES_FILE(tpreclist(ji)%NDIMS_FILE)=='time') THEN + tpreclist(ji)%TFIELD%LTIMEDEP = .TRUE. + ELSE + tpreclist(ji)%TFIELD%LTIMEDEP = .FALSE. + END IF + ELSE + tpreclist(ji)%TFIELD%LTIMEDEP = .FALSE. + END IF + + IF (tpreclist(ji)%NDIMS_FILE>0) THEN + IF (tpreclist(ji)%CDIMNAMES_FILE(tpreclist(ji)%NDIMS_FILE)=='time') THEN + tpreclist(ji)%TFIELD%NDIMS = tpreclist(ji)%TFIELD%NDIMS - 1 + END IF + END IF + ! + IF (IRESP/=0) THEN + tpreclist(ji)%tbw = .FALSE. + tpreclist(ji)%tbr = .FALSE. + tpreclist(ji)%found = .FALSE. + END IF + END IF + ! + IF (runmode==MODELFI2CDF) THEN + tpreclist(ji)%TFIELD%NGRID = NGRIDUNKNOWN !Assumption + IF(tpreclist(ji)%TFIELD%NDIMS == 0 .OR. tpreclist(ji)%TFIELD%NTYPE == TYPECHAR) THEN + tpreclist(ji)%TFIELD%NGRID = 0 + END IF + END IF + ! + IF (.NOT.tpreclist(ji)%found) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','parse_infiles','can not guess dimensions for '// & + TRIM(tpreclist(ji)%TFIELD%CMNHNAME)//' => ignored') + ELSE + IF (tpreclist(ji)%TFIELD%LTIMEDEP) THEN + WRITE(YNDIMS,'( I1 )') tpreclist(ji)%TFIELD%NDIMS-1 + CALL PRINT_MSG(NVERB_WARNING,'IO','unknown field',tpreclist(ji)%TFIELD%CMNHNAME//' seems to be '// & + YNDIMS//'D of type '//TRIM(YTYPE)//' (time dependent)') + ELSE + WRITE(YNDIMS,'( I1 )') tpreclist(ji)%TFIELD%NDIMS + CALL PRINT_MSG(NVERB_WARNING,'IO','unknown field',tpreclist(ji)%TFIELD%CMNHNAME//' seems to be '// & + YNDIMS//'D of type '//TRIM(YTYPE)) + END IF + END IF END IF END IF END DO @@ -522,7 +706,7 @@ END DO END DO !ji=1,maxvar END IF !nbvar_calc>0 - WRITE(*,'("Taille maximale du buffer :",f10.3," Mio")') sizemax*8./1048576. + WRITE(*,'("Maximum buffer size:",f10.3," Mio")') sizemax*8./1048576. END SUBROUTINE parse_infiles @@ -589,9 +773,9 @@ END DO idx = 1 DO ji=1,knaf - IF (.NOT.tpreclist(ji)%tbw) CYCLE + IF (.NOT.tpreclist(ji)%tbw) CYCLE - IDIMS = tpreclist(ji)%TFIELD%NDIMS + IDIMS = tpreclist(ji)%TFIELD%NDIMS SELECT CASE(tpreclist(ji)%TFIELD%NTYPE) CASE (TYPEINT) @@ -762,6 +946,8 @@ END DO CASE (TYPECHAR) + ISRC = ji + IF (IDIMS/=0) THEN CALL PRINT_MSG(NVERB_WARNING,'IO','fill_files','too many dimensions for ' & //TRIM(tpreclist(ISRC)%name)//' => ignored') @@ -775,6 +961,8 @@ END DO CASE (TYPEDATE) + ISRC = ji + IF (IDIMS/=0) THEN CALL PRINT_MSG(NVERB_WARNING,'IO','fill_files','too many dimensions for ' & //TRIM(tpreclist(ISRC)%name)//' => ignored') @@ -783,7 +971,10 @@ END DO CALL IO_READ_FIELD (INFILES(1)%TFILE, tpreclist(ji)%TFIELD%CMNHNAME,TZDATE) CALL IO_WRITE_FIELD(outfiles(idx)%TFILE,tpreclist(ji)%TFIELD,TZDATE) + CASE default + ISRC = ji + CALL PRINT_MSG(NVERB_WARNING,'IO','fill_files','invalid datatype for ' & //TRIM(tpreclist(ISRC)%name)//' => ignored') @@ -803,7 +994,7 @@ END DO USE MODD_IO_ll, ONLY: LIOCDF4 USE MODD_PARAMETERS, ONLY: JPHEXT USE MODD_PARAMETERS_ll, ONLY: JPHEXT_ll=>JPHEXT, JPVEXT_ll=>JPVEXT - USE MODD_TIME_n, ONLY: TDTMOD + USE MODD_TIME_n, ONLY: TDTCUR, TDTMOD USE MODE_FM, ONLY: IO_FILE_OPEN_ll, IO_FILE_CLOSE_ll USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_ADD2LIST @@ -893,7 +1084,11 @@ END DO ALLOCATE(LSLEVE) CALL IO_READ_FIELD(INFILES(1)%TFILE,'SLEVE',LSLEVE) ALLOCATE(TDTMOD) - CALL IO_READ_FIELD(INFILES(1)%TFILE,'DTMOD',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) END IF ! ! Outfiles @@ -1027,4 +1222,38 @@ END DO 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 diff --git a/src/LIB/SURCOUCHE/src/fmreadwrit.f90 b/src/LIB/SURCOUCHE/src/fmreadwrit.f90 index cd989f536..b8aad9a4f 100644 --- a/src/LIB/SURCOUCHE/src/fmreadwrit.f90 +++ b/src/LIB/SURCOUCHE/src/fmreadwrit.f90 @@ -607,6 +607,8 @@ END SUBROUTINE IO_READ_FIELD_LFI_T0 ! SUBROUTINE IO_READ_CHECK_FIELD_LFI(TPFILE,TPFIELD,KLENG,KWORK,KTOTAL,KRESP,OGOOD) ! +USE MODD_PARAMETERS, ONLY: NGRIDUNKNOWN +! TYPE(TFILEDATA), INTENT(IN) :: TPFILE TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD INTEGER, INTENT(IN) :: KLENG @@ -686,6 +688,8 @@ IF (KTOTAL.NE.IROW) THEN RETURN ENDIF ! +IF(TPFIELD%NGRID==NGRIDUNKNOWN) TPFIELD%NGRID=KWORK(1) +! IF (KWORK(1)/=TPFIELD%NGRID) THEN WRITE(YVAL_FILE,'(I12)') KWORK(1) WRITE(YVAL_MEM, '(I12)') TPFIELD%NGRID diff --git a/src/LIB/SURCOUCHE/src/mode_field.f90 b/src/LIB/SURCOUCHE/src/mode_field.f90 index cb0d7105d..8dce892d6 100644 --- a/src/LIB/SURCOUCHE/src/mode_field.f90 +++ b/src/LIB/SURCOUCHE/src/mode_field.f90 @@ -76,7 +76,7 @@ TYPE TFIELDDATA CHARACTER(LEN=2) :: CDIR = '' !Type of the data field (XX,XY,--...) CHARACTER(LEN=4) :: CLBTYPE = 'NONE' !Type of the lateral boundary (LBX,LBY,LBXU,LBYV) CHARACTER(LEN=100) :: CCOMMENT = '' !Comment (for MesoNH, non CF convention) - INTEGER :: NGRID = -1 !Localization on the model grid + INTEGER :: NGRID = NGRIDUNKNOWN !Localization on the model grid INTEGER :: NTYPE = TYPEUNDEF !Datatype INTEGER :: NDIMS = 0 !Number of dimensions LOGICAL :: LTIMEDEP = .FALSE. !Is the field time-dependent? diff --git a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 b/src/LIB/SURCOUCHE/src/mode_netcdf.f90 index 0198c2fc8..b5594f1d6 100644 --- a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 +++ b/src/LIB/SURCOUCHE/src/mode_netcdf.f90 @@ -55,7 +55,8 @@ PUBLIC NF90_CLOSE,NF90_OPEN,NF90_CREATE, & NF90_NOWRITE,NF90_CLOBBER,NF90_NETCDF4,NF90_NOERR,NF90_STRERROR, & NF90_FILL_REAL,NF90_INQUIRE ! Public from this module : -PUBLIC NEWIOCDF,CLEANIOCDF,IO_GUESS_DIMIDS_NC4, & +PUBLIC GETDIMCDF,NEWIOCDF,CLEANIOCDF, & + IO_GUESS_DIMIDS_NC4,IO_FIND_DIM_BYNAME_NC4, & IO_SET_KNOWNDIMS_NC4,IO_WRITE_COORDVAR_NC4, & IO_WRITE_FIELD_NC4,IO_READ_FIELD_NC4,IO_WRITE_HEADER_NC4 @@ -962,6 +963,7 @@ GETDIMCDF => TMP END FUNCTION GETDIMCDF + FUNCTION GETSTRDIMID(TPFILE,KLEN) TYPE(TFILEDATA), INTENT(IN) :: TPFILE INTEGER(KIND=IDCDF_KIND),INTENT(IN) :: KLEN @@ -1005,6 +1007,38 @@ GETSTRDIMID = TMP%ID END FUNCTION GETSTRDIMID +SUBROUTINE IO_FIND_DIM_BYNAME_NC4(TPFILE, HDIMNAME, TPDIM, KRESP) +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +CHARACTER(LEN=*), INTENT(IN) :: HDIMNAME +TYPE(DIMCDF), INTENT(OUT) :: TPDIM +INTEGER, INTENT(OUT) :: KRESP +! +TYPE(DIMCDF), POINTER :: TMP +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_FIND_DIM_BYNAME_NC4','called for dimension name '//TRIM(HDIMNAME)) +! +KRESP = -2 +! +IF(.NOT.ASSOCIATED(TPFILE%TNCDIMS%DIMLIST)) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_FIND_DIM_BYNAME_NC4','DIMLIST not associated for file '//TRIM(TPFILE%CNAME)) + KRESP = -1 + RETURN +END IF +! +TMP => TPFILE%TNCDIMS%DIMLIST +! +DO WHILE(ASSOCIATED(TMP)) + IF (TRIM(TMP%NAME)==TRIM(HDIMNAME)) THEN + TPDIM = TMP + KRESP = 0 + EXIT + END IF + TMP => TMP%NEXT +END DO +! +END SUBROUTINE IO_FIND_DIM_BYNAME_NC4 + + SUBROUTINE FILLVDIMS(TPFILE, TPFIELD, KSHAPE, KVDIMS) TYPE(TFILEDATA), INTENT(IN) :: TPFILE TYPE(TFIELDDATA), INTENT(IN) :: TPFIELD @@ -1107,7 +1141,7 @@ PTDIM => NULL() ! IF(IGRID<0 .OR. IGRID>8) THEN WRITE(YINT,'( I0 )') IGRID - CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4','invalid NGRID ('//TRIM(YINT)//') for field '//TRIM(TPFIELD%CMNHNAME)) + CALL PRINT_MSG(NVERB_FATAL,'IO','IO_GUESS_DIMIDS_NC4','invalid NGRID ('//TRIM(YINT)//') for field '//TRIM(TPFIELD%CMNHNAME)) END IF ! IF(IGRID==0 .AND. YDIR/='--' .AND. YDIR/='' ) THEN @@ -1176,8 +1210,8 @@ ELSE PTDIM => TPFILE%TNCCOORDS(2,IGRID)%TDIM ELSE IF ( YDIR == 'ZZ' ) THEN PTDIM => TPFILE%TNCCOORDS(3,IGRID)%TDIM - ELSE - CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4','can not guess 1st dimension for field '//TRIM(TPFIELD%CMNHNAME)) + ELSE IF (JI==TPFIELD%NDIMS) THEN !Guess last dimension + PTDIM => GETDIMCDF(TPFILE, KLEN) END IF ILEN = PTDIM%LEN TPDIMS(JI) = PTDIM @@ -1186,44 +1220,60 @@ ELSE PTDIM => TPFILE%TNCCOORDS(2,IGRID)%TDIM ELSE IF (JI==TPFIELD%NDIMS) THEN !Guess last dimension ISIZE = KLEN/ILEN - IF (MOD(KLEN,ILEN)/=0) CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4', & - 'can not guess 2nd and last dimension for field '//TRIM(TPFIELD%CMNHNAME)) + IF (MOD(KLEN,ILEN)/=0) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4', & + 'can not guess 2nd and last dimension for field '//TRIM(TPFIELD%CMNHNAME)) + EXIT + END IF PTDIM => GETDIMCDF(TPFILE, ISIZE) ELSE CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4','can not guess 2nd dimension for field '//TRIM(TPFIELD%CMNHNAME)) + EXIT END IF ILEN = ILEN * PTDIM%LEN TPDIMS(JI) = PTDIM ELSE IF (JI == 3) THEN IF ( YDIR == 'XY' ) THEN - PTDIM => TPFILE%TNCCOORDS(3,IGRID)%TDIM + IF (JI==TPFIELD%NDIMS .AND. KLEN/ILEN==1 .AND. MOD(KLEN,ILEN)==0) THEN + !The last dimension is of size 1 => probably time dimension + ISIZE = 1 + PTDIM => GETDIMCDF(TPFILE,ISIZE) + ELSE + PTDIM => TPFILE%TNCCOORDS(3,IGRID)%TDIM + END IF ELSE IF (JI==TPFIELD%NDIMS) THEN !Guess last dimension ISIZE = KLEN/ILEN - IF (MOD(KLEN,ILEN)/=0) CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4', & - 'can not guess 3rd and last dimension for field '//TRIM(TPFIELD%CMNHNAME)) + IF (MOD(KLEN,ILEN)/=0) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4', & + 'can not guess 3rd and last dimension for field '//TRIM(TPFIELD%CMNHNAME)) + EXIT + END IF PTDIM => GETDIMCDF(TPFILE, ISIZE) ELSE CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4','can not guess 3rd dimension for field '//TRIM(TPFIELD%CMNHNAME)) + EXIT END IF ILEN = ILEN * PTDIM%LEN TPDIMS(JI) = PTDIM ELSE IF (JI==4 .AND. JI==TPFIELD%NDIMS) THEN !Guess last dimension ISIZE = KLEN/ILEN - IF (MOD(KLEN,ILEN)/=0) CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4', & - 'can not guess 4th and last dimension for field '//TRIM(TPFIELD%CMNHNAME)) + IF (MOD(KLEN,ILEN)/=0) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4', & + 'can not guess 4th and last dimension for field '//TRIM(TPFIELD%CMNHNAME)) + EXIT + END IF PTDIM => GETDIMCDF(TPFILE, ISIZE) ILEN = ILEN * PTDIM%LEN TPDIMS(JI) = PTDIM ELSE - CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4','can not guess dimension above 4 for field '& - //TRIM(TPFIELD%CMNHNAME)) + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4','can not guess dimension above 4 for field '& + //TRIM(TPFIELD%CMNHNAME)) END IF END DO END IF ! -!print *,'IO_GUESS_DIMIDS_NC4: ',TPFIELD%CMNHNAME,': klen,ilen,dims%len=',KLEN,ILEN,TPDIMS(:)%LEN IF (KLEN /= ILEN) THEN - CALL PRINT_MSG(NVERB_WARNING,'IO','IO_GUESS_DIMIDS_NC4','problem with dimensions for field '& + CALL PRINT_MSG(NVERB_INFO,'IO','IO_GUESS_DIMIDS_NC4','can not guess dimensions of field '& //TRIM(TPFIELD%CMNHNAME)) KRESP = 1 END IF @@ -2408,6 +2458,8 @@ END SUBROUTINE IO_WRITE_FIELD_NC4_T0 ! SUBROUTINE IO_READ_CHECK_FIELD_ATTR_NC4(TPFILE,TPFIELD,KVARID,KRESP,HCALENDAR) ! +USE MODD_PARAMETERS, ONLY: NGRIDUNKNOWN +! TYPE(TFILEDATA), INTENT(IN) :: TPFILE TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD INTEGER(KIND=IDCDF_KIND), INTENT(IN) :: KVARID @@ -2444,7 +2496,7 @@ IF (STATUS == NF90_NOERR) THEN ': expected GRID found in file for field '//TRIM(TPFIELD%CMNHNAME)) ENDIF ELSE !no GRID - IF (TPFIELD%NGRID==0 .OR. TPFIELD%NGRID==-1) THEN + IF (TPFIELD%NGRID==0 .OR. TPFIELD%NGRID==NGRIDUNKNOWN) THEN CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_CHECK_FIELD_ATTR_NC4',TRIM(TPFILE%CNAME)// & ': no GRID (as expected) in file for field '//TRIM(TPFIELD%CMNHNAME)) ELSE diff --git a/src/MNH/modd_parameters.f90 b/src/MNH/modd_parameters.f90 index b24a62e89..a128c34b3 100644 --- a/src/MNH/modd_parameters.f90 +++ b/src/MNH/modd_parameters.f90 @@ -90,4 +90,6 @@ INTEGER, PARAMETER :: NLFIMAXCOMMENTLENGTH = 100 ! Length of comments in LFI fil INTEGER, PARAMETER :: JPLIMACCNMAX = 10 ! Maximum allowed number of CCN modes in LIMA INTEGER, PARAMETER :: JPLIMAIFNMAX = 10 ! Maximum allowed number of IFN modes in LIMA ! +INTEGER, PARAMETER :: NGRIDUNKNOWN = -1 ! Unknown Arakawa grid number +! END MODULE MODD_PARAMETERS -- GitLab