diff --git a/src/LIB/SURCOUCHE/src/fmread_ll.f90 b/src/LIB/SURCOUCHE/src/fmread_ll.f90 index 45426d1fbf2a81c46bff5da02f304f007e74f4bd..9d305f43fcdf0e0e2f582b43d6001af46c9d8589 100644 --- a/src/LIB/SURCOUCHE/src/fmread_ll.f90 +++ b/src/LIB/SURCOUCHE/src/fmread_ll.f90 @@ -44,26 +44,26 @@ INTERFACE IO_READ_FIELD MODULE PROCEDURE IO_READ_FIELD_BYNAME_X0, IO_READ_FIELD_BYNAME_X1, & IO_READ_FIELD_BYNAME_X2, IO_READ_FIELD_BYNAME_X3, & IO_READ_FIELD_BYNAME_N0, & - IO_READ_FIELD_BYNAME_L0, & + IO_READ_FIELD_BYNAME_N2, & + IO_READ_FIELD_BYNAME_L0, IO_READ_FIELD_BYNAME_L1, & IO_READ_FIELD_BYNAME_C0, & IO_READ_FIELD_BYNAME_T0, & IO_READ_FIELD_BYFIELD_X0,IO_READ_FIELD_BYFIELD_X1, & IO_READ_FIELD_BYFIELD_X2,IO_READ_FIELD_BYFIELD_X3, & IO_READ_FIELD_BYFIELD_N0, & - IO_READ_FIELD_BYFIELD_L0, & + IO_READ_FIELD_BYFIELD_N2, & + IO_READ_FIELD_BYFIELD_L0,IO_READ_FIELD_BYFIELD_L1, & IO_READ_FIELD_BYFIELD_C0, & IO_READ_FIELD_BYFIELD_T0 ! IO_READ_FIELD_BYNAME_X4, IO_READ_FIELD_BYNAME_X5, & ! IO_READ_FIELD_BYNAME_X6, & ! IO_READ_FIELD_BYNAME_N1, & -! IO_READ_FIELD_BYNAME_N2, IO_READ_FIELD_BYNAME_N3, & -! IO_READ_FIELD_BYNAME_L1, & +! IO_READ_FIELD_BYNAME_N3, & ! IO_READ_FIELD_BYNAME_C1, & ! IO_READ_FIELD_BYFIELD_X4,IO_READ_FIELD_BYFIELD_X5, & ! IO_READ_FIELD_BYFIELD_X6, & ! IO_READ_FIELD_BYFIELD_N1, & -! IO_READ_FIELD_BYFIELD_N2,IO_READ_FIELD_BYFIELD_N3, & -! IO_READ_FIELD_BYFIELD_L1, & +! IO_READ_FIELD_BYFIELD_N3, & ! IO_READ_FIELD_BYFIELD_C1, & END INTERFACE @@ -2314,6 +2314,132 @@ RETURN END SUBROUTINE FMREADN2_ll +SUBROUTINE IO_READ_FIELD_BYNAME_N2(TPFILE,HNAME,KFIELD,KRESP) +! +USE MODD_IO_ll, ONLY : ISNPROC +USE MODD_STRUCTURE_ll, ONLY : ZONE_ll +! +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +CHARACTER(LEN=*), INTENT(IN) :: HNAME ! name of the field to write +INTEGER,DIMENSION(:,:),INTENT(INOUT) :: KFIELD ! array containing the data field +INTEGER,OPTIONAL, INTENT(OUT) :: KRESP ! return-code +! +INTEGER :: ID ! Index of the field +INTEGER :: IRESP ! return_code +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_FIELD_BYNAME_N2',TRIM(TPFILE%CNAME)//': reading '//TRIM(HNAME)) +! +CALL FIND_FIELD_ID_FROM_MNHNAME(HNAME,ID,IRESP) +! +IF(IRESP==0) CALL IO_READ_FIELD(TPFILE,TFIELDLIST(ID),KFIELD,IRESP) +! +IF (PRESENT(KRESP)) KRESP = IRESP +! +END SUBROUTINE IO_READ_FIELD_BYNAME_N2 + +SUBROUTINE IO_READ_FIELD_BYFIELD_N2(TPFILE,TPFIELD,KFIELD,KRESP) +! +USE MODD_IO_ll, ONLY : GSMONOPROC,ISP,ISNPROC,LPACK,L1D,L2D +USE MODD_STRUCTURE_ll, ONLY : ZONE_ll +USE MODD_TIMEZ, ONLY : TIMEZ +! +USE MODE_ALLOCBUFFER_ll +USE MODE_FD_ll, ONLY : GETFD,FD_LL +USE MODE_SCATTER_ll +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +INTEGER,DIMENSION(:,:),TARGET,INTENT(INOUT) :: KFIELD ! array containing the data field +INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code +! +INTEGER :: IERR +TYPE(FD_ll), POINTER :: TZFD +INTEGER,DIMENSION(:,:),POINTER :: IFIELDP +LOGICAL :: GALLOC +INTEGER :: IRESP +INTEGER :: IHEXTOT +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_FIELD_BYFIELD_N2',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) +! +GALLOC = .FALSE. +IRESP = 0 +! +IHEXTOT = 2*JPHEXT+1 +TZFD=>GETFD(TRIM(ADJUSTL(TPFILE%CNAME))//'.lfi') +IF (ASSOCIATED(TZFD)) THEN + IF (GSMONOPROC) THEN ! sequential execution + IF (LPACK .AND. L1D .AND. SIZE(KFIELD,1)==IHEXTOT .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + IFIELDP=>KFIELD(JPHEXT+1:JPHEXT+1,JPHEXT+1:JPHEXT+1) + ELSE IF (LPACK .AND. L2D .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + IFIELDP=>KFIELD(:,JPHEXT+1:JPHEXT+1) + ELSE + IFIELDP=>KFIELD(:,:) + END IF + IF (TPFILE%CFORMAT=='NETCDF4') THEN + CALL IO_READ_FIELD_NC4(TPFILE,TPFIELD,IFIELDP,IRESP) + ELSE IF (TPFILE%CFORMAT=='LFI') THEN + CALL IO_READ_FIELD_LFI(TPFILE,TPFIELD,IFIELDP,IRESP) + ELSE + CALL PRINT_MSG(NVERB_FATAL,'IO','IO_READ_FIELD_BYFIELD_N2',& + TRIM(TPFILE%CNAME)//': invalid fileformat ('//TRIM(TPFILE%CFORMAT)//')') + END IF + IF (LPACK .AND. L1D .AND. SIZE(KFIELD,1)==IHEXTOT .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + KFIELD(:,:)=SPREAD(SPREAD(KFIELD(JPHEXT+1,JPHEXT+1),DIM=1,NCOPIES=IHEXTOT),DIM=2,NCOPIES=IHEXTOT) + ELSE IF (LPACK .AND. L2D .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + KFIELD(:,:)=SPREAD(KFIELD(:,JPHEXT+1),DIM=2,NCOPIES=IHEXTOT) + END IF + ELSE + IF (ISP == TZFD%OWNER) THEN + ! I/O processor case + CALL ALLOCBUFFER_ll(IFIELDP,KFIELD,TPFIELD%CDIR,GALLOC) + IF (TPFILE%CFORMAT=='NETCDF4') THEN + CALL IO_READ_FIELD_NC4(TPFILE,TPFIELD,IFIELDP,IRESP) + ELSE IF (TPFILE%CFORMAT=='LFI') THEN + CALL IO_READ_FIELD_LFI(TPFILE,TPFIELD,IFIELDP,IRESP) + ELSE + CALL PRINT_MSG(NVERB_FATAL,'IO','IO_READ_FIELD_BYFIELD_N2',& + TRIM(TPFILE%CNAME)//': invalid fileformat ('//TRIM(TPFILE%CFORMAT)//')') + END IF + END IF + ! + CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD%COMM,IERR) + ! + !Broadcast header only if IRESP==-111 + !because metadata of field has been modified in IO_READ_FIELD_xxx + IF (IRESP==-111) CALL IO_BCAST_FIELD_METADATA(TZFD,TPFIELD) + ! + IF (TPFIELD%CDIR == 'XX' .OR. TPFIELD%CDIR == 'YY') THEN + ! XX or YY Scatter Field + CALL SCATTER_XXFIELD(TPFIELD%CDIR,IFIELDP,KFIELD,TZFD%OWNER,TZFD%COMM) + ! Broadcast Field + CALL MPI_BCAST(KFIELD,SIZE(KFIELD),MPI_FLOAT,TZFD%OWNER-1,TZFD%COMM,IERR) + ELSE IF (TPFIELD%CDIR == 'XY') THEN + IF (LPACK .AND. L2D) THEN + ! 2D compact case + CALL SCATTER_XXFIELD('XX',IFIELDP(:,1),KFIELD(:,JPHEXT+1),TZFD%OWNER,TZFD%COMM) + KFIELD(:,:) = SPREAD(KFIELD(:,JPHEXT+1),DIM=2,NCOPIES=IHEXTOT) + ELSE + ! XY Scatter Field + CALL SCATTER_XYFIELD(IFIELDP,KFIELD,TZFD%OWNER,TZFD%COMM) + END IF + ELSE + IF (ISP == TZFD%OWNER) KFIELD = IFIELDP + CALL MPI_BCAST(KFIELD,SIZE(KFIELD),MPI_INTEGER,TZFD%OWNER-1,TZFD%COMM,IERR) + END IF + END IF +ELSE + IRESP = -61 + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_READ_FIELD_BYFIELD_N2','file '//TRIM(TPFILE%CNAME)//' not found') +END IF +! +IF (GALLOC) DEALLOCATE (IFIELDP) +! +IF (PRESENT(KRESP)) KRESP = IRESP +! +END SUBROUTINE IO_READ_FIELD_BYFIELD_N2 + + SUBROUTINE FMREADL0_ll(HFILEM,HRECFM,HFIPRI,HDIR,OFIELD,KGRID,& KLENCH,HCOMMENT,KRESP) USE MODD_IO_ll, ONLY : ISP,GSMONOPROC @@ -2569,6 +2695,85 @@ RETURN END SUBROUTINE FMREADL1_ll +SUBROUTINE IO_READ_FIELD_BYNAME_L1(TPFILE,HNAME,OFIELD,KRESP) +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +CHARACTER(LEN=*), INTENT(IN) :: HNAME ! name of the field to write +LOGICAL,DIMENSION(:),INTENT(INOUT) :: OFIELD ! array containing the data field +INTEGER,OPTIONAL, INTENT(OUT) :: KRESP ! return-code +! +INTEGER :: ID ! Index of the field +INTEGER :: IRESP ! return_code +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_FIELD_BYNAME_L1',TRIM(TPFILE%CNAME)//': reading '//TRIM(HNAME)) +! +CALL FIND_FIELD_ID_FROM_MNHNAME(HNAME,ID,IRESP) +! +IF(IRESP==0) CALL IO_READ_FIELD(TPFILE,TFIELDLIST(ID),OFIELD,IRESP) +! +IF (PRESENT(KRESP)) KRESP = IRESP +! +END SUBROUTINE IO_READ_FIELD_BYNAME_L1 + +SUBROUTINE IO_READ_FIELD_BYFIELD_L1(TPFILE,TPFIELD,OFIELD,KRESP) +! +USE MODD_IO_ll, ONLY : ISP,GSMONOPROC +USE MODE_FD_ll, ONLY : GETFD,FD_LL +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +LOGICAL,DIMENSION(:),INTENT(INOUT) :: OFIELD ! array containing the data field +INTEGER,OPTIONAL, INTENT(OUT) :: KRESP ! return-code +! +INTEGER :: IERR +TYPE(FD_ll), POINTER :: TZFD +INTEGER :: IRESP +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_FIELD_BYFIELD_L1',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) +! +IRESP = 0 +! +TZFD=>GETFD(TRIM(ADJUSTL(TPFILE%CNAME))//'.lfi') +IF (ASSOCIATED(TZFD)) THEN + IF (GSMONOPROC) THEN ! sequential execution + IF (TPFILE%CFORMAT=='NETCDF4') THEN + CALL IO_READ_FIELD_NC4(TPFILE,TPFIELD,OFIELD,IRESP) + ELSE IF (TPFILE%CFORMAT=='LFI') THEN + CALL IO_READ_FIELD_LFI(TPFILE,TPFIELD,OFIELD,IRESP) + ELSE + CALL PRINT_MSG(NVERB_FATAL,'IO','IO_READ_FIELD_BYFIELD_L1',& + TRIM(TPFILE%CNAME)//': invalid fileformat ('//TRIM(TPFILE%CFORMAT)//')') + END IF + ELSE + IF (ISP == TZFD%OWNER) THEN + IF (TPFILE%CFORMAT=='NETCDF4') THEN + CALL IO_READ_FIELD_NC4(TPFILE,TPFIELD,OFIELD,IRESP) + ELSE IF (TPFILE%CFORMAT=='LFI') THEN + CALL IO_READ_FIELD_LFI(TPFILE,TPFIELD,OFIELD,IRESP) + ELSE + CALL PRINT_MSG(NVERB_FATAL,'IO','IO_READ_FIELD_BYFIELD_L1',& + TRIM(TPFILE%CNAME)//': invalid fileformat ('//TRIM(TPFILE%CFORMAT)//')') + END IF + END IF + ! + CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD%COMM,IERR) + ! + !Broadcast header only if IRESP==-111 + !because metadata of field has been modified in IO_READ_FIELD_xxx + IF (IRESP==-111) CALL IO_BCAST_FIELD_METADATA(TZFD,TPFIELD) + ! + CALL MPI_BCAST(OFIELD,1,MPI_LOGICAL,TZFD%OWNER-1,TZFD%COMM,IERR) + END IF +ELSE + IRESP = -61 + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_READ_FIELD_BYFIELD_L1','file '//TRIM(TPFILE%CNAME)//' not found') +END IF +! +IF (PRESENT(KRESP)) KRESP = IRESP +! +END SUBROUTINE IO_READ_FIELD_BYFIELD_L1 + + SUBROUTINE FMREADC0_ll(HFILEM,HRECFM,HFIPRI,HDIR,HFIELD,KGRID,& KLENCH,HCOMMENT,KRESP) USE MODD_IO_ll, ONLY : ISP,GSMONOPROC,LIOCDF4,LLFIREAD diff --git a/src/LIB/SURCOUCHE/src/fmreadwrit.f90 b/src/LIB/SURCOUCHE/src/fmreadwrit.f90 index 733bfed4612dcf2e52428b5b5a2a6eeaeaa00c6e..a54d2675798d551bfec44b0154f536516a9e21f1 100644 --- a/src/LIB/SURCOUCHE/src/fmreadwrit.f90 +++ b/src/LIB/SURCOUCHE/src/fmreadwrit.f90 @@ -274,15 +274,15 @@ PRIVATE INTERFACE IO_READ_FIELD_LFI MODULE PROCEDURE IO_READ_FIELD_LFI_X0, IO_READ_FIELD_LFI_X1, & IO_READ_FIELD_LFI_X2, IO_READ_FIELD_LFI_X3, & - IO_READ_FIELD_LFI_N0, & - IO_READ_FIELD_LFI_L0, & - IO_READ_FIELD_LFI_C0, & + IO_READ_FIELD_LFI_N0, & + IO_READ_FIELD_LFI_N2, & + IO_READ_FIELD_LFI_L0, IO_READ_FIELD_LFI_L1, & + IO_READ_FIELD_LFI_C0, & IO_READ_FIELD_LFI_T0 ! IO_READ_FIELD_LFI_X4,IO_READ_FIELD_LFI_X5, & -! IO_READ_FIELD_LFI_X6, & +! IO_READ_FIELD_LFI_X6, & ! IO_READ_FIELD_LFI_N1, & -! IO_READ_FIELD_LFI_N2,IO_READ_FIELD_LFI_N3, & -! IO_READ_FIELD_LFI_L1, & +! IO_READ_FIELD_LFI_N3, & END INTERFACE IO_READ_FIELD_LFI ! INTERFACE IO_WRITE_FIELD_LFI @@ -481,6 +481,42 @@ IF (ALLOCATED(IWORK)) DEALLOCATE(IWORK) END SUBROUTINE IO_READ_FIELD_LFI_N0 ! ! +SUBROUTINE IO_READ_FIELD_LFI_N2(TPFILE,TPFIELD,KFIELD,KRESP) +USE MODD_FM +USE MODD_CONFZ, ONLY : NZ_VERB +USE MODE_MSG +! +IMPLICIT NONE +! +!* 0.1 Declarations of arguments +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +INTEGER,DIMENSION(:,:),INTENT(OUT) :: KFIELD ! array containing the data field +INTEGER, INTENT(OUT) :: KRESP ! return-code if problems occured +! +!* 0.2 Declarations of local variables +! +INTEGER(KIND=LFI_INT) :: IRESP,ITOTAL +INTEGER :: ILENG +INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: IWORK +LOGICAL :: GGOOD +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_FIELD_LFI_N2',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) +! +ILENG = SIZE(KFIELD) +! +CALL IO_READ_CHECK_FIELD_LFI(TPFILE,TPFIELD,ILENG,IWORK,ITOTAL,IRESP,GGOOD) +! +IF (GGOOD) KFIELD(:,:) = RESHAPE(IWORK(IWORK(2)+3:),SHAPE(KFIELD)) +! +KRESP=IRESP +! +IF (ALLOCATED(IWORK)) DEALLOCATE(IWORK) +! +END SUBROUTINE IO_READ_FIELD_LFI_N2 +! +! SUBROUTINE IO_READ_FIELD_LFI_L0(TPFILE,TPFIELD,OFIELD,KRESP) USE MODD_FM USE MODD_CONFZ, ONLY : NZ_VERB @@ -530,6 +566,60 @@ IF (ALLOCATED(IWORK)) DEALLOCATE(IWORK) END SUBROUTINE IO_READ_FIELD_LFI_L0 ! ! +SUBROUTINE IO_READ_FIELD_LFI_L1(TPFILE,TPFIELD,OFIELD,KRESP) +USE MODD_FM +USE MODD_CONFZ, ONLY : NZ_VERB +USE MODE_MSG +! +IMPLICIT NONE +! +!* 0.1 Declarations of arguments +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +LOGICAL,DIMENSION(:),INTENT(OUT) :: OFIELD ! array containing the data field +INTEGER, INTENT(OUT) :: KRESP ! return-code if problems occured +! +!* 0.2 Declarations of local variables +! +INTEGER(KIND=LFI_INT) :: IRESP,ITOTAL +INTEGER :: ILENG +INTEGER :: JI +INTEGER, DIMENSION(SIZE(OFIELD)) :: IFIELD +INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: IWORK +LOGICAL :: GGOOD +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_FIELD_LFI_L1',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) +! +ILENG = SIZE(OFIELD) +! +CALL IO_READ_CHECK_FIELD_LFI(TPFILE,TPFIELD,ILENG,IWORK,ITOTAL,IRESP,GGOOD) +! +IF (GGOOD) THEN + IFIELD(:) = IWORK(IWORK(2)+3:) + DO JI=1,ILENG + IF (IFIELD(JI)==0) THEN + OFIELD(JI) = .FALSE. + ELSE IF (IFIELD(JI)==1) THEN + OFIELD(JI) = .TRUE. + ELSE + OFIELD(JI) = .TRUE. + IRESP = -112 + END IF + END DO + IF (IRESP==-112) THEN + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_READ_FIELD_LFI_L1',TRIM(TPFILE%CNAME)//': invalid value(s) in file for ' & + //TRIM(TPFIELD%CMNHNAME)) + END IF +END IF +! +KRESP=IRESP +! +IF (ALLOCATED(IWORK)) DEALLOCATE(IWORK) +! +END SUBROUTINE IO_READ_FIELD_LFI_L1 +! +! SUBROUTINE IO_READ_FIELD_LFI_C0(TPFILE,TPFIELD,HFIELD,KRESP) USE MODD_FM USE MODD_CONFZ, ONLY : NZ_VERB @@ -750,7 +840,7 @@ END SELECT ! IF (TRIM(YCOMMENT)/=TRIM(TPFIELD%CCOMMENT)) THEN CALL PRINT_MSG(NVERB_INFO,'IO','IO_READ_CHECK_FIELD_LFI','expected COMMENT ('//TRIM(TPFIELD%CCOMMENT)// & - ') is different than found ('//TRIM(YCOMMENT)//')in file for field '//TRIM(TPFIELD%CMNHNAME)) + ') is different than found ('//TRIM(YCOMMENT)//') in file for field '//TRIM(TPFIELD%CMNHNAME)) TPFIELD%CCOMMENT=TRIM(YCOMMENT) KRESP = -111 !Used later to broadcast modified metadata ELSE diff --git a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 b/src/LIB/SURCOUCHE/src/mode_netcdf.f90 index 26a40a540be941862b84b12713deaecf76381bd0..bc491f914133037e785e834e5e2962ccd4d66b33 100644 --- a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 +++ b/src/LIB/SURCOUCHE/src/mode_netcdf.f90 @@ -37,15 +37,15 @@ END INTERFACE IO_WRITE_FIELD_NC4 INTERFACE IO_READ_FIELD_NC4 MODULE PROCEDURE IO_READ_FIELD_NC4_X0,IO_READ_FIELD_NC4_X1, & IO_READ_FIELD_NC4_X2,IO_READ_FIELD_NC4_X3, & - IO_READ_FIELD_NC4_N0, & - IO_READ_FIELD_NC4_L0, & - IO_READ_FIELD_NC4_C0, & + IO_READ_FIELD_NC4_N0, & + IO_READ_FIELD_NC4_N2, & + IO_READ_FIELD_NC4_L0,IO_READ_FIELD_NC4_L1, & + IO_READ_FIELD_NC4_C0, & IO_READ_FIELD_NC4_T0 ! IO_READ_FIELD_NC4_X4,IO_READ_FIELD_NC4_X5, & ! IO_READ_FIELD_NC4_X6, & ! IO_READ_FIELD_NC4_N1, & -! IO_READ_FIELD_NC4_L1, & -! IO_READ_FIELD_NC4_N2,IO_READ_FIELD_NC4_N3, & +! IO_READ_FIELD_NC4_N3, & ! IO_READ_FIELD_NC4_C1, & END INTERFACE IO_READ_FIELD_NC4 @@ -2446,7 +2446,7 @@ INTEGER(KIND=IDCDF_KIND) :: INCID INTEGER(KIND=IDCDF_KIND) :: IVARID INTEGER(KIND=IDCDF_KIND) :: ITYPE ! variable type INTEGER(KIND=IDCDF_KIND) :: IDIMS ! number of dimensions -INTEGER(KIND=IDCDF_KIND),DIMENSION(1) :: IVDIMS +INTEGER(KIND=IDCDF_KIND),DIMENSION(NF90_MAX_VAR_DIMS) :: IVDIMS CHARACTER(LEN=30) :: YVARNAME INTEGER(KIND=IDCDF_KIND) :: IDIMLEN INTEGER :: IRESP @@ -2590,7 +2590,7 @@ INTEGER(KIND=IDCDF_KIND) :: INCID INTEGER(KIND=IDCDF_KIND) :: IVARID INTEGER(KIND=IDCDF_KIND) :: ITYPE ! variable type INTEGER(KIND=IDCDF_KIND) :: IDIMS ! number of dimensions -INTEGER(KIND=IDCDF_KIND),DIMENSION(3) :: IVDIMS +INTEGER(KIND=IDCDF_KIND),DIMENSION(NF90_MAX_VAR_DIMS) :: IVDIMS CHARACTER(LEN=30) :: YVARNAME INTEGER(KIND=IDCDF_KIND),DIMENSION(3) :: IDIMLEN INTEGER :: IRESP @@ -3247,6 +3247,89 @@ KRESP = IRESP END SUBROUTINE NCREADN2 +SUBROUTINE IO_READ_FIELD_NC4_N2(TPFILE, TPFIELD, KFIELD, KRESP) +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +INTEGER, DIMENSION(:,:), INTENT(OUT) :: KFIELD +INTEGER, INTENT(OUT) :: KRESP ! return-code + +INTEGER(KIND=IDCDF_KIND) :: STATUS +INTEGER(KIND=IDCDF_KIND) :: INCID +INTEGER(KIND=IDCDF_KIND) :: IVARID +INTEGER(KIND=IDCDF_KIND) :: ITYPE ! variable type +INTEGER(KIND=IDCDF_KIND) :: IDIMS ! number of dimensions +INTEGER(KIND=IDCDF_KIND),DIMENSION(NF90_MAX_VAR_DIMS) :: IVDIMS +CHARACTER(LEN=30) :: YVARNAME +INTEGER(KIND=IDCDF_KIND),DIMENSION(3) :: IDIMLEN +INTEGER :: IRESP + +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_FIELD_NC4_N2',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) + +IRESP = 0 +! Get the Netcdf file ID +INCID = TPFILE%NNCID + +CALL CLEANMNHNAME(TPFIELD%CMNHNAME,YVARNAME) + +! Get variable ID, NDIMS and TYPE +STATUS = NF90_INQ_VARID(INCID, YVARNAME, IVARID) +IF (STATUS /= NF90_NOERR) THEN + CALL HANDLE_ERR(status,__LINE__,'IO_READ_FIELD_NC4_N2[NF90_INQ_VARID] '//TRIM(YVARNAME),IRESP) + GOTO 1000 +END IF +STATUS = NF90_INQUIRE_VARIABLE(INCID, IVARID, XTYPE=ITYPE, NDIMS=IDIMS, DIMIDS=IVDIMS) +IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(STATUS,__LINE__,'IO_READ_FIELD_NC4_N2[NF90_INQUIRE_VARIABLE] '//TRIM(YVARNAME)) + +!Treat special case of a degenerated 3D array (3rd dimension size is 1) +IF (IDIMS==3) THEN + STATUS = NF90_INQUIRE_DIMENSION(INCID, IVDIMS(3), LEN=IDIMLEN(3)) + IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_READ_FIELD_NC4_N2[NF90_INQUIRE_DIMENSION] '//TRIM(YVARNAME)) + IF (IDIMLEN(3)==1) THEN + CALL PRINT_MSG(NVERB_INFO,'IO','IO_READ_FIELD_NC4_N2',TRIM(TPFILE%CNAME)// & + ': reading 3D array with degenerated third dimension in 2D array for '//TRIM(YVARNAME)) + IDIMS = 2 + ELSE + CALL PRINT_MSG(NVERB_FATAL,'IO','IO_READ_FIELD_NC4_N2',TRIM(TPFILE%CNAME)//': wrong number of dimensions for '//TRIM(YVARNAME)) + END IF +END IF + +!NF90_INT1 is for the case a boolean was written +#ifndef MNH_INT8 +IF (IDIMS == SIZE(SHAPE(KFIELD)) .AND. (ITYPE == NF90_INT .OR. ITYPE == NF90_INT1) ) THEN +#else +IF (IDIMS == SIZE(SHAPE(KFIELD)) .AND. (ITYPE == NF90_INT64 .OR. ITYPE == NF90_INT1) ) THEN +#endif + ! Check size of variable before reading + STATUS = NF90_INQUIRE_DIMENSION(INCID, IVDIMS(1), LEN=IDIMLEN(1)) + IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_READ_FIELD_NC4_N2[NF90_INQUIRE_DIMENSION] '//TRIM(YVARNAME)) + STATUS = NF90_INQUIRE_DIMENSION(INCID, IVDIMS(2), LEN=IDIMLEN(2)) + IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_READ_FIELD_NC4_N2[NF90_INQUIRE_DIMENSION] '//TRIM(YVARNAME)) + + IF (IDIMLEN(1) == SIZE(KFIELD,1) .AND. IDIMLEN(2) == SIZE(KFIELD,2)) THEN + ! Read variable + STATUS = NF90_GET_VAR(INCID, IVARID, KFIELD) + IF (STATUS /= NF90_NOERR) THEN + CALL HANDLE_ERR(status,__LINE__,'IO_READ_FIELD_NC4_N2[NF90_GET_VAR] '//TRIM(YVARNAME),IRESP) + GOTO 1000 + END IF + ! Read and check attributes of variable + CALL IO_READ_CHECK_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,IRESP) + ELSE + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_READ_FIELD_NC4_N2',TRIM(TPFILE%CNAME)//': '//TRIM(YVARNAME)// & + ' not read (wrong size)') + IRESP = -3 + END IF +ELSE + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_READ_FIELD_NC4_N2',TRIM(TPFILE%CNAME)//': '//TRIM(YVARNAME)// & + ' not read (wrong number of dimensions or wrong type)') + IRESP = -3 +END IF + +1000 CONTINUE +KRESP = IRESP + +END SUBROUTINE IO_READ_FIELD_NC4_N2 + SUBROUTINE IO_READ_FIELD_NC4_L0(TPFILE, TPFIELD, OFIELD, KRESP) TYPE(TFILEDATA), INTENT(IN) :: TPFILE TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD @@ -3314,6 +3397,90 @@ KRESP = IRESP END SUBROUTINE IO_READ_FIELD_NC4_L0 +SUBROUTINE IO_READ_FIELD_NC4_L1(TPFILE, TPFIELD, OFIELD, KRESP) +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +LOGICAL,DIMENSION(:),INTENT(OUT) :: OFIELD +INTEGER, INTENT(OUT) :: KRESP ! return-code + +INTEGER(KIND=IDCDF_KIND) :: STATUS +INTEGER(KIND=IDCDF_KIND) :: INCID +INTEGER(KIND=IDCDF_KIND) :: IVARID +INTEGER(KIND=IDCDF_KIND) :: ITYPE ! variable type +INTEGER(KIND=IDCDF_KIND) :: IDIMS ! number of dimensions +INTEGER(KIND=IDCDF_KIND),DIMENSION(NF90_MAX_VAR_DIMS) :: IVDIMS +INTEGER(KIND=IDCDF_KIND) :: IDIMLEN +CHARACTER(LEN=30) :: YVARNAME +INTEGER :: IRESP +INTEGER :: JI +INTEGER,DIMENSION(SIZE(OFIELD)) :: IFIELD + +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_READ_FIELD_NC4_L1',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) + +IRESP = 0 +! Get the Netcdf file ID +INCID = TPFILE%NNCID + +CALL CLEANMNHNAME(TPFIELD%CMNHNAME,YVARNAME) + +! Get variable ID, NDIMS and TYPE +STATUS = NF90_INQ_VARID(INCID, YVARNAME, IVARID) +IF (STATUS /= NF90_NOERR) THEN + CALL HANDLE_ERR(status,__LINE__,'IO_READ_FIELD_NC4_L1[NF90_INQ_VARID] '//TRIM(YVARNAME),IRESP) + GOTO 1000 +END IF +STATUS = NF90_INQUIRE_VARIABLE(INCID, IVARID, XTYPE=ITYPE, NDIMS=IDIMS, DIMIDS=IVDIMS) +IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(STATUS,__LINE__,'IO_READ_FIELD_NC4_L1[NF90_INQUIRE_VARIABLE] '//TRIM(YVARNAME)) + +!NF90_INT1 is for the case a boolean was written +!Accept also INT and INT64 (for backward compatibility) +IF (IDIMS == 1 .AND. (ITYPE == NF90_INT1 .OR. ITYPE == NF90_INT .OR. ITYPE == NF90_INT64) ) THEN + ! Check size of variable before reading + STATUS = NF90_INQUIRE_DIMENSION(INCID, IVDIMS(1), LEN=IDIMLEN) + IF (STATUS /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_READ_FIELD_NC4_L1[NF90_INQUIRE_DIMENSION] '//TRIM(YVARNAME)) + + IF (IDIMLEN == SIZE(OFIELD)) THEN + ! Read variable + STATUS = NF90_GET_VAR(INCID, IVARID, IFIELD) + IF (STATUS /= NF90_NOERR) THEN + CALL HANDLE_ERR(status,__LINE__,'IO_READ_FIELD_NC4_L1[NF90_GET_VAR] '//TRIM(YVARNAME),IRESP) + GOTO 1000 + END IF + + DO JI=1,IDIMLEN + IF (IFIELD(JI)==0) THEN + OFIELD(JI) = .FALSE. + ELSE IF (IFIELD(JI)==1) THEN + OFIELD(JI) = .TRUE. + ELSE + OFIELD(JI) = .TRUE. + IRESP = -112 + END IF + END DO + IF (IRESP==-112) THEN + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_READ_FIELD_LFI_L1',TRIM(TPFILE%CNAME)//': invalid value(s) in file for ' & + //TRIM(TPFIELD%CMNHNAME)) + END IF + + ! Read and check attributes of variable + CALL IO_READ_CHECK_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID,IRESP) + ELSE + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_READ_FIELD_NC4_L1',TRIM(TPFILE%CNAME)//': '//TRIM(YVARNAME)// & + ' not read (wrong size)') + IRESP = -3 + END IF +ELSE + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_READ_FIELD_NC4_L1',TRIM(TPFILE%CNAME)//': '//TRIM(YVARNAME)// & + ' not read (wrong number of dimensions or wrong type)') + IRESP = -3 +END IF + +1000 CONTINUE +KRESP = IRESP + +END SUBROUTINE IO_READ_FIELD_NC4_L1 + + SUBROUTINE NCREADC0(KNCID, HVARNAME, HFIELD, TPFMH, KRESP) USE MODD_FM, ONLY : FMHEADER, JPXKRK INTEGER(KIND=IDCDF_KIND),INTENT(IN) :: KNCID