*IF DEF,C96_1A,OR,DEF,C96_1B GPB3F403.257
*IF DEF,MPP GPB3F403.258
C ******************************COPYRIGHT****************************** GTS2F400.12752
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved. GTS2F400.12753
C GTS2F400.12754
C Use, duplication or disclosure of this code is subject to the GTS2F400.12755
C restrictions as set forth in the contract. GTS2F400.12756
C GTS2F400.12757
C Meteorological Office GTS2F400.12758
C London Road GTS2F400.12759
C BRACKNELL GTS2F400.12760
C Berkshire UK GTS2F400.12761
C RG12 2SZ GTS2F400.12762
C GTS2F400.12763
C If no contract has been raised with this copy of the code, the use, GTS2F400.12764
C duplication or disclosure of it is strictly prohibited. Permission GTS2F400.12765
C to do so must first be obtained in writing from the Head of Numerical GTS2F400.12766
C Modelling at the above address. GTS2F400.12767
C GTS2F400.12768
!+ Parallel UM interface to BUFFIN RDMULT1A.3
! RDMULT1A.4
! Subroutine Interface: RDMULT1A.5
SUBROUTINE READ_MULTI(NFT,D1,ISIZE,LEN_IO,LOCAL_LEN, 2,7RDMULT1A.6
& IOSTAT,LOOKUP,FIXHD12, GPB4F403.56
& ADDR_INFO,CMESSAGE) GPB4F403.57
IMPLICIT NONE RDMULT1A.8
! RDMULT1A.9
! Description: RDMULT1A.10
! This routine provides an interface to BUFFIN for the parallel RDMULT1A.11
! Unified Model. It is used where each process must read in a RDMULT1A.12
! local section of a global field. RDMULT1A.13
! RDMULT1A.14
! Method: RDMULT1A.15
! PE 0 reads in the global field, and then distributes the RDMULT1A.16
! relevant parts of it to each processor. RDMULT1A.17
! Fields compressed to land points are expanded by PE 0, and RDMULT1A.18
! recompressed after being received by the relevant processor. RDMULT1A.19
! RDMULT1A.20
! Current Code Owner: Paul Burton RDMULT1A.21
! RDMULT1A.22
! History: RDMULT1A.23
! Model Date Modification history from model version 3.5 RDMULT1A.24
! version RDMULT1A.25
! 3.5 5/1/95 New DECK created for the Parallel Unified RDMULT1A.26
! Model. P.Burton + D.Salmond RDMULT1A.27
! 4.1 18/3/96 Simplified communications P.Burton GPB0F401.325
! 4.2 18/11/96 Added *CALL AMAXSIZE for IOVARS comdeck GPB3F402.79
! Added atmos_ prefix to landmask fields P.Burton GPB3F402.80
! 4.2 17/9/96 Modify send/receive maps and change args to GPB2F402.190
! alltoall for GCOM/GCG v1.1 P.Burton GPB2F402.191
! 4.2 12/11/96 Detects non-constant PSTAR on pole rows APB1F402.64
! P.Burton APB1F402.65
! 4.2 18/10/96 New name for group of processors in scatter_field GPB0F402.211
! Allowed reading of LBC files GPB0F402.212
! P.Burton GPB0F402.213
! 4.3 18/03/97 Added D1_ADDR argument, and rewrote field GPB4F403.52
! recognition tests. Now handles diagnostic GPB4F403.53
! fields too. P.Burton GPB4F403.54
! Fix for reading in packed LBCS R.Barnes GPB4F403.55
! 4.4 13/06/97 Use GENERAL_SCATTER_FIELD for distributing data GPB0F404.70
! and change decomposition depending on model GPB0F404.71
! type of field being read in P.Burton GPB0F404.72
! 4.4 25/04/97 Changes to read well-formed records if the GBC5F404.220
! input dumpfile is in that format (almost PP file GBC5F404.221
! format) GBC5F404.222
! Author: Bob Carruthers, Cray Research GBC5F404.223
! 4.5 13/01/98 Replace SHMEM COMMON block with dynamic array GPB2F405.155
! P.Burton GPB2F405.156
! 4.5 14/05/98 Corrected error messages to say READ_MULTI GPB0F405.106
! P.Burton GPB0F405.107
! RDMULT1A.28
! Subroutine Arguments: RDMULT1A.29
RDMULT1A.30
INTEGER RDMULT1A.31
& NFT ! IN : FORTRAN unit number RDMULT1A.32
& ,ISIZE ! IN : no. of words to be read in (global field) RDMULT1A.33
& ,LEN_IO ! OUT : no. of words read in (global field) RDMULT1A.34
& ,LOCAL_LEN ! OUT : no. of words in local field RDMULT1A.35
& ,LOOKUP(64) ! IN : LOOKUP header from dump RDMULT1A.36
& ,FIXHD12 ! IN : 12th element of fixed length header RDMULT1A.37
! Required for dimensioning ADDR_INFO GPB4F403.58
*CALL D1_ADDR
GPB4F403.59
GPB4F403.60
INTEGER GPB4F403.61
& ADDR_INFO(D1_LIST_LEN) ! IN addressing info about field GPB4F403.62
GPB0F401.326
CHARACTER*(80) GPB0F401.327
& CMESSAGE ! OUT : Error message GPB0F401.328
RDMULT1A.38
REAL RDMULT1A.39
& IOSTAT ! OUT : Return code RDMULT1A.40
& ,D1(*) ! OUT : Array to read data in to RDMULT1A.41
RDMULT1A.42
! Parameters and Common blocks RDMULT1A.43
RDMULT1A.44
*CALL CLOOKADD
RDMULT1A.45
*CALL PARVARS
RDMULT1A.46
RDMULT1A.48
GPB0F401.333
! Local variables RDMULT1A.49
RDMULT1A.50
*CALL CPPXREF
GPB4F403.63
*CALL DECOMPTP
GPB0F404.73
*CALL CSMID
GPB4F403.65
INTEGER GPB0F404.74
& ICODE ! return code from GENERAL_SCATTER_FIELD GPB0F404.75
&, info ! GCOM return code GPB0F404.76
&, I ! loop counter GPB0F404.77
GPB0F404.78
INTEGER GPB0F404.79
& orig_decomp ! decomposition on entry GPB0F404.80
&, new_decomp ! decomposition to change to GPB0F404.81
&, io_ret_codes(2) ! return code from I/O GPB0F404.82
*IF DEF,GLOBAL,AND,-DEF,RECON APB1F402.66
REAL pstar_pole_val GPB0F404.83
APB1F402.68
INTEGER pstar_const APB1F402.69
COMMON /RDMULT_SHMEM_COM/ pstar_const APB1F402.70
*ENDIF APB1F402.71
GPB2F405.157
REAL buf(ISIZE*2) ! buffer for reading the field into GPB2F405.158
CDIR$ CACHE_ALIGN buf GPB2F405.159
RDMULT1A.53
! ------------------------------------------------------------------ RDMULT1A.54
RDMULT1A.55
IOSTAT=-1.0 GPB0F401.343
ICODE=-1 GPB0F401.344
LEN_IO=ISIZE GPB0F401.345
LOCAL_LEN=0 GPB0F401.346
GPB0F404.84
orig_decomp=current_decomp_type GPB0F404.85
new_decomp=orig_decomp GPB0F404.86
GPB0F404.87
IF ((ADDR_INFO(d1_imodl) .EQ. ATMOS_IM) .AND. GPB0F404.88
& (orig_decomp .NE. decomp_standard_atmos)) THEN GPB0F404.89
GPB0F404.90
new_decomp=decomp_standard_atmos GPB0F404.91
GPB0F404.92
ELSEIF ((ADDR_INFO(d1_imodl) .EQ. OCEAN_IM) .AND. GPB0F404.93
& (ADDR_INFO(d1_object_type) .EQ. prognostic) .AND. GPB0F404.94
& (orig_decomp .NE. decomp_standard_ocean)) THEN GPB0F404.95
GPB0F404.96
new_decomp=decomp_standard_ocean GPB0F404.97
GPB0F404.98
ELSEIF ((ADDR_INFO(d1_imodl) .EQ. OCEAN_IM) .AND. GPB0F404.99
& (ADDR_INFO(d1_object_type) .NE. prognostic) .AND. GPB0F404.100
& (orig_decomp .NE. decomp_nowrap_ocean)) THEN GPB0F404.101
GPB0F404.102
new_decomp=decomp_nowrap_ocean GPB0F404.103
GPB0F404.104
ENDIF GPB0F404.105
GPB0F404.106
IF (new_decomp .NE. orig_decomp) THEN GPB0F404.107
GPB0F404.108
icode=0 GPB0F404.109
CALL CHANGE_DECOMPOSITION
(new_decomp,icode) GPB0F404.110
GPB0F404.111
IF (icode .NE. 0) THEN GPB0F404.112
IF (mype .EQ. 0) THEN GPB0F404.113
WRITE(6,*) 'ERROR : READ_MULTI' GPB0F405.108
WRITE(6,*) 'Failed to change decomposition to ',new_decomp GPB0F404.115
WRITE(6,*) 'Field M,S,I ', GPB0F404.116
& ADDR_INFO(d1_imodl), GPB0F404.117
& ADDR_INFO(d1_section), GPB0F404.118
& ADDR_INFO(d1_item) GPB0F404.119
ENDIF GPB0F404.120
IOSTAT=-100 GPB0F404.121
CMESSAGE='READ_MULTI : Failed to change decomposition' GPB0F405.109
GOTO 9999 GPB0F404.123
ENDIF GPB0F404.124
GPB0F404.125
ENDIF GPB0F404.126
GPB0F401.347
! First thing to do is to read the field in to PE 0 GPB0F401.348
GPB0F401.349
IF (mype .EQ. 0) THEN GPB0F401.350
GPB0F401.351
! If lateral boundary data are 32-bit packed, GPB4F403.70
! need to halve buffin length, GPB4F403.71
IF (LOOKUP(LBHEM) .EQ. 99 .AND. GPB4F403.72
& MOD((LOOKUP(LBPACK)),10) .EQ. 2) THEN GPB4F403.73
len_io=(isize+1)/2 GBC5F404.225
CALL BUFFIN_SINGLE
(NFT,buf,(ISIZE+1)/2,LEN_IO,IOSTAT) GPB4F403.74
! and double LEN_IO to satisfy tests against ISIZE. GPB4F403.75
LEN_IO = 2*LEN_IO GPB4F403.76
ELSE GPB4F403.77
CALL BUFFIN_SINGLE
(NFT,buf,ISIZE,LEN_IO,IOSTAT) GPB4F403.78
END IF GPB4F403.79
GPB0F401.353
! Has the data been read in OK? GPB0F401.354
IF (.NOT.((IOSTAT .NE. -1.0) .OR. (LEN_IO .NE. ISIZE))) THEN GPB0F401.355
GPB0F401.356
! We must check to see if it is a 32 bit field on disk, and if GPB0F401.357
! so, expand it before doing anything with it. GPB0F401.358
IF (MOD((LOOKUP(LBPACK)),10) .EQ. 2) THEN GPB0F401.359
IF (LOOKUP(DATA_TYPE) .EQ. 1) THEN GPB0F401.360
! For special case of lateral boundary data, the length GPB4F403.80
! is given by ISIZE. GPB4F403.81
IF (LOOKUP(LBHEM) .EQ. 99) THEN GPB4F403.82
CALL EXPAND32B
( ISIZE , buf, FIXHD12 ) GPB4F403.83
ELSE GPB4F403.84
CALL EXPAND32B
( LOOKUP(LBLREC) , buf, FIXHD12 ) GPB0F401.361
ENDIF GPB4F403.85
ELSE GPB0F401.362
IOSTAT=100 GPB0F401.363
ENDIF GPB0F401.364
ENDIF GPB0F401.365
ENDIF GPB0F401.366
GPB0F401.367
io_ret_codes(1)=LEN_IO GPB0F401.368
io_ret_codes(2)=IOSTAT GPB0F401.369
ENDIF ! IF (mype .EQ. 0) GPB0F401.370
GPB0F401.371
! Broadcast the error codes, so we can check if anything's wrong GPB0F401.372
CALL GC_IBCAST(
333,2,0,nproc,info,io_ret_codes) GPB0F401.373
LEN_IO=io_ret_codes(1) GPB0F401.374
IOSTAT=io_ret_codes(2) GPB0F401.375
GPB0F401.376
IF ((IOSTAT .NE. -1.0) .OR. (LEN_IO .NE. ISIZE)) GOTO 9999 GPB0F401.377
GPB0F401.378
*IF DEF,GLOBAL,AND,-DEF,RECON GPB4F403.86
! Check the field for non-constant PSTAR at poles GPB4F403.87
IF ((ADDR_INFO(d1_imodl) .EQ. ATMOS_IM) .AND. GPB4F403.88
& (ADDR_INFO(d1_object_type) .EQ. prognostic) .AND. GPB4F403.89
& (ADDR_INFO(d1_section) .EQ. 0) .AND. GPB4F403.90
& (ADDR_INFO(d1_item) .EQ. 1)) THEN ! this is PSTAR GPB4F403.91
GPB4F403.92
pstar_const=0 GPB4F403.93
IF (mype .EQ. 0) THEN GPB4F403.94
GPB4F403.95
pstar_pole_val=buf(1) GPB4F403.96
DO I=2,glsize(1) ! NP row GPB4F403.97
IF ( buf(I) .NE. pstar_pole_val ) pstar_const=1 GPB4F403.98
ENDDO GPB4F403.99
GPB4F403.100
pstar_pole_val=buf((glsize(2)-1)*glsize(1) + 1) GPB4F403.101
DO I=2,glsize(1) ! SP row GPB4F403.102
IF ( buf(I+ (glsize(2)-1)*glsize(1)) .NE. pstar_pole_val ) GPB4F403.103
& pstar_const=1 GPB4F403.104
ENDDO GPB4F403.105
GPB4F403.106
ENDIF ! if mype .eq. 0 GPB4F403.107
GPB4F403.108
CALL GC_IMAX(
1,nproc,info,pstar_const) GPB4F403.109
GPB4F403.110
IF (pstar_const .EQ. 1) THEN GPB4F403.111
WRITE(6,*) 'Non constant polar PSTAR found in dump' GPB4F403.112
WRITE(6,*) 'Model run aborted' GPB4F403.113
IOSTAT=1.0 GPB4F403.114
CMESSAGE='Non constant polar PSTAR found in dump' GPB4F403.115
GOTO 9999 GPB4F403.116
ENDIF GPB4F403.117
GPB4F403.118
ENDIF ! is this a pstar field GPB4F403.119
*ENDIF GPB4F403.120
GPB4F403.121
! Now we can distribute it out to the other processes GPB0F401.379
GPB0F401.380
! For atmosphere zonal ozone fields - set to zonal grid type GPB0F404.127
GPB0F404.128
IF (( ADDR_INFO(d1_grid_type) .EQ. ppx_atm_ozone) .AND. GPB0F404.129
& ( LOOKUP(LBNPT) .EQ. 1)) THEN GPB0F404.130
GPB0F404.131
ADDR_INFO(d1_grid_type)=ppx_atm_tzonal GPB0F404.132
GPB0F404.133
ENDIF GPB0F404.134
GPB0F404.135
! Now decompose the field in buf to the local D1 arrays GPB0F404.136
GPB0F404.137
ICODE=0 GPB0F404.138
GPB0F404.139
CALL GENERAL_SCATTER_FIELD
( GPB0F404.140
& D1,buf,LOCAL_LEN,LOOKUP(LBLREC), GPB0F404.141
& ADDR_INFO,0, GPB0F404.142
& ICODE,CMESSAGE) GPB0F404.143
GPB0F404.144
IF (ICODE .EQ. 1) THEN GPB0F404.145
WRITE(6,*) 'READ_MULTI: Field number ',LOOKUP(ITEM_CODE), GPB0F404.146
& 'with dimensions ', LOOKUP(LBNPT),' x ', GPB0F404.147
& LOOKUP(LBROW),' and gridtype ', GPB0F404.148
& ADDR_INFO(d1_grid_type), GPB0F404.149
& 'was unrecognized and not read in.' GPB0F404.150
IOSTAT=1.0 GPB0F404.151
CMESSAGE='Unrecognized field on read' GPB0F404.152
ELSEIF (ICODE .NE. 0) THEN GPB0F404.153
IOSTAT=2.0 GPB0F404.154
ENDIF GPB0F404.155
GPB0F404.156
IF (new_decomp .NE. orig_decomp) THEN ! change back GPB0F404.157
GPB0F404.158
icode=0 GPB0F404.159
CALL CHANGE_DECOMPOSITION
(orig_decomp,icode) GPB0F404.160
GPB0F404.161
ENDIF GPB0F404.162
GPB0F401.538
9999 CONTINUE GPB0F401.539
GPB0F401.540
RETURN GPB0F401.541
END GPB0F401.542
*ENDIF RDMULT1A.294
*ENDIF GPB3F403.259