diff --git a/src/LIB/SURCOUCHE/src/modd_io.f90 b/src/LIB/SURCOUCHE/src/modd_io.f90 index ecd4301775634ffb7fdfbaff386c027083bad894..fe3bc68f3c7f9f271a76aec6c1785327aa0d5ddf 100644 --- a/src/LIB/SURCOUCHE/src/modd_io.f90 +++ b/src/LIB/SURCOUCHE/src/modd_io.f90 @@ -10,15 +10,18 @@ ! P. Wautelet 07/02/2019: force TYPE to a known value for IO_File_add2list ! P. Wautelet 12/03/2019: add TMAINFILE field in TFILEDATA ! P. Wautelet 17/01/2020: add 'BUD' category for Print_msg + corresponding namelist variables +! P. Wautelet 22/09/2020: add ldimreduced in tfiledata !----------------------------------------------------------------- +#define MNH_REDUCE_DIMENSIONS_IN_FILES 1 + MODULE MODD_IO ! USE MODD_NETCDF, ONLY: IOCDF, TPTR2DIMCDF USE MODD_PARAMETERS, ONLY: NDIRNAMELGTMAX, NFILENAMELGTMAX use modd_precision, only: CDFINT, LFIINT ! -IMPLICIT NONE +IMPLICIT NONE ! ! INTEGER, PARAMETER :: NVERB_NO=0, NVERB_FATAL=1, NVERB_ERROR=2, NVERB_WARNING=3, NVERB_INFO=4, NVERB_DEBUG=5 @@ -88,6 +91,11 @@ TYPE TFILEDATA INTEGER :: NMPICOMM = -1 !MPI communicator used for IO on this file LOGICAL :: LMASTER = .FALSE. !True if process is master of the file (process that open/read/write/close) LOGICAL :: LMULTIMASTERS = .FALSE. !True if several processes may access the file +#if ( MNH_REDUCE_DIMENSIONS_IN_FILES == 1 ) + logical :: ldimreduced = .true. !True if number of dimensions of fields can be reduced (for 2D simulations) +#else + logical :: ldimreduced = .false. !True if number of dimensions of fields can be reduced (for 2D simulations) +#endif ! INTEGER :: NSUBFILES_IOZ = 0 !Number of sub-files (Z-split files based on this file) !For example if 2 sub-files and this file is abcd, diff --git a/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 b/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 index f342fb3ef75931d74d2765d5501fcba854ec62ef..47c52b7b5eaca79b144229cea96d2548a36ffcf4 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 @@ -17,6 +17,7 @@ ! P. Wautelet 25/06/2019: added IO_Field_read for 3D integer arrays (IO_Field_read_byname_N3 and IO_Field_read_byfield_N3) ! J. Escobar 11/02/2020: for GA & // IO, add update_halo + sync, & mpi_allreduce for error handling in // IO ! P. Wautelet 22/09/2020: add IO_Format_read_select subroutine +! P. Wautelet 22/09/2020: use ldimreduced to allow reduction in the number of dimensions of fields (used by 2D simulations) !----------------------------------------------------------------- MODULE MODE_IO_FIELD_READ @@ -28,7 +29,7 @@ use modd_precision, only: MNHINT_MPI, MNHLOG_MPI, MNHREAL_MPI, MNHTIME ! use mode_field, only: Find_field_id_from_mnhname USE MODE_IO_READ_LFI -#if defined(MNH_IOCDF4) +#ifdef MNH_IOCDF4 USE MODE_IO_READ_NC4 #endif USE MODE_MSG @@ -330,6 +331,7 @@ END SUBROUTINE IO_Field_read_byname_X2 SUBROUTINE IO_Field_read_byfield_X2(TPFILE,TPFIELD,PFIELD,KRESP,KIMAX_ll,KJMAX_ll,TPSPLITTING) ! +use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, ISNPROC, LPACK, L1D, L2D USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_STRUCTURE_ll, ONLY: ZONE_ll @@ -356,13 +358,16 @@ INTEGER, OPTIONAL, INTENT(IN) :: KJMAX_ll TYPE(ZONE_ll),DIMENSION(ISNPROC),OPTIONAL,INTENT(IN) :: TPSPLITTING ! splitting of the domain ! INTEGER :: IERR -REAL,DIMENSION(:,:),POINTER :: ZFIELDP +real :: zfieldp0d +real, dimension(:), pointer :: zfieldp1d +REAL, DIMENSION(:,:), POINTER :: ZFIELDP LOGICAL :: GALLOC logical :: glfi, gnc4 INTEGER :: IRESP INTEGER :: IHEXTOT REAL(kind=MNHTIME), DIMENSION(2) :: T0, T1, T2 REAL(kind=MNHTIME), DIMENSION(2) :: T11, T22 +type(tfielddata) :: tzfield #ifdef MNH_GA REAL,DIMENSION(:,:),POINTER :: ZFIELD_GA TYPE(LIST_ll) ,POINTER :: TZFIELD_ll @@ -383,20 +388,53 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution - 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) - ELSE IF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - ZFIELDP=>PFIELD(:,JPHEXT+1:JPHEXT+1) - ELSE - ZFIELDP=>PFIELD(:,:) - END IF - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, zfieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, zfieldp, iresp ) - IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - PFIELD(:,:)=SPREAD(SPREAD(PFIELD(JPHEXT+1,JPHEXT+1),DIM=1,NCOPIES=IHEXTOT),DIM=2,NCOPIES=IHEXTOT) - ELSE IF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - PFIELD(:,:)=SPREAD(PFIELD(:,JPHEXT+1),DIM=2,NCOPIES=IHEXTOT) - END IF + if ( lpack .and. l1d .and. Size( pfield, 1 ) == ihextot .and. Size( pfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) !Necessary if time dimension + tzfield%ndimlist(2:) = NMNHDIM_UNUSED + end if + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp0d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp0d, iresp ) + pfield(:, :) = Spread( Spread( zfieldp0d, dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) + pfield(:, :) = Spread( Spread( pfield(jphext + 1, jphext + 1), dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) + endif + else if ( lpack .and. l2d .and. Size( pfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) !Necessary if time dimension + tzfield%ndimlist(3:) = NMNHDIM_UNUSED + end if + zfieldp1d => pfield(:, jphext + 1) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp1d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp1d, iresp ) + pfield(:, :) = Spread( pfield(:, jphext + 1), dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = NMNHDIM_ONE + end if + zfieldp => pfield(:, jphext + 1 : jphext + 1) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) + pfield(:,:) = Spread( pfield(:, jphext + 1), dim = 2, ncopies = ihextot ) + endif + else + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, pfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, pfield, iresp ) + end if ELSE CALL SECOND_MNH2(T0) IF (ISP == TPFILE%NMASTER_RANK) THEN @@ -504,6 +542,7 @@ END SUBROUTINE IO_Field_read_byname_X3 SUBROUTINE IO_Field_read_byfield_X3(TPFILE,TPFIELD,PFIELD,KRESP) ! +use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, ISNPROC, LPACK, L1D, L2D USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -540,15 +579,17 @@ LOGICAL :: GALLOC, GALLOC_ll logical :: glfi, gnc4 REAL,DIMENSION(:,:),POINTER :: TX2DP REAL,DIMENSION(:,:),POINTER :: ZSLICE_ll,ZSLICE -REAL,DIMENSION(:,:,:),POINTER :: ZFIELDP +real,dimension(:), pointer :: zfieldp1d +real,dimension(:,:), pointer :: zfieldp2d +REAL,DIMENSION(:,:,:), POINTER :: ZFIELDP REAL(kind=MNHTIME), DIMENSION(2) :: T0, T1, T2 REAL(kind=MNHTIME), DIMENSION(2) :: T11, T22 CHARACTER(LEN=2) :: YDIR CHARACTER(LEN=4) :: YK CHARACTER(LEN=NMNHNAMELGTMAX+4) :: YRECZSLICE CHARACTER(LEN=4) :: YSUFFIX +type(tfielddata) :: tzfield TYPE(TFILEDATA),POINTER :: TZFILE -TYPE(TFIELDDATA) :: TZFIELD TYPE(TX_2DP),ALLOCATABLE,DIMENSION(:) :: T_TX2DP #ifdef MNH_GA REAL,DIMENSION(:,:,:),POINTER :: ZFIELD_GA @@ -573,20 +614,58 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC .AND. TPFILE%NSUBFILES_IOZ==0 ) THEN ! sequential execution - 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,:) - ELSE IF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - ZFIELDP=>PFIELD(:,JPHEXT+1:JPHEXT+1,:) - ELSE - ZFIELDP=>PFIELD(:,:,:) - END IF - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, zfieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, zfieldp, iresp ) - IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - PFIELD(:,:,:)=SPREAD(SPREAD(PFIELD(JPHEXT+1,JPHEXT+1,:),DIM=1,NCOPIES=IHEXTOT),DIM=2,NCOPIES=IHEXTOT) - ELSE IF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - PFIELD(:,:,:)=SPREAD(PFIELD(:,JPHEXT+1,:),DIM=2,NCOPIES=IHEXTOT) - END IF + if ( lpack .and. l1d .and. Size( pfield, 1 ) == ihextot .and. Size( pfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) + tzfield%ndimlist(2) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(3:) = NMNHDIM_UNUSED + end if + zfieldp1d => pfield(jphext+1, jphext+1, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp1d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp1d, iresp ) + pfield(:, :, :) = Spread( Spread( pfield(jphext + 1, jphext + 1, :), dim = 1, ncopies = ihextot ), & + dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) + pfield(:, :, :) = Spread( Spread( pfield(jphext + 1, jphext + 1, :), dim = 1, ncopies = ihextot ), & + dim = 2, ncopies = ihextot ) + endif + else if ( lpack .and. l2d .and. Size( pfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(4:) = NMNHDIM_UNUSED + end if + zfieldp2d => pfield(:, jphext + 1, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp2d, iresp ) + pfield(:, :, :) = Spread( pfield(:, jphext + 1, :), dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = NMNHDIM_ONE + end if + zfieldp => pfield(:, jphext + 1 : jphext + 1, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) + pfield(:,:, :) = Spread( pfield(:, jphext + 1, :), dim = 2, ncopies = ihextot ) + endif + else + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, pfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, pfield, iresp ) + end if ELSE IF ( TPFILE%NSUBFILES_IOZ==0 .OR. YDIR == '--' ) THEN ! multiprocesses execution & 1 IO proc IF (ISP == TPFILE%NMASTER_RANK) THEN ! I/O process case @@ -859,6 +938,7 @@ END SUBROUTINE IO_Field_read_byname_X4 SUBROUTINE IO_Field_read_byfield_X4(TPFILE,TPFIELD,PFIELD,KRESP) ! +use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, LPACK, L1D, L2D USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -873,11 +953,14 @@ REAL,DIMENSION(:,:,:,:),TARGET,INTENT(INOUT) :: PFIELD ! array containing the INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code ! INTEGER :: IERR -REAL,DIMENSION(:,:,:,:),POINTER :: ZFIELDP +real, dimension(:,:), pointer :: zfieldp2d +real, dimension(:,:,:), pointer :: zfieldp3d +REAL, DIMENSION(:,:,:,:), POINTER :: ZFIELDP LOGICAL :: GALLOC logical :: glfi, gnc4 INTEGER :: IRESP INTEGER :: IHEXTOT +type(tfielddata) :: tzfield ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_X4',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! @@ -892,20 +975,60 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution - 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,:,:) - ELSE IF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - ZFIELDP=>PFIELD(:,JPHEXT+1:JPHEXT+1,:,:) - ELSE - ZFIELDP=>PFIELD(:,:,:,:) - END IF - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, zfieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, zfieldp, iresp ) - IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - PFIELD(:,:,:,:)=SPREAD(SPREAD(PFIELD(JPHEXT+1,JPHEXT+1,:,:),DIM=1,NCOPIES=IHEXTOT),DIM=2,NCOPIES=IHEXTOT) - ELSE IF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - PFIELD(:,:,:,:)=SPREAD(PFIELD(:,JPHEXT+1,:,:),DIM=2,NCOPIES=IHEXTOT) - END IF + if ( lpack .and. l1d .and. Size( pfield, 1 ) == ihextot .and. Size( pfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) + tzfield%ndimlist(2) = tzfield%ndimlist(4) + tzfield%ndimlist(3) = tzfield%ndimlist(5) !Necessary if time dimension + tzfield%ndimlist(4:) = NMNHDIM_UNUSED + end if + zfieldp2d => pfield(jphext+1, jphext+1, :, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp2d, iresp ) + pfield(:, :, :, :) = Spread( Spread( pfield(jphext + 1, jphext + 1, :, :), dim = 1, ncopies = ihextot ), & + dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1, :, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) + pfield(:, :, :, :) = Spread( Spread( pfield(jphext + 1, jphext + 1, :, :), dim = 1, ncopies = ihextot ), & + dim = 2, ncopies = ihextot ) + endif + else if ( lpack .and. l2d .and. Size( pfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) + tzfield%ndimlist(4) = tzfield%ndimlist(5) !Necessary if time dimension + tzfield%ndimlist(5:) = NMNHDIM_UNUSED + end if + zfieldp3d => pfield(:, jphext + 1, :, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp3d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp3d, iresp ) + pfield(:, :, :, :) = Spread( pfield(:, jphext + 1, :, :), dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = NMNHDIM_ONE + end if + zfieldp => pfield(:, jphext + 1 : jphext + 1, :, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) + pfield(:,:, :, :) = Spread( pfield(:, jphext + 1, :, :), dim = 2, ncopies = ihextot ) + endif + else + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, pfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, pfield, iresp ) + end if ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN ! I/O process case @@ -974,6 +1097,7 @@ END SUBROUTINE IO_Field_read_byname_X5 SUBROUTINE IO_Field_read_byfield_X5(TPFILE,TPFIELD,PFIELD,KRESP) ! +use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, LPACK, L1D, L2D USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -988,11 +1112,14 @@ REAL,DIMENSION(:,:,:,:,:),TARGET,INTENT(INOUT) :: PFIELD ! array containing th INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code ! INTEGER :: IERR -REAL,DIMENSION(:,:,:,:,:),POINTER :: ZFIELDP +real, dimension(:,:,:), pointer :: zfieldp3d +real, dimension(:,:,:,:), pointer :: zfieldp4d +REAL, DIMENSION(:,:,:,:,:), POINTER :: ZFIELDP LOGICAL :: GALLOC logical :: glfi, gnc4 INTEGER :: IRESP INTEGER :: IHEXTOT +type(tfielddata) :: tzfield ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_X5',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! @@ -1007,20 +1134,62 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution - 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,:,:,:) - ELSE IF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - ZFIELDP=>PFIELD(:,JPHEXT+1:JPHEXT+1,:,:,:) - ELSE - ZFIELDP=>PFIELD(:,:,:,:,:) - END IF - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, zfieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, zfieldp, iresp ) - IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - PFIELD(:,:,:,:,:)=SPREAD(SPREAD(PFIELD(JPHEXT+1,JPHEXT+1,:,:,:),DIM=1,NCOPIES=IHEXTOT),DIM=2,NCOPIES=IHEXTOT) - ELSE IF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN - PFIELD(:,:,:,:,:)=SPREAD(PFIELD(:,JPHEXT+1,:,:,:),DIM=2,NCOPIES=IHEXTOT) - END IF + if ( lpack .and. l1d .and. Size( pfield, 1 ) == ihextot .and. Size( pfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) + tzfield%ndimlist(2) = tzfield%ndimlist(4) + tzfield%ndimlist(3) = tzfield%ndimlist(5) + tzfield%ndimlist(4) = tzfield%ndimlist(6) !Necessary if time dimension + tzfield%ndimlist(5:) = NMNHDIM_UNUSED + end if + zfieldp3d => pfield(jphext+1, jphext+1, :, :, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp3d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp3d, iresp ) + pfield(:, :, :, :, :) = Spread( Spread( pfield(jphext + 1, jphext + 1, :, :, :), dim = 1, ncopies = ihextot ), & + dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1, :, :, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) + pfield(:, :, :, :, :) = Spread( Spread( pfield(jphext + 1, jphext + 1, :, :, :), dim = 1, ncopies = ihextot ), & + dim = 2, ncopies = ihextot ) + endif + else if ( lpack .and. l2d .and. Size( pfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) + tzfield%ndimlist(4) = tzfield%ndimlist(5) + tzfield%ndimlist(5) = tzfield%ndimlist(6) !Necessary if time dimension + tzfield%ndimlist(6:) = NMNHDIM_UNUSED + end if + zfieldp4d => pfield(:, jphext + 1, :, :, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp4d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp4d, iresp ) + pfield(:, :, :, :, :) = Spread( pfield(:, jphext + 1, :, :, :), dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = NMNHDIM_ONE + end if + zfieldp => pfield(:, jphext + 1 : jphext + 1, :, :, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, zfieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, zfieldp, iresp ) + pfield(:,:, :, :, :) = Spread( pfield(:, jphext + 1, :, :, :), dim = 2, ncopies = ihextot ) + endif + else + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, pfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, pfield, iresp ) + end if ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN ! I/O process case @@ -1341,6 +1510,7 @@ END SUBROUTINE IO_Field_read_byname_N2 SUBROUTINE IO_Field_read_byfield_N2(TPFILE,TPFIELD,KFIELD,KRESP) ! +use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, LPACK, L1D, L2D USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -1354,11 +1524,14 @@ INTEGER,DIMENSION(:,:),TARGET,INTENT(INOUT) :: KFIELD ! array containing the d INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code ! INTEGER :: IERR -INTEGER,DIMENSION(:,:),POINTER :: IFIELDP +integer :: ifieldp0d +integer, dimension(:), pointer :: ifieldp1d +INTEGER, DIMENSION(:,:), POINTER :: IFIELDP LOGICAL :: GALLOC logical :: glfi, gnc4 INTEGER :: IRESP INTEGER :: IHEXTOT +type(tfielddata) :: tzfield ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_N2',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! @@ -1373,20 +1546,53 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) 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 ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, ifieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, ifieldp, iresp ) - 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 + if ( lpack .and. l1d .and. Size( kfield, 1 ) == ihextot .and. Size( kfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) !Necessary if time dimension + tzfield%ndimlist(2:) = NMNHDIM_UNUSED + end if + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp0d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp0d, iresp ) + kfield(:, :) = Spread( Spread( ifieldp0d, dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + ifieldp => kfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp, iresp ) + kfield(:, :) = Spread( Spread( kfield(jphext + 1, jphext + 1), dim = 1, ncopies = ihextot ), dim = 2, ncopies = ihextot ) + endif + else if ( lpack .and. l2d .and. Size( kfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) !Necessary if time dimension + tzfield%ndimlist(3:) = NMNHDIM_UNUSED + end if + ifieldp1d => kfield(:, jphext + 1) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp1d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp1d, iresp ) + kfield(:, :) = Spread( kfield(:, jphext + 1), dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = NMNHDIM_ONE + end if + ifieldp => kfield(:, jphext + 1 : jphext + 1) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp, iresp ) + kfield(:, :) = Spread( kfield(:, jphext + 1), dim = 2, ncopies = ihextot ) + endif + else + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, kfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, kfield, iresp ) + end if ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN ! I/O process case @@ -1458,6 +1664,7 @@ END SUBROUTINE IO_Field_read_byname_N3 SUBROUTINE IO_Field_read_byfield_N3(TPFILE,TPFIELD,KFIELD,KRESP) ! +use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, LPACK, L1D, L2D USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -1471,11 +1678,14 @@ INTEGER,DIMENSION(:,:,:),TARGET,INTENT(INOUT) :: KFIELD ! array containing the INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code ! INTEGER :: IERR -INTEGER,DIMENSION(:,:,:),POINTER :: IFIELDP +integer, dimension(:), pointer :: ifieldp1d +integer, dimension(:,:), pointer :: ifieldp2d +INTEGER, DIMENSION(:,:,:), POINTER :: IFIELDP LOGICAL :: GALLOC logical :: glfi, gnc4 INTEGER :: IRESP INTEGER :: IHEXTOT +type(tfielddata) :: tzfield ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_N3',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) ! @@ -1490,20 +1700,58 @@ call IO_Format_read_select( tpfile, glfi, gnc4 ) IF (IRESP==0) 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 ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, ifieldp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, ifieldp, iresp ) - 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 + if ( lpack .and. l1d .and. Size( kfield, 1 ) == ihextot .and. Size( kfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) + tzfield%ndimlist(2) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(3:) = NMNHDIM_UNUSED + end if + ifieldp1d => kfield(jphext + 1, jphext + 1, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp1d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp1d, iresp ) + kfield(:, :, :) = Spread( Spread( kfield(jphext + 1, jphext + 1, :), dim = 1, ncopies = ihextot ), & + dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + ifieldp => kfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp, iresp ) + kfield(:, :, :) = Spread( Spread( kfield(jphext + 1, jphext + 1, :), dim = 1, ncopies = ihextot ), & + dim = 2, ncopies = ihextot ) + endif + else if ( lpack .and. l2d .and. Size( kfield, 2 ) == ihextot ) then + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(4:) = NMNHDIM_UNUSED + end if + ifieldp2d => kfield(:, jphext + 1, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp2d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp2d, iresp ) + kfield(:, :, :) = Spread( kfield(:, jphext + 1, :), dim = 2, ncopies = ihextot ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = NMNHDIM_ONE + end if + ifieldp => kfield(:, jphext + 1 : jphext + 1, :) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, ifieldp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, ifieldp, iresp ) + kfield(:, :, :) = Spread( kfield(:, jphext + 1, :), dim = 2, ncopies = ihextot ) + endif + else + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, kfield, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, kfield, iresp ) + end if ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN ! I/O process case @@ -1860,6 +2108,7 @@ END SUBROUTINE IO_Field_read_byname_lb SUBROUTINE IO_Field_read_byfield_lb(TPFILE,TPFIELD,KL3D,KRIM,PLB,KRESP) ! +use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, ISNPROC, LPACK, L2D USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -1894,9 +2143,11 @@ INTEGER, ALLOCATABLE,DIMENSION(:,:) :: STATUSES INTEGER,ALLOCATABLE,DIMENSION(:) :: REQ_TAB logical :: glfi, gnc4 REAL,DIMENSION(:,:,:),ALLOCATABLE,TARGET :: Z3D +real, dimension(:,:), pointer :: tx2dp REAL,DIMENSION(:,:,:), POINTER :: TX3DP REAL(kind=MNHTIME), DIMENSION(2) :: T0, T1, T2, T3 REAL(kind=MNHTIME), DIMENSION(2) :: T11, T22 +type(tfielddata) :: tzfield TYPE(TX_3DP),ALLOCATABLE,DIMENSION(:) :: T_TX3DP ! CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_lb','reading '//TRIM(TPFIELD%CMNHNAME)) @@ -1923,24 +2174,37 @@ IF (IRESP==0) THEN IF (GSMONOPROC) THEN ! sequential execution IF (YLBTYPE == 'LBX' .OR. YLBTYPE == 'LBXU') THEN ALLOCATE(Z3D(KL3D,SIZE(PLB,2),SIZE(PLB,3))) - Z3D = 0.0 IF (LPACK .AND. L2D) THEN - TX3DP=>Z3D(:,JPHEXT+1:JPHEXT+1,:) + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(4:) = NMNHDIM_UNUSED + end if + TX2DP=>Z3D(:,JPHEXT+1,:) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, tx2dp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, tx2dp, iresp ) + Z3D(:,:,:) = SPREAD(Z3D(:,JPHEXT+1,:),DIM=2,NCOPIES=IHEXTOT) + else + tzfield = tpfield + if ( tzfield%ndimlist(2) /= NMNHDIM_UNKNOWN ) tzfield%ndimlist(2) = NMNHDIM_ONE + TX3DP=>Z3D(:,JPHEXT+1:JPHEXT+1,:) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tzfield, tx3dp, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tzfield, tx3dp, iresp ) + Z3D(:,:,:) = SPREAD(Z3D(:,JPHEXT+1,:),DIM=2,NCOPIES=IHEXTOT) + endif ELSE - TX3DP => Z3D(:,:,:) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, z3d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, z3d, iresp ) END IF - ELSE !(YLBTYPE == 'LBY' .OR. YLBTYPE == 'LBYV') - ALLOCATE(Z3D(SIZE(PLB,1),KL3D,SIZE(PLB,3))) - Z3D = 0.0 - TX3DP => Z3D(:,:,:) - END IF - if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, tx3dp, iresp ) - if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, tx3dp, iresp ) - IF (YLBTYPE == 'LBX' .OR. YLBTYPE == 'LBXU') THEN - IF (LPACK .AND. L2D) Z3D(:,:,:) = SPREAD(Z3D(:,JPHEXT+1,:),DIM=2,NCOPIES=IHEXTOT) PLB(1:KRIM+JPHEXT,:,:) = Z3D(1:KRIM+JPHEXT,:,:) PLB(KRIM+JPHEXT+1:2*(KRIM+JPHEXT),:,:) = Z3D(KL3D-KRIM-JPHEXT+1:KL3D,:,:) ELSE !(YLBTYPE == 'LBY' .OR. YLBTYPE == 'LBYV') + ALLOCATE(Z3D(SIZE(PLB,1),KL3D,SIZE(PLB,3))) + if ( gnc4 ) call IO_Field_read_nc4( tpfile, tpfield, z3d, iresp ) + if ( glfi ) call IO_Field_read_lfi( tpfile, tpfield, z3d, iresp ) PLB(:,1:KRIM+JPHEXT,:) = Z3D(:,1:KRIM+JPHEXT,:) PLB(:,KRIM+JPHEXT+1:2*(KRIM+JPHEXT),:) = Z3D(:,KL3D-KRIM-JPHEXT+1:KL3D,:) END IF diff --git a/src/LIB/SURCOUCHE/src/mode_io_field_write.f90 b/src/LIB/SURCOUCHE/src/mode_io_field_write.f90 index 4cecf884ac96a50aef7754d3f20b4c2f2f70a371..d8d08fcdc134e5a55f3fee3ea29b379ce56de06f 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_field_write.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_field_write.f90 @@ -14,6 +14,7 @@ ! P. Wautelet 12/04/2019: use MNHTIME for time measurement variables ! P. Wautelet 12/07/2019: add support for 1D array of dates ! J. Escobar 11/02/2020: for GA & // IO, add sync, & mpi_allreduce for error handling in // IO +! P. Wautelet 22/09/2020: use ldimreduced to allow reduction in the number of dimensions of fields (used by 2D simulations) !----------------------------------------------------------------- #define MNH_SCALARS_IN_SPLITFILES 0 @@ -28,7 +29,7 @@ MODULE MODE_IO_FIELD_WRITE use mode_field, only: Find_field_id_from_mnhname USE MODE_IO_WRITE_LFI -#if defined(MNH_IOCDF4) +#ifdef MNH_IOCDF4 USE MODE_IO_WRITE_NC4 #endif use mode_msg @@ -160,7 +161,9 @@ CONTAINS OLFI = .FALSE. ONC4 = .FALSE. IF (TPFILE%CFORMAT=='LFI' .OR. TPFILE%CFORMAT=='LFICDF4') OLFI = .TRUE. +#ifdef MNH_IOCDF4 IF (TPFILE%CFORMAT=='NETCDF4' .OR. TPFILE%CFORMAT=='LFICDF4') ONC4 = .TRUE. +#endif END SUBROUTINE IO_Format_write_select @@ -485,6 +488,7 @@ CONTAINS SUBROUTINE IO_Field_write_byfield_X2(TPFILE,TPFIELD,PFIELD,KRESP) + use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC,ISP,L1D,L2D,LPACK USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -513,7 +517,9 @@ CONTAINS INTEGER :: IERR INTEGER :: ISIZEMAX INTEGER :: IRESP - REAL,DIMENSION(:,:),POINTER :: ZFIELDP + real :: zfieldp0d + real, dimension(:), pointer :: zfieldp1d + REAL, DIMENSION(:,:), POINTER :: ZFIELDP LOGICAL :: GALLOC LOGICAL :: GLFI, GNC4 ! @@ -525,6 +531,7 @@ CONTAINS INTEGER :: IHEXTOT CHARACTER(LEN=:),ALLOCATABLE :: YMSG CHARACTER(LEN=6) :: YRESP + type(tfielddata) :: tzfield ! YFILEM = TPFILE%CNAME YRECFM = TPFIELD%CMNHNAME @@ -545,22 +552,54 @@ CONTAINS CALL IO_Format_write_select(TPFILE,GLFI,GNC4) ! IF (IRESP==0) THEN - IF (GSMONOPROC) THEN ! sequential execution - ! IF (LPACK .AND. L1D .AND. YDIR=='XY') THEN - 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 (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,ZFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,ZFIELDP,IRESP) + IF (GSMONOPROC) THEN ! sequential execution + ! IF (LPACK .AND. L1D .AND. YDIR=='XY') THEN + IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) !Necessary if time dimension + tzfield%ndimlist(2:) = NMNHDIM_UNUSED + end if + zfieldp0d = pfield(jphext + 1, jphext + 1) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp0d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp0d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp, iresp ) + endif ! 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 (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,ZFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,ZFIELDP,IRESP) - ELSE - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PFIELD,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PFIELD,IRESP) - END IF - ELSE ! multiprocesses execution + ELSEIF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) !Necessary if time dimension + tzfield%ndimlist(3:) = NMNHDIM_UNUSED + end if + zfieldp1d => pfield(:, jphext + 1) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp1d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp1d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = NMNHDIM_ONE + end if + zfieldp => pfield(:, jphext + 1 : jphext + 1) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp, iresp ) + endif + ELSE + IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PFIELD,IRESP) + IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PFIELD,IRESP) + END IF + ELSE ! multiprocesses execution CALL SECOND_MNH2(T0) CALL MPI_ALLREDUCE(SIZE(PFIELD),ISIZEMAX,1,MNHINT_MPI,MPI_MAX,TPFILE%NMPICOMM,IRESP) IF (ISIZEMAX==0) THEN @@ -622,7 +661,7 @@ CONTAINS END IF #ifdef MNH_GA call ga_sync -#endif +#endif CALL SECOND_MNH2(T2) TIMEZ%T_WRIT2D_WRIT=TIMEZ%T_WRIT2D_WRIT + T2 - T1 ! @@ -668,6 +707,7 @@ CONTAINS SUBROUTINE IO_Field_write_byfield_X3(TPFILE,TPFIELD,PFIELD,KRESP) + use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISNPROC, ISP, L1D, L2D, LPACK USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -698,6 +738,8 @@ CONTAINS INTEGER :: IERR INTEGER :: ISIZEMAX INTEGER :: IRESP,IRESP_ISP,IRESP_TMP + real,dimension(:), pointer :: zfieldp1d + real,dimension(:,:), pointer :: zfieldp2d REAL,DIMENSION(:,:,:),POINTER :: ZFIELDP LOGICAL :: GALLOC LOGICAL :: GLFI, GNC4 @@ -722,6 +764,7 @@ CONTAINS INTEGER :: IHEXTOT CHARACTER(LEN=:),ALLOCATABLE :: YMSG CHARACTER(LEN=6) :: YRESP + type(tfielddata) :: tzfield TYPE(TFILEDATA),POINTER :: TZFILE ! TZFILE => NULL() @@ -749,22 +792,53 @@ CONTAINS CALL IO_Format_write_select(TPFILE,GLFI,GNC4) ! IF (IRESP==0) THEN - IF (GSMONOPROC .AND. TPFILE%NSUBFILES_IOZ==0 ) THEN ! sequential execution + IF (GSMONOPROC .AND. TPFILE%NSUBFILES_IOZ==0 ) THEN ! sequential execution ! IF (LPACK .AND. L1D .AND. YDIR=='XY') THEN - 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 (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,ZFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,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 (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,ZFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,ZFIELDP,IRESP) - ELSE - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PFIELD,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PFIELD,IRESP) - END IF - ELSEIF ( TPFILE%NSUBFILES_IOZ==0 .OR. YDIR=='--' ) THEN ! multiprocesses execution & 1 proc IO + IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) + tzfield%ndimlist(2) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(3:) = NMNHDIM_UNUSED + end if + zfieldp1d => pfield(jphext + 1, jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp1d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp1d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp, iresp ) + endif + ELSEIF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(4:) = NMNHDIM_UNUSED + end if + zfieldp2d => pfield(:, jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp2d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp2d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(2) /= NMNHDIM_UNKNOWN ) tzfield%ndimlist(2) = NMNHDIM_ONE + zfieldp => pfield(:, jphext + 1 : jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp, iresp ) + endif + ELSE + IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PFIELD,IRESP) + IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PFIELD,IRESP) + END IF + ELSEIF ( TPFILE%NSUBFILES_IOZ==0 .OR. YDIR=='--' ) THEN ! multiprocesses execution & 1 proc IO CALL MPI_ALLREDUCE(SIZE(PFIELD),ISIZEMAX,1,MNHINT_MPI,MPI_MAX,TPFILE%NMPICOMM,IRESP) IF (ISIZEMAX==0) THEN CALL PRINT_MSG(NVERB_INFO,'IO','IO_Field_write_byfield_X3','ignoring variable with a zero size ('//TRIM(YRECFM)//')') @@ -798,7 +872,7 @@ CONTAINS ! CALL MPI_BCAST(IRESP,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) ! - ELSE ! multiprocesses execution & // IO + ELSE ! multiprocesses execution & // IO CALL MPI_ALLREDUCE(SIZE(PFIELD),ISIZEMAX,1,MNHINT_MPI,MPI_MAX,TPFILE%NMPICOMM,IRESP) IF (ISIZEMAX==0) THEN CALL PRINT_MSG(NVERB_INFO,'IO','IO_Field_write_byfield_X3','ignoring variable with a zero size ('//TRIM(YRECFM)//')') @@ -1036,6 +1110,7 @@ CONTAINS SUBROUTINE IO_Field_write_byfield_X4(TPFILE,TPFIELD,PFIELD,KRESP) + use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, L1D, L2D, LPACK USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -1062,12 +1137,15 @@ CONTAINS INTEGER :: IERR INTEGER :: ISIZEMAX INTEGER :: IRESP + real,dimension(:,:), pointer :: zfieldp2d + real,dimension(:,:,:), pointer :: zfieldp3d REAL,DIMENSION(:,:,:,:),POINTER :: ZFIELDP LOGICAL :: GALLOC LOGICAL :: GLFI, GNC4 INTEGER :: IHEXTOT CHARACTER(LEN=:),ALLOCATABLE :: YMSG CHARACTER(LEN=6) :: YRESP + type(tfielddata) :: tzfield ! YFILEM = TPFILE%CNAME YRECFM = TPFIELD%CMNHNAME @@ -1087,20 +1165,56 @@ CONTAINS CALL IO_Format_write_select(TPFILE,GLFI,GNC4) ! IF (IRESP==0) THEN - IF (GSMONOPROC) THEN ! sequential execution - ! IF (LPACK .AND. L1D .AND. YDIR=='XY') THEN - 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 (GSMONOPROC) THEN ! sequential execution + ! IF (LPACK .AND. L1D .AND. YDIR=='XY') THEN + IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) + tzfield%ndimlist(2) = tzfield%ndimlist(4) + tzfield%ndimlist(3) = tzfield%ndimlist(5) !Necessary if time dimension + tzfield%ndimlist(4:) = NMNHDIM_UNUSED + end if + zfieldp2d => pfield(jphext + 1, jphext + 1, :, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp2d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp2d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1, :, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp, iresp ) + endif ! 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 (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,ZFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,ZFIELDP,IRESP) - ELSE - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PFIELD,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PFIELD,IRESP) - END IF - ELSE + ELSEIF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) + tzfield%ndimlist(4) = tzfield%ndimlist(5) !Necessary if time dimension + tzfield%ndimlist(5:) = NMNHDIM_UNUSED + end if + zfieldp3d => pfield(:, jphext + 1, :, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp3d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp3d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(2) /= NMNHDIM_UNKNOWN ) tzfield%ndimlist(2) = NMNHDIM_ONE + zfieldp => pfield(:, jphext + 1 : jphext + 1, :, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp, iresp ) + endif + ELSE + IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PFIELD,IRESP) + IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PFIELD,IRESP) + END IF + ELSE CALL MPI_ALLREDUCE(SIZE(PFIELD),ISIZEMAX,1,MNHINT_MPI,MPI_MAX,TPFILE%NMPICOMM,IRESP) IF (ISIZEMAX==0) THEN CALL PRINT_MSG(NVERB_INFO,'IO','IO_Field_write_byfield_X4','ignoring variable with a zero size ('//TRIM(YRECFM)//')') @@ -1171,6 +1285,7 @@ CONTAINS SUBROUTINE IO_Field_write_byfield_X5(TPFILE,TPFIELD,PFIELD,KRESP) + use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, L1D, L2D, LPACK USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -1197,12 +1312,15 @@ CONTAINS INTEGER :: IERR INTEGER :: ISIZEMAX INTEGER :: IRESP + real,dimension(:,:,:), pointer :: zfieldp3d + real,dimension(:,:,:,:), pointer :: zfieldp4d REAL,DIMENSION(:,:,:,:,:),POINTER :: ZFIELDP LOGICAL :: GALLOC LOGICAL :: GLFI, GNC4 INTEGER :: IHEXTOT CHARACTER(LEN=:),ALLOCATABLE :: YMSG CHARACTER(LEN=6) :: YRESP + type(tfielddata) :: tzfield ! YFILEM = TPFILE%CNAME YRECFM = TPFIELD%CMNHNAME @@ -1222,20 +1340,58 @@ CONTAINS CALL IO_Format_write_select(TPFILE,GLFI,GNC4) ! IF (IRESP==0) THEN - IF (GSMONOPROC) THEN ! sequential execution - ! IF (LPACK .AND. L1D .AND. YDIR=='XY') THEN - 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 (GSMONOPROC) THEN ! sequential execution + ! IF (LPACK .AND. L1D .AND. YDIR=='XY') THEN + IF (LPACK .AND. L1D .AND. SIZE(PFIELD,1)==IHEXTOT .AND. SIZE(PFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) + tzfield%ndimlist(2) = tzfield%ndimlist(4) + tzfield%ndimlist(3) = tzfield%ndimlist(5) + tzfield%ndimlist(4) = tzfield%ndimlist(6) !Necessary if time dimension + tzfield%ndimlist(5:) = NMNHDIM_UNUSED + end if + zfieldp3d => pfield(jphext + 1, jphext + 1, :, :, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp3d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp3d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + zfieldp => pfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1, :, :, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp, iresp ) + endif ! 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 (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,ZFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,ZFIELDP,IRESP) - ELSE - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PFIELD,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PFIELD,IRESP) - END IF - ELSE + ELSEIF (LPACK .AND. L2D .AND. SIZE(PFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) + tzfield%ndimlist(4) = tzfield%ndimlist(5) + tzfield%ndimlist(5) = tzfield%ndimlist(6) !Necessary if time dimension + tzfield%ndimlist(6:) = NMNHDIM_UNUSED + end if + zfieldp4d => pfield(:, jphext + 1, :, :, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp4d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp4d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(2) /= NMNHDIM_UNKNOWN ) tzfield%ndimlist(2) = NMNHDIM_ONE + zfieldp => pfield(:, jphext + 1 : jphext + 1, :, :, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, zfieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, zfieldp, iresp ) + endif + ELSE + IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PFIELD,IRESP) + IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PFIELD,IRESP) + END IF + ELSE CALL MPI_ALLREDUCE(SIZE(PFIELD),ISIZEMAX,1,MNHINT_MPI,MPI_MAX,TPFILE%NMPICOMM,IRESP) IF (ISIZEMAX==0) THEN CALL PRINT_MSG(NVERB_INFO,'IO','IO_Field_write_byfield_X5','ignoring variable with a zero size ('//TRIM(YRECFM)//')') @@ -1633,6 +1789,7 @@ CONTAINS SUBROUTINE IO_Field_write_byfield_N2(TPFILE,TPFIELD,KFIELD,KRESP) + use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, L1D, L2D, LPACK USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -1658,6 +1815,8 @@ CONTAINS INTEGER :: IERR INTEGER :: ISIZEMAX INTEGER :: IRESP + integer :: ifieldp0d + integer,dimension(:), pointer :: ifieldp1d INTEGER,DIMENSION(:,:),POINTER :: IFIELDP LOGICAL :: GALLOC LOGICAL :: GLFI, GNC4 @@ -1667,6 +1826,7 @@ CONTAINS INTEGER :: IHEXTOT CHARACTER(LEN=:),ALLOCATABLE :: YMSG CHARACTER(LEN=6) :: YRESP + type(tfielddata) :: tzfield ! YFILEM = TPFILE%CNAME YRECFM = TPFIELD%CMNHNAME @@ -1688,21 +1848,53 @@ CONTAINS CALL IO_Format_write_select(TPFILE,GLFI,GNC4) ! IF (IRESP==0) 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) - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,IFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,IFIELDP,IRESP) + IF (GSMONOPROC) THEN ! sequential execution + IF (LPACK .AND. L1D .AND. SIZE(KFIELD,1)==IHEXTOT .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) !Necessary if time dimension + tzfield%ndimlist(2:) = NMNHDIM_UNUSED + end if + ifieldp0d = kfield(jphext + 1, jphext + 1) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, ifieldp0d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, ifieldp0d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + ifieldp => kfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1) + if ( glfi) call IO_Field_write_lfi( tpfile, tzfield, ifieldp, iresp ) + if ( gnc4) call IO_Field_write_nc4( tpfile, tzfield, ifieldp, iresp ) + endif ! ELSE IF (LPACK .AND. L2D .AND. YDIR=='XY') THEN - ELSEIF (LPACK .AND. L2D .AND. SIZE(KFIELD,2)==IHEXTOT) THEN - IFIELDP=>KFIELD(:,JPHEXT+1:JPHEXT+1) - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,IFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,IFIELDP,IRESP) - ELSE - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,KFIELD,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,KFIELD,IRESP) - END IF - ELSE ! multiprocesses execution + ELSEIF (LPACK .AND. L2D .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) !Necessary if time dimension + tzfield%ndimlist(3:) = NMNHDIM_UNUSED + end if + ifieldp1d => kfield(:, jphext + 1) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, ifieldp1d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, ifieldp1d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = NMNHDIM_ONE + end if + ifieldp => kfield(:, jphext + 1 : jphext + 1) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, ifieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, ifieldp, iresp ) + endif + ELSE + IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,KFIELD,IRESP) + IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,KFIELD,IRESP) + END IF + ELSE ! multiprocesses execution CALL MPI_ALLREDUCE(SIZE(KFIELD),ISIZEMAX,1,MNHINT_MPI,MPI_MAX,TPFILE%NMPICOMM,IRESP) IF (ISIZEMAX==0) THEN CALL PRINT_MSG(NVERB_INFO,'IO','IO_Field_write_byfield_N2','ignoring variable with a zero size ('//TRIM(YRECFM)//')') @@ -1781,6 +1973,7 @@ CONTAINS END SUBROUTINE IO_Field_write_byname_N3 SUBROUTINE IO_Field_write_byfield_N3(TPFILE,TPFIELD,KFIELD,KRESP) + use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED USE MODD_IO, ONLY: GSMONOPROC, ISP, L1D, L2D, LPACK USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_TIMEZ, ONLY: TIMEZ @@ -1806,7 +1999,9 @@ CONTAINS INTEGER :: IERR INTEGER :: ISIZEMAX INTEGER :: IRESP - INTEGER,DIMENSION(:,:,:),POINTER :: IFIELDP + integer, dimension(:), pointer :: ifieldp1d + integer, dimension(:,:), pointer :: ifieldp2d + INTEGER, DIMENSION(:,:,:), POINTER :: IFIELDP LOGICAL :: GALLOC LOGICAL :: GLFI, GNC4 ! @@ -1814,6 +2009,7 @@ CONTAINS INTEGER :: IHEXTOT CHARACTER(LEN=:),ALLOCATABLE :: YMSG CHARACTER(LEN=6) :: YRESP + type(tfielddata) :: tzfield ! YFILEM = TPFILE%CNAME YRECFM = TPFIELD%CMNHNAME @@ -1835,21 +2031,53 @@ CONTAINS CALL IO_Format_write_select(TPFILE,GLFI,GNC4) ! IF (IRESP==0) 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,:) - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,IFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,IFIELDP,IRESP) + IF (GSMONOPROC) THEN ! sequential execution + IF (LPACK .AND. L1D .AND. SIZE(KFIELD,1)==IHEXTOT .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 2 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1) = tzfield%ndimlist(3) + tzfield%ndimlist(2) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(3:) = NMNHDIM_UNUSED + end if + ifieldp1d => kfield(jphext + 1, jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, ifieldp1d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, ifieldp1d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(1:2) = NMNHDIM_ONE + end if + ifieldp => kfield(jphext + 1 : jphext + 1, jphext + 1 : jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, ifieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, ifieldp, iresp ) + endif ! ELSE IF (LPACK .AND. L2D .AND. YDIR=='XY') THEN - ELSEIF (LPACK .AND. L2D .AND. SIZE(KFIELD,2)==IHEXTOT) THEN - IFIELDP=>KFIELD(:,JPHEXT+1:JPHEXT+1,:) - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,IFIELDP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,IFIELDP,IRESP) - ELSE - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,KFIELD,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,KFIELD,IRESP) - END IF - ELSE ! multiprocesses execution + ELSEIF (LPACK .AND. L2D .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(4:) = NMNHDIM_UNUSED + end if + ifieldp2d => kfield(:, jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, ifieldp2d, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, ifieldp2d, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(2) /= NMNHDIM_UNKNOWN ) tzfield%ndimlist(2) = NMNHDIM_ONE + ifieldp => kfield(:, jphext + 1 : jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, ifieldp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, ifieldp, iresp ) + endif + ELSE + IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,KFIELD,IRESP) + IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,KFIELD,IRESP) + END IF + ELSE ! multiprocesses execution CALL MPI_ALLREDUCE(SIZE(KFIELD),ISIZEMAX,1,MNHINT_MPI,MPI_MAX,TPFILE%NMPICOMM,IRESP) IF (ISIZEMAX==0) THEN CALL PRINT_MSG(NVERB_INFO,'IO','IO_Field_write_byfield_N3','ignoring variable with a zero size ('//TRIM(YRECFM)//')') @@ -2489,7 +2717,8 @@ CONTAINS SUBROUTINE IO_Field_write_byfield_lb(TPFILE,TPFIELD,KL3D,PLB,KRESP) ! - USE MODD_IO, ONLY: GSMONOPROC, ISNPROC, ISP, L1D, L2D, LPACK + use modd_field, only: NMNHDIM_UNKNOWN, NMNHDIM_ONE, NMNHDIM_UNUSED + USE MODD_IO, ONLY: GSMONOPROC, ISNPROC, ISP, L2D, LPACK USE MODD_PARAMETERS_ll, ONLY: JPHEXT USE MODD_VAR_ll, ONLY: MNH_STATUSES_IGNORE ! @@ -2514,6 +2743,7 @@ CONTAINS INTEGER :: IERR INTEGER :: IRESP REAL,DIMENSION(:,:,:),ALLOCATABLE,TARGET :: Z3D + real,dimension(:,:), pointer :: tx2dp REAL,DIMENSION(:,:,:), POINTER :: TX3DP INTEGER :: IIMAX_ll,IJMAX_ll INTEGER :: JI @@ -2528,6 +2758,7 @@ CONTAINS TYPE(TX_3DP),ALLOCATABLE,DIMENSION(:) :: T_TX3DP CHARACTER(LEN=:),ALLOCATABLE :: YMSG CHARACTER(LEN=6) :: YRESP + type(tfielddata) :: tzfield ! YFILEM = TPFILE%CNAME YRECFM = TPFIELD%CMNHNAME @@ -2558,16 +2789,31 @@ CONTAINS CALL IO_Format_write_select(TPFILE,GLFI,GNC4) ! IF (IRESP==0) THEN - IF (GSMONOPROC) THEN ! sequential execution - IF (LPACK .AND. L2D) THEN - TX3DP=>PLB(:,JPHEXT+1:JPHEXT+1,:) - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,TX3DP,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,TX3DP,IRESP) - ELSE - IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PLB,IRESP) - IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PLB,IRESP) - END IF - ELSE + IF (GSMONOPROC) THEN ! sequential execution + IF (LPACK .AND. L2D) THEN + if ( tpfile%ldimreduced ) then + tzfield = tpfield + tzfield%ndims = tzfield%ndims - 1 + if ( tzfield%ndimlist(1) /= NMNHDIM_UNKNOWN ) then + tzfield%ndimlist(2) = tzfield%ndimlist(3) + tzfield%ndimlist(3) = tzfield%ndimlist(4) !Necessary if time dimension + tzfield%ndimlist(4:) = NMNHDIM_UNUSED + end if + tx2dp => plb(:, jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, tx2dp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, tx2dp, iresp ) + else + tzfield = tpfield + if ( tzfield%ndimlist(2) /= NMNHDIM_UNKNOWN ) tzfield%ndimlist(2) = NMNHDIM_ONE + tx3dp => plb(:, jphext + 1 : jphext + 1, :) + if ( glfi ) call IO_Field_write_lfi( tpfile, tzfield, tx3dp, iresp ) + if ( gnc4 ) call IO_Field_write_nc4( tpfile, tzfield, tx3dp, iresp ) + endif + ELSE + IF (GLFI) CALL IO_Field_write_lfi(TPFILE,TPFIELD,PLB,IRESP) + IF (GNC4) CALL IO_Field_write_nc4(TPFILE,TPFIELD,PLB,IRESP) + END IF + ELSE IF (ISP == TPFILE%NMASTER_RANK) THEN ! I/O proc case CALL GET_GLOBALDIMS_ll(IIMAX_ll,IJMAX_ll) diff --git a/src/LIB/SURCOUCHE/src/mode_io_file_nc4.f90 b/src/LIB/SURCOUCHE/src/mode_io_file_nc4.f90 index 5a80880fa4e74e5bcee57266b095c9bead5d8e6e..58d7bfedcd9c7d8dabd0c75e97d13463eda08085 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_file_nc4.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_file_nc4.f90 @@ -17,9 +17,9 @@ ! P. Wautelet 05/03/2019: rename IO subroutines and modules ! P. Wautelet 07/03/2019: bugfix: io_set_mnhversion must be called by all the processes ! P. Wautelet 18/09/2019: correct support of 64bit integers (MNH_INT=8) -! +! P. Wautelet 22/09/2020: use ldimreduced to allow reduction in the number of dimensions of fields (used by 2D simulations) !----------------------------------------------------------------- -#if defined(MNH_IOCDF4) +#ifdef MNH_IOCDF4 module mode_io_file_nc4 use modd_io, only: tfiledata @@ -126,11 +126,42 @@ subroutine IO_File_open_nc4(tpfile) if (trim(tpfile%cmode) == 'READ') then call IO_Mnhversion_get(tpfile) if (tpfile%lmaster) call IO_Cleanly_closed_check_nc4(tpfile) + call IO_Are_dimension_reduced(tpfile) end if end subroutine IO_File_open_nc4 +subroutine IO_Are_dimension_reduced(tpfile) + type(tfiledata), intent(inout) :: tpfile + + integer(kind=CDFINT) :: istatus + character(len=1) :: ydimred + + call print_msg(NVERB_DEBUG,'IO','IO_Are_dimension_reduced','called for '//trim(tpfile%cname)) + + if ( tpfile%nmnhversion(1) < 5 .or. ( tpfile%nmnhversion(1) == 5 .and. tpfile%nmnhversion(2) < 5 ) ) then + call Print_msg( NVERB_DEBUG, 'IO', 'IO_Are_dimension_reduced', 'ldimreduced set to false (created with MesoNH < 5.5.0)' ) + tpfile%ldimreduced = .false. + else + istatus = NF90_GET_ATT( tpfile%nncid, NF90_GLOBAL, 'MNH_REDUCE_DIMENSIONS_IN_FILES', ydimred ) + if ( istatus == NF90_NOERR ) then + if ( ydimred == '0' ) then + tpfile%ldimreduced = .false. + else if ( ydimred == '1' ) then + tpfile%ldimreduced = .true. + else + call Print_msg( NVERB_ERROR, 'IO', 'IO_Are_dimension_reduced', & + 'invalid value for MNH_REDUCE_DIMENSIONS_IN_FILES attribute' ) + end if + else !attribute not found + call Print_msg( NVERB_ERROR, 'IO', 'IO_Are_dimension_reduced', 'MNH_REDUCE_DIMENSIONS_IN_FILES attribute not found' ) + end if + end if + +end subroutine IO_Are_dimension_reduced + + subroutine IO_Cleanly_closed_check_nc4(tpfile) type(tfiledata), intent(in) :: tpfile diff --git a/src/LIB/SURCOUCHE/src/mode_io_write_nc4.f90 b/src/LIB/SURCOUCHE/src/mode_io_write_nc4.f90 index 6a91f4e926b93d0c56e6025b66fb85daaacaa83e..7b49c02b5f327832ebef39e88f9a59c7815c55aa 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_write_nc4.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_write_nc4.f90 @@ -20,6 +20,7 @@ ! P. Wautelet 11/02/2020: add 'dims' attribute in IO_Write_field_header_split_nc4 ! P. Wautelet 25/06/2020: remove workaround for netCDF bug (see 19/09/2019) ! P. Wautelet 14/09/2020: IO_Coordvar_write_nc4: do not store 'time' coordinate in diachronic files +! P. Wautelet 22/09/2020: add ldimreduced field to allow reduction in the number of dimensions of fields (used by 2D simulations) !----------------------------------------------------------------- #ifdef MNH_IOCDF4 module mode_io_write_nc4 @@ -2178,6 +2179,12 @@ IF (TPFILE%LMASTER) THEN #endif IF (ISTATUS /= NF90_NOERR) CALL IO_Err_handle_nc4(istatus,'IO_FILE_WRITE_HEADER','NF90_PUT_ATT','MNH_INT') + if ( tpfile%ldimreduced ) then + istatus = NF90_PUT_ATT( tpfile%nncid, NF90_GLOBAL, 'MNH_REDUCE_DIMENSIONS_IN_FILES', '1') + else + istatus = NF90_PUT_ATT( tpfile%nncid, NF90_GLOBAL, 'MNH_REDUCE_DIMENSIONS_IN_FILES', '0') + endif + !title !history