From 0caf5d23676fd2ff30b7720833273910e4e2d2f5 Mon Sep 17 00:00:00 2001 From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr> Date: Mon, 6 Mar 2017 15:34:57 +0100 Subject: [PATCH] Philippe 06/03/2017: IO: added writing of 1D logical and integer variables * added IO_WRITE_FIELD_BYNAME_L1 and IO_WRITE_FIELD_BYFIELD_L1 subroutines to IO_WRITE_FIELD procedure * added IO_WRITE_FIELD_BYNAME_N1 and IO_WRITE_FIELD_BYFIELD_N1 subroutines to IO_WRITE_FIELD procedure * added IO_WRITE_FIELD_LFI_N1 subroutine to IO_WRITE_FIELD_LFI procedure * added IO_WRITE_FIELD_NC4_N1 subroutine to IO_WRITE_FIELD_NC1 procedure --- src/LIB/SURCOUCHE/src/fmreadwrit.f90 | 37 +++++- src/LIB/SURCOUCHE/src/fmwrit_ll.f90 | 169 +++++++++++++++++++++++++- src/LIB/SURCOUCHE/src/mode_netcdf.f90 | 65 +++++++++- 3 files changed, 264 insertions(+), 7 deletions(-) diff --git a/src/LIB/SURCOUCHE/src/fmreadwrit.f90 b/src/LIB/SURCOUCHE/src/fmreadwrit.f90 index 93a84a446..e4ebd9991 100644 --- a/src/LIB/SURCOUCHE/src/fmreadwrit.f90 +++ b/src/LIB/SURCOUCHE/src/fmreadwrit.f90 @@ -267,7 +267,8 @@ PRIVATE INTERFACE IO_WRITE_FIELD_LFI MODULE PROCEDURE IO_WRITE_FIELD_LFI_X0,IO_WRITE_FIELD_LFI_X1, & IO_WRITE_FIELD_LFI_X2,IO_WRITE_FIELD_LFI_X3, & - IO_WRITE_FIELD_LFI_N0,IO_WRITE_FIELD_LFI_N2, & + IO_WRITE_FIELD_LFI_N0,IO_WRITE_FIELD_LFI_N1, & + IO_WRITE_FIELD_LFI_N2, & IO_WRITE_FIELD_LFI_C0, & IO_WRITE_FIELD_LFI_T0 END INTERFACE IO_WRITE_FIELD_LFI @@ -455,6 +456,40 @@ IF (ALLOCATED(IWORK)) DEALLOCATE(IWORK) ! END SUBROUTINE IO_WRITE_FIELD_LFI_N0 ! +SUBROUTINE IO_WRITE_FIELD_LFI_N1(TPFIELD,KFLU,KFIELD,KRESP) +! +IMPLICIT NONE +! +!* 0.1 Declarations of arguments +! +TYPE(TFIELDDATA), INTENT(IN) :: TPFIELD +INTEGER, INTENT(IN) :: KFLU ! Fortran Logical Unit +INTEGER,DIMENSION(:), INTENT(IN) :: KFIELD ! array containing the data field +INTEGER, INTENT(OUT):: KRESP ! return-code if problems araised +! +!* 0.2 Declarations of local variables +! +INTEGER :: ILENG +INTEGER(kind=LFI_INT) :: IRESP, ITOTAL +INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: IWORK +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_LFI_N1','writing '//TRIM(TPFIELD%CMNHNAME)) +! +ILENG = SIZE(KFIELD) +! +CALL WRITE_PREPARE(TPFIELD,ILENG,IWORK,ITOTAL,IRESP) +! +IF (IRESP==0) THEN + IWORK(LEN_TRIM(TPFIELD%CCOMMENT)+3:) = KFIELD(:) + CALL LFIECR(IRESP,KFLU,TPFIELD%CMNHNAME,IWORK,ITOTAL) +ENDIF +! +KRESP=IRESP +! +IF (ALLOCATED(IWORK)) DEALLOCATE(IWORK) +! +END SUBROUTINE IO_WRITE_FIELD_LFI_N1 +! SUBROUTINE IO_WRITE_FIELD_LFI_N2(TPFIELD,KFLU,KFIELD,KRESP) ! IMPLICIT NONE diff --git a/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 b/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 index d00f992d2..a6006a90f 100644 --- a/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 +++ b/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 @@ -181,14 +181,16 @@ MODULE MODE_FMWRIT INTERFACE IO_WRITE_FIELD MODULE PROCEDURE IO_WRITE_FIELD_BYNAME_X0, IO_WRITE_FIELD_BYNAME_X1, & IO_WRITE_FIELD_BYNAME_X2, IO_WRITE_FIELD_BYNAME_X3, & - IO_WRITE_FIELD_BYNAME_N0, IO_WRITE_FIELD_BYNAME_N2, & - IO_WRITE_FIELD_BYNAME_L0, & + IO_WRITE_FIELD_BYNAME_N0, IO_WRITE_FIELD_BYNAME_N1, & + IO_WRITE_FIELD_BYNAME_N2, & + IO_WRITE_FIELD_BYNAME_L0, IO_WRITE_FIELD_BYNAME_L1, & IO_WRITE_FIELD_BYNAME_C0, & IO_WRITE_FIELD_BYNAME_T0, & IO_WRITE_FIELD_BYFIELD_X0,IO_WRITE_FIELD_BYFIELD_X1, & IO_WRITE_FIELD_BYFIELD_X2,IO_WRITE_FIELD_BYFIELD_X3, & - IO_WRITE_FIELD_BYFIELD_N0,IO_WRITE_FIELD_BYFIELD_N2, & - IO_WRITE_FIELD_BYFIELD_L0, & + IO_WRITE_FIELD_BYFIELD_N0,IO_WRITE_FIELD_BYFIELD_N1, & + IO_WRITE_FIELD_BYFIELD_N2, & + IO_WRITE_FIELD_BYFIELD_L0,IO_WRITE_FIELD_BYFIELD_L1, & IO_WRITE_FIELD_BYFIELD_C0, & IO_WRITE_FIELD_BYFIELD_T0 END INTERFACE @@ -2313,6 +2315,111 @@ CONTAINS KRESP = IRESP END SUBROUTINE FMWRITN1_ll + + SUBROUTINE IO_WRITE_FIELD_BYNAME_N1(TPFILE,HNAME,HFIPRI,KRESP,KFIELD) + ! + USE MODD_IO_ll, ONLY : TFILEDATA + ! + !* 0.1 Declarations of arguments + ! + TYPE(TFILEDATA), INTENT(IN) :: TPFILE + CHARACTER(LEN=*), INTENT(IN) :: HNAME ! name of the field to write + CHARACTER(LEN=*), INTENT(IN) :: HFIPRI ! output file for error messages + INTEGER, INTENT(OUT):: KRESP ! return-code + INTEGER,DIMENSION(:), INTENT(IN) :: KFIELD ! array containing the data field + ! + !* 0.2 Declarations of local variables + ! + INTEGER :: ID ! Index of the field + ! + CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_BYNAME_N1','writing '//TRIM(HNAME)) + ! + CALL FIND_FIELD_ID_FROM_MNHNAME(HNAME,ID,KRESP) + ! + IF(KRESP==0) CALL IO_WRITE_FIELD(TPFILE,TFIELDLIST(ID),HFIPRI,KRESP,KFIELD) + ! + END SUBROUTINE IO_WRITE_FIELD_BYNAME_N1 + + + SUBROUTINE IO_WRITE_FIELD_BYFIELD_N1(TPFILE,TPFIELD,HFIPRI,KRESP,KFIELD) + ! + USE MODD_IO_ll, ONLY : ISP,GSMONOPROC,LIOCDF4,LLFIOUT,TFILEDATA + USE MODE_FD_ll, ONLY : GETFD,JPFINL,FD_LL + USE MODE_ALLOCBUFFER_ll + USE MODE_GATHER_ll + ! + IMPLICIT NONE + ! + !* 0.1 Declarations of arguments + ! + TYPE(TFILEDATA), INTENT(IN) :: TPFILE + TYPE(TFIELDDATA), INTENT(IN) :: TPFIELD + CHARACTER(LEN=*), INTENT(IN) :: HFIPRI ! output file for error messages + INTEGER, INTENT(OUT):: KRESP ! return-code + INTEGER,DIMENSION(:),TARGET, INTENT(IN) :: KFIELD ! array containing the data field + ! + !* 0.2 Declarations of local variables + ! + CHARACTER(LEN=28) :: YFILEM ! FM-file name + CHARACTER(LEN=NMNHNAMELGTMAX) :: YRECFM ! name of the article to write + CHARACTER(LEN=2) :: YDIR ! field form + CHARACTER(LEN=JPFINL) :: YFNLFI + INTEGER :: IERR + TYPE(FD_ll), POINTER :: TZFD + INTEGER :: IRESP + INTEGER,DIMENSION(:),POINTER :: IFIELDP + LOGICAL :: GALLOC + ! + YFILEM = TPFILE%CNAME + YRECFM = TPFIELD%CMNHNAME + YDIR = TPFIELD%CDIR + ! + CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_BYFIELD_N1','writing '//TRIM(YRECFM)) + ! + !* 1.1 THE NAME OF LFIFM + ! + IRESP = 0 + GALLOC = .FALSE. + YFNLFI=TRIM(ADJUSTL(YFILEM))//'.lfi' + !------------------------------------------------------------------ + TZFD=>GETFD(YFNLFI) + IF (ASSOCIATED(TZFD)) THEN + IF (GSMONOPROC) THEN ! sequential execution + IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,KFIELD,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,KFIELD,IRESP) + ELSE ! multiprocessor execution + IF (ISP == TZFD%OWNER) THEN + CALL ALLOCBUFFER_ll(IFIELDP,KFIELD,YDIR,GALLOC) + ELSE + ALLOCATE(IFIELDP(0)) + GALLOC = .TRUE. + END IF + ! + IF (YDIR == 'XX' .OR. YDIR =='YY') THEN + CALL GATHER_XXFIELD(YDIR,KFIELD,IFIELDP,TZFD%OWNER,TZFD%COMM) + END IF + ! + IF (ISP == TZFD%OWNER) THEN + IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,IFIELDP,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,IFIELDP,IRESP) + END IF + ! + CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD%COMM,IERR) + END IF + ELSE + IRESP = -61 + END IF + !---------------------------------------------------------------- + IF (IRESP.NE.0) THEN + CALL FM_WRIT_ERR("IO_WRITE_FIELD_BYFIELD_N1",YFILEM,HFIPRI,YRECFM,YDIR,TPFIELD%NGRID,LEN(TPFIELD%CCOMMENT),IRESP) + END IF + IF (GALLOC) DEALLOCATE(IFIELDP) + KRESP = IRESP + IF (ASSOCIATED(TZFD)) CALL MPI_BARRIER(TZFD%COMM,IERR) + ! + END SUBROUTINE IO_WRITE_FIELD_BYFIELD_N1 + + SUBROUTINE FMWRITN2_ll(HFILEM,HRECFM,HFIPRI,HDIR,KFIELD,KGRID,& KLENCH,HCOMMENT,KRESP) USE MODD_IO_ll, ONLY : ISP,GSMONOPROC,LIOCDF4,LLFIOUT,LPACK,L1D,L2D @@ -2763,6 +2870,60 @@ CONTAINS KRESP = IRESP END SUBROUTINE FMWRITL1_ll + SUBROUTINE IO_WRITE_FIELD_BYFIELD_L1(TPFILE,TPFIELD,HFIPRI,KRESP,OFIELD) + USE MODD_IO_ll + !* 0. DECLARATIONS + ! ------------ + ! + ! + !* 0.1 Declarations of arguments + ! + TYPE(TFILEDATA), INTENT(IN) :: TPFILE + TYPE(TFIELDDATA), INTENT(IN) :: TPFIELD + CHARACTER(LEN=*), INTENT(IN) :: HFIPRI ! output file for error messages + INTEGER, INTENT(OUT):: KRESP ! return-code + LOGICAL,DIMENSION(:), INTENT(IN) :: OFIELD ! array containing the data field + ! + !* 0.2 Declarations of local variables + ! + INTEGER, DIMENSION(SIZE(OFIELD)) :: IFIELD + ! + CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_BYFIELD_L1','writing '//TRIM(TPFIELD%CMNHNAME)) + ! + WHERE (OFIELD) + IFIELD = 1 + ELSEWHERE + IFIELD = 0 + END WHERE + ! + CALL IO_WRITE_FIELD(TPFILE,TPFIELD,HFIPRI,KRESP,IFIELD) + ! + END SUBROUTINE IO_WRITE_FIELD_BYFIELD_L1 + + SUBROUTINE IO_WRITE_FIELD_BYNAME_L1(TPFILE,HNAME,HFIPRI,KRESP,OFIELD) + ! + USE MODD_IO_ll, ONLY : TFILEDATA + ! + !* 0.1 Declarations of arguments + ! + TYPE(TFILEDATA), INTENT(IN) :: TPFILE + CHARACTER(LEN=*), INTENT(IN) :: HNAME ! name of the field to write + CHARACTER(LEN=*), INTENT(IN) :: HFIPRI ! output file for error messages + INTEGER, INTENT(OUT):: KRESP ! return-code + LOGICAL,DIMENSION(:), INTENT(IN) :: OFIELD ! array containing the data field + ! + !* 0.2 Declarations of local variables + ! + INTEGER :: ID ! Index of the field + ! + CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_BYNAME_L1','writing '//TRIM(HNAME)) + ! + CALL FIND_FIELD_ID_FROM_MNHNAME(HNAME,ID,KRESP) + ! + IF(KRESP==0) CALL IO_WRITE_FIELD(TPFILE,TFIELDLIST(ID),HFIPRI,KRESP,OFIELD) + ! + END SUBROUTINE IO_WRITE_FIELD_BYNAME_L1 + SUBROUTINE FMWRITC0_ll(HFILEM,HRECFM,HFIPRI,HDIR,HFIELD,KGRID,& KLENCH,HCOMMENT,KRESP) USE MODD_IO_ll, ONLY : ISP,GSMONOPROC,LIOCDF4,LLFIOUT diff --git a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 b/src/LIB/SURCOUCHE/src/mode_netcdf.f90 index bc0736233..81d6b4a42 100644 --- a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 +++ b/src/LIB/SURCOUCHE/src/mode_netcdf.f90 @@ -25,7 +25,8 @@ INTEGER(KIND=IDCDF_KIND),PARAMETER :: DEFLATE = 1 INTERFACE IO_WRITE_FIELD_NC4 MODULE PROCEDURE IO_WRITE_FIELD_NC4_X0,IO_WRITE_FIELD_NC4_X1, & IO_WRITE_FIELD_NC4_X2,IO_WRITE_FIELD_NC4_X3, & - IO_WRITE_FIELD_NC4_N0,IO_WRITE_FIELD_NC4_N2, & + IO_WRITE_FIELD_NC4_N0,IO_WRITE_FIELD_NC4_N1, & + IO_WRITE_FIELD_NC4_N2, & IO_WRITE_FIELD_NC4_C0, & IO_WRITE_FIELD_NC4_T0 END INTERFACE IO_WRITE_FIELD_NC4 @@ -705,7 +706,6 @@ CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_NC4_X2','writing '//TRIM(YVARNAM ! ! Get the Netcdf file ID INCID = TZFILE%NNCID -print *,'PW:IO_WRITE_FIELD_NC4_X2: INCID=',INCID, trim(TZFILE%CNAME) ! NetCDF var names can't contain '%' nor '.' YVARNAME = str_replace(YVARNAME, '%', '__') YVARNAME = str_replace(YVARNAME, '.', '--') @@ -1164,6 +1164,67 @@ IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'NCWRITN1[NF90_PUT_VAR KRESP = IRESP END SUBROUTINE NCWRITN1 +SUBROUTINE IO_WRITE_FIELD_NC4_N1(TPFILE,TPFIELD,PZCDF,KFIELD,KRESP) +! +USE MODD_PARAMETERS_ll, ONLY : JPVEXT +#if 0 +USE MODD_PARAMETERS_ll, ONLY : JPHEXT, JPVEXT +USE MODD_IO_ll, ONLY : LPACK,L1D,L2D +#endif +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(IN) :: TPFIELD +TYPE(IOCDF), POINTER :: PZCDF +INTEGER, DIMENSION(:), INTENT(IN) :: KFIELD +INTEGER, INTENT(OUT):: KRESP +! +INTEGER(KIND=IDCDF_KIND) :: STATUS +INTEGER(KIND=IDCDF_KIND) :: INCID +CHARACTER(LEN=LEN(TPFIELD%CMNHNAME)) :: YVARNAME +INTEGER(KIND=IDCDF_KIND) :: IVARID +INTEGER(KIND=IDCDF_KIND), DIMENSION(SIZE(SHAPE(KFIELD))) :: IVDIMS +INTEGER :: IRESP +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_WRITE_FIELD_NC4_N1','writing '//TRIM(TPFIELD%CMNHNAME)) +! +IRESP = 0 +! Get the Netcdf file ID +INCID = TPFILE%NNCID + +! NetCDF var names can't contain '%' nor '.' +YVARNAME = str_replace(TPFIELD%CMNHNAME, '%', '__') +YVARNAME = str_replace(YVARNAME, '.', '--') + +! The variable should not already exist but who knows ? +STATUS = NF90_INQ_VARID(INCID, YVARNAME, IVARID) +IF (STATUS /= NF90_NOERR) THEN + IF (SIZE(KFIELD)==0) THEN + CALL PRINT_MSG(NVERB_INFO,'IO','IO_WRITE_FIELD_NC4_N1','ignoring variable with a zero size ('//TRIM(YVARNAME)//')') + RETURN + END IF + + ! Get the netcdf dimensions + CALL FILLVDIMS(PZCDF, INT(SHAPE(KFIELD),KIND=IDCDF_KIND), TPFIELD%CDIR, IVDIMS) + + ! Define the variable +#ifndef MNH_INT8 + STATUS = NF90_DEF_VAR(INCID, YVARNAME, NF90_INT, IVDIMS, IVARID) +#else + STATUS = NF90_DEF_VAR(INCID, YVARNAME, NF90_INT64, IVDIMS, IVARID) +#endif + IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_N1[NF90_DEF_VAR]') + CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID) +ELSE + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_WRITE_FIELD_NC4_N1',TRIM(YVARNAME)//' already defined') +END IF + +! Write the data +STATUS = NF90_PUT_VAR(INCID, IVARID, KFIELD) +IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_N1[NF90_PUT_VAR] '//TRIM(TPFIELD%CMNHNAME),IRESP) + +KRESP = IRESP +END SUBROUTINE IO_WRITE_FIELD_NC4_N1 + SUBROUTINE NCWRITN2(PZCDF, HVARNAME, HDIR, KFIELD, TPFMH, KRESP) USE MODD_FM, ONLY : FMHEADER TYPE(IOCDF), POINTER :: PZCDF -- GitLab