SURFEX v8.1
General documentation of Surfex
mode_read_surf_layers.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 
7 !
9  MODULE PROCEDURE read_surf_layers
10 END INTERFACE
11 !
12 CONTAINS
13 !
14 ! #############################################################
15  SUBROUTINE read_surf_layers (HPROGRAM,HREC,ODIM,PFIELD,KRESP,HCOMMENT,HDIR,KPATCH)
16 ! #############################################################
17 !
18 !
19 !
21 USE modd_surf_par, ONLY : xundef
22 !
23 #ifdef SFX_LFI
24 USE modd_io_surf_lfi, ONLY : nmask_lfi=>nmask, nfull_lfi=>nfull
25 #endif
26 #ifdef SFX_NC
27 USE modd_io_surf_nc, ONLY : nmask_nc=>nmask, nfull_nc=>nfull
28 #endif
29 #ifdef SFX_ASC
30 USE modd_io_surf_asc, ONLY : nmask_asc=>nmask, nfull_asc=>nfull
31 #endif
32 #ifdef SFX_FA
33 USE modd_io_surf_fa, ONLY : nmask_fa=>nmask, nfull_fa=>nfull
34 #endif
35 #ifdef SFX_MNH
37 #endif
38 !
39 USE modi_abor1_sfx
42 USE modi_make_choice_array
43 !
44 USE yomhook ,ONLY : lhook, dr_hook
45 USE parkind1 ,ONLY : jprb
46 !
47 IMPLICIT NONE
48 !
49 #ifdef SFX_MPI
50 include "mpif.h"
51 #endif
52 !
53 !* 0.1 Declarations of arguments
54 !
55 !
56 !
57  CHARACTER(LEN=6), INTENT(IN) :: HPROGRAM ! calling program
58  CHARACTER(LEN=*), INTENT(IN) :: HREC ! name of the article to be read
59 LOGICAL, INTENT(IN) :: ODIM
60 REAL, DIMENSION(:,:,:), INTENT(OUT) :: PFIELD ! array containing the data field
61 INTEGER, INTENT(OUT) :: KRESP ! KRESP : return-code if a problem appears
62  CHARACTER(LEN=*), OPTIONAL, INTENT(OUT) :: HCOMMENT ! name of the article to be read
63  CHARACTER(LEN=1), OPTIONAL, INTENT(IN) :: HDIR ! type of field :
64 ! ! 'H' : field with
65 ! ! horizontal spatial dim.
66 ! ! '-' : no horizontal dim.
67 INTEGER, OPTIONAL, INTENT(IN) :: KPATCH
68 !
69 !* 0.2 Declarations of local variables
70 !
71 #ifdef SFX_MPI
72 INTEGER, DIMENSION(MPI_STATUS_SIZE,NPROC-1) :: ISTATUS
73 #endif
74 !INTEGER, DIMENSION(NPROC) :: ITREQ
75 REAL, DIMENSION(:,:),ALLOCATABLE :: ZWORKR
76 REAL, DIMENSION(:,:),ALLOCATABLE :: ZFIELD
77 INTEGER, DIMENSION(:), POINTER :: IMASKF
78  CHARACTER(LEN=100) :: YCOMMENT
79  CHARACTER(LEN=16) :: YREC
80  CHARACTER(LEN=1) :: YDIR
81  CHARACTER(LEN=4) :: YLVL
82 INTEGER :: IFLAG, IPATCH, INPATCH
83 INTEGER :: IPIO_SAVE, IPAS, JP, IDEB, IFIN, JJ, JL
84 INTEGER :: JLAYER, JPROC, IPROC, IRESP
85 INTEGER :: IL1, IL2, IL3, IDX_SAVE, IDX, IVAL
86 INTEGER :: INFOMPI, IREQ, JPROC2, IFULL
87 REAL(KIND=JPRB) :: ZHOOK_HANDLE, ZHOOK_HANDLE_OMP
88 !
89 IF (lhook) CALL dr_hook('READ_SURF_LAYERS_1',0,zhook_handle)
90 !
91 idx_save = idx_r
92 yrec = hrec
93 ycomment="empty"
94 ydir = 'H'
95 IF (PRESENT(hdir)) ydir = hdir
96 inpatch = SIZE(pfield,3)
97 ipatch = -1
98 IF (PRESENT(kpatch).AND.inpatch==1) ipatch = kpatch
99 !
100 il1 = SIZE(pfield,1)
101 il2 = SIZE(pfield,2)
102 il3 = SIZE(pfield,3)
103 !
104 IF (lhook) CALL dr_hook('READ_SURF_LAYERS_1',1,zhook_handle)
105 !
106 IF (hprogram=='MESONH') THEN
107 #ifdef SFX_MNH
108  DO jl=1,il2
109  WRITE(ylvl,'(I4)') jl
110  yrec=trim(hrec)//adjustl(ylvl(:len_trim(ylvl)))
111  CALL make_choice_array(hprogram, inpatch, odim, yrec, pfield(:,jl,:), hdir=ydir, kpatch=ipatch)
112  END DO
113 #endif
114 ELSE
115  !
116  IF (lhook) CALL dr_hook('READ_SURF_LAYERS_2',0,zhook_handle)
117  !
118  !the mask to call read_and_send_mpi depends on the I/O type
119  IF (hprogram=='LFI ') THEN
120 #ifdef SFX_LFI
121  ifull = nfull_lfi
122  ALLOCATE(zfield(nfull_lfi,il3))
123  imaskf=>nmask_lfi
124 #endif
125  ELSEIF (hprogram=='ASCII ') THEN
126 #ifdef SFX_ASC
127  ifull = nfull_asc
128  ALLOCATE(zfield(nfull_asc,il3))
129  imaskf=>nmask_asc
130 #endif
131  ELSEIF (hprogram=='FA ') THEN
132 #ifdef SFX_FA
133  ifull = nfull_fa
134  ALLOCATE(zfield(nfull_fa,il3))
135  imaskf=>nmask_fa
136 #endif
137  ELSEIF (hprogram=='NC ') THEN
138 #ifdef SFX_NC
139  ifull = nfull_nc
140  ALLOCATE(zfield(nfull_nc,il3))
141  imaskf=>nmask_nc
142 #endif
143  ELSE
144  ALLOCATE(zfield(0,0))
145  ENDIF
146  !
147  !if we want to get covers for the current task or for the whole domain
148  IF (ydir=='H') THEN
149  !second dimension because the reading of covers is parallelized with MPI
150  ALLOCATE(zworkr(nsize,il3))
151  ELSEIF (nrank==npio) THEN
152  ALLOCATE(zworkr(ifull,il3))
153  ELSE
154  ALLOCATE(zworkr(0,0))
155  ENDIF
156  zworkr(:,:) = 0.
157  !
158  IF (nproc>1 .AND. ydir=='H') THEN
159  iflag = 0
160  !for the parallelization of reading, NINDEX must be known by all tasks
161  IF (nrank/=npio) THEN
162  IF (ALLOCATED(nindex)) THEN
163  IF (SIZE(nindex)==ifull) iflag=1
164  DEALLOCATE(nindex)
165  ENDIF
166  ALLOCATE(nindex(ifull))
167  ENDIF
168 #ifdef SFX_MPI
169  CALL mpi_bcast(nindex,SIZE(nindex)*kind(nindex)/4,mpi_integer,npio,ncomm,infompi)
170 #endif
171  ENDIF
172  !
173  ipio_save = npio
174  !number of covers read by each task
175  ipas = ceiling(il2*1./nproc)
176  !
177  pfield(:,:,:) = 0.
178  !
179  !first cover number read by the current task
180  ideb = ipas*nrank
181  !
182  IF (lhook) CALL dr_hook('READ_SURF_LAYERS_2',1,zhook_handle)
183  !
184  DO jp = 1,ipas
185  !
186  IF (lhook) CALL dr_hook('READ_SURF_LAYERS_3',0,zhook_handle)
187  !
188  !index of the cover read by this task at this loop index
189  jlayer = ideb + jp
190  !
191  IF (jlayer<=il2) THEN
192  !
193  WRITE(ylvl,'(I4)') jlayer
194  yrec = trim(hrec)//adjustl(ylvl(:len_trim(ylvl)))
195  ycomment='X_Y_'//yrec
196  !
197  !
198  IF (hprogram=='AROME ') THEN
199 #ifdef ARO
200  CALL make_choice_array(hprogram, inpatch, odim, yrec, pfield(:,jlayer,:), hdir=ydir, kpatch=ipatch)
201 #endif
202  ELSE
203  !
204  !reads one cover by task
205  !
206  !number of the I/O task for this read
207  npio = nrank
208  !
209  !reading of the whol cover (HDIR='A')
210  CALL make_choice_array(hprogram, inpatch, odim, yrec, zfield, hdir='A', kpatch=ipatch)
211  !
212  !NPIO rebecomes the I/O task
213  npio = ipio_save
214  !
215  idx = idx_save + jp
216  IF (ydir=='H') THEN
217  !
218  !send covers to other tasks
219  CALL read_and_send_mpi(zfield,pfield(:,jlayer,:),imaskf,nrank,idx)
220  !
221  ELSEIF (ydir=='A' .OR. ydir=='E') THEN
222  !
223  !NPIO needs to know all covers read
224  IF (nrank/=npio) THEN
225  idx = idx + 1
226 #ifdef SFX_MPI
227  CALL mpi_send(zfield,SIZE(zfield)*kind(zfield)/4,mpi_real,npio,idx,ncomm,infompi)
228 #endif
229  ELSE
230  CALL pack_same_rank(imaskf,zfield,pfield(:,jlayer,:))
231  ENDIF
232  !
233  ELSE
234  CALL abor1_sfx("READ_SURF_LAYERS:HDIR MUST BE H OR A OR E")
235  ENDIF
236  !
237  ENDIF
238  !
239  ENDIF
240  !
241  IF (lhook) CALL dr_hook('READ_SURF_LAYERS_3',1,zhook_handle)
242  !
243  IF (nrank==npio .OR. ydir=='H') THEN
244  !
245  !receives pieces of cover fields
246  !ITREQ(:) = 0
247  !
248 !$OMP PARALLEL PRIVATE(ZHOOK_HANDLE_OMP)
249 IF (lhook) CALL dr_hook('READ_SURF_LAYERS_4',0,zhook_handle_omp)
250 #ifdef SFX_MPI
251 !$OMP DO SCHEDULE(DYNAMIC,1) PRIVATE(JPROC,IDX,ISTATUS,INFOMPI)
252 #endif
253  DO jproc=0,nproc-1
254  !
255  !the cover exists and was read
256  IF (ipas*jproc + jp<=il2) THEN
257  !
258  !IF (JPROC<NRANK) THEN
259  ! ITREQ(JPROC+1) = JPROC+1
260  !ELSE
261  ! ITREQ(JPROC+1) = JPROC
262  !ENDIF
263  !
264  IF (jproc/=nrank) THEN
265  idx = idx_save + jp + 1
266  !each task receives the part of the cover read that concerns it
267  !only NPIO in cas of HDIR/=H
268 #ifdef SFX_MPI
269  CALL mpi_recv(zworkr(:,:),SIZE(zworkr)*kind(zworkr)/4,&
270  mpi_real,jproc,idx,ncomm,istatus,infompi)
271 #endif
272  ival = ipas*jproc + jp
273  CALL pack_same_rank(imaskf,zworkr(:,:),pfield(:,ival,:))
274  !
275  ENDIF
276  !
277  ENDIF
278  !
279  ENDDO
280 #ifdef SFX_MPI
281 !$OMP END DO
282 #endif
283 IF (lhook) CALL dr_hook('READ_SURF_LAYERS_4',1,zhook_handle_omp)
284 !$OMP END PARALLEL
285 
286 !
287  IF (lhook) CALL dr_hook('READ_SURF_LAYERS_5',0,zhook_handle)
288  !
289  !waits that all cover pieces are sent
290 #ifdef SFX_MPI
291  IF (ydir=='H' .AND. ipas*nrank+jp<=il2 .AND. nproc>1) THEN
292  CALL mpi_waitall(nproc-1,nreq(1:nproc-1),istatus,infompi)
293  ENDIF
294 #endif
295  !
296  IF (lhook) CALL dr_hook('READ_SURF_LAYERS_5',1,zhook_handle)
297  !
298 ! IF (YDIR=='H' .OR. NRANK==NPIO) THEN
299 ! !packs data
300 ! IREQ = MAXVAL(ITREQ)
301 !!$OMP PARALLEL PRIVATE(ZHOOK_HANDLE_OMP)
302 !IF (LHOOK) CALL DR_HOOK('READ_SURF_LAYERS_6',0,ZHOOK_HANDLE_OMP)
303 !!$OMP DO SCHEDULE(DYNAMIC,1) PRIVATE(JPROC,IVAL)
304 ! DO JPROC=0,IREQ-1
305 ! IVAL = IPAS*JPROC + JP
306 ! IF (JPROC>=NRANK ) IVAL = IVAL + IPAS
307 ! CALL PACK_SAME_RANK(IMASKF,ZWORKR(:,:,JPROC+1),PFIELD(:,IVAL,:))
308 ! ENDDO
309 !!$OMP END DO
310 !IF (LHOOK) CALL DR_HOOK('READ_SURF_LAYERS_6',1,ZHOOK_HANDLE_OMP)
311 !!$OMP END PARALLEL
312 ! ENDIF
313  !
314  ENDIF
315  !
316  ENDDO
317  !
318  IF (lhook) CALL dr_hook('READ_SURF_LAYERS_7',0,zhook_handle)
319  !
320  IF (nrank/=npio .AND. ydir=='H' .AND. iflag==0) THEN
321  DEALLOCATE(nindex)
322  ALLOCATE(nindex(0))
323  ENDIF
324  !
325  idx_r = idx_r + ipas + 1
326  DEALLOCATE(zworkr)
327  IF (hprogram/="AROME ") DEALLOCATE(zfield)
328  imaskf=>null()
329  !
330  IF (lhook) CALL dr_hook('READ_SURF_LAYERS_7',1,zhook_handle)
331  !
332 ENDIF
333 !
334 IF (lhook) CALL dr_hook('READ_SURF_LAYERS_8',0,zhook_handle)
335 !
336 !RJ: what is a point of comment here? last field comment? Should be 'COVER_PACKED' status?
337 IF (PRESENT(hcomment)) hcomment = ycomment
338 !
339 IF (lhook) CALL dr_hook('READ_SURF_LAYERS_8',1,zhook_handle)
340 !
341 END SUBROUTINE read_surf_layers
342 
343 END MODULE mode_read_surf_layers
static const char * trim(const char *name, int *n)
Definition: drhook.c:2383
subroutine make_choice_array(HPROGRAM, KNPATCH, ODIM, HRECFM, PWORK, HDIR, KPATCH)
integer, dimension(:), allocatable nreq
integer, dimension(:), pointer nmask
subroutine read_surf_layers(HPROGRAM, HREC, ODIM, PFIELD, KRESP, HCOMMENT, HDIR, KPATCH)
subroutine abor1_sfx(YTEXT)
Definition: abor1_sfx.F90:7
real, parameter xundef
integer, parameter jprb
Definition: parkind1.F90:32
integer, dimension(:), pointer nmask
logical lhook
Definition: yomhook.F90:15
integer, dimension(:), allocatable nindex