SURFEX v8.1
General documentation of Surfex
topodyn_lat.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 !-----------------------------------------------------------------
6 ! ###########################
7 SUBROUTINE topodyn_lat(PRW,PDEF,PKAPPA,PKAPPAC,GTOPD)
8 !,PERROR)
9 ! ###########################
10 !
11 !
12 ! PURPOSE
13 ! -------
14 ! to distribute laterally soil water following topodyn concept
15 !
16 !
17 ! METHOD
18 ! ------
19 !
20 ! EXTERNAL
21 ! --------
22 ! none
23 !
24 !
25 ! AUTHOR
26 ! ------
27 !
28 ! G.-M. Saulnier * LTHE *
29 ! K. Chancibault * CNRM *
30 !
31 ! MODIFICATIONS
32 ! -------------
33 !
34 ! Original 12/2003
35 ! writing in fortran 90 12/2004
36 !------------------------------------------------------------------------------------------
37 !
38 !* 0.0 DECLARATIONS
39 ! ------------
43 USE modd_topd_par, ONLY : xstepk
44 !
45 USE modd_surf_par, ONLY : xundef
46 !
47 USE modi_flowdown
48 USE modi_abor1_sfx
49 USE modi_write_file_vecmap
50 USE modi_write_file_map
51 !
52 USE yomhook ,ONLY : lhook, dr_hook
53 USE parkind1 ,ONLY : jprb
54 !
55 IMPLICIT NONE
56 !
57 !* 0.1 declarations of arguments
58 !
59 REAL, DIMENSION(:,:), INTENT(IN) :: PRW
60 REAL, DIMENSION(:,:), INTENT(OUT) :: PDEF
61 REAL, DIMENSION(:,:), INTENT(OUT) :: PKAPPA
62 REAL, DIMENSION(:), INTENT(OUT) :: PKAPPAC
63 LOGICAL, DIMENSION(:), INTENT(OUT) :: GTOPD
64 !
65 !* 0.2 declarations of local variables
66 !
67 LOGICAL :: GFOUND ! logical variable
68 REAL :: ZSOMME
69 REAL :: ZM ! XMPARA in m
70 REAL :: ZDX ! XDXT in m
71 REAL :: ZKVAL, ZKVALMIN, ZKVALMAX
72 REAL :: ZDAV ! Averaged deficit (m)
73 REAL :: ZDAV2 ! Averaged deficit on ZA-ZAS-ZAD (m)
74 REAL :: ZNDMAXAV,ZNKAV ! temporary averaged maximal deficit and averaged similarity index
75 REAL :: ZDMAXAV,ZKAV ! averaged maximal deficit and averaged similarity index
76 REAL :: ZFUNC
77 REAL :: ZDIF,ZDIFMIN ! difference calcul
78 REAL :: ZNAS, ZNAD ! temporary saturated and dry relative catchment area
79 REAL :: ZAS,ZAD ! saturated and dry relative catchment area
80 REAL :: ZA ! total catchment area
81 REAL :: ZTMP
82 !
83 REAL, DIMENSION(NMESHT) :: ZDMAX ! XDMAXT in m
84 REAL, DIMENSION(NMESHT) :: ZRW ! PRW in m
85 REAL, DIMENSION(NMESHT) :: ZDINI ! initial deficit
86 REAL, DIMENSION(NMESHT) :: ZMASK
87 REAL, DIMENSION(NMESHT) :: ZKAPPA_PACK, ZDMAX_PACK
88 !REAL, DIMENSION(NMESHT) :: ZTMP
89 !
90 INTEGER :: J1, J2, JJ !
91 INTEGER :: INKAPPA ! number of steps in similarity index distribution
92 INTEGER :: INPCON ! number of connected pixels
93 INTEGER :: INAS ! number of saturated pixels
94 INTEGER :: INAD ! number of dry pixels
95 INTEGER :: I_DIM
96 !
97 REAL(KIND=JPRB) :: ZHOOK_HANDLE
98 !-----------------------------------------------------------------------------------
99 IF (lhook) CALL dr_hook('TOPODYN_LAT',0,zhook_handle)
100 !
101 pkappa(:,: )= 0.0
102 pkappac(:) = 0.
103 gtopd(:) = .true.
104 pdef(:,:) = 0.
105 zas=0.
106 zad=1.
107 !
108 DO jj = 1,nncat
109  !* 0. Initialisation
110  ! --------------
111  zmask(:) = 0.0
112  zrw(:) = 0.0
113  zdmax(:) = 0.0
114  inpcon = 0
115  zdav = 0.0
116  zdav2 = 0.0
117  gfound = .false.
118  zdifmin = 99999.
119  !
120  zkav = 0.
121  !
122  zrw(:) = prw(jj,:)
123  zdmax(:) = xdmaxt(jj,:)
124  zdx = xdxt(jj)
125  zm = xmpara(jj)
126  zdini(:) = zdmax(:)
127  !
128  !* 0.2 definition of the catchment area concerned by lateral distribution
129  ! ------------------------------------------------------------------
130  !
131  DO j1=1,nnmc(jj)
132  !
133  IF ( zrw(j1)>0.0 .AND. zrw(j1)/=xundef) THEN
134  zmask(j1)=1.0
135  ELSE
136  zmask(j1)=0.0
137  ENDIF
138  !
139  ENDDO
140  !
141  CALL flowdown(nnmc(jj),zmask,xconn(jj,:,:),nline(jj,:))
142  !
143  WHERE (zmask == 0.0) zmask = xundef
144  !
145  !
146  !* 1. Calcul of hydrological similarity and topographic indexes
147  ! ---------------------------------------------------------
148  !* 1.1 Calcul of averaged deficit and initialisation of indexes
149  ! --------------------------------------------------------
150  !
151  za = nnmc(jj) * zdx**2
152  ztmp=0.
153  !
154  DO j1=1,nnmc(jj)
155  !
156  IF (zmask(j1)/=xundef) THEN
157  !
158  pkappa(jj,j1) = zrw(j1)
159  inpcon = inpcon + 1
160  zdini(j1) = zdmax(j1) - zrw(j1)
161  !
162  IF ( zdini(j1) <0.0 ) THEN
163  ! WRITE(*,*) J1,'Dini negatif !'
164  ztmp = ztmp - zdini(j1) !we stock here water above saturation to be
165  ! distributed among the others pixels
166  zdini(j1) = 0.
167  ENDIF
168  !
169  zdav = zdav + zdini(j1)
170  !
171  ELSE
172  !
173  pkappa(jj,j1) = xundef
174  !
175  ENDIF
176  !
177  ENDDO
178  !
179  IF (ztmp>0.) THEN
180  !write(*,*) COUNT(ZDINI(:)<0.),' pixels avec ZDINI negatif. Volume total :', ZTMP
181  WHERE ( zdini(:)>0. ) zdini(:) = zdini(:)-ztmp/(count(zdini(:)>0.))
182  ENDIF
183  !
184  IF (inpcon >= nnmc(jj)/1000) THEN
185  !
186  zdav = zdav / inpcon
187  zdav = zdav / zm
188  !
189  !* 1.2 Propagation of indexes
190  ! ----------------------
191  !
192  CALL flowdown(nnmc(jj),pkappa(jj,:),xconn(jj,:,:),nline(jj,:))
193  !
194  !* 1.3 Distribution of indexes
195  ! ----------------------
196  !
197  j2=1
198  !
199  DO WHILE ( .NOT.gfound .AND. j2.LE.nnmc(jj) )
200  !
201  IF (zmask(j2)/=xundef) THEN
202  !
203  gfound = .true.
204  zkval = pkappa(jj,j2) * exp(xlambda(jj,j2))
205  !ZKVAL = PKAPPA(JJ,J2) * XDAREA(JJ,J2) / XSLOP(JJ,J2)
206  zkval = log(zkval)
207  zkvalmax = zkval
208  zkvalmin = zkval
209  pkappa(jj,j2) = zkval
210  !
211  ELSE
212  !
213  pkappa(jj,j2) = xundef
214  !
215  ENDIF
216  !
217  j2 = j2 + 1
218  !
219  ENDDO
220  !
221  DO j1 = j2,nnmc(jj)
222  !
223  IF (zmask(j1)/=xundef) THEN
224  !
225  zkval = pkappa(jj,j1) * exp(xlambda(jj,j1))
226 ! ZKVAL = PKAPPA(JJ,J1) * XDAREA(JJ,J1) / XSLOP(JJ,J1)
227  zkval = log(zkval)
228  !
229  IF (zkval.GT.zkvalmax) THEN
230  zkvalmax = zkval
231  ELSEIF (zkval.LT.zkvalmin) THEN
232  zkvalmin = zkval
233  ENDIF
234  !
235  pkappa(jj,j1) = zkval
236  !
237  ELSE
238  !
239  pkappa(jj,j1) = xundef
240  !
241  ENDIF
242  !
243  ENDDO
244  !
245  !* 1.4 Calcul of saturation index
246  ! --------------------------
247  !
248  i_dim = count( zmask(1:nnmc(jj))/=xundef )
249  zkappa_pack(:) = xundef
250  zdmax_pack(:) = xundef
251  zkappa_pack(1:i_dim) = pack(pkappa(jj,1:nnmc(jj)),zmask(1:nnmc(jj))/=xundef)
252  zdmax_pack(1:i_dim) = pack(zdmax(1:nnmc(jj)),zmask(1:nnmc(jj))/=xundef)
253  !
254  inkappa = int((zkvalmax - zkvalmin) / xstepk)
255  !
256  DO j1=1,inkappa
257  !
258  zkval = zkvalmin + (xstepk * (j1-1))
259  inas = 0
260  inad = 0
261  zndmaxav = 0.0
262  znkav = 0.0
263  !
264  DO j2=1,i_dim
265  !
266  IF ( zkappa_pack(j2).GE.zkval ) THEN
267  ! saturated pixel
268  inas = inas + 1
269  ELSEIF (zkappa_pack(j2).LE.( zkval-(zdmax_pack(j2)/zm)) ) THEN
270  ! dry pixel
271  inad = inad + 1
272  zndmaxav = zndmaxav + zdmax_pack(j2)
273  ELSE
274  znkav = znkav + zkappa_pack(j2)
275  ENDIF
276  !
277  ENDDO
278  !
279  IF (inad == 0) THEN
280  zndmaxav = 0.0
281  ELSE
282  zndmaxav = zndmaxav / REAL(inad)
283  ENDIF
284  !
285  IF ( inpcon == inas .OR. inpcon == inad .OR. inpcon == (inad+inas)) THEN
286  znkav = 0.0
287  ELSE
288  znkav = znkav / REAL(inpcon - inad - inas)
289  ENDIF
290  !
291  IF (inpcon /= 0) THEN
292  znas = REAL(INAS) / REAL(inpcon)
293  znad = REAL(INAD) / REAL(inpcon)
294  ENDIF
295  !
296  zfunc = (1 - znas - znad) * ( zkval - znkav )
297  IF (zm /= 0.) zfunc = zfunc + (znad * (zndmaxav / zm))
298  !
299  zdif = abs( zfunc - zdav )
300  !
301  IF ( zdif.LT.zdifmin ) THEN
302  !
303  zdifmin = zdif
304  pkappac(jj) = zkval
305  zas = znas
306  zad = znad
307  zdmaxav = zndmaxav
308  zkav = znkav
309  !
310  ENDIF
311  !
312  ENDDO
313  !
314  !* 2. Local deficits calculation
315  ! --------------------------
316  !
317  !* 2.1 New averaged deficit on A-Ad-As
318  ! -------------------------------
319  !
320  zdav = zdav * zm
321  !
322  IF ( zas<1. .AND. zad<1. .AND. (zas + zad/=1.) ) THEN
323  !
324  zdav2 = (zdav - zdmaxav * zad) / (1 - zas - zad)
325  !
326  ELSE
327  !
328  IF (zas>=1.) WRITE(*,*) 'ALL THE AREA IS SATURATED'
329  IF (zad>=1.) WRITE(*,*) 'ALL THE AREA HAS A MAXIMAL DEFICIT'
330  WRITE(*,*) 'ALL THE AREA',zas,zad
331  ! CALL ABOR1_SFX("TOPODYN_LAT: ALL THE AREA IS SATURATED OR HAS A MAXIMAL DEFICIT")
332  !
333  ENDIF
334  !
335  !* 2.2 Local deficits
336  ! --------------
337  !
338  ! ZSOMME=0.0
339  !ZTMP(:)=XUNDEF
340  !
341  DO j1=1,nnmc(jj)
342  !
343  IF ( zmask(j1)/=xundef ) THEN
344  !
345  IF ( (pkappa(jj,j1).GT.(pkappac(jj) - zdmax(j1)/zm)) .AND. (pkappa(jj,j1).LT.pkappac(jj)) ) THEN
346  !
347  pdef(jj,j1) = zm * (zkav - pkappa(jj,j1)) + zdav2
348  !ZTMP(J1) = 0.5
349  IF (pdef(jj,j1) < 0.0) pdef(jj,j1) = 0.0
350  !
351  ELSEIF ( pkappa(jj,j1).GE.pkappac(jj) ) THEN
352  !
353  pdef(jj,j1) = 0.0
354  !ZTMP(J1) = 1.
355  !
356  ELSEIF ( pkappa(jj,j1).LE.(pkappac(jj) - zdmax(j1)/zm) ) THEN
357  !
358  pdef(jj,j1) = zdmax(j1)
359  !ZTMP(J1) = -1.0
360  !
361  ENDIF
362  !
363  ! nouveau contenu en eau total (m)
364  !ZSOMME = ZSOMME + ( XWSTOPT(JJ,J1)*XDTOPT(JJ,J1) - PDEF(JJ,J1) )
365  !
366  ELSE
367  !
368  pdef(jj,j1) = zdmax(j1)
369  !
370  ENDIF
371  !
372  ENDDO
373  !
374  ! variation du contenu en eau total
375  DO j1=1,nnmc(jj)
376  !
377  IF (pdef(jj,j1)<0.0) THEN
378  WRITE(*,*) 'LAMBDA=',pkappa(jj,j1),'LAMBDAC=',pkappac(jj)
379  ENDIF
380  !
381  ENDDO
382  !
383  gtopd(jj)=.true.
384  !
385  ELSE
386  !
387  ! 'Pas de redistribution laterale'
388  gtopd(jj)=.false.
389  !
390  pkappa(jj,:) = xundef
391  ! PDEF(JJ,:) = ZDMAX(:) - ZRW(:)
392  pdef(jj,:) = zdini(:)
393  pkappac(jj) = xundef
394  !
395  ENDIF
396  !
397 ENDDO
398 !
399 IF (lhook) CALL dr_hook('TOPODYN_LAT',1,zhook_handle)
400 !
401 END SUBROUTINE topodyn_lat
402 
real, dimension(:,:), allocatable xlambda
real, dimension(:), allocatable xmpara
real, dimension(:,:), allocatable xslop
real, dimension(:,:), allocatable xdmaxt
real, dimension(:,:), allocatable xdarea
integer, dimension(:,:), allocatable nline
real, parameter xundef
integer nmesht
subroutine flowdown(KNMC, PVAR, PCONN, KLINE)
Definition: flowdown.F90:8
integer, parameter jprb
Definition: parkind1.F90:32
real, dimension(:,:), allocatable xdtopt
subroutine topodyn_lat(PRW, PDEF, PKAPPA, PKAPPAC, GTOPD)
Definition: topodyn_lat.F90:8
real, dimension(:), allocatable xdxt
logical lhook
Definition: yomhook.F90:15
real, dimension(:,:), allocatable xwstopt
real, dimension(:,:,:), allocatable xconn
integer, dimension(:), allocatable nnmc
static int count
Definition: memory_hook.c:21
real, parameter xstepk