diff --git a/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 b/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 index b6d25f3475352a9d2d76ea85e33a140ce6250e7b..f2b16e1cbb3996b6e29e5ec68f3a0cd07484ed9d 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_field_read.f90 @@ -14,6 +14,7 @@ ! P. Wautelet 10/04/2019: replace ABORT and STOP calls by Print_msg ! P. Wautelet 12/04/2019: use MNHTIME for time measurement variables ! P. Wautelet 26/04/2019: use modd_precision parameters for datatypes of MPI communications +! P. Wautelet 25/06/2019: added IO_Field_read for 3D integer arrays (IO_Field_read_byname_N3 and IO_Field_read_byfield_N3) !----------------------------------------------------------------- MODULE MODE_IO_FIELD_READ @@ -41,7 +42,7 @@ INTERFACE IO_Field_read IO_Field_read_byname_X4, IO_Field_read_byname_X5, & IO_Field_read_byname_X6, & IO_Field_read_byname_N0, IO_Field_read_byname_N1, & - IO_Field_read_byname_N2, & + IO_Field_read_byname_N2, IO_Field_read_byname_N3, & IO_Field_read_byname_L0, IO_Field_read_byname_L1, & IO_Field_read_byname_C0, & IO_Field_read_byname_T0, & @@ -50,7 +51,7 @@ INTERFACE IO_Field_read IO_Field_read_byfield_X4,IO_Field_read_byfield_X5, & IO_Field_read_byfield_X6, & IO_Field_read_byfield_N0,IO_Field_read_byfield_N1, & - IO_Field_read_byfield_N2, & + IO_Field_read_byfield_N2,IO_Field_read_byfield_N3, & IO_Field_read_byfield_L0,IO_Field_read_byfield_L1, & IO_Field_read_byfield_C0, & IO_Field_read_byfield_T0 @@ -1468,6 +1469,129 @@ IF (PRESENT(KRESP)) KRESP = IRESP END SUBROUTINE IO_Field_read_byfield_N2 +SUBROUTINE IO_Field_read_byname_N3(TPFILE,HNAME,KFIELD,KRESP) +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +CHARACTER(LEN=*), INTENT(IN) :: HNAME ! name of the field to write +INTEGER,DIMENSION(:,:,:),INTENT(INOUT) :: KFIELD ! array containing the data field +INTEGER,OPTIONAL, INTENT(OUT) :: KRESP ! return-code +! +INTEGER :: ID ! Index of the field +INTEGER :: IRESP ! return_code +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byname_N3',TRIM(TPFILE%CNAME)//': reading '//TRIM(HNAME)) +! +CALL FIND_FIELD_ID_FROM_MNHNAME(HNAME,ID,IRESP) +! +IF(IRESP==0) CALL IO_Field_read(TPFILE,TFIELDLIST(ID),KFIELD,IRESP) +! +IF (PRESENT(KRESP)) KRESP = IRESP +! +END SUBROUTINE IO_Field_read_byname_N3 + +SUBROUTINE IO_Field_read_byfield_N3(TPFILE,TPFIELD,KFIELD,KRESP) +! +USE MODD_IO, ONLY: GSMONOPROC, ISP, LPACK, L1D, L2D +USE MODD_PARAMETERS_ll, ONLY: JPHEXT +USE MODD_TIMEZ, ONLY: TIMEZ +! +USE MODE_ALLOCBUFFER_ll +USE MODE_SCATTER_ll +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +INTEGER,DIMENSION(:,:,:),TARGET,INTENT(INOUT) :: KFIELD ! array containing the data field +INTEGER, OPTIONAL, INTENT(OUT) :: KRESP ! return-code +! +INTEGER :: IERR +INTEGER,DIMENSION(:,:,:),POINTER :: IFIELDP +LOGICAL :: GALLOC +INTEGER :: IRESP +INTEGER :: IHEXTOT +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_byfield_N3',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) +! +GALLOC = .FALSE. +IRESP = 0 +IFIELDP => NULL() +! +IHEXTOT = 2*JPHEXT+1 +CALL IO_File_read_check(TPFILE,'IO_Field_read_byfield_N3',IRESP) +! +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 (TPFILE%CFORMAT=='NETCDF4') THEN + CALL IO_Field_read_nc4(TPFILE,TPFIELD,IFIELDP,IRESP) + ELSE IF (TPFILE%CFORMAT=='LFI') THEN + CALL IO_Field_read_lfi(TPFILE,TPFIELD,IFIELDP,IRESP) + ELSE IF (TPFILE%CFORMAT=='LFICDF4') THEN + CALL IO_Field_read_nc4(TPFILE,TPFIELD,IFIELDP,IRESP) + END IF + IF (LPACK .AND. L1D .AND. SIZE(KFIELD,1)==IHEXTOT .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + KFIELD(:,:,:)=SPREAD(SPREAD(KFIELD(JPHEXT+1,JPHEXT+1,:),DIM=1,NCOPIES=IHEXTOT),DIM=2,NCOPIES=IHEXTOT) + ELSE IF (LPACK .AND. L2D .AND. SIZE(KFIELD,2)==IHEXTOT) THEN + KFIELD(:,:,:)=SPREAD(KFIELD(:,JPHEXT+1,:),DIM=2,NCOPIES=IHEXTOT) + END IF + ELSE + IF (ISP == TPFILE%NMASTER_RANK) THEN + ! I/O process case + CALL ALLOCBUFFER_ll(IFIELDP,KFIELD,TPFIELD%CDIR,GALLOC) + IF (TPFILE%CFORMAT=='NETCDF4') THEN + CALL IO_Field_read_nc4(TPFILE,TPFIELD,IFIELDP,IRESP) + ELSE IF (TPFILE%CFORMAT=='LFI') THEN + CALL IO_Field_read_lfi(TPFILE,TPFIELD,IFIELDP,IRESP) + ELSE IF (TPFILE%CFORMAT=='LFICDF4') THEN + CALL IO_Field_read_nc4(TPFILE,TPFIELD,IFIELDP,IRESP) + END IF + ELSE + !Not really necessary but useful to suppress alerts with Valgrind + ALLOCATE(IFIELDP(0,0,0)) + GALLOC = .TRUE. + END IF + ! + CALL MPI_BCAST(IRESP,1,MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + ! + !Broadcast header only if IRESP==-111 + !because metadata of field has been modified in IO_Field_read_xxx + IF (IRESP==-111) CALL IO_Field_metadata_bcast(TPFILE,TPFIELD) + ! + IF (TPFIELD%CDIR == 'XX' .OR. TPFIELD%CDIR == 'YY') THEN + ! XX or YY Scatter Field + CALL SCATTER_XXFIELD(TPFIELD%CDIR,IFIELDP,KFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) + ! Broadcast Field + CALL MPI_BCAST(KFIELD,SIZE(KFIELD),MNHREAL_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + ELSE IF (TPFIELD%CDIR == 'XY') THEN + IF (LPACK .AND. L2D) THEN + ! 2D compact case + CALL SCATTER_XXFIELD('XX',IFIELDP(:,1,:),KFIELD(:,JPHEXT+1,:),TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) + KFIELD(:,:,:) = SPREAD(KFIELD(:,JPHEXT+1,:),DIM=2,NCOPIES=IHEXTOT) + ELSE + ! XY Scatter Field + CALL SCATTER_XYFIELD(IFIELDP,KFIELD,TPFILE%NMASTER_RANK,TPFILE%NMPICOMM) + END IF + ELSE + IF (ISP == TPFILE%NMASTER_RANK) KFIELD = IFIELDP + CALL MPI_BCAST(KFIELD,SIZE(KFIELD),MNHINT_MPI,TPFILE%NMASTER_RANK-1,TPFILE%NMPICOMM,IERR) + END IF + END IF +END IF +! +IF (GALLOC) DEALLOCATE (IFIELDP) +! +IF (IRESP==-111) IRESP = 0 !-111 is not really an error (metadata has changed) +! +IF (PRESENT(KRESP)) KRESP = IRESP +! +END SUBROUTINE IO_Field_read_byfield_N3 + + SUBROUTINE IO_Field_read_byname_L0(TPFILE,HNAME,OFIELD,KRESP) ! TYPE(TFILEDATA), INTENT(IN) :: TPFILE diff --git a/src/LIB/SURCOUCHE/src/mode_io_read_lfi.f90 b/src/LIB/SURCOUCHE/src/mode_io_read_lfi.f90 index 525930eefaaacc6ab5082f76e814085488220ca2..01b03897d2134c902a7b0aa0c1384771bdc04557 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_read_lfi.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_read_lfi.f90 @@ -9,6 +9,7 @@ ! P. Wautelet 14/12/2018: split fmreadwrit.f90 ! P. Wautelet 21/02/2019: bugfix: intent of read fields: OUT->INOUT to keep initial value if not found in file ! P. Wautelet 05/03/2019: rename IO subroutines and modules +! P. Wautelet 25/06/2019: added IO_Field_read for 3D integer arrays (IO_Field_read_lfi_N3) !----------------------------------------------------------------- module mode_io_read_lfi ! @@ -34,7 +35,7 @@ INTERFACE IO_Field_read_lfi IO_Field_read_lfi_X4, IO_Field_read_lfi_X5, & IO_Field_read_lfi_X6, & IO_Field_read_lfi_N0, IO_Field_read_lfi_N1, & - IO_Field_read_lfi_N2, & + IO_Field_read_lfi_N2, IO_Field_read_lfi_N3, & IO_Field_read_lfi_L0, IO_Field_read_lfi_L1, & IO_Field_read_lfi_C0, & IO_Field_read_lfi_T0 @@ -387,6 +388,40 @@ IF (ALLOCATED(IWORK)) DEALLOCATE(IWORK) END SUBROUTINE IO_Field_read_lfi_N2 ! ! +SUBROUTINE IO_Field_read_lfi_N3(TPFILE,TPFIELD,KFIELD,KRESP) +USE MODE_MSG +! +IMPLICIT NONE +! +!* 0.1 Declarations of arguments +! +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +INTEGER,DIMENSION(:,:,:),INTENT(INOUT) :: KFIELD ! array containing the data field +INTEGER, INTENT(OUT) :: KRESP ! return-code if problems occured +! +!* 0.2 Declarations of local variables +! +INTEGER(KIND=LFIINT) :: IRESP,ITOTAL +INTEGER :: ILENG +INTEGER(KIND=8),DIMENSION(:),ALLOCATABLE :: IWORK +LOGICAL :: GGOOD +! +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_lfi_N3',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) +! +ILENG = SIZE(KFIELD) +! +CALL IO_Field_read_check_lfi(TPFILE,TPFIELD,ILENG,IWORK,ITOTAL,IRESP,GGOOD) +! +IF (GGOOD) KFIELD(:,:,:) = RESHAPE(IWORK(IWORK(2)+3:),SHAPE(KFIELD)) +! +KRESP=IRESP +! +IF (ALLOCATED(IWORK)) DEALLOCATE(IWORK) +! +END SUBROUTINE IO_Field_read_lfi_N3 +! +! SUBROUTINE IO_Field_read_lfi_L0(TPFILE,TPFIELD,OFIELD,KRESP) USE MODE_MSG ! diff --git a/src/LIB/SURCOUCHE/src/mode_io_read_nc4.f90 b/src/LIB/SURCOUCHE/src/mode_io_read_nc4.f90 index 3aaed8fb95ca02eccf016fb1b8256d33b3dc435f..74c69fbcf0a9f2d061d80c7e7d554c61dad7c846 100644 --- a/src/LIB/SURCOUCHE/src/mode_io_read_nc4.f90 +++ b/src/LIB/SURCOUCHE/src/mode_io_read_nc4.f90 @@ -11,6 +11,7 @@ ! P. Wautelet 10/01/2019: replace handle_err by IO_Err_handle_nc4 for better netCDF error messages ! P. Wautelet 21/02/2019: bugfix: intent of read fields: OUT->INOUT to keep initial value if not found in file ! P. Wautelet 05/03/2019: rename IO subroutines and modules +! P. Wautelet 25/06/2019: added IO_Field_read for 3D integer arrays (IO_Field_read_nc4_N3) !----------------------------------------------------------------- #if defined(MNH_IOCDF4) module mode_io_read_nc4 @@ -39,7 +40,7 @@ INTERFACE IO_Field_read_nc4 IO_Field_read_nc4_X4,IO_Field_read_nc4_X5, & IO_Field_read_nc4_X6, & IO_Field_read_nc4_N0,IO_Field_read_nc4_N1, & - IO_Field_read_nc4_N2, & + IO_Field_read_nc4_N2,IO_Field_read_nc4_N3, & IO_Field_read_nc4_L0,IO_Field_read_nc4_L1, & IO_Field_read_nc4_C0, & IO_Field_read_nc4_T0 @@ -968,6 +969,77 @@ KRESP = IRESP END SUBROUTINE IO_Field_read_nc4_N2 +SUBROUTINE IO_Field_read_nc4_N3(TPFILE, TPFIELD, KFIELD, KRESP) +TYPE(TFILEDATA), INTENT(IN) :: TPFILE +TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD +INTEGER, DIMENSION(:,:,:), INTENT(INOUT) :: KFIELD +INTEGER, INTENT(OUT) :: KRESP ! return-code + +INTEGER(KIND=CDFINT) :: STATUS +INTEGER(KIND=CDFINT) :: INCID +INTEGER(KIND=CDFINT) :: IVARID +INTEGER(KIND=CDFINT) :: ITYPE ! variable type +INTEGER(KIND=CDFINT) :: IDIMS ! number of dimensions +INTEGER(KIND=CDFINT),DIMENSION(NF90_MAX_VAR_DIMS) :: IVDIMS +CHARACTER(LEN=30) :: YVARNAME +INTEGER(KIND=CDFINT),DIMENSION(3) :: IDIMLEN +INTEGER :: IRESP + +CALL PRINT_MSG(NVERB_DEBUG,'IO','IO_Field_read_nc4_N3',TRIM(TPFILE%CNAME)//': reading '//TRIM(TPFIELD%CMNHNAME)) + +IRESP = 0 +! Get the Netcdf file ID +INCID = TPFILE%NNCID + +CALL IO_Mnhname_clean(TPFIELD%CMNHNAME,YVARNAME) + +! Get variable ID, NDIMS and TYPE +STATUS = NF90_INQ_VARID(INCID, YVARNAME, IVARID) +IF (STATUS /= NF90_NOERR) THEN + CALL IO_Err_handle_nc4(status,'IO_Field_read_nc4_N3','NF90_INQ_VARID',TRIM(YVARNAME),IRESP) + GOTO 1000 +END IF +STATUS = NF90_INQUIRE_VARIABLE(INCID, IVARID, XTYPE=ITYPE, NDIMS=IDIMS, DIMIDS=IVDIMS) +IF (STATUS /= NF90_NOERR) CALL IO_Err_handle_nc4(status,'IO_Field_read_nc4_N3','NF90_INQUIRE_VARIABLE',TRIM(YVARNAME)) + +!Neglect the time dimension (of size 1) +IF (TPFIELD%LTIMEDEP) IDIMS=IDIMS-1 + +!NF90_INT1 is for the case a boolean was written +IF (IDIMS == SIZE(SHAPE(KFIELD)) .AND. (ITYPE == NF90_INT .OR. ITYPE == NF90_INT64 .OR. ITYPE == NF90_INT1) ) THEN + ! Check size of variable before reading + STATUS = NF90_INQUIRE_DIMENSION(INCID, IVDIMS(1), LEN=IDIMLEN(1)) + IF (STATUS /= NF90_NOERR) CALL IO_Err_handle_nc4(status,'IO_Field_read_nc4_N3','NF90_INQUIRE_DIMENSION',TRIM(YVARNAME)) + STATUS = NF90_INQUIRE_DIMENSION(INCID, IVDIMS(2), LEN=IDIMLEN(2)) + IF (STATUS /= NF90_NOERR) CALL IO_Err_handle_nc4(status,'IO_Field_read_nc4_N3','NF90_INQUIRE_DIMENSION',TRIM(YVARNAME)) + STATUS = NF90_INQUIRE_DIMENSION(INCID, IVDIMS(3), LEN=IDIMLEN(3)) + IF (STATUS /= NF90_NOERR) CALL IO_Err_handle_nc4(status,'IO_Field_read_nc4_N3','NF90_INQUIRE_DIMENSION',TRIM(YVARNAME)) + + IF (IDIMLEN(1) == SIZE(KFIELD,1) .AND. IDIMLEN(2) == SIZE(KFIELD,2) .AND. IDIMLEN(3) == SIZE(KFIELD,3)) THEN + ! Read variable + STATUS = NF90_GET_VAR(INCID, IVARID, KFIELD) + IF (STATUS /= NF90_NOERR) THEN + CALL IO_Err_handle_nc4(status,'IO_Field_read_nc4_N3','NF90_GET_VAR',TRIM(YVARNAME),IRESP) + GOTO 1000 + END IF + ! Read and check attributes of variable + CALL IO_Field_attr_read_check_nc4(TPFILE,TPFIELD,IVARID,IRESP) + ELSE + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_Field_read_nc4_N3',TRIM(TPFILE%CNAME)//': '//TRIM(YVARNAME)// & + ' not read (wrong size)') + IRESP = -3 + END IF +ELSE + CALL PRINT_MSG(NVERB_ERROR,'IO','IO_Field_read_nc4_N3',TRIM(TPFILE%CNAME)//': '//TRIM(YVARNAME)// & + ' not read (wrong number of dimensions or wrong type)') + IRESP = -3 +END IF + +1000 CONTINUE +KRESP = IRESP + +END SUBROUTINE IO_Field_read_nc4_N3 + SUBROUTINE IO_Field_read_nc4_L0(TPFILE, TPFIELD, OFIELD, KRESP) TYPE(TFILEDATA), INTENT(IN) :: TPFILE TYPE(TFIELDDATA), INTENT(INOUT) :: TPFIELD diff --git a/src/LIB/SURCOUCHE/src/mode_scatter.f90 b/src/LIB/SURCOUCHE/src/mode_scatter.f90 index f16f8f6145411a02a68b86cfa0947bf777adbd92..32eaa729052794702023468e113cecabaa913449 100644 --- a/src/LIB/SURCOUCHE/src/mode_scatter.f90 +++ b/src/LIB/SURCOUCHE/src/mode_scatter.f90 @@ -6,6 +6,7 @@ ! Modifications: ! J. Escobar 10/02/2012: bug in MPI_RECV: replace MPI_STATUSES_IGNORE with MPI_STATUS_IGNORE ! P. Wautelet 26/04/2019: use modd_precision parameters for datatypes of MPI communications +! P. Wautelet 25/06/2019: added IO_Field_read for 3D integer arrays (SCATTERXX_N3 and SCATTERXY_N3) !----------------------------------------------------------------- MODULE MODE_SCATTER_ll @@ -19,14 +20,17 @@ IMPLICIT NONE PRIVATE INTERFACE SCATTER_XXFIELD - MODULE PROCEDURE SCATTERXX_X1,SCATTERXX_X2,SCATTERXX_X3& - & ,SCATTERXX_X4,SCATTERXX_X5,SCATTERXX_X6,& - & SCATTERXX_N1,SCATTERXX_N2 + MODULE PROCEDURE & + SCATTERXX_X1, SCATTERXX_X2, SCATTERXX_X3, & + SCATTERXX_X4, SCATTERXX_X5, SCATTERXX_X6, & + SCATTERXX_N1, SCATTERXX_N2, SCATTERXX_N3 END INTERFACE -INTERFACE SCATTER_XYFIELD - MODULE PROCEDURE SCATTERXY_X2,SCATTERXY_X3,SCATTERXY_X4,& - & SCATTERXY_X5,SCATTERXY_X6,SCATTERXY_N2 +INTERFACE SCATTER_XYFIELD + MODULE PROCEDURE & + SCATTERXY_X2, SCATTERXY_X3, & + SCATTERXY_X4, SCATTERXY_X5, SCATTERXY_X6, & + SCATTERXY_N2, SCATTERXY_N3 END INTERFACE PUBLIC SCATTER_XXFIELD,SCATTER_XYFIELD,GET_DOMREAD_ll @@ -371,6 +375,44 @@ END IF END SUBROUTINE SCATTERXX_N2 +SUBROUTINE SCATTERXX_N3(HDIR,KSEND,KRECV,KROOT,KCOMM) +USE MODD_IO, ONLY: ISP, ISNPROC + +CHARACTER(LEN=*), INTENT(IN) :: HDIR +INTEGER,DIMENSION(:,:,:), TARGET, INTENT(IN) :: KSEND +INTEGER,DIMENSION(:,:,:), INTENT(INOUT) :: KRECV +INTEGER, INTENT(IN) :: KROOT +INTEGER, INTENT(IN) :: KCOMM + +INTEGER :: IERR +INTEGER :: JI +INTEGER :: IXO,IXE,IYO,IYE +INTEGER,DIMENSION(:,:,:), POINTER :: TI2DP + +IF (ISP == KROOT) THEN + DO JI = 1,ISNPROC + CALL GET_DOMREAD_ll(JI,IXO,IXE,IYO,IYE) + IF (HDIR == 'XX') THEN + TI2DP=>KSEND(IXO:IXE,:,:) + ELSE ! HDIR ='YY' + TI2DP=>KSEND(IYO:IYE,:,:) + END IF + + IF (ISP /= JI) THEN + CALL MPI_BSEND(TI2DP,SIZE(TI2DP),MNHINT_MPI,JI-1,199+KROOT,KCOMM& + & ,IERR) + ELSE + KRECV(:,:,:) = TI2DP(:,:,:) + END IF + END DO +ELSE + CALL MPI_RECV(KRECV,SIZE(KRECV),MNHINT_MPI,KROOT-1,199+KROOT,KCOMM& + & ,MPI_STATUS_IGNORE,IERR) +END IF + +END SUBROUTINE SCATTERXX_N3 + + SUBROUTINE SCATTERXY_X2(PSEND,PRECV,KROOT,KCOMM) USE MODD_IO, ONLY: ISP, ISNPROC USE MODD_VAR_ll, ONLY: MNH_STATUSES_IGNORE @@ -584,6 +626,39 @@ END IF END SUBROUTINE SCATTERXY_N2 +SUBROUTINE SCATTERXY_N3(KSEND,KRECV,KROOT,KCOMM) +USE MODD_IO, ONLY: ISP, ISNPROC + +INTEGER,DIMENSION(:,:,:),TARGET,INTENT(IN) :: KSEND +INTEGER,DIMENSION(:,:,:), INTENT(INOUT) :: KRECV +INTEGER, INTENT(IN) :: KROOT +INTEGER, INTENT(IN) :: KCOMM + +INTEGER :: IERR +INTEGER :: JI +INTEGER :: IXO,IXE,IYO,IYE +INTEGER,DIMENSION(:,:,:), POINTER :: TI3DP + +IF (ISP == KROOT) THEN + DO JI = 1,ISNPROC + CALL GET_DOMREAD_ll(JI,IXO,IXE,IYO,IYE) + TI3DP=>KSEND(IXO:IXE,IYO:IYE,:) + + IF (ISP /= JI) THEN + CALL MPI_BSEND(TI3DP,SIZE(TI3DP),MNHINT_MPI,JI-1,199+KROOT,KCOMM& + & ,IERR) + ELSE + KRECV(:,:,:) = TI3DP(:,:,:) + END IF + END DO +ELSE + CALL MPI_RECV(KRECV,SIZE(KRECV),MNHINT_MPI,KROOT-1,199+KROOT,KCOMM& + & ,MPI_STATUS_IGNORE,IERR) +END IF + +END SUBROUTINE SCATTERXY_N3 + + SUBROUTINE GET_DOMREAD_ll(KIP,KXOR,KXEND,KYOR,KYEND) USE MODD_STRUCTURE_ll, ONLY: MODELSPLITTING_ll USE MODD_VAR_ll, ONLY: TCRRT_PROCONF