From a947bc2a8e0b0da41e6f29f3a6347b4e2b82dc92 Mon Sep 17 00:00:00 2001 From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr> Date: Thu, 15 Dec 2016 10:20:49 +0100 Subject: [PATCH] Philippe 15/12/2016: IO: * added TPFILE argument to IO_WRITE_FIELD_NC4 * added optional KZFILE argument to IO_WRITE_FIELD_NC4_ * provide the correct file to IO_WRITE_FIELD_NC4 if z-splitted file in IO_WRITE_FIELD_BYFIELD_N0 * added TFILE_IOZ array of pointer to TOUTBAK type to point to z-splitted files * manage z-splitted files in IO_FILE_OPEN_ll and IO_FILE_CLOSE_ll * manage z-splitted files in IO_PREPARE_BAKOUT_STRUCT * created IO_FILE_FIND_BYNAME subroutine * merged linked lists concerning output and backup files --- src/LIB/SURCOUCHE/src/fmwrit_ll.f90 | 42 ++++---- src/LIB/SURCOUCHE/src/modd_io.f90 | 13 ++- src/LIB/SURCOUCHE/src/mode_fm.f90 | 54 ++++++++++- .../SURCOUCHE/src/mode_io_manage_struct.f90 | 97 +++++++++++++++++-- src/LIB/SURCOUCHE/src/mode_netcdf.f90 | 29 ++++-- 5 files changed, 196 insertions(+), 39 deletions(-) diff --git a/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 b/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 index 354b17653..9141ee8c5 100644 --- a/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 +++ b/src/LIB/SURCOUCHE/src/fmwrit_ll.f90 @@ -676,15 +676,15 @@ CONTAINS IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN ZFIELDP=>PFIELD(JPHEXT+1:JPHEXT+1,JPHEXT+1:JPHEXT+1) IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP) ! ELSE IF (LPACK .AND. L2D .AND. YDIR=='XY') THEN ELSEIF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN ZFIELDP=>PFIELD(:,JPHEXT+1:JPHEXT+1) IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP) ELSE IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,PFIELD,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,PFIELD,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,PFIELD,IRESP) END IF ELSE ! multiprocessor execution CALL SECOND_MNH2(T0) @@ -747,7 +747,7 @@ CONTAINS ! IF (ISP == TZFD%OWNER) THEN IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP) END IF #ifdef MNH_GA !!$ IF (ISP .EQ. 1 ) THEN @@ -1167,8 +1167,7 @@ CONTAINS USE MODE_FD_ll, ONLY : GETFD,JPFINL,FD_LL USE MODE_ALLOCBUFFER_ll USE MODE_GATHER_ll - !JUANZ - USE MODD_IO_ll, ONLY : ISNPROC + !JUANZ USE MODE_IO_ll, ONLY : io_file,io_rank USE MODD_TIMEZ, ONLY : TIMEZ USE MODE_MNH_TIMING, ONLY : SECOND_MNH2 @@ -1248,15 +1247,15 @@ CONTAINS IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN ZFIELDP=>PFIELD(JPHEXT+1:JPHEXT+1,JPHEXT+1:JPHEXT+1,:) IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP) ! ELSE IF (LPACK .AND. L2D .AND. YDIR=='XY') THEN ELSEIF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN ZFIELDP=>PFIELD(:,JPHEXT+1:JPHEXT+1,:) IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP) ELSE IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,PFIELD,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,PFIELD,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,PFIELD,IRESP) END IF ELSEIF ( (TZFD%nb_procio .eq. 1 ) .OR. ( YDIR == '--' ) ) THEN ! multiprocessor execution & 1 proc IO ! write 3D field in 1 time = output for graphique @@ -1279,7 +1278,7 @@ CONTAINS ! IF (ISP == TZFD%OWNER) THEN IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,ZFIELDP,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,ZFIELDP,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,ZFIELDP,IRESP) END IF ! CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD& @@ -1341,7 +1340,7 @@ CONTAINS TIMEZ%T_WRIT3D_RECV=TIMEZ%T_WRIT3D_RECV + T1 - T0 ! IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD_IOZ%FLU,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD_IOZ%CDF,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD_IOZ%CDF,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK,KZFILE=IK_FILE+1) CALL SECOND_MNH2(T2) TIMEZ%T_WRIT3D_WRIT=TIMEZ%T_WRIT3D_WRIT + T2 - T1 END IF @@ -1460,7 +1459,7 @@ CONTAINS TIMEZ%T_WRIT3D_RECV=TIMEZ%T_WRIT3D_RECV + T1 - T0 !JUANIOZ IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD_IOZ%FLU,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD_IOZ%CDF,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD_IOZ%CDF,ZSLIDE_ll,IRESP,KVERTLEVEL=JKK,KZFILE=IK_FILE+1) CALL SECOND_MNH2(T2) TIMEZ%T_WRIT3D_WRIT=TIMEZ%T_WRIT3D_WRIT + T2 - T1 END IF @@ -1901,6 +1900,7 @@ CONTAINS USE MODD_IO_ll USE MODD_FM USE MODE_FD_ll, ONLY : GETFD,JPFINL,FD_LL + USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME !* 0. DECLARATIONS ! ------------ ! @@ -1923,6 +1923,7 @@ CONTAINS CHARACTER(len=5) :: YK_FILE CHARACTER(len=128) :: YFILE_IOZ TYPE(FD_ll), POINTER :: TZFD_IOZ + TYPE(TFILEDATA),POINTER :: TZFILE INTEGER,DIMENSION(1) :: IDIMS ! IDIMS(1) = 0 @@ -1934,11 +1935,11 @@ CONTAINS 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(TPFIELD,TZFD%CDF,KFIELD,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,KFIELD,IRESP) ELSE IF (ISP == TZFD%OWNER) THEN IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,KFIELD,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,KFIELD,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,KFIELD,IRESP) END IF ! CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD%COMM,IERR) @@ -1952,7 +1953,14 @@ CONTAINS IK_RANK = TZFD_IOZ%OWNER IF ( ISP == IK_RANK ) THEN IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD_IOZ%FLU,KFIELD,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD_IOZ%CDF,KFIELD,IRESP) + IF (LIOCDF4) THEN + CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//YK_FILE,TZFILE,IRESP) + IF (IRESP/=0) THEN + PRINT *,'FATAL: IO_WRITE_FIELD_BYFIELD_N0: file ',TRIM(TRIM(TPFILE%CNAME)//YK_FILE),' not found in list' + STOP + END IF + CALL IO_WRITE_FIELD_NC4(TZFILE,TPFIELD,TZFD_IOZ%CDF,KFIELD,IRESP) + END IF END IF END DO ENDIF @@ -2436,11 +2444,11 @@ CONTAINS IF (ASSOCIATED(TZFD)) THEN IF (GSMONOPROC) THEN ! sequential execution IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,HFIELD,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,HFIELD,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,HFIELD,IRESP) ELSE IF (ISP == TZFD%OWNER) THEN IF (LLFIOUT) CALL IO_WRITE_FIELD_LFI(TPFIELD,TZFD%FLU,HFIELD,IRESP) - IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFIELD,TZFD%CDF,HFIELD,IRESP) + IF (LIOCDF4) CALL IO_WRITE_FIELD_NC4(TPFILE,TPFIELD,TZFD%CDF,HFIELD,IRESP) END IF ! CALL MPI_BCAST(IRESP,1,MPI_INTEGER,TZFD%OWNER-1,TZFD%COMM,IERR) diff --git a/src/LIB/SURCOUCHE/src/modd_io.f90 b/src/LIB/SURCOUCHE/src/modd_io.f90 index 7cb024053..8487b96c2 100644 --- a/src/LIB/SURCOUCHE/src/modd_io.f90 +++ b/src/LIB/SURCOUCHE/src/modd_io.f90 @@ -38,6 +38,12 @@ TYPE LFIPARAM INTEGER :: FITYP ! FM File Type (used in FMCLOSE) END TYPE LFIPARAM +!Structure containing one pointer to a file +!Useful to create arrays of pointers to files +TYPE TFILE_ELT + TYPE(TFILEDATA),POINTER :: TFILE +END TYPE TFILE_ELT + !Structure describing the characteristics of an output or a backup TYPE TOUTBAK INTEGER :: NID = -1 !Backup number @@ -46,6 +52,7 @@ TYPE TOUTBAK INTEGER :: NOUTDAD = -1 !Index of the corresponding dad file (file with same time) CHARACTER(LEN=28) :: CDADFILENAME !Filename of dad TYPE(TFILEDATA),POINTER :: TFILE => NULL() !Corresponding file + TYPE(TFILE_ELT),DIMENSION(:),ALLOCATABLE :: TFILE_IOZ !Corresponding Z-splitted files INTEGER,DIMENSION(:),POINTER :: NFIELDLIST => NULL() !List of the fields to read or write END TYPE TOUTBAK @@ -76,9 +83,7 @@ TYPE TFILEDATA TYPE(TFILEDATA),POINTER :: TFILE_NEXT => NULL() END TYPE TFILEDATA -TYPE(TFILEDATA),POINTER,SAVE :: TFILE_BAK_FIRST => NULL() -TYPE(TFILEDATA),POINTER,SAVE :: TFILE_OUT_FIRST => NULL() -TYPE(TFILEDATA),POINTER,SAVE :: TFILE_BAK_LAST => NULL() -TYPE(TFILEDATA),POINTER,SAVE :: TFILE_OUT_LAST => NULL() +TYPE(TFILEDATA),POINTER,SAVE :: TFILE_FIRST => NULL() +TYPE(TFILEDATA),POINTER,SAVE :: TFILE_LAST => NULL() END MODULE MODD_IO_ll diff --git a/src/LIB/SURCOUCHE/src/mode_fm.f90 b/src/LIB/SURCOUCHE/src/mode_fm.f90 index a04d04e3f..67acb8ba4 100644 --- a/src/LIB/SURCOUCHE/src/mode_fm.f90 +++ b/src/LIB/SURCOUCHE/src/mode_fm.f90 @@ -132,15 +132,19 @@ END SUBROUTINE FMLOOK_ll SUBROUTINE IO_FILE_OPEN_ll(TPFILE,HFIPRI,KRESP) ! -USE MODD_IO_ll, ONLY: LIOCDF4,TFILEDATA +USE MODD_IO_ll, ONLY: ISP,LIOCDF4,TFILEDATA USE MODE_FD_ll, ONLY: FD_ll,GETFD +USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME ! TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE ! File structure CHARACTER(LEN=*), INTENT(IN) :: HFIPRI ! File for prints in FM INTEGER, INTENT(OUT) :: KRESP ! Return code ! INTEGER :: ININAR ! Number of articles present in LFI file (unused here) -TYPE(FD_ll), POINTER :: TZFDLFI +INTEGER :: JI,IRESP +CHARACTER (LEN=3) :: YNUMBER ! Character string for Z-level +TYPE(FD_ll), POINTER :: TZFDLFI,TZFD_IOZ +TYPE(TFILEDATA),POINTER :: TZFILE_IOZ ! IF (TPFILE%LOPENED) THEN PRINT *,'ERROR: IO_FILE_OPEN_ll: file ',TRIM(TPFILE%CNAME),' already opened' @@ -154,7 +158,25 @@ TPFILE%LOPENED = .TRUE. TPFILE%NOPEN = TPFILE%NOPEN + 1 ! TZFDLFI=>GETFD(ADJUSTL(TRIM(TPFILE%CNAME)//'.lfi')) -IF (LIOCDF4) TPFILE%NNCID = TZFDLFI%CDF%NCID +!TZFDLFI%CDF exists only if ISP == TZFDLFI%OWNER +IF (ISP == TZFDLFI%OWNER .AND. LIOCDF4) TPFILE%NNCID = TZFDLFI%CDF%NCID +! +IF (TZFDLFI%NB_PROCIO>1) THEN + DO JI = 1,TZFDLFI%NB_PROCIO + WRITE (YNUMBER,FMT="(I3.3)") JI + TZFD_IOZ => GETFD(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER//'.lfi') + IF (ISP == TZFD_IOZ%OWNER .AND. LIOCDF4) THEN + CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER,TZFILE_IOZ,IRESP) + IF (IRESP/=0) THEN + PRINT *,'FATAL: IO_FILE_OPEN_ll: file ',TRIM(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER),' not found in list' + STOP + END IF + TZFILE_IOZ%NNCID = TZFD_IOZ%CDF%NCID + TZFILE_IOZ%LOPENED = .TRUE. + TZFILE_IOZ%NOPEN = TZFILE_IOZ%NOPEN + 1 + END IF + END DO +END IF ! END SUBROUTINE IO_FILE_OPEN_ll @@ -383,23 +405,49 @@ END SUBROUTINE FMOPEN_ll SUBROUTINE IO_FILE_CLOSE_ll(TPFILE,HFIPRI,KRESP) ! USE MODD_IO_ll, ONLY: TFILEDATA +USE MODE_FD_ll, ONLY: FD_ll,GETFD +USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME ! TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE ! File structure CHARACTER(LEN=*), INTENT(IN) :: HFIPRI ! File for prints in FM INTEGER, INTENT(OUT) :: KRESP ! Return code ! +INTEGER :: INB_PROCIO, IRESP, JI +CHARACTER (LEN=3) :: YNUMBER ! Character string for Z-level +TYPE(FD_ll), POINTER :: TZFDLFI +TYPE(TFILEDATA),POINTER :: TZFILE_IOZ +! IF (.NOT.TPFILE%LOPENED) THEN PRINT *,'ERROR: IO_FILE_CLOSE_ll: trying to close a file not opened: ',TRIM(TPFILE%CNAME) CALL ABORT STOP ENDIF ! +!Next lines done before the close to be sure the FD_ll still exists +TZFDLFI=>GETFD(ADJUSTL(TRIM(TPFILE%CNAME)//'.lfi')) +INB_PROCIO=TZFDLFI%NB_PROCIO +! CALL FMCLOS_ll(TPFILE%CNAME,'KEEP',HFIPRI,KRESP,TPFILE=TPFILE) ! TPFILE%LOPENED = .FALSE. TPFILE%NCLOSE = TPFILE%NCLOSE + 1 TPFILE%NNCID = -1 ! +IF (INB_PROCIO>1) THEN + DO JI = 1,TZFDLFI%NB_PROCIO + WRITE (YNUMBER,FMT="(I3.3)") JI + CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER,TZFILE_IOZ,IRESP) + IF (IRESP/=0) THEN + PRINT *,'ERROR: IO_FILE_CLOSE_ll: file ',TRIM(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER),' not found in list' + END IF + IF (TZFILE_IOZ%LOPENED) THEN + TZFILE_IOZ%LOPENED = .FALSE. + TZFILE_IOZ%NCLOSE = TZFILE_IOZ%NCLOSE + 1 + TZFILE_IOZ%NNCID = -1 + END IF + END DO +END IF +! END SUBROUTINE IO_FILE_CLOSE_ll SUBROUTINE FMCLOS_ll(HFILEM,HSTATU,HFIPRI,KRESP,OPARALLELIO,TPFILE) diff --git a/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90 b/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90 index f85038a76..155417349 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_manage_struct.f90 @@ -164,8 +164,8 @@ DO IMI = 1, NMODEL ALLOCATE(OUT_MODEL(IMI)%TBACKUPN(IBAK_NUMB)) ALLOCATE(OUT_MODEL(IMI)%TOUTPUTN(IOUT_NUMB)) ! - CALL POPULATE_STRUCT(TFILE_BAK_FIRST,TFILE_BAK_LAST,IBAK_STEP,"BACKUP",OUT_MODEL(IMI)%TBACKUPN) - CALL POPULATE_STRUCT(TFILE_OUT_FIRST,TFILE_OUT_LAST,IOUT_STEP,"OUTPUT",OUT_MODEL(IMI)%TOUTPUTN) + CALL POPULATE_STRUCT(TFILE_FIRST,TFILE_LAST,IBAK_STEP,"BACKUP",OUT_MODEL(IMI)%TBACKUPN) + CALL POPULATE_STRUCT(TFILE_FIRST,TFILE_LAST,IOUT_STEP,"OUTPUT",OUT_MODEL(IMI)%TOUTPUTN) ! !* Find dad output number ! @@ -460,13 +460,16 @@ END SUBROUTINE SORT_ENTRIES !######################################################################### SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN) !######################################################################### + ! + USE MODD_CONFZ, ONLY: NB_PROCIO_W ! TYPE(TFILEDATA), POINTER,INTENT(INOUT) :: TPFILE_FIRST,TPFILE_LAST INTEGER,DIMENSION(:), INTENT(IN) :: KSTEPS CHARACTER(LEN=*), INTENT(IN) :: HFILETYPE TYPE(TOUTBAK),DIMENSION(:),POINTER,INTENT(OUT) :: TPBAKOUTN ! - CHARACTER (LEN=4) :: YNUMBER ! Character string for the file number + CHARACTER (LEN=3) :: YNUMBER ! Character string for the file number + INTEGER :: JI ! IPOS = 0 DO JOUT = 1,SIZE(KSTEPS) @@ -490,10 +493,10 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN) TPBAKOUTN(IPOS)%TFILE => TPFILE_LAST TPBAKOUTN(IPOS)%TFILE%CTYPE=HFILETYPE TPBAKOUTN(IPOS)%TFILE%CMODE="WRITE" - WRITE (YNUMBER,FMT="('.',I3.3)") IPOS + WRITE (YNUMBER,FMT="(I3.3)") IPOS IF (HFILETYPE=='OUTPUT') THEN ! Add a "OUT" suffix for output files - TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//'.OUT'//YNUMBER) + TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//'.OUT.'//YNUMBER) !Reduce the float precision if asked TPBAKOUTN(IPOS)%TFILE%LNCREDUCE_FLOAT_PRECISION = LOUT_REDUCE_FLOAT_PRECISION(IMI) !Set compression if asked @@ -504,7 +507,7 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN) END IF TPBAKOUTN(IPOS)%TFILE%NNCCOMPRESS_LEVEL = NOUT_COMPRESS_LEVEL(IMI) ELSE IF (HFILETYPE=='BACKUP') THEN - TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//YNUMBER) + TPBAKOUTN(IPOS)%TFILE%CNAME=ADJUSTL(ADJUSTR(IO_SURF_MNH_MODEL(IMI)%COUTFILE)//'.'//YNUMBER) ELSE PRINT *,'Error: unknown filetype (',TRIM(HFILETYPE),')' CALL ABORT @@ -517,19 +520,97 @@ SUBROUTINE POPULATE_STRUCT(TPFILE_FIRST,TPFILE_LAST,KSTEPS,HFILETYPE,TPBAKOUTN) TPBAKOUTN(IPOS)%TFILE%CFORMAT='NETCDF4' ELSE TPBAKOUTN(IPOS)%TFILE%CFORMAT='LFICDF4' - TPBAKOUTN(IPOS)%TFILE%NLFINPRAR= 22+2*(4+NRR+NSV) + IF (HFILETYPE=='BACKUP') TPBAKOUTN(IPOS)%TFILE%NLFINPRAR= 22+2*(4+NRR+NSV) END IF ELSE IF (LLFIOUT) THEN TPBAKOUTN(IPOS)%TFILE%CFORMAT='LFI' - TPBAKOUTN(IPOS)%TFILE%NLFINPRAR= 22+2*(4+NRR+NSV) + IF (HFILETYPE=='BACKUP') TPBAKOUTN(IPOS)%TFILE%NLFINPRAR= 22+2*(4+NRR+NSV) ELSE PRINT *,'Error: unknown backup/output fileformat' CALL ABORT ENDIF + ! + !Create file structures if Z-splitted files + IF (NB_PROCIO_W>1) THEN + ALLOCATE(TPBAKOUTN(IPOS)%TFILE_IOZ(NB_PROCIO_W)) + IF (NB_PROCIO_W>999) THEN + print *,'ERROR in SET_GRID: more than 999 z-levels' + STOP + END IF + DO JI = 1,NB_PROCIO_W + ALLOCATE(TPFILE_LAST%TFILE_NEXT) + TPFILE_LAST%TFILE_NEXT%TFILE_PREV => TPFILE_LAST + TPFILE_LAST => TPFILE_LAST%TFILE_NEXT + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE => TPFILE_LAST + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CTYPE=HFILETYPE + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CMODE="WRITE" + WRITE (YNUMBER,FMT="(I3.3)") JI + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CNAME = TRIM(TPBAKOUTN(IPOS)%TFILE%CNAME)//'.Z'//YNUMBER + IF (HFILETYPE=='OUTPUT') THEN + !Reduce the float precision if asked + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%LNCREDUCE_FLOAT_PRECISION = LOUT_REDUCE_FLOAT_PRECISION(IMI) + !Set compression if asked + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%LNCCOMPRESS = LOUT_COMPRESS(IMI) + IF ( NOUT_COMPRESS_LEVEL(IMI)<0 .OR. NOUT_COMPRESS_LEVEL(IMI)>9 ) THEN + PRINT *,'ERROR: NOUT_COMPRESS_LEVEL must be in the [0..9] range. Value forced to 4' + NOUT_COMPRESS_LEVEL(IMI) = 4 + END IF + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%NNCCOMPRESS_LEVEL = NOUT_COMPRESS_LEVEL(IMI) + END IF + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%NLFITYPE=1 !1: to be transfered +!PW: TODO: set NLFIVERB only when useful (only if LFI file...) + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%NLFIVERB=NVERB + IF (LIOCDF4) THEN + IF (.NOT.LLFIOUT) THEN + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CFORMAT='NETCDF4' + ELSE + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CFORMAT='LFICDF4' + END IF + ELSE IF (LLFIOUT) THEN + TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%CFORMAT='LFI' + !TPBAKOUTN(IPOS)%TFILE_IOZ(JI)%TFILE%NLFINPRAR= 0 + ELSE + PRINT *,'Error: unknown backup/output fileformat' + CALL ABORT + ENDIF + END DO + END IF + ! END IF END DO END SUBROUTINE POPULATE_STRUCT ! END SUBROUTINE IO_PREPARE_BAKOUT_STRUCT ! +SUBROUTINE IO_FILE_FIND_BYNAME(HNAME,TPFILE,KRESP) +! +USE MODD_IO_ll, ONLY: TFILE_FIRST,TFILEDATA +! +CHARACTER(LEN=*), INTENT(IN) :: HNAME ! Name of the file to find +TYPE(TFILEDATA),POINTER,INTENT(OUT) :: TPFILE ! File structure to return +INTEGER, INTENT(OUT) :: KRESP ! Return value +! +TYPE(TFILEDATA),POINTER :: TZFILE ! File structure +! +NULLIFY(TPFILE) +KRESP = 0 +! +TZFILE => TFILE_FIRST +! +DO + IF (TRIM(TZFILE%CNAME) == TRIM(HNAME) ) THEN + TPFILE => TZFILE + EXIT + END IF + IF (.NOT.ASSOCIATED(TZFILE%TFILE_NEXT)) EXIT + TZFILE => TZFILE%TFILE_NEXT +END DO +! +IF (.NOT.ASSOCIATED(TPFILE)) THEN + PRINT *,'ERROR: IO_FILE_FIND_BYNAME: file ',TRIM(HNAME),' not found in list' + KRESP = -1 !File not found +END IF +! +END SUBROUTINE IO_FILE_FIND_BYNAME +! END MODULE MODE_IO_MANAGE_STRUCT diff --git a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 b/src/LIB/SURCOUCHE/src/mode_netcdf.f90 index da68aef61..8beac9810 100644 --- a/src/LIB/SURCOUCHE/src/mode_netcdf.f90 +++ b/src/LIB/SURCOUCHE/src/mode_netcdf.f90 @@ -541,37 +541,52 @@ IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'NCWRITX2[NF90_PUT_VAR KRESP = IRESP END SUBROUTINE NCWRITX2 -SUBROUTINE IO_WRITE_FIELD_NC4_X2(TPFILE,TPFIELD,PZCDF,PFIELD,KRESP,KVERTLEVEL) +SUBROUTINE IO_WRITE_FIELD_NC4_X2(TPFILE,TPFIELD,PZCDF,PFIELD,KRESP,KVERTLEVEL,KZFILE) ! USE MODD_FM, ONLY : FMHEADER +USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME ! -TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFILEDATA),TARGET,INTENT(IN) :: TPFILE TYPE(TFIELDDATA), INTENT(IN) :: TPFIELD TYPE(IOCDF), POINTER :: PZCDF REAL,DIMENSION(:,:), INTENT(IN) :: PFIELD ! array containing the data field INTEGER, INTENT(OUT):: KRESP INTEGER,OPTIONAL, INTENT(IN) :: KVERTLEVEL ! Number of the vertical level (needed for Z-level splitted files) +INTEGER,OPTIONAL, INTENT(IN) :: KZFILE ! Number of the Z-level splitted file ! INTEGER(KIND=IDCDF_KIND) :: STATUS INTEGER(KIND=IDCDF_KIND) :: INCID CHARACTER(LEN=4) :: YSUFFIX +CHARACTER(LEN=3) :: YNUMBER CHARACTER(LEN=LEN(TPFIELD%CMNHNAME)+4) :: YVARNAME INTEGER(KIND=IDCDF_KIND) :: IVARID INTEGER(KIND=IDCDF_KIND), DIMENSION(SIZE(SHAPE(PFIELD))) :: IVDIMS INTEGER :: IRESP +TYPE(TFILEDATA),POINTER :: TZFILE ! IRESP = 0 IF (PRESENT(KVERTLEVEL)) THEN WRITE(YSUFFIX,'(I4.4)') KVERTLEVEL + IF (.NOT.PRESENT(KZFILE)) THEN + PRINT *,'FATAL: IO_WRITE_FIELD_NC4_X2: KZFILE argument not provided' + STOP + END IF + WRITE(YNUMBER,'(I3.3)') KZFILE YVARNAME = TRIM(TPFIELD%CMNHNAME)//YSUFFIX +!PW: TODO: try to not do a find (for better perf) + CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER,TZFILE,IRESP) + IF (IRESP/=0) THEN + PRINT *,'FATAL: IO_FILE_OPEN_ll: file ',TRIM(TRIM(TPFILE%CNAME)//'.Z'//YNUMBER),' not found in list' + STOP + END IF ELSE YVARNAME = TRIM(TPFIELD%CMNHNAME) + TZFILE => TPFILE ENDIF ! Get the Netcdf file ID -INCID = TPFILE%NNCID - +INCID = TZFILE%NNCID ! NetCDF var names can't contain '%' nor '.' YVARNAME = str_replace(YVARNAME, '%', '__') YVARNAME = str_replace(YVARNAME, '.', '--') @@ -583,15 +598,15 @@ IF (STATUS /= NF90_NOERR) THEN CALL FILLVDIMS(PZCDF, INT(SHAPE(PFIELD),KIND=IDCDF_KIND), TPFIELD%CDIR, IVDIMS) ! Define the variable - IF (TPFILE%LNCREDUCE_FLOAT_PRECISION) THEN + IF (TZFILE%LNCREDUCE_FLOAT_PRECISION) THEN STATUS = NF90_DEF_VAR(INCID, YVARNAME, NF90_FLOAT, IVDIMS, IVARID) ELSE STATUS = NF90_DEF_VAR(INCID, YVARNAME, NF90_DOUBLE, IVDIMS, IVARID) END IF IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X2[NF90_DEF_VAR]') ! Add compression if asked for - IF (TPFILE%LNCCOMPRESS) THEN - STATUS = NF90_DEF_VAR_DEFLATE(INCID, IVARID, SHUFFLE, DEFLATE, TPFILE%NNCCOMPRESS_LEVEL) + IF (TZFILE%LNCCOMPRESS) THEN + STATUS = NF90_DEF_VAR_DEFLATE(INCID, IVARID, SHUFFLE, DEFLATE, TZFILE%NNCCOMPRESS_LEVEL) IF (status /= NF90_NOERR) CALL HANDLE_ERR(status,__LINE__,'IO_WRITE_FIELD_NC4_X2[NF90_DEF_VAR_DEFLATE]') END IF CALL IO_WRITE_FIELD_ATTR_NC4(TPFIELD,INCID,IVARID) -- GitLab