From ee2805f313c15e1c999f1e4f0a8af2c1e58959c2 Mon Sep 17 00:00:00 2001 From: Philippe WAUTELET <philippe.wautelet@aero.obs-mip.fr> Date: Fri, 1 Mar 2019 13:39:14 +0100 Subject: [PATCH] Philippe 01/03/2019: IO: restructuration of mode_io and mode_fm , creation of mode_io_file --- src/LIB/SURCOUCHE/src/mode_fm.f90 | 420 +------------ src/LIB/SURCOUCHE/src/mode_io.f90 | 384 +----------- src/LIB/SURCOUCHE/src/mode_io_file.f90 | 787 +++++++++++++++++++++++++ 3 files changed, 803 insertions(+), 788 deletions(-) create mode 100644 src/LIB/SURCOUCHE/src/mode_io_file.f90 diff --git a/src/LIB/SURCOUCHE/src/mode_fm.f90 b/src/LIB/SURCOUCHE/src/mode_fm.f90 index 4b54121aa..04252af39 100644 --- a/src/LIB/SURCOUCHE/src/mode_fm.f90 +++ b/src/LIB/SURCOUCHE/src/mode_fm.f90 @@ -25,426 +25,10 @@ !----------------------------------------------------------------- MODULE MODE_FM -USE MODE_MSG -IMPLICIT NONE - -PRIVATE - -PUBLIC SET_FMPACK_ll -PUBLIC IO_FILE_OPEN_ll, IO_FILE_CLOSE_ll - -CONTAINS - -SUBROUTINE SET_FMPACK_ll(O1D,O2D,OPACK) -USE MODD_IO_ll, ONLY: LPACK, L1D, L2D -USE MODD_VAR_ll, ONLY: IP +use mode_io_ll +use mode_io_file IMPLICIT NONE -LOGICAL, INTENT(IN) :: O1D,O2D,OPACK - -LPACK = OPACK -L1D = O1D -L2D = O2D - -IF ( IP == 1 ) PRINT *,'INIT L1D,L2D,LPACK = ',L1D,L2D,LPACK - -END SUBROUTINE SET_FMPACK_ll - -recursive SUBROUTINE IO_FILE_OPEN_ll(TPFILE,KRESP,HPOSITION,HSTATUS,HPROGRAM_ORIG) -! -USE MODD_CONF, ONLY: CPROGRAM -USE MODD_IO_ll, ONLY: LIO_NO_WRITE, TFILEDATA -! -USE MODE_IO_ll, ONLY: GCONFIO, OPEN_ll -USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_ADD2LIST, IO_FILE_FIND_BYNAME -! -TYPE(TFILEDATA), POINTER, INTENT(INOUT) :: TPFILE ! File structure -INTEGER, INTENT(OUT), OPTIONAL :: KRESP ! Return code -CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: HPOSITION -CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: HSTATUS -CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: HPROGRAM_ORIG !To emulate a file coming from this program -! -INTEGER :: IRESP -TYPE(TFILEDATA), POINTER :: TZFILE_DES -TYPE(TFILEDATA), POINTER :: TZFILE_DUMMY -! -CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_FILE_OPEN_ll','opening '//TRIM(TPFILE%CNAME)//' for '//TRIM(TPFILE%CMODE)// & - ' (filetype='//TRIM(TPFILE%CTYPE)//')') -! -IF (.NOT.ASSOCIATED(TPFILE)) CALL PRINT_MSG(NVERB_FATAL,'IO','IO_FILE_OPEN_ll','TPFILE is not associated') -! -IF ( LIO_NO_WRITE .AND. TPFILE%CMODE == 'WRITE' .AND. TPFILE%CTYPE/='OUTPUTLISTING') THEN - CALL PRINT_MSG(NVERB_WARNING,'IO','IO_FILE_OPEN_ll','opening file '//TRIM(TPFILE%CNAME)// & - ' in write mode but LIO_NO_WRITE is set') -END IF -! -TZFILE_DES => NULL() -TZFILE_DUMMY => NULL() -! -TPFILE%NOPEN = TPFILE%NOPEN + 1 -TPFILE%NOPEN_CURRENT = TPFILE%NOPEN_CURRENT + 1 -! -IF (TPFILE%LOPENED) THEN - CALL PRINT_MSG(NVERB_INFO,'IO','IO_FILE_OPEN_ll','file '//TRIM(TPFILE%CNAME)//' is already in open state') - RETURN -END IF -! -TPFILE%LOPENED = .TRUE. -! -!Check if file is in filelist -CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME),TZFILE_DUMMY,IRESP) -IF (IRESP/=0) CALL PRINT_MSG(NVERB_ERROR,'IO','IO_FILE_OPEN_ll','file '//TRIM(TPFILE%CNAME)//' not in filelist') -! -SELECT CASE(TPFILE%CTYPE) - !Chemistry input files - CASE('CHEMINPUT') - CALL OPEN_ll(TPFILE,IRESP,HPOSITION='REWIND',HSTATUS='OLD',HMODE='GLOBAL') - - - !Chemistry tabulation files - CASE('CHEMTAB') - CALL OPEN_ll(TPFILE,IRESP,HMODE='GLOBAL') - - - !DES files - CASE('DES') - CALL OPEN_ll(TPFILE,IRESP,HDELIM='QUOTE') - - - !GPS files - CASE('GPS') - CALL OPEN_ll(TPFILE,IRESP,HMODE='SPECIFIC') - - - !Meteo files - CASE('METEO') - CALL OPEN_ll(TPFILE,IRESP,HMODE='GLOBAL') - - - !Namelist files - CASE('NML') - CALL OPEN_ll(TPFILE,IRESP,HDELIM='QUOTE',HMODE='GLOBAL') - - - !OUTPUTLISTING files - CASE('OUTPUTLISTING') - CALL OPEN_ll(TPFILE,IRESP,HMODE='GLOBAL') - - - !SURFACE_DATA files - CASE('SURFACE_DATA') - CALL OPEN_ll(TPFILE,IRESP,HMODE='GLOBAL') - - - !Text files - CASE('TXT') - CALL OPEN_ll(TPFILE,IRESP,HPOSITION=HPOSITION,HSTATUS=HSTATUS,HMODE='GLOBAL') - - - !MesoNH files - !Remark: 'MNH' is more general than MNHBACKUP and could be in fact a MNHBACKUP file - CASE ('MNH', 'MNHBACKUP', 'MNHDIACHRONIC', 'MNHDIAG', 'MNHOUTPUT', 'PGD') - if (.not.GCONFIO) CALL PRINT_MSG(NVERB_FATAL,'IO','IO_FILE_OPEN_ll','SET_CONFIO_ll must be called before IO_FILE_OPEN_ll') - !Do not open '.des' file if OUTPUT - IF(TPFILE%CTYPE/='MNHOUTPUT' .AND. CPROGRAM/='LFICDF') THEN - !OOLD=T because the file may already be in the list - CALL IO_FILE_ADD2LIST(TZFILE_DES,TRIM(TPFILE%CNAME)//'.des','DES',TPFILE%CMODE,TPDATAFILE=TPFILE,OOLD=.TRUE.) - CALL IO_FILE_OPEN_ll(TZFILE_DES,HPROGRAM_ORIG=HPROGRAM_ORIG) - ENDIF - ! - CALL FMOPEN_ll(TPFILE,IRESP,HPROGRAM_ORIG=HPROGRAM_ORIG) - - - CASE DEFAULT - call print_msg(NVERB_FATAL,'IO','IO_FILE_OPEN_ll','invalid type '//trim(tpfile%ctype)//' for file '//trim(tpfile%cname)) -END SELECT -! -IF (PRESENT(KRESP)) KRESP = IRESP -! -END SUBROUTINE IO_FILE_OPEN_ll - - -SUBROUTINE FMOPEN_ll(TPFILE,KRESP,HPROGRAM_ORIG) - -USE MODD_IO_ll, ONLY: TFILEDATA - -#if defined(MNH_IOCDF4) -use mode_io_file_nc4, only: io_create_file_nc4, io_open_file_nc4 -#endif -use mode_io_file_lfi, only: io_create_file_lfi, io_open_file_lfi -USE MODE_IO_ll, ONLY: OPEN_ll, GCONFIO - -TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE ! File structure -INTEGER, INTENT(OUT) :: KRESP ! return-code -CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: HPROGRAM_ORIG !To emulate a file coming from this program -! -! Local variables -! -INTEGER :: IRESP -CHARACTER(LEN=7) :: YACTION ! Action upon the file ('READ' or 'WRITE') -CHARACTER(LEN=8) :: YRESP -LOGICAL :: GEXIST_LFI, GEXIST_NC4 - -YACTION = TPFILE%CMODE - -CALL PRINT_MSG(NVERB_DEBUG,'IO','FMOPEN_ll','opening '//TRIM(TPFILE%CNAME)//' for '//TRIM(YACTION)) - -IF (.NOT. GCONFIO) THEN - PRINT *, 'FMOPEN_ll Aborting... Please, ensure to call SET_CONFIO_ll before & - &the first FMOPEN_ll call.' - STOP -END IF - -IRESP = 0 - -CALL OPEN_ll(TPFILE,IRESP,HMODE='IO_ZSPLIT',HPROGRAM_ORIG=HPROGRAM_ORIG) - -IF (TPFILE%LMASTER) THEN - ! Proc I/O case - INQUIRE(FILE=TRIM(TPFILE%CNAME)//'.lfi',EXIST=GEXIST_LFI) - INQUIRE(FILE=TRIM(TPFILE%CNAME)//'.nc',EXIST=GEXIST_NC4) - - IF (YACTION == 'READ') THEN - IF (.NOT.GEXIST_LFI .AND. .NOT.GEXIST_NC4) & - CALL PRINT_MSG(NVERB_FATAL,'IO','FMOPEN_ll',TRIM(TPFILE%CNAME)//': no .nc or .lfi file') - - SELECT CASE (TRIM(TPFILE%CFORMAT)) - CASE ('NETCDF4') - IF (.NOT.GEXIST_NC4 .AND. GEXIST_LFI) THEN - CALL PRINT_MSG(NVERB_WARNING,'IO','FMOPEN_ll',TRIM(TPFILE%CNAME)// & - ': .nc file does not exist but .lfi exists -> forced to LFI') - TPFILE%CFORMAT='LFI' - END IF - CASE ('LFI') - IF (.NOT.GEXIST_LFI .AND. GEXIST_NC4) THEN - CALL PRINT_MSG(NVERB_WARNING,'IO','FMOPEN_ll',TRIM(TPFILE%CNAME)// & - ': .lfi file does not exist but .nc exists -> forced to NETCDF4') - TPFILE%CFORMAT='NETCDF4' - END IF - CASE ('LFICDF4') - IF (GEXIST_NC4) THEN - CALL PRINT_MSG(NVERB_WARNING,'IO','FMOPEN_ll',TRIM(TPFILE%CNAME)// & - ': LFICDF4 format is not allowed in READ mode -> forced to NETCDF4') - TPFILE%CFORMAT='NETCDF4' - ELSE IF (GEXIST_LFI) THEN - CALL PRINT_MSG(NVERB_WARNING,'IO','FMOPEN_ll',TRIM(TPFILE%CNAME)// & - ': LFICDF4 format is not allowed in READ mode -> forced to LFI') - TPFILE%CFORMAT='LFI' - END IF - CASE DEFAULT - IF (GEXIST_NC4) THEN - CALL PRINT_MSG(NVERB_ERROR,'IO','FMOPEN_ll',TRIM(TPFILE%CNAME)// & - ': invalid fileformat (-> forced to NETCDF4 if no abort)') - TPFILE%CFORMAT='NETCDF4' - ELSE IF (GEXIST_LFI) THEN - CALL PRINT_MSG(NVERB_ERROR,'IO','FMOPEN_ll',TRIM(TPFILE%CNAME)// & - ': invalid fileformat (-> forced to LFI if no abort)') - TPFILE%CFORMAT='LFI' - END IF - END SELECT - END IF -END IF - -#if defined(MNH_IOCDF4) -IF (TPFILE%CFORMAT=='NETCDF4' .OR. TPFILE%CFORMAT=='LFICDF4') THEN - SELECT CASE (YACTION) - CASE('READ') - call io_open_file_nc4(tpfile) - CASE('WRITE') - call io_create_file_nc4(TPFILE, hprogram_orig=HPROGRAM_ORIG) - END SELECT -END IF -#endif - -IF (TPFILE%CFORMAT=='LFI' .OR. TPFILE%CFORMAT=='LFICDF4') THEN - SELECT CASE (YACTION) - CASE('READ') - call io_open_file_lfi(tpfile,iresp) - CASE('WRITE') - call io_create_file_lfi(tpfile,iresp) - END SELECT -END IF - -IF ( IRESP /= 0 ) THEN - WRITE(YRESP,"( I0 )") IRESP - CALL PRINT_MSG(NVERB_ERROR,'IO','FMOPEN_ll',TRIM(TPFILE%CNAME)//': exit with IRESP='//TRIM(YRESP)) -END IF - -KRESP=IRESP - -END SUBROUTINE FMOPEN_ll - - -recursive SUBROUTINE IO_FILE_CLOSE_ll(TPFILE,KRESP,HPROGRAM_ORIG) -! -USE MODD_CONF, ONLY: CPROGRAM -USE MODD_IO_ll, ONLY: NNULLUNIT, TFILEDATA - -use mode_io_file_lfi, only: io_close_file_lfi -#if defined(MNH_IOCDF4) -use mode_io_file_nc4, only: io_close_file_nc4 -use mode_io_write_nc4, only: io_write_coordvar_nc4 -#endif -USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME -! -TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE ! File structure -INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! Return code -CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: HPROGRAM_ORIG !To emulate a file coming from this program -! -character(len=256) :: yioerrmsg -INTEGER :: IRESP, JI -TYPE(TFILEDATA),POINTER :: TZFILE_DES -TYPE(TFILEDATA),POINTER :: TZFILE_IOZ -! -CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_FILE_CLOSE_ll','closing '//TRIM(TPFILE%CNAME)) -! -IF (.NOT.TPFILE%LOPENED) THEN - CALL PRINT_MSG(NVERB_ERROR,'IO','IO_FILE_CLOSE_ll','trying to close a file not opened: '//TRIM(TPFILE%CNAME)) - RETURN -ENDIF -! -IF (TPFILE%NOPEN_CURRENT>1) THEN - CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_FILE_CLOSE_ll',TRIM(TPFILE%CNAME)// & - ': decrementing NOPEN_CURRENT (still opened after this call)') - TPFILE%NOPEN_CURRENT = TPFILE%NOPEN_CURRENT - 1 - TPFILE%NCLOSE = TPFILE%NCLOSE + 1 - ! - DO JI = 1,TPFILE%NSUBFILES_IOZ - TZFILE_IOZ => TPFILE%TFILES_IOZ(JI)%TFILE - TZFILE_IOZ%NOPEN_CURRENT = TZFILE_IOZ%NOPEN_CURRENT - 1 - TZFILE_IOZ%NCLOSE = TZFILE_IOZ%NCLOSE + 1 - END DO - ! - RETURN -END IF -! -SELECT CASE(TPFILE%CTYPE) - CASE('CHEMINPUT','CHEMTAB','DES','GPS','METEO','NML','OUTPUTLISTING','SURFACE_DATA','TXT') - IF (TPFILE%LMASTER) THEN - IF (TPFILE%NLU/=-1 .AND. TPFILE%NLU/=NNULLUNIT) THEN - CLOSE(UNIT=TPFILE%NLU, STATUS='KEEP', IOSTAT=IRESP, IOMSG=yioerrmsg) - END IF - END IF - - !Warning and not error or fatal if close fails to allow continuation of execution - IF (IRESP/=0) CALL PRINT_MSG(NVERB_WARNING,'IO','IO_FILE_CLOSE_ll','Problem when closing ' & - //TRIM(TPFILE%CNAME)//': '//TRIM(YIOERRMSG)) - - TPFILE%NLU = -1 - - - !MesoNH files - !Remark: 'MNH' is more general than MNHBACKUP and could be in fact a MNHBACKUP file - CASE ('MNH', 'MNHBACKUP', 'MNHDIACHRONIC', 'MNHDIAG', 'MNHOUTPUT', 'PGD') - !Do not close (non-existing) '.des' file if OUTPUT - IF(TPFILE%CTYPE/='OUTPUT' .AND. CPROGRAM/='LFICDF') THEN - CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//'.des',TZFILE_DES,IRESP) - IF (IRESP/=0) CALL PRINT_MSG(NVERB_ERROR,'IO','IO_FILE_CLOSE_ll','file '//TRIM(TPFILE%CNAME)//'.des not in filelist') - CALL IO_FILE_CLOSE_ll(TZFILE_DES,KRESP=IRESP,HPROGRAM_ORIG=HPROGRAM_ORIG) - ENDIF - ! -#if defined(MNH_IOCDF4) - !Write coordinates variables in NetCDF file - IF (TPFILE%CMODE == 'WRITE' .AND. (TPFILE%CFORMAT=='NETCDF4' .OR. TPFILE%CFORMAT=='LFICDF4')) THEN - CALL IO_WRITE_COORDVAR_NC4(TPFILE,HPROGRAM_ORIG=HPROGRAM_ORIG) - END IF -#endif - - if (tpfile%lmaster) then - if (tpfile%cformat == 'LFI' .or. tpfile%cformat == 'LFICDF4') call io_close_file_lfi(tpfile,iresp) -#if defined(MNH_IOCDF4) - if (tpfile%cformat == 'NETCDF4' .or. tpfile%cformat == 'LFICDF4') call io_close_file_nc4(tpfile,iresp) -#endif - end if - ! - CALL IO_ADD2TRANSFER_LIST(TPFILE) - ! - SUBFILES: DO JI = 1,TPFILE%NSUBFILES_IOZ - TZFILE_IOZ => TPFILE%TFILES_IOZ(JI)%TFILE - IF (.NOT.TZFILE_IOZ%LOPENED) & - CALL PRINT_MSG(NVERB_ERROR,'IO','IO_FILE_CLOSE_ll','file '//TRIM(TZFILE_IOZ%CNAME)//' is not opened') - IF (TZFILE_IOZ%NOPEN_CURRENT/=1) & - CALL PRINT_MSG(NVERB_WARNING,'IO','IO_FILE_CLOSE_ll','file '//TRIM(TZFILE_IOZ%CNAME)//& - ' is currently opened 0 or several times (expected only 1)') - TZFILE_IOZ%LOPENED = .FALSE. - TZFILE_IOZ%NOPEN_CURRENT = 0 - TZFILE_IOZ%NCLOSE = TZFILE_IOZ%NCLOSE + 1 -#if defined(MNH_IOCDF4) - !Write coordinates variables in netCDF file - IF (TZFILE_IOZ%CMODE == 'WRITE' .AND. (TZFILE_IOZ%CFORMAT=='NETCDF4' .OR. TZFILE_IOZ%CFORMAT=='LFICDF4')) THEN - CALL IO_WRITE_COORDVAR_NC4(TZFILE_IOZ,HPROGRAM_ORIG=HPROGRAM_ORIG) - END IF -#endif - IF (TZFILE_IOZ%LMASTER) THEN - if (tzfile_ioz%cformat == 'LFI' .or. tzfile_ioz%cformat == 'LFICDF4') call io_close_file_lfi(tzfile_ioz,iresp) -#if defined(MNH_IOCDF4) - if (tzfile_ioz%cformat == 'NETCDF4' .or. tzfile_ioz%cformat == 'LFICDF4') call io_close_file_nc4(tzfile_ioz,iresp) -#endif - END IF - END DO SUBFILES - - - CASE DEFAULT - call print_msg(NVERB_FATAL,'IO','IO_FILE_CLOSE_ll','invalid type '//trim(tpfile%ctype)//' for file '//trim(tpfile%cname)) -END SELECT -! -TPFILE%LOPENED = .FALSE. -TPFILE%NOPEN_CURRENT = 0 -TPFILE%NCLOSE = TPFILE%NCLOSE + 1 -! -IF (PRESENT(KRESP)) KRESP=IRESP -! -END SUBROUTINE IO_FILE_CLOSE_ll - - -subroutine IO_ADD2TRANSFER_LIST(TPFILE) - -USE MODD_CONF, ONLY : CPROGRAM -USE MODD_IO_ll, ONLY : TFILEDATA - -USE MODI_SYSTEM_MNH - -TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE ! File structure - -CHARACTER(len=:),allocatable :: YFILEM ! name of the file -CHARACTER(len=:),allocatable :: YCPIO -CHARACTER(len=:),allocatable :: YTRANS -CHARACTER(LEN=100) :: YCOMMAND -INTEGER, SAVE :: ICPT = 0 - -YFILEM = TPFILE%CNAME - -CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_ADD2TRANSFER_LIST','called for '//TRIM(YFILEM)) - -IF (TPFILE%LMASTER .AND. CPROGRAM/='LFICDF') THEN - !! Write in pipe -#if defined(MNH_SX5) - YTRANS='nectransfer.x' -#else - YTRANS='xtransfer.x' -#endif - - SELECT CASE (TPFILE%NLFITYPE) - CASE(:-1,3:) - CALL PRINT_MSG(NVERB_ERROR,'IO','IO_ADD2TRANSFER_LIST',TRIM(YFILEM)//': incorrect NLFITYPE') - CASE(0) - YCPIO='NIL' - CASE(1) - YCPIO='MESONH' - CASE(2) - CALL PRINT_MSG(NVERB_INFO,'IO','IO_ADD2TRANSFER_LIST','file '//TRIM(YFILEM)//' not transferred') - END SELECT - - if (TPFILE%NLFITYPE==0 .or. TPFILE%NLFITYPE==1) then - ICPT=ICPT+1 - WRITE (YCOMMAND,'(A," ",A," ",A," >> OUTPUT_TRANSFER",I3.3," 2>&1 &")') YTRANS,YCPIO,TRIM(YFILEM),ICPT - CALL PRINT_MSG(NVERB_INFO,'IO','IO_ADD2TRANSFER_LIST','YCOMMAND='//TRIM(YCOMMAND)) - CALL SYSTEM_MNH(YCOMMAND) - end if -END IF - -end subroutine IO_ADD2TRANSFER_LIST - END MODULE MODE_FM diff --git a/src/LIB/SURCOUCHE/src/mode_io.f90 b/src/LIB/SURCOUCHE/src/mode_io.f90 index 85b9c1078..912ee2e51 100644 --- a/src/LIB/SURCOUCHE/src/mode_io.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io.f90 @@ -6,30 +6,7 @@ ! Author(s) ! D. Gazen ! Modifications: -! J. Escobar 19/08/2005: bug argument optinonel ACCESS --> YACCESS -! J. Escobar 22/05/2008: bug mode SPECIFIC in OPEN_ll -! J. Escobar 05/11/2009: allow JPMAX_UNIT=48 open files -! J. Escobar 18/10/2010: bug with PGI compiler on ADJUSTL -! P. Wautelet 04/02/2016: bug with DELIM='NONE' and GCC 5.2/5.3 -! D.Gazen April 2016: change error message -! P. Wautelet May 2016 : use netCDF Fortran module -! P. Wautelet July 2016 : added type OUTBAK -! P. Wautelet 05/2016-04/2018: new data structures and calls for I/O -! J. Pianezze 01/08/2016: add LOASIS flag -! P. Wautelet 13/12/2018: moved some operations to new mode_io_*_nc4 modules -! P. Wautelet 10/01/2019: bug correction: close correctly Z-split files -! P. Wautelet 10/01/2019: use NEWUNIT argument of OPEN -! + move IOFREEFLU and IONEWFLU to mode_io_file_lfi.f90 -! + move management of NNCID and NLFIFLU to the nc4 and lfi subroutines -! P. Wautelet 10/01/2019: bug: modify some metadata before open calls -! P. Wautelet 21/01/2019: add LIO_ALLOW_NO_BACKUP and LIO_NO_WRITE to modd_io_ll to allow -! to disable writes (for bench purposes) -! P. Wautelet 06/02/2019: simplify OPEN_ll and do somme assignments at a more logical place -! P. Wautelet 07/02/2019: remove OPARALLELIO argument from open and close files subroutines -! (nsubfiles_ioz is now determined in IO_FILE_ADD2LIST) -! P. Wautelet 14/02/2019: move UPCASE function to tools.f90 -! P. Wautelet 19/02/2019: simplification/restructuration/cleaning of open/close subroutines (TBCto be continued) -! P. Wautelet 27/02/2019: remove CLOSE_ll subroutine +! P. Wautelet 01/03/2019: move OPEN_ll to mode_io_file.f90 and SET_FMPACK_ll to here from mode_fm.f90 ! !----------------------------------------------------------------- MODULE MODE_IO_ll @@ -45,8 +22,9 @@ MODULE MODE_IO_ll LOGICAL,SAVE :: GCONFIO = .FALSE. ! Turn TRUE when SET_CONFIO_ll is called. - PUBLIC INITIO_ll,OPEN_ll - PUBLIC SET_CONFIO_ll,GCONFIO + public :: GCONFIO + public :: INITIO_ll, SET_CONFIO_ll + public :: SET_FMPACK_ll CONTAINS @@ -132,354 +110,20 @@ CONTAINS END SUBROUTINE INITIO_ll - SUBROUTINE OPEN_ll(TPFILE, KRESP, HMODE, HSTATUS, HPOSITION, HDELIM, HPROGRAM_ORIG) +SUBROUTINE SET_FMPACK_ll(O1D,O2D,OPACK) +USE MODD_IO_ll, ONLY: LPACK, L1D, L2D +USE MODD_VAR_ll, ONLY: IP - USE MODD_IO_ll -#if defined(MNH_IOCDF4) - use mode_io_file_nc4, only: io_create_file_nc4, io_open_file_nc4 -#endif - use mode_io_file_lfi, only: io_create_file_lfi, io_open_file_lfi - USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_ADD2LIST, IO_FILE_FIND_BYNAME - use mode_io_tools, only: io_rank - use mode_tools, only: upcase - - TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE - INTEGER, INTENT(OUT) :: KRESP - CHARACTER(len=*), OPTIONAL, INTENT(IN) :: HMODE - CHARACTER(len=*), OPTIONAL, INTENT(IN) :: HSTATUS - CHARACTER(len=*), OPTIONAL, INTENT(IN) :: HPOSITION - CHARACTER(len=*), OPTIONAL, INTENT(IN) :: HDELIM - CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: HPROGRAM_ORIG !To emulate a file coming from this program - ! - ! local var - ! - INTEGER, PARAMETER :: RECL_DEF = 10000 - ! - CHARACTER(len=5) :: YFILE - CHARACTER(len=20) :: YSTATUS - CHARACTER(len=20) :: YPOSITION - CHARACTER(len=20) :: YDELIM - CHARACTER(len=20) :: YACTION - CHARACTER(len=20) :: YMODE - CHARACTER(LEN=256) :: YIOERRMSG - CHARACTER(LEN=:),ALLOCATABLE :: YPREFILENAME !To store the directory + filename - INTEGER :: IFILE, IRANK_PROCIO - INTEGER :: YRECL - INTEGER :: IOS, IRESP - TYPE(TFILEDATA),POINTER :: TZSPLITFILE - - CALL PRINT_MSG(NVERB_DEBUG,'IO','OPEN_ll','opening '//TRIM(TPFILE%CNAME)//' for '//TRIM(TPFILE%CMODE)) - - IOS = 0 - - IF (PRESENT(HMODE)) THEN - YMODE = HMODE - YMODE = UPCASE(TRIM(ADJUSTL(YMODE))) - ELSE - YMODE = 'GLOBAL' ! Default Mode - END IF - - YACTION = TPFILE%CMODE - YACTION = UPCASE(TRIM(ADJUSTL(YACTION))) - IF (YACTION /= "READ" .AND. YACTION /= "WRITE") THEN - KRESP = 99 - TPFILE%NLU = -1 - CALL PRINT_MSG(NVERB_ERROR,'IO','OPEN_ll','action='//TRIM(YACTION)//' not supported') - RETURN - END IF - - IF (.NOT. ANY(YMODE == (/'GLOBAL ','SPECIFIC ', 'IO_ZSPLIT '/))) THEN - KRESP = 99 - TPFILE%NLU = -1 - CALL PRINT_MSG(NVERB_ERROR,'IO','OPEN_ll','ymode='//TRIM(YMODE)//' not supported') - RETURN - END IF - - IF (PRESENT(HSTATUS)) THEN - YSTATUS=HSTATUS - ELSE - YSTATUS='UNKNOWN' - ENDIF - - IF (TPFILE%NRECL == -1) THEN - YRECL = RECL_DEF - ELSE - YRECL = TPFILE%NRECL - END IF - - IF (PRESENT(HPOSITION)) THEN - YPOSITION=HPOSITION - ELSE - YPOSITION='ASIS' - ENDIF - IF (PRESENT(HDELIM)) THEN - YDELIM=HDELIM - ELSE - YDELIM='NONE' - ENDIF - - IF (ALLOCATED(TPFILE%CDIRNAME)) THEN - IF(LEN_TRIM(TPFILE%CDIRNAME)>0) THEN - YPREFILENAME = TRIM(TPFILE%CDIRNAME)//'/'//TRIM(TPFILE%CNAME) - ELSE - YPREFILENAME = TRIM(TPFILE%CNAME) - END IF - ELSE - YPREFILENAME = TRIM(TPFILE%CNAME) - END IF - - SELECT CASE(YMODE) - - CASE('GLOBAL') - IF (YACTION == 'READ') THEN - TPFILE%NMASTER_RANK = -1 - TPFILE%LMASTER = .TRUE. !Every process read the file - TPFILE%LMULTIMASTERS = .TRUE. - ELSE - IF (TPFILE%CTYPE=='OUTPUTLISTING') THEN - IF (LVERB_ALLPRC) THEN - TPFILE%NMASTER_RANK = -1 - TPFILE%LMASTER = .TRUE. !Every process may write in the file - TPFILE%LMULTIMASTERS = .TRUE. - ELSE - TPFILE%NMASTER_RANK = ISIOP - TPFILE%LMASTER = (ISP == ISIOP) - TPFILE%LMULTIMASTERS = .FALSE. - END IF - ELSE - TPFILE%NMASTER_RANK = ISIOP - TPFILE%LMASTER = (ISP == ISIOP) - TPFILE%LMULTIMASTERS = .FALSE. - END IF - END IF - TPFILE%NSUBFILES_IOZ = 0 - - IF (TPFILE%LMASTER) THEN - !! I/O processor case - !JUAN : 31/03/2000 modif pour acces direct - IF (TPFILE%CACCESS=='STREAM') THEN - OPEN(NEWUNIT=TPFILE%NLU, & - FILE=TRIM(YPREFILENAME),& - STATUS=YSTATUS, & - ACCESS=TPFILE%CACCESS, & - IOSTAT=IOS, & - IOMSG=YIOERRMSG, & - FORM=TPFILE%CFORM, & - ACTION=YACTION) - ELSEIF (TPFILE%CACCESS=='DIRECT') THEN - OPEN(NEWUNIT=TPFILE%NLU, & - FILE=TRIM(YPREFILENAME),& - STATUS=YSTATUS, & - ACCESS=TPFILE%CACCESS, & - IOSTAT=IOS, & - IOMSG=YIOERRMSG, & - FORM=TPFILE%CFORM, & - RECL=YRECL, & - ACTION=YACTION) - ELSE - IF (TPFILE%CFORM=="FORMATTED") THEN - IF (YACTION=='READ') THEN - OPEN(NEWUNIT=TPFILE%NLU, & - FILE=TRIM(YPREFILENAME),& - STATUS=YSTATUS, & - ACCESS=TPFILE%CACCESS, & - IOSTAT=IOS, & - IOMSG=YIOERRMSG, & - FORM=TPFILE%CFORM, & - RECL=YRECL, & - POSITION=YPOSITION, & - ACTION=YACTION) - !DELIM=YDELIM, & !Philippe: commented because bug with GCC 5.X - ELSE - OPEN(NEWUNIT=TPFILE%NLU, & - FILE=TRIM(YPREFILENAME),& - STATUS=YSTATUS, & - ACCESS=TPFILE%CACCESS, & - IOSTAT=IOS, & - IOMSG=YIOERRMSG, & - FORM=TPFILE%CFORM, & - RECL=YRECL, & - POSITION=YPOSITION, & - ACTION=YACTION, & - DELIM=YDELIM) - ENDIF - ELSE - OPEN(NEWUNIT=TPFILE%NLU, & - FILE=TRIM(YPREFILENAME),& - STATUS=YSTATUS, & - ACCESS=TPFILE%CACCESS, & - IOSTAT=IOS, & - IOMSG=YIOERRMSG, & - FORM=TPFILE%CFORM, & - RECL=YRECL, & - POSITION=YPOSITION, & - ACTION=YACTION) - ENDIF - ENDIF - - IF (IOS/=0) CALL PRINT_MSG(NVERB_FATAL,'IO','OPEN_ll','Problem when opening '//TRIM(YPREFILENAME)//': '//TRIM(YIOERRMSG)) - ELSE - !! NON I/O processors case - IOS = 0 - TPFILE%NLU = NNULLUNIT - END IF - - - CASE('SPECIFIC') - TPFILE%NMASTER_RANK = -1 - TPFILE%LMASTER = .TRUE. !Every process use the file - TPFILE%LMULTIMASTERS = .TRUE. - TPFILE%NSUBFILES_IOZ = 0 - - IF (TPFILE%CACCESS=='DIRECT') THEN - OPEN(NEWUNIT=TPFILE%NLU, & - FILE=TRIM(YPREFILENAME)//SUFFIX(".P"), & - STATUS=YSTATUS, & - ACCESS=TPFILE%CACCESS, & - IOSTAT=IOS, & - IOMSG=YIOERRMSG, & - FORM=TPFILE%CFORM, & - RECL=YRECL, & - ACTION=YACTION) - ELSE - IF (YACTION=='READ') THEN - OPEN(NEWUNIT=TPFILE%NLU, & - FILE=TRIM(YPREFILENAME)//SUFFIX(".P"), & - STATUS=YSTATUS, & - ACCESS=TPFILE%CACCESS, & - IOSTAT=IOS, & - IOMSG=YIOERRMSG, & - FORM=TPFILE%CFORM, & - RECL=YRECL, & - POSITION=YPOSITION, & - ACTION=YACTION) - !DELIM=YDELIM, & !Philippe: commented because bug with GCC 5.X - ELSE - OPEN(NEWUNIT=TPFILE%NLU, & - FILE=TRIM(YPREFILENAME)//SUFFIX(".P"), & - STATUS=YSTATUS, & - ACCESS=TPFILE%CACCESS, & - IOSTAT=IOS, & - IOMSG=YIOERRMSG, & - FORM=TPFILE%CFORM, & - RECL=YRECL, & - POSITION=YPOSITION, & - ACTION=YACTION, & - DELIM=YDELIM) - ENDIF - ENDIF - - IF (IOS/=0) CALL PRINT_MSG(NVERB_FATAL,'IO','OPEN_ll','Problem when opening '//TRIM(YPREFILENAME)//': '//TRIM(YIOERRMSG)) - - - - CASE('IO_ZSPLIT') - TPFILE%NMASTER_RANK = ISIOP - TPFILE%LMASTER = (ISP == ISIOP) - TPFILE%LMULTIMASTERS = .FALSE. - -#if defined(MNH_IOCDF4) - IF (TPFILE%LMASTER .AND. (TPFILE%CFORMAT=='LFI' .OR. TPFILE%CFORMAT=='LFICDF4') ) THEN -#else - IF (TPFILE%LMASTER) THEN -#endif - ELSE - !! NON I/O processors OR netCDF read case - IOS = 0 - END IF - - IF (TPFILE%NSUBFILES_IOZ > 0) THEN - IF (.NOT.ALLOCATED(TPFILE%TFILES_IOZ)) THEN - ALLOCATE(TPFILE%TFILES_IOZ(TPFILE%NSUBFILES_IOZ)) - ELSE IF ( SIZE(TPFILE%TFILES_IOZ) /= TPFILE%NSUBFILES_IOZ ) THEN - CALL PRINT_MSG(NVERB_FATAL,'IO','OPEN_ll','SIZE(TPFILE%TFILES_IOZ) /= TPFILE%NSUBFILES_IOZ for '//TRIM(TPFILE%CNAME)) - END IF - DO IFILE=1,TPFILE%NSUBFILES_IOZ - IRANK_PROCIO = 1 + IO_RANK(IFILE-1,ISNPROC,TPFILE%NSUBFILES_IOZ) - WRITE(YFILE ,'(".Z",i3.3)') IFILE - - CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//TRIM(YFILE),TZSPLITFILE,IRESP) - - IF (IRESP/=0) THEN !File not yet in filelist => add it (nothing to do if already in list) - IF (ALLOCATED(TPFILE%CDIRNAME)) THEN - CALL IO_FILE_ADD2LIST(TZSPLITFILE,TRIM(TPFILE%CNAME)//TRIM(YFILE),TPFILE%CTYPE,TPFILE%CMODE, & - HDIRNAME=TPFILE%CDIRNAME, & - KLFINPRAR=TPFILE%NLFINPRAR,KLFITYPE=TPFILE%NLFITYPE,KLFIVERB=TPFILE%NLFIVERB, & - HFORMAT=TPFILE%CFORMAT) - ELSE - CALL IO_FILE_ADD2LIST(TZSPLITFILE,TRIM(TPFILE%CNAME)//TRIM(YFILE),TPFILE%CTYPE,TPFILE%CMODE, & - KLFINPRAR=TPFILE%NLFINPRAR,KLFITYPE=TPFILE%NLFITYPE,KLFIVERB=TPFILE%NLFIVERB, & - HFORMAT=TPFILE%CFORMAT) - END IF - END IF - - IF (ALLOCATED(TPFILE%CDIRNAME)) THEN - IF (LEN_TRIM(TZSPLITFILE%CDIRNAME)>0) THEN - YPREFILENAME = TRIM(TZSPLITFILE%CDIRNAME)//'/'//TRIM(TZSPLITFILE%CNAME) - ELSE - YPREFILENAME = TRIM(TZSPLITFILE%CNAME) - END IF - ELSE - YPREFILENAME = TRIM(TZSPLITFILE%CNAME) - END IF - - TPFILE%TFILES_IOZ(IFILE)%TFILE => TZSPLITFILE - !Done outside of the previous IF to prevent problems with .OUT files - TZSPLITFILE%NMPICOMM = NMNH_COMM_WORLD - TZSPLITFILE%NMASTER_RANK = IRANK_PROCIO - TZSPLITFILE%LMASTER = (ISP == IRANK_PROCIO) - TZSPLITFILE%LMULTIMASTERS = .FALSE. - TZSPLITFILE%NSUBFILES_IOZ = 0 - - ! Must be done BEFORE the call to io_open_file_* because we need to read things in these subroutines - TZSPLITFILE%LOPENED = .TRUE. - TZSPLITFILE%NOPEN = TZSPLITFILE%NOPEN + 1 - TZSPLITFILE%NOPEN_CURRENT = TZSPLITFILE%NOPEN_CURRENT + 1 - -#if defined(MNH_IOCDF4) - IF (TZSPLITFILE%CFORMAT=='NETCDF4' .OR. TZSPLITFILE%CFORMAT=='LFICDF4') THEN - IF (YACTION == 'READ') THEN - ! Open netCDF File for reading - call io_open_file_nc4(tzsplitfile) - IOS = 0 - END IF - - IF (YACTION == 'WRITE') THEN - ! Create netCDF File for writing - call io_create_file_nc4(TZSPLITFILE, hprogram_orig=HPROGRAM_ORIG) - IOS = 0 - END IF - END IF -#endif - IF (TZSPLITFILE%CFORMAT=='LFI' .OR. TZSPLITFILE%CFORMAT=='LFICDF4') THEN - SELECT CASE (YACTION) - CASE('READ') - call io_open_file_lfi(tzsplitfile,iresp) - CASE('WRITE') - call io_create_file_lfi(tzsplitfile,iresp) - END SELECT - ENDIF - ! - ENDDO - END IF - - - END SELECT - - TPFILE%NMPICOMM = NMNH_COMM_WORLD - - KRESP = IOS - - CONTAINS - FUNCTION SUFFIX(HEXT) +IMPLICIT NONE - CHARACTER(len=*) :: HEXT - CHARACTER(len=LEN(HEXT)+3) :: SUFFIX +LOGICAL, INTENT(IN) :: O1D,O2D,OPACK - WRITE(SUFFIX,'(A,i3.3)') TRIM(HEXT), ISP +LPACK = OPACK +L1D = O1D +L2D = O2D - END FUNCTION SUFFIX +IF ( IP == 1 ) PRINT *,'INIT L1D,L2D,LPACK = ',L1D,L2D,LPACK - END SUBROUTINE OPEN_ll +END SUBROUTINE SET_FMPACK_ll END MODULE MODE_IO_ll diff --git a/src/LIB/SURCOUCHE/src/mode_io_file.f90 b/src/LIB/SURCOUCHE/src/mode_io_file.f90 new file mode 100644 index 000000000..fd980c03c --- /dev/null +++ b/src/LIB/SURCOUCHE/src/mode_io_file.f90 @@ -0,0 +1,787 @@ +!MNH_LIC Copyright 1994-2019 CNRS, Meteo-France and Universite Paul Sabatier +!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence +!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt +!MNH_LIC for details. version 1. +!----------------------------------------------------------------- +! Author(s) +! D. Gazen, P. Wautelet +! Modifications: +! J. Escobar 19/08/2005: bug argument optinonel ACCESS --> YACCESS +! J. Escobar 22/05/2008: bug mode SPECIFIC in OPEN_ll +! J. Escobar 05/11/2009: allow JPMAX_UNIT=48 open files +! J. Escobar 18/10/2010: bug with PGI compiler on ADJUSTL +! P. Wautelet 04/02/2016: bug with DELIM='NONE' and GCC 5.2/5.3 +! D. Gazen April 2016: change error message +! P. Wautelet May 2016 : use netCDF Fortran module +! P. Wautelet July 2016 : added type OUTBAK +! P. Wautelet 05/2016-04/2018: new data structures and calls for I/O +! J. Pianezze 01/08/2016: add LOASIS flag +! P. Wautelet 29/10/2018: better detection of older MNH version numbers +! P. Wautelet 13/12/2018: moved some operations to new mode_io_*_nc4 modules +! P. Wautelet 10/01/2019: bug correction: close correctly Z-split files +! P. Wautelet 10/01/2019: use NEWUNIT argument of OPEN +! + move IOFREEFLU and IONEWFLU to mode_io_file_lfi.f90 +! + move management of NNCID and NLFIFLU to the nc4 and lfi subroutines +! P. Wautelet 10/01/2019: bug: modify some metadata before open calls +! P. Wautelet 21/01/2019: add LIO_ALLOW_NO_BACKUP and LIO_NO_WRITE to modd_io_ll to allow +! to disable writes (for bench purposes) +! P. Wautelet 06/02/2019: simplify OPEN_ll and do somme assignments at a more logical place +! P. Wautelet 07/02/2019: remove OPARALLELIO argument from open and close files subroutines +! (nsubfiles_ioz is now determined in IO_FILE_ADD2LIST) +! P. Wautelet 07/02/2019: force TYPE to a known value for IO_FILE_ADD2LIST +! P. Wautelet 14/02/2019: move UPCASE function to tools.f90 +! P. Wautelet 19/02/2019: simplification/restructuration/cleaning of open/close subroutines (TBCto be continued) +! P. Wautelet 27/02/2019: use recursive calls to open/close DES files +! P. Wautelet 27/02/2019: remove CLOSE_ll subroutine +! P. Wautelet 01/03/2019: move open/close subroutines to mode_io_file.f90 +! +!----------------------------------------------------------------- +module mode_io_file + +use modd_io_ll, only: tfiledata + +use mode_msg + +implicit none + +private + +public :: IO_File_close_ll, IO_File_open_ll + +interface IO_File_close_ll + module procedure IO_File_close +end interface + +interface IO_File_open_ll + module procedure IO_File_open +end interface + + +contains + + +recursive SUBROUTINE IO_File_open(TPFILE,KRESP,HPOSITION,HSTATUS,HPROGRAM_ORIG) +! +USE MODD_CONF, ONLY: CPROGRAM +USE MODD_IO_ll, ONLY: LIO_NO_WRITE +! +USE MODE_IO_ll, ONLY: GCONFIO +USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_ADD2LIST, IO_FILE_FIND_BYNAME +! +TYPE(TFILEDATA), POINTER, INTENT(INOUT) :: TPFILE ! File structure +INTEGER, INTENT(OUT), OPTIONAL :: KRESP ! Return code +CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: HPOSITION +CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: HSTATUS +CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: HPROGRAM_ORIG !To emulate a file coming from this program +! +INTEGER :: IRESP +TYPE(TFILEDATA), POINTER :: TZFILE_DES +TYPE(TFILEDATA), POINTER :: TZFILE_DUMMY +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_File_open','opening '//TRIM(TPFILE%CNAME)//' for '//TRIM(TPFILE%CMODE)// & + ' (filetype='//TRIM(TPFILE%CTYPE)//')') +! +IF (.NOT.ASSOCIATED(TPFILE)) CALL PRINT_MSG(NVERB_FATAL,'IO','IO_File_open','TPFILE is not associated') +! +IF ( LIO_NO_WRITE .AND. TPFILE%CMODE == 'WRITE' .AND. TPFILE%CTYPE/='OUTPUTLISTING') THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_File_open','opening file '//TRIM(TPFILE%CNAME)// & + ' in write mode but LIO_NO_WRITE is set') +END IF +! +TZFILE_DES => NULL() +TZFILE_DUMMY => NULL() +! +TPFILE%NOPEN = TPFILE%NOPEN + 1 +TPFILE%NOPEN_CURRENT = TPFILE%NOPEN_CURRENT + 1 +! +IF (TPFILE%LOPENED) THEN + CALL PRINT_MSG(NVERB_INFO,'IO','IO_File_open','file '//TRIM(TPFILE%CNAME)//' is already in open state') + RETURN +END IF +! +TPFILE%LOPENED = .TRUE. +! +!Check if file is in filelist +CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME),TZFILE_DUMMY,IRESP) +IF (IRESP/=0) CALL PRINT_MSG(NVERB_ERROR,'IO','IO_File_open','file '//TRIM(TPFILE%CNAME)//' not in filelist') +! +SELECT CASE(TPFILE%CTYPE) + !Chemistry input files + CASE('CHEMINPUT') + CALL OPEN_ll(TPFILE,IRESP,HPOSITION='REWIND',HSTATUS='OLD',HMODE='GLOBAL') + + + !Chemistry tabulation files + CASE('CHEMTAB') + CALL OPEN_ll(TPFILE,IRESP,HMODE='GLOBAL') + + + !DES files + CASE('DES') + CALL OPEN_ll(TPFILE,IRESP,HDELIM='QUOTE') + + + !GPS files + CASE('GPS') + CALL OPEN_ll(TPFILE,IRESP,HMODE='SPECIFIC') + + + !Meteo files + CASE('METEO') + CALL OPEN_ll(TPFILE,IRESP,HMODE='GLOBAL') + + + !Namelist files + CASE('NML') + CALL OPEN_ll(TPFILE,IRESP,HDELIM='QUOTE',HMODE='GLOBAL') + + + !OUTPUTLISTING files + CASE('OUTPUTLISTING') + CALL OPEN_ll(TPFILE,IRESP,HMODE='GLOBAL') + + + !SURFACE_DATA files + CASE('SURFACE_DATA') + CALL OPEN_ll(TPFILE,IRESP,HMODE='GLOBAL') + + + !Text files + CASE('TXT') + CALL OPEN_ll(TPFILE,IRESP,HPOSITION=HPOSITION,HSTATUS=HSTATUS,HMODE='GLOBAL') + + + !MesoNH files + !Remark: 'MNH' is more general than MNHBACKUP and could be in fact a MNHBACKUP file + CASE ('MNH', 'MNHBACKUP', 'MNHDIACHRONIC', 'MNHDIAG', 'MNHOUTPUT', 'PGD') + if (.not.GCONFIO) CALL PRINT_MSG(NVERB_FATAL,'IO','IO_File_open','SET_CONFIO_ll must be called before IO_File_open') + !Do not open '.des' file if OUTPUT + IF(TPFILE%CTYPE/='MNHOUTPUT' .AND. CPROGRAM/='LFICDF') THEN + !OOLD=T because the file may already be in the list + CALL IO_FILE_ADD2LIST(TZFILE_DES,TRIM(TPFILE%CNAME)//'.des','DES',TPFILE%CMODE,TPDATAFILE=TPFILE,OOLD=.TRUE.) + CALL IO_File_open(TZFILE_DES,HPROGRAM_ORIG=HPROGRAM_ORIG) + ENDIF + + CALL OPEN_ll(TPFILE,IRESP,HMODE='IO_ZSPLIT',HPROGRAM_ORIG=HPROGRAM_ORIG) + + call IO_File_check_format_exist( tpfile ) + + call IO_File_open_format( tpfile ) + + + CASE DEFAULT + call print_msg(NVERB_FATAL,'IO','IO_File_open','invalid type '//trim(tpfile%ctype)//' for file '//trim(tpfile%cname)) +END SELECT +! +IF (PRESENT(KRESP)) KRESP = IRESP +! +END SUBROUTINE IO_File_open + + +SUBROUTINE OPEN_ll(TPFILE, KRESP, HMODE, HSTATUS, HPOSITION, HDELIM, HPROGRAM_ORIG) + + use modd_io_ll, only: ISNPROC, ISP, LVERB_ALLPRC, ISIOP, NNULLUNIT + use modd_var_ll, only : nmnh_comm_world + +#if defined(MNH_IOCDF4) + use mode_io_file_nc4, only: io_create_file_nc4, io_open_file_nc4 +#endif + use mode_io_file_lfi, only: io_create_file_lfi, io_open_file_lfi + USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_ADD2LIST, IO_FILE_FIND_BYNAME + use mode_io_tools, only: io_rank + use mode_tools, only: upcase + + TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE + INTEGER, INTENT(OUT) :: KRESP + CHARACTER(len=*), OPTIONAL, INTENT(IN) :: HMODE + CHARACTER(len=*), OPTIONAL, INTENT(IN) :: HSTATUS + CHARACTER(len=*), OPTIONAL, INTENT(IN) :: HPOSITION + CHARACTER(len=*), OPTIONAL, INTENT(IN) :: HDELIM + CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: HPROGRAM_ORIG !To emulate a file coming from this program + ! + ! local var + ! + INTEGER, PARAMETER :: RECL_DEF = 10000 + ! + CHARACTER(len=5) :: YFILE + CHARACTER(len=20) :: YSTATUS + CHARACTER(len=20) :: YPOSITION + CHARACTER(len=20) :: YDELIM + CHARACTER(len=20) :: YACTION + CHARACTER(len=20) :: YMODE + CHARACTER(LEN=256) :: YIOERRMSG + CHARACTER(LEN=:),ALLOCATABLE :: YPREFILENAME !To store the directory + filename + INTEGER :: IFILE, IRANK_PROCIO + INTEGER :: YRECL + INTEGER :: IOS, IRESP + TYPE(TFILEDATA),POINTER :: TZSPLITFILE + + CALL PRINT_MSG(NVERB_DEBUG,'IO','OPEN_ll','opening '//TRIM(TPFILE%CNAME)//' for '//TRIM(TPFILE%CMODE)) + + IOS = 0 + + IF (PRESENT(HMODE)) THEN + YMODE = HMODE + YMODE = UPCASE(TRIM(ADJUSTL(YMODE))) + ELSE + YMODE = 'GLOBAL' ! Default Mode + END IF + + YACTION = TPFILE%CMODE + YACTION = UPCASE(TRIM(ADJUSTL(YACTION))) + IF (YACTION /= "READ" .AND. YACTION /= "WRITE") THEN + KRESP = 99 + TPFILE%NLU = -1 + CALL PRINT_MSG(NVERB_ERROR,'IO','OPEN_ll','action='//TRIM(YACTION)//' not supported') + RETURN + END IF + + IF (.NOT. ANY(YMODE == (/'GLOBAL ','SPECIFIC ', 'IO_ZSPLIT '/))) THEN + KRESP = 99 + TPFILE%NLU = -1 + CALL PRINT_MSG(NVERB_ERROR,'IO','OPEN_ll','ymode='//TRIM(YMODE)//' not supported') + RETURN + END IF + + IF (PRESENT(HSTATUS)) THEN + YSTATUS=HSTATUS + ELSE + YSTATUS='UNKNOWN' + ENDIF + + IF (TPFILE%NRECL == -1) THEN + YRECL = RECL_DEF + ELSE + YRECL = TPFILE%NRECL + END IF + + IF (PRESENT(HPOSITION)) THEN + YPOSITION=HPOSITION + ELSE + YPOSITION='ASIS' + ENDIF + IF (PRESENT(HDELIM)) THEN + YDELIM=HDELIM + ELSE + YDELIM='NONE' + ENDIF + + IF (ALLOCATED(TPFILE%CDIRNAME)) THEN + IF(LEN_TRIM(TPFILE%CDIRNAME)>0) THEN + YPREFILENAME = TRIM(TPFILE%CDIRNAME)//'/'//TRIM(TPFILE%CNAME) + ELSE + YPREFILENAME = TRIM(TPFILE%CNAME) + END IF + ELSE + YPREFILENAME = TRIM(TPFILE%CNAME) + END IF + + SELECT CASE(YMODE) + + CASE('GLOBAL') + IF (YACTION == 'READ') THEN + TPFILE%NMASTER_RANK = -1 + TPFILE%LMASTER = .TRUE. !Every process read the file + TPFILE%LMULTIMASTERS = .TRUE. + ELSE + IF (TPFILE%CTYPE=='OUTPUTLISTING') THEN + IF (LVERB_ALLPRC) THEN + TPFILE%NMASTER_RANK = -1 + TPFILE%LMASTER = .TRUE. !Every process may write in the file + TPFILE%LMULTIMASTERS = .TRUE. + ELSE + TPFILE%NMASTER_RANK = ISIOP + TPFILE%LMASTER = (ISP == ISIOP) + TPFILE%LMULTIMASTERS = .FALSE. + END IF + ELSE + TPFILE%NMASTER_RANK = ISIOP + TPFILE%LMASTER = (ISP == ISIOP) + TPFILE%LMULTIMASTERS = .FALSE. + END IF + END IF + TPFILE%NSUBFILES_IOZ = 0 + + IF (TPFILE%LMASTER) THEN + !! I/O processor case + !JUAN : 31/03/2000 modif pour acces direct + IF (TPFILE%CACCESS=='STREAM') THEN + OPEN(NEWUNIT=TPFILE%NLU, & + FILE=TRIM(YPREFILENAME),& + STATUS=YSTATUS, & + ACCESS=TPFILE%CACCESS, & + IOSTAT=IOS, & + IOMSG=YIOERRMSG, & + FORM=TPFILE%CFORM, & + ACTION=YACTION) + ELSEIF (TPFILE%CACCESS=='DIRECT') THEN + OPEN(NEWUNIT=TPFILE%NLU, & + FILE=TRIM(YPREFILENAME),& + STATUS=YSTATUS, & + ACCESS=TPFILE%CACCESS, & + IOSTAT=IOS, & + IOMSG=YIOERRMSG, & + FORM=TPFILE%CFORM, & + RECL=YRECL, & + ACTION=YACTION) + ELSE + IF (TPFILE%CFORM=="FORMATTED") THEN + IF (YACTION=='READ') THEN + OPEN(NEWUNIT=TPFILE%NLU, & + FILE=TRIM(YPREFILENAME),& + STATUS=YSTATUS, & + ACCESS=TPFILE%CACCESS, & + IOSTAT=IOS, & + IOMSG=YIOERRMSG, & + FORM=TPFILE%CFORM, & + RECL=YRECL, & + POSITION=YPOSITION, & + ACTION=YACTION) + !DELIM=YDELIM, & !Philippe: commented because bug with GCC 5.X + ELSE + OPEN(NEWUNIT=TPFILE%NLU, & + FILE=TRIM(YPREFILENAME),& + STATUS=YSTATUS, & + ACCESS=TPFILE%CACCESS, & + IOSTAT=IOS, & + IOMSG=YIOERRMSG, & + FORM=TPFILE%CFORM, & + RECL=YRECL, & + POSITION=YPOSITION, & + ACTION=YACTION, & + DELIM=YDELIM) + ENDIF + ELSE + OPEN(NEWUNIT=TPFILE%NLU, & + FILE=TRIM(YPREFILENAME),& + STATUS=YSTATUS, & + ACCESS=TPFILE%CACCESS, & + IOSTAT=IOS, & + IOMSG=YIOERRMSG, & + FORM=TPFILE%CFORM, & + RECL=YRECL, & + POSITION=YPOSITION, & + ACTION=YACTION) + ENDIF + ENDIF + + IF (IOS/=0) CALL PRINT_MSG(NVERB_FATAL,'IO','OPEN_ll','Problem when opening '//TRIM(YPREFILENAME)//': '//TRIM(YIOERRMSG)) + ELSE + !! NON I/O processors case + IOS = 0 + TPFILE%NLU = NNULLUNIT + END IF + + + CASE('SPECIFIC') + TPFILE%NMASTER_RANK = -1 + TPFILE%LMASTER = .TRUE. !Every process use the file + TPFILE%LMULTIMASTERS = .TRUE. + TPFILE%NSUBFILES_IOZ = 0 + + IF (TPFILE%CACCESS=='DIRECT') THEN + OPEN(NEWUNIT=TPFILE%NLU, & + FILE=TRIM(YPREFILENAME)//SUFFIX(".P"), & + STATUS=YSTATUS, & + ACCESS=TPFILE%CACCESS, & + IOSTAT=IOS, & + IOMSG=YIOERRMSG, & + FORM=TPFILE%CFORM, & + RECL=YRECL, & + ACTION=YACTION) + ELSE + IF (YACTION=='READ') THEN + OPEN(NEWUNIT=TPFILE%NLU, & + FILE=TRIM(YPREFILENAME)//SUFFIX(".P"), & + STATUS=YSTATUS, & + ACCESS=TPFILE%CACCESS, & + IOSTAT=IOS, & + IOMSG=YIOERRMSG, & + FORM=TPFILE%CFORM, & + RECL=YRECL, & + POSITION=YPOSITION, & + ACTION=YACTION) + !DELIM=YDELIM, & !Philippe: commented because bug with GCC 5.X + ELSE + OPEN(NEWUNIT=TPFILE%NLU, & + FILE=TRIM(YPREFILENAME)//SUFFIX(".P"), & + STATUS=YSTATUS, & + ACCESS=TPFILE%CACCESS, & + IOSTAT=IOS, & + IOMSG=YIOERRMSG, & + FORM=TPFILE%CFORM, & + RECL=YRECL, & + POSITION=YPOSITION, & + ACTION=YACTION, & + DELIM=YDELIM) + ENDIF + ENDIF + + IF (IOS/=0) CALL PRINT_MSG(NVERB_FATAL,'IO','OPEN_ll','Problem when opening '//TRIM(YPREFILENAME)//': '//TRIM(YIOERRMSG)) + + + + CASE('IO_ZSPLIT') + TPFILE%NMASTER_RANK = ISIOP + TPFILE%LMASTER = (ISP == ISIOP) + TPFILE%LMULTIMASTERS = .FALSE. + + IF (TPFILE%NSUBFILES_IOZ > 0) THEN + IF (.NOT.ALLOCATED(TPFILE%TFILES_IOZ)) THEN + ALLOCATE(TPFILE%TFILES_IOZ(TPFILE%NSUBFILES_IOZ)) + ELSE IF ( SIZE(TPFILE%TFILES_IOZ) /= TPFILE%NSUBFILES_IOZ ) THEN + CALL PRINT_MSG(NVERB_FATAL,'IO','OPEN_ll','SIZE(TPFILE%TFILES_IOZ) /= TPFILE%NSUBFILES_IOZ for '//TRIM(TPFILE%CNAME)) + END IF + DO IFILE=1,TPFILE%NSUBFILES_IOZ + IRANK_PROCIO = 1 + IO_RANK(IFILE-1,ISNPROC,TPFILE%NSUBFILES_IOZ) + WRITE(YFILE ,'(".Z",i3.3)') IFILE + + CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//TRIM(YFILE),TZSPLITFILE,IRESP) + + IF (IRESP/=0) THEN !File not yet in filelist => add it (nothing to do if already in list) + IF (ALLOCATED(TPFILE%CDIRNAME)) THEN + CALL IO_FILE_ADD2LIST(TZSPLITFILE,TRIM(TPFILE%CNAME)//TRIM(YFILE),TPFILE%CTYPE,TPFILE%CMODE, & + HDIRNAME=TPFILE%CDIRNAME, & + KLFINPRAR=TPFILE%NLFINPRAR,KLFITYPE=TPFILE%NLFITYPE,KLFIVERB=TPFILE%NLFIVERB, & + HFORMAT=TPFILE%CFORMAT) + ELSE + CALL IO_FILE_ADD2LIST(TZSPLITFILE,TRIM(TPFILE%CNAME)//TRIM(YFILE),TPFILE%CTYPE,TPFILE%CMODE, & + KLFINPRAR=TPFILE%NLFINPRAR,KLFITYPE=TPFILE%NLFITYPE,KLFIVERB=TPFILE%NLFIVERB, & + HFORMAT=TPFILE%CFORMAT) + END IF + END IF + + IF (ALLOCATED(TPFILE%CDIRNAME)) THEN + IF (LEN_TRIM(TZSPLITFILE%CDIRNAME)>0) THEN + YPREFILENAME = TRIM(TZSPLITFILE%CDIRNAME)//'/'//TRIM(TZSPLITFILE%CNAME) + ELSE + YPREFILENAME = TRIM(TZSPLITFILE%CNAME) + END IF + ELSE + YPREFILENAME = TRIM(TZSPLITFILE%CNAME) + END IF + + TPFILE%TFILES_IOZ(IFILE)%TFILE => TZSPLITFILE + !Done outside of the previous IF to prevent problems with .OUT files + TZSPLITFILE%NMPICOMM = NMNH_COMM_WORLD + TZSPLITFILE%NMASTER_RANK = IRANK_PROCIO + TZSPLITFILE%LMASTER = (ISP == IRANK_PROCIO) + TZSPLITFILE%LMULTIMASTERS = .FALSE. + TZSPLITFILE%NSUBFILES_IOZ = 0 + + ! Must be done BEFORE the call to io_open_file_* because we need to read things in these subroutines + TZSPLITFILE%LOPENED = .TRUE. + TZSPLITFILE%NOPEN = TZSPLITFILE%NOPEN + 1 + TZSPLITFILE%NOPEN_CURRENT = TZSPLITFILE%NOPEN_CURRENT + 1 + +#if defined(MNH_IOCDF4) + IF (TZSPLITFILE%CFORMAT=='NETCDF4' .OR. TZSPLITFILE%CFORMAT=='LFICDF4') THEN + IF (YACTION == 'READ') THEN + ! Open netCDF File for reading + call io_open_file_nc4(tzsplitfile) + END IF + + IF (YACTION == 'WRITE') THEN + ! Create netCDF File for writing + call io_create_file_nc4(TZSPLITFILE, hprogram_orig=HPROGRAM_ORIG) + END IF + END IF +#endif + IF (TZSPLITFILE%CFORMAT=='LFI' .OR. TZSPLITFILE%CFORMAT=='LFICDF4') THEN + SELECT CASE (YACTION) + CASE('READ') + call io_open_file_lfi(tzsplitfile,iresp) + CASE('WRITE') + call io_create_file_lfi(tzsplitfile,iresp) + END SELECT + ENDIF + ! + ENDDO + END IF + + + END SELECT + + TPFILE%NMPICOMM = NMNH_COMM_WORLD + + KRESP = IOS + + CONTAINS + FUNCTION SUFFIX(HEXT) + + CHARACTER(len=*) :: HEXT + CHARACTER(len=LEN(HEXT)+3) :: SUFFIX + + WRITE(SUFFIX,'(A,i3.3)') TRIM(HEXT), ISP + + END FUNCTION SUFFIX + +END SUBROUTINE OPEN_ll + + +recursive SUBROUTINE IO_File_close(TPFILE,KRESP,HPROGRAM_ORIG) +! +USE MODD_CONF, ONLY: CPROGRAM +USE MODD_IO_ll, ONLY: NNULLUNIT + +use mode_io_file_lfi, only: io_close_file_lfi +#if defined(MNH_IOCDF4) +use mode_io_file_nc4, only: io_close_file_nc4 +use mode_io_write_nc4, only: io_write_coordvar_nc4 +#endif +USE MODE_IO_MANAGE_STRUCT, ONLY: IO_FILE_FIND_BYNAME +! +TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE ! File structure +INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! Return code +CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: HPROGRAM_ORIG !To emulate a file coming from this program +! +character(len=256) :: yioerrmsg +INTEGER :: IRESP, JI +TYPE(TFILEDATA),POINTER :: TZFILE_DES +TYPE(TFILEDATA),POINTER :: TZFILE_IOZ +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_File_close','closing '//TRIM(TPFILE%CNAME)) +! +IF (.NOT.TPFILE%LOPENED) THEN + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_File_close','trying to close a file not opened: '//TRIM(TPFILE%CNAME)) + RETURN +ENDIF +! +IF (TPFILE%NOPEN_CURRENT>1) THEN + CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_File_close',TRIM(TPFILE%CNAME)// & + ': decrementing NOPEN_CURRENT (still opened after this call)') + TPFILE%NOPEN_CURRENT = TPFILE%NOPEN_CURRENT - 1 + TPFILE%NCLOSE = TPFILE%NCLOSE + 1 + ! + DO JI = 1,TPFILE%NSUBFILES_IOZ + TZFILE_IOZ => TPFILE%TFILES_IOZ(JI)%TFILE + TZFILE_IOZ%NOPEN_CURRENT = TZFILE_IOZ%NOPEN_CURRENT - 1 + TZFILE_IOZ%NCLOSE = TZFILE_IOZ%NCLOSE + 1 + END DO + ! + RETURN +END IF +! +SELECT CASE(TPFILE%CTYPE) + CASE('CHEMINPUT','CHEMTAB','DES','GPS','METEO','NML','OUTPUTLISTING','SURFACE_DATA','TXT') + IF (TPFILE%LMASTER) THEN + IF (TPFILE%NLU/=-1 .AND. TPFILE%NLU/=NNULLUNIT) THEN + CLOSE(UNIT=TPFILE%NLU, STATUS='KEEP', IOSTAT=IRESP, IOMSG=yioerrmsg) + END IF + END IF + + !Warning and not error or fatal if close fails to allow continuation of execution + IF (IRESP/=0) CALL PRINT_MSG(NVERB_WARNING,'IO','IO_File_close','Problem when closing ' & + //TRIM(TPFILE%CNAME)//': '//TRIM(YIOERRMSG)) + + TPFILE%NLU = -1 + + + !MesoNH files + !Remark: 'MNH' is more general than MNHBACKUP and could be in fact a MNHBACKUP file + CASE ('MNH', 'MNHBACKUP', 'MNHDIACHRONIC', 'MNHDIAG', 'MNHOUTPUT', 'PGD') + !Do not close (non-existing) '.des' file if OUTPUT + IF(TPFILE%CTYPE/='OUTPUT' .AND. CPROGRAM/='LFICDF') THEN + CALL IO_FILE_FIND_BYNAME(TRIM(TPFILE%CNAME)//'.des',TZFILE_DES,IRESP) + IF (IRESP/=0) CALL PRINT_MSG(NVERB_ERROR,'IO','IO_File_close','file '//TRIM(TPFILE%CNAME)//'.des not in filelist') + CALL IO_File_close(TZFILE_DES,KRESP=IRESP,HPROGRAM_ORIG=HPROGRAM_ORIG) + ENDIF + ! +#if defined(MNH_IOCDF4) + !Write coordinates variables in NetCDF file + IF (TPFILE%CMODE == 'WRITE' .AND. (TPFILE%CFORMAT=='NETCDF4' .OR. TPFILE%CFORMAT=='LFICDF4')) THEN + CALL IO_WRITE_COORDVAR_NC4(TPFILE,HPROGRAM_ORIG=HPROGRAM_ORIG) + END IF +#endif + + if (tpfile%lmaster) then + if (tpfile%cformat == 'LFI' .or. tpfile%cformat == 'LFICDF4') call io_close_file_lfi(tpfile,iresp) +#if defined(MNH_IOCDF4) + if (tpfile%cformat == 'NETCDF4' .or. tpfile%cformat == 'LFICDF4') call io_close_file_nc4(tpfile,iresp) +#endif + end if + ! + CALL IO_ADD2TRANSFER_LIST(TPFILE) + ! + SUBFILES: DO JI = 1,TPFILE%NSUBFILES_IOZ + TZFILE_IOZ => TPFILE%TFILES_IOZ(JI)%TFILE + IF (.NOT.TZFILE_IOZ%LOPENED) & + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_File_close','file '//TRIM(TZFILE_IOZ%CNAME)//' is not opened') + IF (TZFILE_IOZ%NOPEN_CURRENT/=1) & + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_File_close','file '//TRIM(TZFILE_IOZ%CNAME)//& + ' is currently opened 0 or several times (expected only 1)') + TZFILE_IOZ%LOPENED = .FALSE. + TZFILE_IOZ%NOPEN_CURRENT = 0 + TZFILE_IOZ%NCLOSE = TZFILE_IOZ%NCLOSE + 1 +#if defined(MNH_IOCDF4) + !Write coordinates variables in netCDF file + IF (TZFILE_IOZ%CMODE == 'WRITE' .AND. (TZFILE_IOZ%CFORMAT=='NETCDF4' .OR. TZFILE_IOZ%CFORMAT=='LFICDF4')) THEN + CALL IO_WRITE_COORDVAR_NC4(TZFILE_IOZ,HPROGRAM_ORIG=HPROGRAM_ORIG) + END IF +#endif + IF (TZFILE_IOZ%LMASTER) THEN + if (tzfile_ioz%cformat == 'LFI' .or. tzfile_ioz%cformat == 'LFICDF4') call io_close_file_lfi(tzfile_ioz,iresp) +#if defined(MNH_IOCDF4) + if (tzfile_ioz%cformat == 'NETCDF4' .or. tzfile_ioz%cformat == 'LFICDF4') call io_close_file_nc4(tzfile_ioz,iresp) +#endif + END IF + END DO SUBFILES + + + CASE DEFAULT + call print_msg(NVERB_FATAL,'IO','IO_File_close','invalid type '//trim(tpfile%ctype)//' for file '//trim(tpfile%cname)) +END SELECT +! +TPFILE%LOPENED = .FALSE. +TPFILE%NOPEN_CURRENT = 0 +TPFILE%NCLOSE = TPFILE%NCLOSE + 1 +! +IF (PRESENT(KRESP)) KRESP=IRESP +! +END SUBROUTINE IO_File_close + + +subroutine IO_ADD2TRANSFER_LIST(TPFILE) + +USE MODD_CONF, ONLY : CPROGRAM + +USE MODI_SYSTEM_MNH + +TYPE(TFILEDATA), INTENT(INOUT) :: TPFILE ! File structure + +CHARACTER(len=:),allocatable :: YFILEM ! name of the file +CHARACTER(len=:),allocatable :: YCPIO +CHARACTER(len=:),allocatable :: YTRANS +CHARACTER(LEN=100) :: YCOMMAND +INTEGER, SAVE :: ICPT = 0 + +YFILEM = TPFILE%CNAME + +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_ADD2TRANSFER_LIST','called for '//TRIM(YFILEM)) + +IF (TPFILE%LMASTER .AND. CPROGRAM/='LFICDF') THEN + !! Write in pipe +#if defined(MNH_SX5) + YTRANS='nectransfer.x' +#else + YTRANS='xtransfer.x' +#endif + + SELECT CASE (TPFILE%NLFITYPE) + CASE(:-1,3:) + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_ADD2TRANSFER_LIST',TRIM(YFILEM)//': incorrect NLFITYPE') + CASE(0) + YCPIO='NIL' + CASE(1) + YCPIO='MESONH' + CASE(2) + CALL PRINT_MSG(NVERB_INFO,'IO','IO_ADD2TRANSFER_LIST','file '//TRIM(YFILEM)//' not transferred') + END SELECT + + if (TPFILE%NLFITYPE==0 .or. TPFILE%NLFITYPE==1) then + ICPT=ICPT+1 + WRITE (YCOMMAND,'(A," ",A," ",A," >> OUTPUT_TRANSFER",I3.3," 2>&1 &")') YTRANS,YCPIO,TRIM(YFILEM),ICPT + CALL PRINT_MSG(NVERB_INFO,'IO','IO_ADD2TRANSFER_LIST','YCOMMAND='//TRIM(YCOMMAND)) + CALL SYSTEM_MNH(YCOMMAND) + end if +END IF + +end subroutine IO_ADD2TRANSFER_LIST + + +subroutine IO_File_check_format_exist( tpfile ) + +type(tfiledata), intent(inout) :: tpfile ! File structure + +logical :: gexist_lfi, gexist_nc4 + + +call Print_msg( NVERB_DEBUG, 'IO', 'IO_File_check_format_exist', 'called for '//TRIM(tpfile%cname) ) + +IF (TPFILE%LMASTER) THEN + ! Proc I/O case + INQUIRE(FILE=TRIM(TPFILE%CNAME)//'.lfi',EXIST=GEXIST_LFI) + INQUIRE(FILE=TRIM(TPFILE%CNAME)//'.nc', EXIST=GEXIST_NC4) + + MODE: if ( tpfile%cmode == 'READ' ) then + IF (.NOT.GEXIST_LFI .AND. .NOT.GEXIST_NC4) & + CALL PRINT_MSG(NVERB_FATAL,'IO','IO_File_check_format_exist',TRIM(TPFILE%CNAME)//': no .nc or .lfi file') + + SELECT CASE (TRIM(TPFILE%CFORMAT)) + CASE ('NETCDF4') + IF (.NOT.GEXIST_NC4 .AND. GEXIST_LFI) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_File_check_format_exist',TRIM(TPFILE%CNAME)// & + ': .nc file does not exist but .lfi exists -> forced to LFI') + TPFILE%CFORMAT='LFI' + END IF + CASE ('LFI') + IF (.NOT.GEXIST_LFI .AND. GEXIST_NC4) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_File_check_format_exist',TRIM(TPFILE%CNAME)// & + ': .lfi file does not exist but .nc exists -> forced to NETCDF4') + TPFILE%CFORMAT='NETCDF4' + END IF + CASE ('LFICDF4') + IF (GEXIST_NC4) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_File_check_format_exist',TRIM(TPFILE%CNAME)// & + ': LFICDF4 format is not allowed in READ mode -> forced to NETCDF4') + TPFILE%CFORMAT='NETCDF4' + ELSE IF (GEXIST_LFI) THEN + CALL PRINT_MSG(NVERB_WARNING,'IO','IO_File_check_format_exist',TRIM(TPFILE%CNAME)// & + ': LFICDF4 format is not allowed in READ mode -> forced to LFI') + TPFILE%CFORMAT='LFI' + END IF + CASE DEFAULT + IF (GEXIST_NC4) THEN + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_File_check_format_exist',TRIM(TPFILE%CNAME)// & + ': invalid fileformat (-> forced to NETCDF4 if no abort)') + TPFILE%CFORMAT='NETCDF4' + ELSE IF (GEXIST_LFI) THEN + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_File_check_format_exist',TRIM(TPFILE%CNAME)// & + ': invalid fileformat (-> forced to LFI if no abort)') + TPFILE%CFORMAT='LFI' + END IF + END SELECT + end if MODE +END IF + +end subroutine IO_File_check_format_exist + + +subroutine IO_File_open_format( tpfile, hprogram_orig ) + +#if defined(MNH_IOCDF4) +use mode_io_file_nc4, only: io_create_file_nc4, io_open_file_nc4 +#endif +use mode_io_file_lfi, only: io_create_file_lfi, io_open_file_lfi + +type(tfiledata), intent(inout) :: tpfile ! File structure +character(len=*), optional, intent(in) :: hprogram_orig !To emulate a file coming from this program + +integer :: iresp + + +call Print_msg( NVERB_DEBUG, 'IO', 'IO_File_open_format', 'called for '//TRIM(tpfile%cname) ) + +#if defined(MNH_IOCDF4) + IF (TPFILE%CFORMAT=='NETCDF4' .OR. TPFILE%CFORMAT=='LFICDF4') THEN + SELECT CASE (TPFILE%CMODE) + CASE('READ') + call io_open_file_nc4(tpfile) + CASE('WRITE') + call io_create_file_nc4(TPFILE, hprogram_orig=HPROGRAM_ORIG) + END SELECT + END IF +#endif + + IF (TPFILE%CFORMAT=='LFI' .OR. TPFILE%CFORMAT=='LFICDF4') THEN + SELECT CASE (TPFILE%CMODE) + CASE('READ') + call io_open_file_lfi(tpfile,iresp) + CASE('WRITE') + call io_create_file_lfi(tpfile,iresp) + END SELECT + END IF + +end subroutine IO_File_open_format + +end module mode_io_file -- GitLab