source: perso/abdelouhab.djerrah/ORCHIDEE_OL/weather.f90 @ 855

Last change on this file since 855 was 732, checked in by didier.solyga, 12 years ago

Update weather module in order to respect documentation protocol

File size: 125.8 KB
Line 
1! =================================================================================================================================
2! MODULE       : weather
3!
4! CONTACT      : orchidee-help _at_ ipsl.jussieu.fr
5!
6! LICENCE      : IPSL (2006)
7! This software is governed by the CeCILL licence see ORCHIDEE/ORCHIDEE_CeCILL.LIC
8!
9!>\BRIEF        This module simulates weather.
10!!
11!!\n DESCRIPTION: None
12!!
13!! RECENT CHANGE(S): None
14!!
15!! REFERENCE(S) :
16!!
17!! SVN          :
18!! $HeadURL: $
19!! $Date: $
20!! $Revision: $
21!! \n
22!_ ================================================================================================================================
23
24MODULE weather
25!---------------------------------------------------------------------
26  USE netcdf
27!-
28  USE defprec
29  USE ioipsl
30  USE constantes
31  USE parallel
32  USE grid, ONLY : year,month,day,sec
33!-
34  IMPLICIT NONE
35!-
36  PRIVATE
37  PUBLIC weathgen_main, weathgen_domain_size, weathgen_init, weathgen_read_file
38!
39! Only for root proc
40  INTEGER, SAVE                              :: iim_file, jjm_file, llm_file, ttm_file !(unitless)
41  INTEGER,DIMENSION(:,:),SAVE,ALLOCATABLE    :: ncorr !(unitless)
42  INTEGER,DIMENSION(:,:,:),SAVE,ALLOCATABLE  :: icorr,jcorr !(unitless)
43  INTEGER,SAVE                               :: i_cut, n_agg !(unitless)
44
45  REAL,DIMENSION(:,:),SAVE,ALLOCATABLE :: xinwet   !! climatological wet days + anomaly @tex $(days.month^{-1})$ @endtex
46  REAL,DIMENSION(:,:),SAVE,ALLOCATABLE :: xinprec  !! climatological precipition + anomaly @tex $(mm.day^{-1})$ @endtex
47  REAL,DIMENSION(:,:),SAVE,ALLOCATABLE :: xint     !! climatological temp + anomaly (C)
48  REAL,DIMENSION(:,:),SAVE,ALLOCATABLE :: xinq     !! climatological relative humidity + anomaly (0-1, unitless)
49  REAL,DIMENSION(:,:),SAVE,ALLOCATABLE :: xinwind  !! climatological wind speed + anomaly @tex $(m.s^{-1})$ @endtex
50  REAL,DIMENSION(:,:),SAVE,ALLOCATABLE :: xincld   !! climatological cloudiness + anomaly (0-1, unitless)
51  REAL,DIMENSION(:,:),SAVE,ALLOCATABLE :: xintrng  !! climatological temp range + anomaly (C)
52  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: xintopo  !! topography (m)
53  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: lat_land !! latitudes of land points (unitless)
54!-
55! daily values
56!-
57  REAL,SAVE :: julian_last
58  INTEGER,DIMENSION(:),SAVE,ALLOCATABLE :: iwet    !! flag for wet day / dry day (0-1, unitless)
59!-
60! today's values (m0 means "minus 0")
61!-
62  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: psurfm0  !! surface pressure today(Pa)
63  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: cloudm0  !! cloud fraction today (0-1, unitless)
64  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: tmaxm0   !! maximum daily temperature today (K)
65  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: tminm0   !! minimum daily temperature today (K)
66  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: qdm0     !! daily average specific humidity today (kg_h2o/kg_air)
67  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: udm0     !! daily average wind speed today  @tex $(m.s^{-1})$ @endtex
68  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: precipm0 !! daily precitation today @tex $(mm.day^{-1})$ @endtex
69!-
70! yesterday's values (m1 means "minus 1")
71!-
72  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: psurfm1  !! surface pressure yesterday (Pa)
73  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: cloudm1  !! cloud fraction yesterday (0-1, unitless)
74  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: tmaxm1   !! maximum daily temperature yesterday (K)
75  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: tminm1   !! minimum daily temperature yesterday (K)
76  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: qdm1     !! daily average specific humidity yesterday (kg_h2o/kg_air)
77  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: udm1     !! daily average wind speed  yesterday  @tex $(m.s^{-1})$ @endtex
78  REAL,DIMENSION(:),SAVE,ALLOCATABLE   :: precipm1 !! daily precitation  yesterday @tex $(mm.day^{-1})$ @endtex
79!-
80! other
81!-
82  REAL,PARAMETER   :: undef=1.e+20  !! special value
83  INTEGER,SAVE     :: ipprec        !! statistical (0) or prescribed (1) daily values
84
85  LOGICAL,SAVE                  :: precip_exact  !! respect monthly precipitation
86  INTEGER,DIMENSION(31,12),SAVE :: jour_precip
87
88
89  INTEGER,PARAMETER      :: seedsize_max = 300  !! max size of random seed
90  LOGICAL,SAVE           :: dump_weather
91  CHARACTER(LEN=20),SAVE :: dump_weather_file
92  LOGICAL,SAVE           :: gathered
93  INTEGER,SAVE           :: dump_id
94
95!
96  REAL,PARAMETER         :: zero_t=273.16   !! Absolute zero
97!-
98! Parametres orbitaux:
99!-
100  REAL,SAVE :: ecc    !! Eccentricity
101  REAL,SAVE :: perh   !! Longitude of perihelie
102  REAL,SAVE :: xob    !! obliquity
103!-
104  INTEGER,PARAMETER :: nmon = 12  !! Number of months
105
106!
107  CHARACTER(LEN=3),DIMENSION(12) :: cal = &             !! Months of the year (unitless)
108 &  (/ 'JAN','FEB','MAR','APR','MAY','JUN', &
109 &     'JUL','AUG','SEP','OCT','NOV','DEC' /)
110  INTEGER,DIMENSION(12),SAVE :: ndaypm = &              !! Number of days per month (noleap year) (unitless)
111 &  (/ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /)
112  INTEGER,SAVE :: soldownid, rainfid, snowfid, lwradid, &
113 &                tairid, qairid,  psolid, uid, vid, &
114 &                time_id, timestp_id
115!-
116  INTEGER,SAVE :: n_rtp = nf90_real4      !! Parameters for NETCDF
117!-
118  INTEGER  :: ALLOC_ERR                   !! Flag for dynamic allocations
119!-
120  CHARACTER(LEN=20),SAVE :: calendar_str   !! Calendar type
121!-
122  INTEGER, DIMENSION(:), ALLOCATABLE, SAVE :: kindex_w  !! Land points index
123  INTEGER, SAVE                            :: nbindex_w  !! Land points index
124!-
125  INTEGER, PARAMETER :: termcol = 100     !! Plot of projection file => grid, number of column on terminal
126!80
127  CONTAINS
128!-
129!===
130!-
131
132!! ================================================================================================================================
133!! SUBROUTINE   : daily
134!!
135!>\BRIEF          This routine generates daily weather conditions from monthly-mean
136!! climatic parameters.
137!!
138!! DESCRIPTION  :  Specifically, this routine generates daily values of
139!!                 - daily total precipitation \n
140!!                 - daily maximum temperature \n
141!!                 - daily minimum temperature \n
142!!                 - daily average cloud cover \n
143!!                 - daily average relative humidity \n
144!!                 - daily average wind speed \n
145!!                 In order to generate daily weather conditions, the model uses
146!!                 a series of 'weather generator' approaches,
147!!                 which generate random combinations of weather conditions
148!!                 based upon the climatological conditions in general. \n
149!!                 This weather generator is based upon the so-called Richardson
150!!                 weather generator. \n
151!!
152!! RECENT CHANGE(S): None
153!!
154!! MAIN OUTPUT VARIABLE(S): ::psurf, ::cloud, ::tmax, ::tmin, ::qd, ::ud, ::precip
155!!
156!! REFERENCE(S) :
157!! -  Geng, S., F.W.T. Penning de Vries, and L. Supit, 1985:  A simple
158!! method for generating rainfall data, Agricultural and Forest
159!! Meteorology, 36, 363-376.
160!! -  Richardson, C. W. and Wright, D. A., 1984: WGEN: A model for
161!! generating daily weather variables: U. S. Department of
162!! Agriculture, Agricultural Research Service.
163!! - Richardson, C., 1981: Stochastic simulation of daily
164!! precipitation, temperature, and solar radiation. Water Resources
165!! Research 17, 182-190.
166!!
167!! FLOWCHART    : None
168!! \n
169!_ ================================================================================================================================
170
171SUBROUTINE daily &
172 &  (npoi, imonth, iday, cloud, tmax, tmin, precip, qd, ud, psurf)
173
174!-
175! in & out: global variables
176!-
177
178! INTEGER,INTENT(INOUT):: iwet(npoi) !! wet day / dry day flag!*
179!-
180
181  !! 0. Parameters and variables declaration
182
183  REAL,PARAMETER :: rair = 287.     !! Molecular weight of one mole of dry air @tex $(g.mol{-1})$ @endtex
184  REAL,PARAMETER :: grav = 9.81     !! Acceleration of the gravity @tex $(m.s^{-2})$ @endtex
185  REAL,PARAMETER :: pi = 3.1415927  !! pi
186
187  !! 0.1 Input variables
188
189  INTEGER,INTENT(IN) :: npoi         !! total number of land points
190  INTEGER,INTENT(IN) :: imonth, iday
191
192  !! 0.2 Output variables
193
194  REAL,INTENT(OUT) :: psurf(npoi)   !! surface pressure (Pa)
195  REAL,INTENT(OUT) :: cloud(npoi)   !! cloud fraction (0-1, unitless)
196  REAL,INTENT(OUT) :: tmax(npoi)    !! maximum daily temperature (K)
197  REAL,INTENT(OUT) :: tmin(npoi)    !! minimum daily temperature (K)
198  REAL,INTENT(OUT) :: qd(npoi)      !! daily average specific humidity (kg_h2o/kg_air)
199  REAL,INTENT(OUT) :: ud(npoi)      !! daily average wind speed  @tex $(m.s^{-1})$ @endtex
200  REAL,INTENT(OUT) :: precip(npoi)  !! daily precitation @tex $(mm.day^{-1})$ @endtex
201
202  !! 0.4 Local variables
203
204  REAL :: td(npoi)                                 !! daily average temperature (K)
205  REAL,allocatable,save,dimension(:,:) ::  xstore  !! weather generator 'memory' matrix
206  REAL :: ee(3), r(3), rr(npoi,3)
207  REAL :: alpha(npoi), rndnum, pwd, pww
208  REAL :: beta(npoi)
209  REAL :: pwet(npoi)
210  REAL :: rwork
211  REAL :: omcloud, omqd, omtmax
212  REAL :: cloudm, cloudw, cloudd
213  REAL :: cloude(npoi), clouds(npoi)
214  REAL :: tmaxd, tmaxw, tmaxm
215  REAL :: tminm
216  REAL :: tmins(npoi), tmaxs(npoi)
217  REAL :: tmine(npoi), tmaxe(npoi)
218  REAL :: qdm(npoi),qdd(npoi),qde(npoi),qdw(npoi),qdup(npoi),qdlow(npoi)
219  INTEGER :: i,j,k
220  REAL :: amn,b1,b2,b3,eud,rn,rn1,rn2,rn3,rn4,s1,s2,s12,x1,y, z(npoi)
221  REAL :: aa(npoi),ab(npoi),tr1(npoi), tr2(npoi)
222  REAL :: tdm,trngm,tdum
223  REAL :: qsattd(npoi)
224  INTEGER :: it1w, it2w
225  REAL :: dt
226  REAL :: rainpwd(npoi)
227  INTEGER :: not_ok(npoi)
228  INTEGER :: count_not_ok,count_not_ok_g
229  LOGICAL,SAVE :: firstcall = .TRUE.
230  INTEGER,save :: npoi0
231  REAL :: xx,e
232
233  REAL, DIMENSION(3,3) :: a,b              !! define autocorrelation matrices for Richardson generator
234                                           !!
235                                           !! note that this matrix should be based upon a statistical
236                                           !! analysis of regional weather patterns
237                                           !!
238                                           !! for global simulations, we use 'nominal' values
239
240  LOGICAL :: Warning_aa_ab(npoi), Warning_iwet(npoi) !! Warnings
241!---------------------------------------------------------------------
242!-
243! initial setup for daily climate calculations
244!-
245  a(1,:) = (/ 0.600,  0.500,  0.005 /)
246  a(2,:) = (/ 0.010,  0.250,  0.005 /)
247  a(3,:) = (/ 0.020,  0.125,  0.250 /)
248!-
249  b(1,:) = (/ 0.500,  0.250, -0.250 /)
250  b(2,:) = (/ 0.000,  0.500,  0.250 /)
251  b(3,:) = (/ 0.000,  0.000,  0.500 /)
252!-
253  e = EXP(1.)
254! GK240100
255  IF (firstcall) THEN
256    firstcall = .FALSE.
257    ALLOC_ERR=-1
258    ALLOCATE(xstore(npoi,3), STAT=ALLOC_ERR)
259    IF (ALLOC_ERR/=0) THEN
260      WRITE(numout,*) "ERROR IN ALLOCATION of xstore : ",ALLOC_ERR
261      STOP
262    ENDIF
263    xstore(:,:) = 0.
264    npoi0 = npoi
265  ELSE IF (npoi /= npoi0) THEN
266    WRITE(numout,*) 'Domain size old, new: ',npoi0,npoi
267    STOP 'WG Daily: Problem: Domain has changed since last call'
268  ENDIF
269!-
270! define working variables
271!-
272  rwork = (grav/rair/0.0065)
273!-
274! 'omega' parameters used to calculate differences in expected
275! climatic parameters on wet and dry days
276!
277! following logic of weather generator used in the EPIC crop model
278!
279! omcloud -- cloud cover
280! omqd    -- humidity
281! omtmax  -- maximum temperature
282!-
283  omcloud = 0.90    ! originally 0.90
284  omqd    = 0.50    ! originally 0.50
285  omtmax  = 0.75    ! originally 0.75
286!-
287! calculate weighting factors used in interpolating climatological
288! monthly-mean input values to daily-mean values
289!-
290! this is a simple linear interpolation technique that takes into
291! account the length of each month
292!-
293  IF (ipprec == 0) THEN
294    IF (REAL(iday) < REAL(ndaypm(imonth)+1)/2.0) then
295      it1w = imonth-1
296      it2w = imonth
297      dt   = (REAL(iday)-0.5)/ndaypm(imonth)+0.5
298    ELSE
299      it1w = imonth
300      it2w = imonth+1
301      dt   = (REAL(iday)-0.5)/ndaypm(imonth)-0.5
302    ENDIF
303    if (it1w <  1)  it1w = 12
304    if (it2w > 12)  it2w = 1
305  ELSE
306     dt = -1.
307     it1w = -1
308     it2w = -1
309  ENDIF
310!-
311  IF (ipprec == 0) THEN
312!---
313!-- use weather generator to create daily statistics
314!---
315! (1) determine if today will rain or not
316!---
317!-- calculate monthly-average probability of rainy day
318!---
319    DO i=1,npoi
320      pwet(i) = xinwet(i,imonth)/ndaypm(imonth)
321    ENDDO
322!---
323    IF (.NOT.precip_exact) THEN
324!-----
325!---- (1.1) following Geng et al.
326!-----
327      IF (is_root_prc) THEN
328         CALL random_number (rndnum)
329      ENDIF
330      CALL bcast(rndnum)
331!-----
332      DO i=1,npoi
333        IF (xinprec(i,imonth) > 1.e-6) THEN
334!---------
335!-------- implement simple first-order Markov-chain precipitation
336!-------- generator logic based on Geng et al. (1986),
337!-------- Richardson and Wright (1984), and Richardson (1981)
338!---------
339!-------- basically, this allows for the probability of today being
340!-------- a wet day (a day with measureable precipitation)
341!-------- to be a function of what yesterday was (wet or dry)
342!---------
343!-------- the logic here is that it is more likely that a wet day
344!-------- will follow another wet day -- allowing
345!-------- for 'storm events' to persist
346!---------
347!-------- estimate the probability of a wet day after a dry day
348!---------
349          pwd = 0.75*pwet(i)
350!---------
351!-------- estimate the probability of a wet day after a wet day
352!---------
353          pww = 0.25+pwd
354!---------
355!-------- decide if today is a wet day or a dry day
356!-------- using a random number
357!---------
358!-------- call random_number(rndnum) ! done before
359!---------
360          IF (iwet(i) == 0) then
361            IF (rndnum <= pwd) iwet(i) = 1
362          ELSE
363            IF (rndnum > pww) iwet(i) = 0
364          ENDIF
365        ELSE
366          iwet(i) = 0
367        ENDIF
368      ENDDO
369    ELSE
370!-----
371!---- (1.2) preserving the monthly number of precip days
372!----       and monthly precip
373!-----
374      DO i=1,npoi
375        IF (ABS(xinwet(i,imonth)) < 32.) THEN
376          IF (xinprec(i,imonth) > 1.e-6) THEN
377            IF (   jour_precip(iday,imonth) &
378 &              <= NINT(MAX(1.,xinwet(i,imonth))) ) THEN
379              iwet(i) = 1
380            ELSE
381              iwet(i) = 0
382            ENDIF
383          ELSE
384           iwet(i) = 0
385          ENDIF
386        ENDIF
387      ENDDO
388    ENDIF
389!---
390!-- (2) determine today's precipitation amount
391!---
392    IF (.not.precip_exact) THEN
393       Warning_aa_ab(:)=.FALSE.
394       Warning_iwet(:)=.FALSE.
395!-----
396!---- (2.1) following Geng et al.
397!-----
398      aa(:) = zero
399      ab(:) = zero
400      tr2(:)= zero
401      tr1(:)= zero
402      beta(:) = un
403      DO i=1,npoi
404!-------
405!------ initialize daily precipitation to zero
406!-------
407        precip(i) = 0.0
408!-------
409        IF (xinprec(i,imonth) > 1.e-6) THEN
410!---------
411!-------- if it is going to rain today
412!---------
413          IF (iwet(i) == 1) THEN
414!-----------
415!---------- calculate average rainfall per wet day
416!-----------
417            rainpwd(i) = xinprec(i,imonth) &
418 &                      *ndaypm(imonth)/MAX(0.1,xinwet(i,imonth))
419!-----------
420!---------- randomly select a daily rainfall amount
421!---------- from a probability density function of rainfall
422!----------
423!---------- method i --
424!-----------
425!---------- use the following technique from Geng et al. and Richardson
426!---------- to distribute rainfall probabilities
427!-----------
428!---------- pick a random rainfall amount
429!---------- from a two-parameter gamma function distribution function
430!-----------
431!---------- estimate two parameters for gamma function
432!---------- (following Geng et al.)
433!-----------
434            beta(i) = MAX(1.0,-2.16+1.83*rainpwd(i))
435            alpha(i) = rainpwd(i)/beta(i)
436!-----------
437!---------- determine daily precipitation amount
438!---------- from gamma distribution function
439!---------- (following WGEN code of Richardson and Wright (1984))
440!-----------
441            IF (ABS(1.-alpha(i)) < 1.e-6) THEN
442              alpha(i) = 1.e-6*(alpha(i)/ABS(alpha(i)))
443            ENDIF
444            aa(i) = 1.0/alpha(i)
445            ab(i) = 1.0/(1.0-alpha(i))
446!-----------
447            IF ( (ABS(aa(i)) < 1.e-6) .OR. (ABS(ab(i)) < 1.e-6) ) THEN
448               Warning_aa_ab(:)=.TRUE.
449            ENDIF
450            tr1(i) = exp(-18.42/aa(i))
451            tr2(i) = exp(-18.42/ab(i))
452          ENDIF
453        ELSE
454          IF (iwet(i) == 1) THEN
455            Warning_iwet(i)=.TRUE.
456          ENDIF
457        ENDIF
458      ENDDO
459
460      DO i=1,npoi
461         IF ( Warning_aa_ab(i) ) THEN
462            WRITE(numout,*) ' ATTENTION, aa ou ab:'
463            WRITE(numout,*) ' aa, ab = ',aa(i),ab(i)
464            WRITE(numout,*) '   alpha, rainpwd, beta =', &
465 &                       alpha(i),rainpwd(i),beta(i)
466         ENDIF
467         IF ( Warning_iwet(i) ) THEN
468            WRITE(numout,*) ' ATTENTION, iwet = 1 alors que xinprec = 0)'
469            WRITE(numout,*) '   xinprec, iwet = ',xinprec(i,imonth),iwet(i)
470          ENDIF
471      ENDDO
472!-----
473      where ( iwet(:) == 1 )
474        not_ok(:) = 1
475      elsewhere
476        not_ok(:) = 0
477      endwhere
478!-----
479      count_not_ok_g=0
480      count_not_ok=SUM(not_ok(:))
481      CALL reduce_sum(count_not_ok,count_not_ok_g)
482      CALL bcast(count_not_ok_g)
483!-
484      z(:)=0.0
485      DO WHILE (count_not_ok_g > 0)
486        IF (is_root_prc) THEN
487        CALL random_number (rn1)
488        CALL random_number (rn2)
489        ENDIF
490        CALL bcast(rn1)
491        CALL bcast(rn2)
492
493        DO i=1,npoi
494          IF ((iwet(i) == 1).AND.(not_ok(i) == 1)) then
495            IF ( (rn1-tr1(i)) <= 0. ) THEN
496              s1 = 0.0
497            ELSE
498              s1 = rn1**aa(i)
499            ENDIF
500!-----------
501            IF ((rn2-tr2(i)) <= 0.) THEN
502              s2 = 0.0
503            ELSE
504              s2 = rn2**ab(i)
505            ENDIF
506!-----------
507            s12 = s1+s2
508            IF ((s12-1.0) <= 0.) THEN
509              z(i) = s1/s12
510              not_ok(i) = 0
511            ENDIF
512          ENDIF
513        ENDDO
514
515        count_not_ok_g=0
516        count_not_ok=SUM(not_ok(:))
517        CALL reduce_sum(count_not_ok,count_not_ok_g)
518        CALL bcast(count_not_ok_g)
519      ENDDO
520!-----
521      IF (is_root_prc) THEN
522         CALL random_number (rn3)
523      ENDIF
524      CALL bcast(rn3)
525!      WRITE(*,*) mpi_rank,"rn3=",rn3
526!-----
527      DO i=1,npoi
528        IF (iwet(i) == 1) then
529          precip(i) = -z(i)*log(rn3)*beta(i)
530        ENDIF
531      ENDDO
532!-----
533!---- method ii --
534!-----
535!---- here we use a one-parameter Weibull distribution function
536!---- following the analysis of Selker and Haith (1990)
537!-----
538!---- Selker, J.S. and D.A. Haith, 1990: Development and testing
539!---- of single- parameter precipitation distributions,
540!---- Water Resources Research, 11, 2733-2740.
541!-----
542!---- this technique seems to have a significant advantage over other
543!---- means of generating rainfall distribution functions
544!-----
545!---- by calibrating the Weibull function to U.S. precipitation records,
546!---- Selker and Haith were able to establish the following relationship
547!-----
548!---- the cumulative probability of rainfall intensity x is given as:
549!-----
550!---- f(x) = 1.0-exp(-(1.191 x / rainpwd)**0.75)
551!-----
552!---- where x       : rainfall intensity
553!----       rainpwd : rainfall per wet day
554!-----
555!---- using transformation method, take uniform deviate and convert
556!---- it to a random number weighted by the following Weibull function
557!-----
558!----    call random_number(rndnum)
559!-----
560!----    precip(i) = rainpwd / 1.191*(-log(1.0-rndnum))**1.333333
561!-----
562!---- bound daily precipitation to "REAListic" range
563!-----
564      DO i=1,npoi
565        IF (iwet(i) == 1) THEN
566!---------
567!-------- lower end is determined by definition of a 'wet day'
568!-------- (at least 0.25 mm of total precipitation)
569!---------
570!-------- upper end is to prevent ibis from blowing up
571!---------
572          precip(i) = MAX(precip(i),  0.25) ! min =   0.25 mm/day
573          precip(i) = MIN(precip(i),150.00) ! max = 150.00 mm/day
574        ENDIF
575      ENDDO
576    ELSE
577!-----
578!---- (2.2) preserving the monthly number of precip days
579!----       and monthly precip
580!-----
581      DO i=1,npoi
582!-------
583!------ Correction Nathalie. C'est abs(xinwet) < 32 qu'il faut tester
584!------ et non pas abs(xinprec(i,imonth)) < 32.
585!-------
586!------ IF ( (iwet(i) == 1).and.(abs(xinprec(i,imonth)) < 32.) ) THEN
587        IF ( (iwet(i) == 1).and.(abs(xinwet(i,imonth)) < 32.) ) THEN
588          precip(i) = xinprec(i,imonth)*REAL(ndaypm(imonth)) &
589 &                   /REAL(NINT(MAX(1.,xinwet(i,imonth))))
590        ELSE
591          precip(i) = 0.
592        ENDIF
593      ENDDO
594    ENDIF
595!---
596!-- (3) estimate expected minimum and maximum temperatures
597!---
598    DO i=1,npoi
599!-----
600!---- first determine the expected maximum and minimum temperatures
601!---- (from climatological means) for this day of the year
602!-----
603!---- mean daily mean temperature (K)
604      tdm = xint(i,it1w)+dt*(xint(i,it2w)-xint(i,it1w))+zero_t
605!---- mean daily temperature range (K)
606      trngm = xintrng(i,it1w)+dt*(xintrng(i,it2w)-xintrng(i,it1w))
607!---- mean minimum and maximum temperatures
608      tmaxm = tdm+0.56*trngm
609      tminm = tdm-0.44*trngm
610!-----
611!---- modify maximum temperatures for wet and dry days
612!-----
613      IF (pwet(i) /= 0.0) THEN
614        tmaxd = tmaxm+pwet(i)*omtmax*trngm
615        tmaxw = tmaxd-        omtmax*trngm
616      ELSE
617        tmaxd = tmaxm
618        tmaxw = tmaxm
619      ENDIF
620!-----
621!---- set the 'expected' maximum and minimum temperatures for today
622!-----
623!---- note that the expected minimum temperatures are the same for
624!---- both wet and dry days
625!-----
626      if (iwet(i) == 0)  tmaxe(i) = tmaxd
627      if (iwet(i) == 1)  tmaxe(i) = tmaxw
628!-----
629      tmine(i) = tminm
630!-----
631!---- estimate variability in minimum and maximum temperatures
632!-----
633!---- tmaxs : standard deviation in maximum temperature (K)
634!---- tmins : standard deviation in minimum temperature (K)
635!-----
636!---- Regression is based on analysis of 2-m air temperature data
637!---- from the NCEP/NCAR reanalysis (1958-1997) for 294 land points
638!---- over central North America
639!---- (24N-52N, 130W-60W, 0.5-degree resolution):
640!---- Daily max and min temperatures were calculated for each
641!---- land point from daily mean temperature and temperature range.
642!---- Anomalies were calculated
643!---- by subtracting similar max and min temperatures calculated from
644!---- monthly mean temperature and range (interpolated to daily).
645!---- The 40 years of anomalies were then binned by month
646!---- and the standard deviation calculated for each month.
647!---- The 294 x 12 standard deviations were then regressed
648!---- against the 3528 long-term monthly mean temperatures.
649!-----
650!---- note: the values are bound to be greater than 1.0 K
651!----       (at the very least they must be bound
652!----        so they don't go below zero)
653!-----
654      tmaxs(i) = MAX(1.0,-0.0713*(tdm-zero_t)+4.89)
655      tmins(i) = MAX(1.0,-0.1280*(tdm-zero_t)+5.73)
656    ENDDO
657!---
658!-- (4) estimate expected cloud cover
659!---
660!---
661!-- the formulation of dry and wet cloud cover has been
662!-- derived from the weather generator used in the epic crop model
663!---
664    DO i=1,npoi
665!-----
666!---- cloudm : mean cloud cover for today
667!---- cloudd : dry day cloud cover
668!---- cloudw : dry day cloud cover
669!---- cloude : expected cloud cover today
670!-----
671!---- mean cloud cover (%)
672!-----
673      cloudm = xincld(i,it1w)+dt*(xincld(i,it2w)-xincld(i,it1w))
674!-----
675!---- convert from percent to fraction
676!-----
677      cloudm = cloudm/100.0
678!-----
679!---- adjust cloud cover depending on dry day / rainy day
680!---- following logic of the EPIC weather generator code
681!-----
682      IF (pwet(i) /= 0.0) THEN
683        cloudd = (cloudm-pwet(i)*omcloud)/(1.0-pwet(i)*omcloud)
684        cloudd = MIN(1.0,MAX(0.0,cloudd))
685        cloudw = (cloudm-(1.0-pwet(i))*cloudd)/pwet(i)
686      ELSE
687        cloudd = cloudm
688        cloudw = cloudm
689      ENDIF
690      IF (iwet(i) == 0)  cloude(i) = cloudd
691      IF (iwet(i) == 1)  cloude(i) = cloudw
692!-----
693!---- estimate variability in cloud cover for wet and dry days
694!---- following numbers proposed by Richardson
695!-----
696!---- clouds : standard deviation of cloud fraction
697!-----
698      IF (iwet(i) == 0)  clouds(i) = 0.24*cloude(i)
699      IF (iwet(i) == 1)  clouds(i) = 0.48*cloude(i)
700    ENDDO
701!---
702! (5) determine today's temperatures and cloud cover using
703!     first-order serial autoregressive technique
704!---
705!-- use the Richardson (1981) weather generator approach to simulate the
706!-- daily values of minimum / maximum temperature and cloud cover
707!---
708!-- following the implementation of the Richardson WGEN weather
709!-- generator used in the EPIC crop model
710!---
711!-- this approach uses a multivariate generator, which assumes that the
712!-- perturbation of minimum / maximum temperature and cloud cover are
713!-- normally distributed and that the serial correlation of each
714!-- variable may be described by a first-order autoregressive model
715!---
716!-- generate standard deviates for weather generator
717!---
718    DO j=1,3
719      ee(j) = 9999.
720      DO WHILE (ee(j) > 2.5)
721        IF (is_root_prc) THEN
722           CALL random_number (rn1)
723           CALL random_number (rn2)
724        ENDIF
725        CALL bcast(rn1)
726        CALL bcast(rn2)
727        ee(j) = SQRT(-2.0*LOG(rn1))*COS(6.283185*rn2)
728      ENDDO
729    ENDDO
730!---
731!-- zero out vectors
732!---
733    r(1:3)  = 0.0
734    rr(1:npoi,1:3) = 0.0
735!---
736!-- update working vectors
737!---
738    do j=1,3
739      do k=1,3
740        r(j) = r(j)+b(j,k)*ee(j)
741      enddo
742    enddo
743!---
744    do j=1,3
745      do k=1,3
746        do i=1,npoi
747          rr(i,j) = rr(i,j)+a(j,k)*xstore(i,k)
748        enddo
749      enddo
750    enddo
751!---
752!-- solve for x() perturbation vector and save current vector
753!-- into the xim1() storage vector (saved for each point)
754!---
755    do j=1,3
756      do i=1,npoi
757        xstore(i,j) = r(j)+rr(i,j)
758      enddo
759    enddo
760!---
761!-- determine today's minimum and maximum temperature
762!--
763    do i=1,npoi
764      tmax(i) = tmaxe(i)+tmaxs(i)*xstore(i,1)
765      tmin(i) = tmine(i)+tmins(i)*xstore(i,2)
766!-----
767!---- if tmin > tmax, then switch the two around
768!-----
769      if (tmin(i) > tmax(i)) then
770        tdum    = tmax(i)
771        tmax(i) = tmin(i)
772        tmin(i) = tdum
773      ENDIF
774!---- daily average temperature
775      td(i) = 0.44*tmax(i)+0.56*tmin(i)
776!---- determine today's cloud cover
777      cloud(i) = cloude(i)+clouds(i)*xstore(i,3)
778!---- constrain cloud cover to be between 0 and 100%
779      cloud(i) = MAX(0.0,MIN(1.0,cloud(i)))
780    enddo
781!---
782!-- (6) estimate today's surface atmospheric pressure
783!---
784    do i=1,npoi
785!-----
786!---- simply a function of the daily average temperature
787!---- and topographic height -- nothing fancy here
788!-----
789      psurf(i) = 101325.0*(td(i)/(td(i)+0.0065*xintopo(i)))**rwork
790    enddo
791!---
792!-- (7) estimate today's relative humidity
793!---
794    IF (is_root_prc) THEN
795       CALL random_number (rn)
796    ENDIF
797    CALL bcast(rn)
798!---
799    CALL weathgen_qsat (npoi,td,psurf,qsattd)
800!---
801    do i=1,npoi
802!-----
803!---- the formulation of dry and wet relative humidities has been
804!---- derived from the weather generator used in the epic crop model
805!-----
806!---- qdm : mean relative humidity
807!---- qdd : dry day relative humidity
808!---- qdw : rainy day relative humidity
809!---- qde : expected relative humidity (based on wet/dry decision)
810!-----
811!---- mean relative humidity (%)
812      qdm(i) = xinq(i,it1w)+dt*(xinq(i,it2w)-xinq(i,it1w))
813!---- convert from percent to fraction
814      qdm(i) = qdm(i)/100.0
815!-----
816!---- adjust humidity depending on dry day / rainy day
817!---- following logic of the EPIC weather generator code
818!-----
819      if (pwet(i) /= 0.0) then
820        qdd(i) = (qdm(i)-pwet(i)*omqd)/(1.0-pwet(i)*omqd)
821        if (qdd(i) < 0.2) then
822          qdd(i) = 0.2
823          if (qdd(i) > qdm(i)) qdm(i) = qdd(i)
824        ENDIF
825        qdd(i) = MIN(1.0,qdd(i))
826        qdw(i) = (qdm(i)-(1.0-pwet(i))*qdd(i))/pwet(i)
827      ELSE
828        qdd(i) = qdm(i)
829        qdw(i) = qdm(i)
830      ENDIF
831!-----
832      if (iwet(i) == 0)  qde(i) = qdd(i)
833      if (iwet(i) == 1)  qde(i) = qdw(i)
834!-----
835!---- estimate lower and upper bounds of humidity distribution function
836!---- following logic of the EPIC weather generator code
837!-----
838      xx = exp(qde(i))
839      qdup(i)  = qde(i)+(1.0-qde(i))*xx/e
840      qdlow(i) = qde(i)*(1.0-1./xx)
841!-----
842!---- randomlly select humidity from triangular distribution function
843!---- following logic of the EPIC weather generator code
844!-----
845!---- call random_number(rn) ! GK done before
846!-----
847      y  = 2.0/(qdup(i)-qdlow(i))
848!-----
849      b3 = qde(i)-qdlow(i)
850      b2 = qdup(i)-qde(i)
851      b1 = rn/y
852!-----
853      x1 = y*b3/2.0
854!-----
855      if (rn > x1) then
856        qd(i) = qdup(i)-sqrt (b2*b2-2.0*b2*(b1-0.5*b3))
857      ELSE
858        qd(i) = qdlow(i)+sqrt (2.0*b1*b3)
859      ENDIF
860!-----
861!---- adjust daily humidity to conserve monthly mean values
862!-----
863!---- note that this adjustment sometimes gives rise to humidity
864!---- values greater than 1.0 -- which is corrected below
865!-----
866      amn = (qdup(i)+qde(i)+qdlow(i))/3.0
867      qd(i) = qd(i)*qde(i)/amn
868!-----
869!---- constrain daily average relative humidity
870!-----
871      qd(i) = MAX(0.30,MIN(qd(i),0.99))
872!-----
873!---- convert from relative humidity to specific humidity at
874!---- daily mean temperature
875!-----
876      qd(i) = qd(i)*qsattd(i)
877    enddo
878!---
879!-- (8) estimate today's daily average wind speed
880!---
881    IF (is_root_prc) THEN
882        CALL random_number (rn4)
883    ENDIF
884    CALL bcast(rn4)
885
886    do i=1,npoi
887!-----
888!---- first estimate the expected daily average wind speed (from monthly
889!---- means)
890!-----
891      eud = xinwind(i,it1w)+dt*(xinwind(i,it2w)-xinwind(i,it1w))
892!-----
893!---- following logic of the EPIC weather generator
894!---- select random wind speed following this equation
895!-----
896!---- call random_number(rn4)
897!-----
898      ud(i) = 1.13989*eud*(-log(rn4))**0.30
899!---- constrain daily wind speeds to be between 2.5 and 10.0 m/sec
900      ud(i) = MAX(2.5,MIN(ud(i),10.0))
901    ENDDO
902  ELSE
903!---
904!-- use REAL daily climate data
905!---
906    DO i=1,npoi
907!-----
908!---- use basic daily climate data, converting units
909!-----
910!---- daily total precipitation
911      precip(i) = xinprec(i,imonth)
912!---- daily average temperatures
913      td(i) = xint(i,imonth)+zero_t
914      trngm = MIN(44.0,xintrng(i,imonth))
915!-----
916      tmax(i) = td(i)+0.56*trngm
917      tmin(i) = td(i)-0.44*trngm
918!---- daily average cloud cover
919      cloud(i) = xincld(i,imonth)*0.01
920!---- daily average specific humidity
921      qd(i) = xinq(i,imonth)
922!---- daily average wind speed
923      ud(i) = xinwind(i,imonth)
924!-----
925!---- compute surface atmospheric pressure
926!-----
927      psurf(i) = 101325.0*(td(i)/(td(i)+0.0065*xintopo(i)))**rwork
928    ENDDO
929  ENDIF
930!-------------------
931END SUBROUTINE daily
932!-
933!===
934!-
935
936!! ================================================================================================================================
937!! SUBROUTINE   : diurnal
938!!
939!>\BRIEF          This routine interpolates values from the!*
940!! subroutine daily into instantaneous values for simulating a diurnal cycle.
941!!
942!! DESCRIPTION  : 
943!!
944!! RECENT CHANGE(S): None
945!!
946!! MAIN OUTPUT VARIABLE(S):  ::fira, ::solad, ::ua, ::ta, ::qa, ::raina, ::snowa, ::rh.
947!!
948!! REFERENCE(S) :
949!!
950!! FLOWCHART    : None
951!! \n
952!_ ================================================================================================================================
953
954SUBROUTINE diurnal &
955& (npoi, nband, time, jday, plens, startp, endp, latitude, &
956&  cloud, tmax, tmin, precip, qd, ud, psurf, &
957&  fira, solad, solai, ua, ta, qa, raina, snowa, rh)
958!---------------------------------------------------------------------
959  IMPLICIT NONE
960!-
961
962  !! 0. Parameter and variables declaration
963
964  REAL,PARAMETER :: stef = 5.67051E-8  !! Stefan-Boltzman constant @tex $(W.m^{-2}.K^{-4})$ @endtex
965  REAL,PARAMETER :: pi = 3.1415927     !! pi
966  REAL,PARAMETER :: pir = pi/180.      !! conversion factor degrees to radians
967
968  !! 0.1 Input variables
969
970  INTEGER,INTENT(IN) :: npoi    !! number of grid points (unitless)
971  INTEGER,INTENT(IN) :: nband   !! number of visible bands (unitless)
972  REAL,INTENT(IN) :: time
973  INTEGER, INTENT(IN) :: jday
974  REAL,INTENT(IN) :: plens,startp,endp
975  REAL,INTENT(IN) :: latitude(npoi)   !! latitude in degrees
976  REAL,INTENT(IN) :: cloud(npoi)      !! cloud fraction (0-1, unitless)
977  REAL,INTENT(IN) :: tmax(npoi)       !! maximum daily temperature (K)
978  REAL,INTENT(IN) :: tmin(npoi)       !! maximum daily temperature (K)
979  REAL,INTENT(IN) :: precip(npoi)     !! daily precitation @tex $(mm.day^{-1})$ @endtex
980  REAL,INTENT(IN) :: qd(npoi)         !! daily average specific humidity (kg_h2o/kg_air)
981  REAL,INTENT(IN) :: ud(npoi)         !! daily average wind speed @tex $(m.s^{-1})$ @endtex
982  REAL,INTENT(IN) :: psurf(npoi)      !! surface pressure (Pa)
983
984  !! 0.2 Output variables
985
986  REAL,INTENT(OUT) :: fira(npoi)          !! incoming ir flux  @tex $(W.m^{-2})$ @endtex
987  REAL,INTENT(OUT) :: solad(npoi,nband)   !! direct downward solar flux @tex $(W.m^{-2})$ @endtex
988  REAL,INTENT(OUT) :: solai(npoi,nband)   !! diffuse downward solar flux @tex $(W.m^{-2})$ @endtex
989  REAL,INTENT(OUT) :: ua(npoi)            !! wind speed @tex $(m.s^{-1})$ @endtex
990  REAL,INTENT(OUT) :: ta(npoi)            !! air temperature (K)
991  REAL,INTENT(OUT) :: qa(npoi)            !! specific humidity (kg_h2o/kg_air)
992  REAL,INTENT(OUT) :: raina(npoi)         !! rainfall rate @tex $(mm.day^{-1})$ @endtex
993  REAL,INTENT(OUT) :: snowa(npoi)         !! snowfall rate @tex $(mm.day^{-1})$ @endtex
994  REAL,INTENT(OUT) :: rh(npoi)            !! relative humidity (0-1, unitless)
995
996  !! 0.4 Local variables
997
998  REAL,SAVE      :: step
999  REAL :: xl,so,xllp,xee,xse
1000  REAL :: xlam,dlamm,anm,ranm,ranv,anv,tls,rlam
1001  REAL :: sd,cd,deltar,delta,Dis_ST,ddt
1002!-
1003  REAL :: coszen(npoi)                      !! cosine of solar zenith angle
1004  REAL :: rtime
1005  REAL :: orbit,angle,xdecl,xlat
1006  REAL :: sw,frac,gamma,qmin,qmax,qsa,emb,ea,ec,dtair,dtcloud,rn
1007  REAL :: trans(npoi), fdiffuse(npoi), qsatta(npoi), qsattmin(npoi)
1008  INTEGER :: i,ib
1009  INTEGER,SAVE :: npoi0
1010  LOGICAL,SAVE :: firstcall = .TRUE.
1011
1012!---------------------------------------------------------------------
1013! GK240100
1014  IF (firstcall) THEN
1015     IF ( TRIM(calendar_str) .EQ. 'gregorian' ) THEN 
1016        step = 1.0
1017     ELSE
1018        step = one_year/365.2425
1019     ENDIF
1020    firstcall = .FALSE.
1021    npoi0 = npoi
1022  ELSE IF (npoi /= npoi0) THEN
1023    WRITE(numout,*) 'Domain size old, new: ',npoi0,npoi
1024    STOP 'WG Diurnal: Problem: Domain has changed since last call'
1025  ENDIF
1026!-
1027! calendar and orbital calculations
1028!-
1029! calculate time in hours
1030  rtime = time/3600.0
1031!-
1032! calculate the earth's orbital angle (around the sun) in radians
1033  orbit = 2.0*pi*REAL(jday)/365.2425
1034!-
1035! calculate the solar hour angle in radians
1036  angle = 2.0*pi*(rtime-12.0)/24.0
1037!-
1038! calculate the current solar declination angle
1039! ref: global physical climatology, hartmann, appendix a
1040!
1041! xdecl = 0.006918 &
1042!        -0.399912*cos(orbit) &
1043!        +0.070257*sin(orbit) &
1044!        -0.006758*cos(2.0*orbit) &
1045!        +0.000907*sin(2.0*orbit) &
1046!        -0.002697*cos(3.0*orbit) &
1047!        +0.001480*sin(3.0*orbit)
1048!
1049! calculate the effective solar constant,
1050! including effects of eccentricity
1051! ref: global physical climatology, hartmann, appendix a
1052!
1053! sw = 1370.*( 1.000110 &
1054!             +0.034221*cos(orbit) &
1055!             +0.001280*sin(orbit) &
1056!             +0.000719*cos(2.0*orbit) &
1057!             +0.000077*sin(2.0*orbit))
1058!
1059! correction Marie-France Loutre
1060!
1061!    orbital parameters
1062!
1063!    ecc = 0.016724
1064!    perh = 102.04
1065!    xob = 23.446
1066!-
1067  xl = perh+180.0
1068! so : sinus of obliquity
1069  so = sin(xob*pir)
1070!-
1071  xllp = xl*pir
1072  xee  = ecc*ecc
1073  xse  = sqrt(1.0d0-xee)
1074! xlam : true long. sun for mean long. = 0
1075  xlam = (ecc/2.0+ecc*xee/8.0d0)*(1.0+xse)*sin(xllp)-xee/4.0 &
1076 &      *(0.5+xse)*sin(2.0*xllp)+ecc*xee/8.0*(1.0/3.0+xse) &
1077 &      *sin(3.0*xllp)
1078  xlam  =2.0d0*xlam/pir
1079! dlamm : mean long. sun for ma-ja
1080  dlamm =xlam+(jday-79)*step
1081  anm   = dlamm-xl
1082  ranm  = anm*pir
1083  xee   = xee*ecc
1084! ranv : anomalie vraie    (radian)
1085  ranv = ranm+(2.0*ecc-xee/4.0)*sin(ranm)+5.0/4.0*ecc*ecc &
1086 &      *sin(2.0*ranm)+13.0/12.0*xee*sin(3.0*ranm)
1087! anv  : anomalie vraie    (degrees)
1088  anv  = ranv/pir
1089! tls  : longitude vraie   (degrees)
1090  tls  = anv+xl
1091! rlam : longitude vraie   (radian)
1092  rlam = tls*pir
1093! sd and cd: cosinus and sinus of solar declination angle (delta)
1094! sinus delta = sin (obl)*sin(lambda) with lambda = real longitude
1095! (Phd. thesis of Marie-France Loutre, ASTR-UCL, Belgium, 1993)
1096  sd    = so*sin(rlam)
1097  cd    = sqrt(1.0d0-sd*sd)
1098! delta : Solar Declination (degrees, angle sun at equator)
1099  deltar = atan(sd/cd)
1100  delta  = deltar/pir
1101!-
1102! Eccentricity Effect
1103!-
1104  Dis_ST  =(1.0-ecc*ecc)/(1.0+ecc*cos(ranv))
1105! ddt :    1 / normalized earth's sun distance
1106  ddt = 1.0/Dis_ST
1107!-
1108! Insolation normal to the atmosphere (W/m2)
1109!-
1110  sw  = ddt *ddt *1370.d0
1111!-
1112  xdecl = deltar
1113!-
1114! solar calculations
1115!-
1116  do i=1,npoi
1117!---
1118!-- calculate the latitude in radians
1119!---
1120    xlat = latitude(i)*pi/180.0
1121!---
1122!-- calculate the cosine of the solar zenith angle
1123!---
1124    coszen(i) = MAX(0.0, (sin(xlat)*sin(xdecl) &
1125 &                      + cos(xlat)*cos(xdecl)*cos(angle)))
1126!---
1127!-- calculate the solar transmission through the atmosphere
1128!-- using simple linear function of tranmission and cloud cover
1129!---
1130!-- note that the 'cloud cover' data is typically obtained from
1131!-- sunshine hours -- not direct cloud observations
1132!---
1133!-- where, cloud cover = 1 - sunshine fraction
1134!---
1135!-- different authors present different values for the slope and
1136!-- intercept terms of this equation
1137!---
1138!-- Friend, A: Parameterization of a global daily weather generator
1139!-- for terrestrial ecosystem and biogeochemical modelling,
1140!-- Ecological Modelling
1141!---
1142!-- Spitters et al., 1986: Separating the diffuse and direct component
1143!-- of global radiation and its implications for modeling canopy
1144!-- photosynthesis, Part I: Components of incoming radiation,
1145!-- Agricultural and Forest Meteorology, 38, 217-229.
1146!---
1147!-- A. Friend       : trans = 0.251+0.509*(1.0-cloud(i))
1148!-- Spitters et al. : trans = 0.200+0.560*(1.0-cloud(i))
1149!---
1150!-- we are using the values from A. Friend
1151!---
1152    trans(i) = 0.251+0.509*(1.0-cloud(i))
1153!---
1154!-- calculate the fraction of indirect (diffuse) solar radiation
1155!-- based upon the cloud cover
1156!---
1157!-- note that these relationships typically are measured for either
1158!-- monthly or daily timescales, and may not be exactly appropriate
1159!-- for hourly calculations -- however, in ibis, cloud cover is fixed
1160!-- through the entire day so it may not make much difference
1161!---
1162!-- method i --
1163!---
1164!-- we use a simple empirical relationships
1165!-- from Nikolov and Zeller (1992)
1166!---
1167!-- Nikolov, N. and K.F. Zeller, 1992:  A solar radiation algorithm
1168!-- for ecosystem dynamics models, Ecological Modelling, 61, 149-168.
1169!---
1170    fdiffuse(i) = 1.0045+trans(i)*( 0.0435+trans(i) &
1171 &                                 *(-3.5227+trans(i)*2.6313))
1172!---
1173    IF (trans(i) > 0.75) fdiffuse(i) = 0.166
1174!---
1175!-- method ii --
1176!---
1177!-- another method was suggested by Spitters et al. (1986) based on
1178!-- long-term data from the Netherlands
1179!--
1180!-- Spitters et al., 1986: Separating the diffuse and direct component
1181!-- of global radiation and its implications for modeling canopy
1182!-- photosynthesis, Part I: Components of incoming radiation,
1183!-- Agricultural and Forest Meteorology, 38, 217-229.
1184!---
1185!--       if ((trans == 0.00).and.(trans < 0.07)) then
1186!--         fdiffuse = 1.0
1187!--       else if ((trans >= 0.07).and.(trans < 0.35)) then
1188!--         fdiffuse = 1.0-2.3*(trans-0.07)**2
1189!--       else if ((trans >= 0.35).and.(trans < 0.75)) then
1190!--         fdiffuse = 1.33-1.46*trans
1191!--       ELSE
1192!--         fdiffuse = 0.23
1193!--       endif
1194!---
1195  ENDDO
1196!-
1197! do for each waveband
1198!-
1199  DO ib=1,nband
1200!---
1201!-- calculate the fraction in each waveband
1202!---
1203!-- GK010200
1204    IF (nband == 2) then
1205      frac = 0.46+0.08*REAL(ib-1)
1206    ELSE
1207      frac = 1./REAL(nband)
1208    ENDIF
1209!---
1210    DO i=1,npoi
1211!-----
1212!---- calculate the direct and indirect solar radiation
1213!-----
1214      solad(i,ib) = sw*coszen(i)*frac*trans(i)*(1.-fdiffuse(i))
1215      solai(i,ib) = sw*coszen(i)*frac*trans(i)*fdiffuse(i)
1216    ENDDO
1217  ENDDO
1218!-
1219! temperature calculations
1220!-
1221!---
1222!-- assign hourly temperatures using tmax and tmin
1223!-- following Environmental Biophysics, by Campbell and Norman, p.23
1224!---
1225!-- this function fits a fourier series to the diurnal temperature cycle
1226!-- note that the maximum temperature occurs at 2:00 pm local solar time
1227!---
1228!-- note that the daily mean value of gamma is 0.44,
1229!-- so td = 0.44*tmax+0.56*tmin,  instead of
1230!--    td = 0.50*tmax+0.50*tmin
1231!---
1232  gamma = 0.44-0.46*SIN(    pi/12.0*rtime+0.9) &
1233              +0.11*SIN(2.0*pi/12.0*rtime+0.9)
1234  DO i=1,npoi
1235    ta(i) = tmax(i)*gamma+tmin(i)*(1.0-gamma)
1236  ENDDO
1237!-
1238! humidity calculations
1239!-
1240  CALL weathgen_qsat (npoi,tmin,psurf,qsattmin)
1241  CALL weathgen_qsat (npoi,ta,psurf,qsatta)
1242!-
1243  DO i=1,npoi
1244!---
1245!-- adjust specific humidity against daily minimum temperatures
1246!---
1247!-- To do this, qa is written as an approximate sine function
1248!-- (same as ta) to preserve the daily mean specific humidity,
1249!-- while also preventing rh from exceeding 99% at night
1250!---
1251!-- Note that the daily mean RH is *not* preserved, and therefore the
1252!-- output RH will be slightly different from what was read in.
1253!---
1254!-- first adjust so that maximum RH cannot exceed 99% at night
1255!---
1256    qmin = MIN(qd(i),0.99*qsattmin(i))
1257    qmax = (qd(i)-0.56*qmin)/0.44
1258!---
1259!-- if needed, adjust again to 99% at other times of the day (in which
1260!-- case the daily mean *specific* humidity is also not preserved)
1261!---
1262    qsa  = 0.99*qsatta(i)
1263!---
1264!-- calculate the hourly specific humidity, using the above adjustments
1265!---
1266    qa(i) = MIN(qsa,qmax*gamma+qmin*(1.0-gamma))
1267!---
1268!-- calculate the hourly relative humidity
1269!--
1270    rh(i) = 100.*qa(i)/qsatta(i)
1271  ENDDO
1272!-
1273! wind speed calculations
1274!-
1275  IF (is_root_prc) THEN
1276     CALL random_number (rn)
1277  ENDIF
1278  CALL bcast(rn)
1279!-
1280  DO i=1,npoi
1281!---
1282!-- following logic of the EPIC weather generator
1283!-- select random wind speed following this equation
1284!---
1285!-- call random_number(rn) ! done before
1286!---
1287    ua(i) = 1.13989*ud(i)*(-log(rn))**0.30
1288!---
1289!-- fix wind speeds to always be above 2.5 m/sec and below 10.0 m/sec
1290!---
1291    ua(i) = MAX(2.5,MIN(10.0,ua(i)))
1292  ENDDO
1293!-
1294! ir flux calculations
1295!-
1296  DO i=1,npoi
1297!---
1298!-- clear-sky emissivity as a function of water vapor pressure
1299!-- and atmospheric temperature
1300!---
1301!-- calculate the ir emissivity of the clear sky
1302!-- using equation from idso (1981) water resources res., 17, 295-304
1303!---
1304    emb = 0.01*(psurf(i)*qa(i)/(0.622+qa(i)))
1305    ea  = 0.70+5.95e-5*emb*EXP(1500.0/ta(i))
1306!---
1307!-- assign the ir emissivity of clouds
1308!-- (assume they are ~black in the ir)
1309!---
1310    ec = 0.950
1311!---
1312!-- assign the temperature difference of emissions (air+cloud) from
1313!-- the surface air temperature
1314!---
1315    dtair   = 0.0
1316    dtcloud = 0.0
1317!---
1318!-- total downward ir is equal to the sum of:
1319!---
1320!-- (1) clear sky contribution to downward ir radiation flux
1321!-- (2) cloud contribution to downward ir radiation flux
1322!---
1323    fira(i) = (1.-cloud(i))*ea*stef*(ta(i)-dtair)**4 &
1324 &           +cloud(i)*ec*stef*(ta(i)-dtcloud)**4
1325  ENDDO
1326!-
1327! snow and rain calculations
1328!-
1329  DO i=1,npoi
1330!---
1331!-- reset snow and rain to zero
1332!---
1333    snowa(i) = 0.0
1334    raina(i) = 0.0
1335!---
1336!-- if precipitation event then calculate
1337!---
1338    IF (time >= startp .and. time < endp) then
1339!-----
1340!---- for rain / snow partitioning, make it all rain if
1341!---- ta > 2.5 C and all snow if ta <= 2.5 C
1342!-----
1343!---- reference:
1344!-----
1345!---- Auer, A. H., 1974: The rain versus snow threshold temperatures,
1346!---- Weatherwise, 27, 67.
1347!-----
1348      IF (ta(i)-273.15 > 2.5) then
1349        raina(i) = precip(i)/plens
1350      ELSE
1351        snowa(i) = precip(i)/plens
1352      ENDIF
1353    ENDIF
1354  ENDDO
1355!---------------------
1356END SUBROUTINE diurnal
1357!-
1358!===
1359!-
1360
1361!! ================================================================================================================================
1362!! SUBROUTINE   : weathgen_main
1363!!
1364!>\BRIEF        This subroutine manages the calls to the different subroutines of the weather module.
1365!!
1366!! DESCRIPTION  : None
1367!!
1368!! RECENT CHANGE(S): None
1369!!
1370!! MAIN OUTPUT VARIABLE(S): ::tair, ::pb, ::qair, ::swdown, ::rainf, ::snowf, ::u, ::v, ::lwdown
1371!!
1372!! REFERENCE(S) :
1373!!
1374!! FLOWCHART    : None
1375!! \n
1376!_ ================================================================================================================================
1377
1378SUBROUTINE weathgen_main &
1379& (itau, istp, filename, force_id, iim, jjm, nband, &
1380&  rest_id, lrstread, lrstwrite, &
1381&  limit_west, limit_east, limit_north, limit_south, &
1382&  zonal_res, merid_res, lon, lat, date0, dt_force, &
1383&  kindex, nbindex, &
1384&  swdown, rainf, snowf, tair, u, v, qair, pb, lwdown)
1385!---------------------------------------------------------------------
1386  IMPLICIT NONE
1387!-
1388
1389  !! 0. Variables and parameters declaration
1390
1391  !! 0.1 Input variables
1392
1393  INTEGER,INTENT(IN)                  :: itau,istp
1394  CHARACTER(LEN=*),INTENT(IN)         :: filename
1395  INTEGER,INTENT(IN)                  :: force_id
1396  INTEGER,INTENT(IN)                  :: iim,jjm
1397  INTEGER,INTENT(IN)                  :: nband
1398  INTEGER,INTENT(IN)                  :: rest_id
1399  LOGICAL,INTENT(IN)                  :: lrstread, lrstwrite
1400  REAL,INTENT(IN)                     :: limit_west,limit_east
1401  REAL,INTENT(IN)                     :: limit_north,limit_south
1402  REAL,INTENT(IN)                     :: zonal_res,merid_res
1403  REAL,INTENT(IN)                     :: date0,dt_force
1404  REAL,DIMENSION(iim,jjm),INTENT(IN)  :: lon,lat  !! longitude, latitude
1405
1406  !! 0.2 Output variables
1407
1408  REAL,DIMENSION(iim,jjm),INTENT(OUT) :: &
1409 &  tair,pb,qair,swdown,rainf,snowf, u,v,lwdown
1410
1411  !! 0.3 Mofified variables
1412
1413  INTEGER,INTENT(INOUT)                    :: nbindex
1414  INTEGER,DIMENSION(iim*jjm),INTENT(INOUT) :: kindex
1415
1416  !! 0.4 Local variables
1417
1418  REAL, ALLOCATABLE, DIMENSION(:,:) :: &
1419 &  tair_g,pb_g,qair_g,swdown_g,rainf_g,snowf_g, u_g,v_g,lwdown_g
1420  REAL,DIMENSION(nbindex) :: &
1421 &  tairl,pbl,qairl,swdownl,rainfl,snowfl, ul,vl,lwdownl
1422  INTEGER :: i,j,ij
1423!---------------------------------------------------------------------
1424  IF (lrstread) THEN
1425    CALL weathgen_begin ( &
1426     & dt_force,itau, date0, &
1427     & rest_id,iim,jjm, &
1428     & lon,lat,tair,pb,qair,kindex,nbindex)
1429        RETURN
1430  ELSE
1431    CALL weathgen_get &
1432 &   (itau, date0, dt_force, nbindex, nband, lat_land, &
1433 &    swdownl, rainfl, snowfl, tairl, ul, vl, qairl, pbl, lwdownl)
1434
1435    tair(:,:)=val_exp
1436    qair(:,:)=val_exp
1437    pb(:,:)=val_exp
1438!!$    tair(:,:)=280.
1439!!$    qair(:,:)=1.E-03
1440!!$    pb(:,:)=101325
1441    DO ij=1,nbindex
1442       j = (((kindex(ij)-1)/iim) + 1)
1443       i = (kindex(ij) - (j-1)*iim)
1444       !
1445       swdown(i,j)=swdownl(ij)
1446       rainf(i,j)=rainfl(ij)
1447       snowf(i,j)=snowfl(ij)
1448       tair(i,j)=tairl(ij)
1449       u(i,j)=ul(ij)
1450       v(i,j)=vl(ij)
1451       qair(i,j)=qairl(ij)
1452       pb(i,j)=pbl(ij)
1453       lwdown(i,j)=lwdownl(ij)
1454    ENDDO
1455!---
1456    IF (dump_weather) THEN
1457      ALLOCATE(tair_g(iim_g,jjm_g))
1458      ALLOCATE(pb_g(iim_g,jjm_g))
1459      ALLOCATE(qair_g(iim_g,jjm_g))
1460      ALLOCATE(swdown_g(iim_g,jjm_g))
1461      ALLOCATE(rainf_g(iim_g,jjm_g))
1462      ALLOCATE(snowf_g(iim_g,jjm_g))
1463      ALLOCATE(u_g(iim_g,jjm_g))
1464      ALLOCATE(v_g(iim_g,jjm_g))
1465      ALLOCATE(lwdown_g(iim_g,jjm_g))
1466
1467      CALL gather2D(tair, tair_g)
1468      CALL gather2D(pb, pb_g)
1469      CALL gather2D(qair, qair_g)
1470      CALL gather2D(swdown, swdown_g)
1471      CALL gather2D(rainf, rainf_g)
1472      CALL gather2D(snowf, snowf_g)
1473      CALL gather2D(u, u_g)
1474      CALL gather2D(v, v_g)
1475      CALL gather2D(lwdown, lwdown_g)
1476      IF (is_root_prc) THEN
1477         CALL weathgen_dump &
1478 &           (itau, dt_force, iim_g, jjm_g, nbp_glo, index_g, lrstwrite, &
1479 &            swdown_g, rainf_g, snowf_g, tair_g, u_g, v_g, qair_g, pb_g, lwdown_g)
1480      ENDIF
1481    ENDIF
1482!---
1483    IF (lrstwrite) THEN
1484      CALL weathgen_restwrite (rest_id,istp,iim,jjm,nbindex,kindex)
1485    ENDIF
1486  ENDIF
1487!---------------------------
1488END SUBROUTINE weathgen_main
1489!-
1490!===
1491!-
1492
1493!! ================================================================================================================================
1494!! SUBROUTINE   : weathgen_init
1495!!
1496!>\BRIEF         This subroutine initializes weather variables.
1497!!
1498!! DESCRIPTION  : None
1499!!
1500!! RECENT CHANGE(S): None
1501!!
1502!! MAIN OUTPUT VARIABLE(S):  ::kindex, ::nbindex
1503!!
1504!! REFERENCE(S) :
1505!!
1506!! FLOWCHART    : None
1507!! \n
1508!_ ================================================================================================================================
1509
1510SUBROUTINE weathgen_init &
1511     & (filename,dt_force,force_id,iim,jjm, &
1512     &  zonal_res,merid_res,lon,lat,kindex,nbindex)
1513!!$,iind,jind)
1514  !---------------------------------------------------------------------
1515  IMPLICIT NONE
1516  !-
1517
1518  !! 0. Variables and parameters declaration
1519
1520  REAL,PARAMETER  :: fcrit = .5       !! Minimum land fraction on original grid
1521
1522  !! 0.1 Input variables
1523
1524  CHARACTER(LEN=*),INTENT(IN)         :: filename
1525  REAL,INTENT(IN)                     :: dt_force
1526  INTEGER,INTENT(IN)                  :: iim, jjm
1527  REAL,INTENT(IN)                     :: zonal_res,merid_res
1528  REAL,DIMENSION(iim,jjm),INTENT(IN)  :: lon,lat
1529
1530  !! 0.2 Output variables 
1531
1532  INTEGER,INTENT(OUT)                 :: nbindex
1533  INTEGER,DIMENSION(iim*jjm),INTENT(OUT)  :: kindex
1534!!$  INTEGER,DIMENSION(iim),INTENT(OUT) :: iind
1535!!$  INTEGER,DIMENSION(jjm),INTENT(OUT) :: jind
1536
1537  !! 0.3 Modified variables
1538
1539  INTEGER,INTENT(INOUT)               :: force_id
1540
1541  !! 0.4 Local variables
1542
1543  REAL,DIMENSION(:),ALLOCATABLE         :: lon_file, lon_temp
1544  REAL,DIMENSION(:,:),ALLOCATABLE       :: nav_lon, nav_lat
1545  REAL,DIMENSION(:),ALLOCATABLE         :: lat_file, lat_temp
1546  REAL,DIMENSION(:,:),ALLOCATABLE       :: lsm_file
1547  REAL     :: xextent_file, yextent_file, xres_file, yres_file
1548  INTEGER  :: i, j, plotstep
1549  REAL,DIMENSION(iim,jjm)               :: mask
1550  CHARACTER(LEN=1),DIMENSION(0:1)       :: maskchar
1551  CHARACTER(LEN=30)                     :: var_name
1552  REAL     :: x_cut
1553  REAL,DIMENSION(iim) :: tmp_lon
1554  REAL,DIMENSION(jjm) :: tmp_lat
1555
1556!_ ================================================================================================================================
1557
1558  !-
1559  ! 0. messages, initialisations
1560  !-
1561  WRITE(numout,*) &
1562       &  'weathgen_init: Minimum land fraction on original grid =',fcrit
1563  CALL ioget_calendar(calendar_str)
1564  !-
1565  ! 1. on lit les longitudes et latitudes de la grille de depart
1566  !    ainsi que le masque terre-ocean
1567  !-
1568  CALL flinclo(force_id)
1569  CALL flininfo (filename,iim_file,jjm_file,llm_file,ttm_file,force_id)
1570  !-
1571  ALLOC_ERR=-1
1572  ALLOCATE(nav_lon(iim_file,jjm_file), STAT=ALLOC_ERR)
1573  IF (ALLOC_ERR/=0) THEN
1574     WRITE(numout,*) "ERROR IN ALLOCATION of nav_lon : ",ALLOC_ERR
1575     STOP
1576  ENDIF
1577
1578  ALLOC_ERR=-1
1579  ALLOCATE(nav_lat(iim_file,jjm_file), STAT=ALLOC_ERR)
1580  IF (ALLOC_ERR/=0) THEN
1581     WRITE(numout,*) "ERROR IN ALLOCATION of nav_lat : ",ALLOC_ERR
1582     STOP
1583  ENDIF
1584  !-
1585  var_name='nav_lon'
1586  CALL flinget (force_id,var_name,iim_file,jjm_file,0,0,1,1,nav_lon)
1587  var_name='nav_lat'
1588  CALL flinget (force_id,var_name,iim_file,jjm_file,0,0,1,1,nav_lat)
1589  !-
1590
1591  ALLOC_ERR=-1
1592  ALLOCATE(lon_file(iim_file), STAT=ALLOC_ERR)
1593  IF (ALLOC_ERR/=0) THEN
1594     WRITE(numout,*) "ERROR IN ALLOCATION of lon_file : ",ALLOC_ERR
1595     STOP
1596  ENDIF
1597
1598  ALLOC_ERR=-1
1599  ALLOCATE(lat_file(jjm_file), STAT=ALLOC_ERR)
1600  IF (ALLOC_ERR/=0) THEN
1601     WRITE(numout,*) "ERROR IN ALLOCATION of lat_file : ",ALLOC_ERR
1602     STOP
1603  ENDIF
1604  !-
1605  DO i=1,iim_file
1606     lon_file(i) = nav_lon(i,1)
1607  ENDDO
1608  DO j=1,jjm_file
1609     lat_file(j) = nav_lat(1,j)
1610  ENDDO
1611!-
1612
1613  ALLOC_ERR=-1
1614  ALLOCATE(lsm_file(iim_file,jjm_file), STAT=ALLOC_ERR)
1615  IF (ALLOC_ERR/=0) THEN
1616    WRITE(numout,*) "ERROR IN ALLOCATION of lsm_file : ",ALLOC_ERR
1617    STOP
1618  ENDIF
1619!-
1620  var_name='lsmera'
1621  CALL flinget (force_id,var_name,iim_file,jjm_file,0,0,1,1,lsm_file)
1622!-
1623! 2. La resolution du modele ne doit pas etre superieure
1624!    a celle de la grille de depart
1625!-
1626  xextent_file = lon_file(iim_file)-lon_file(1)
1627  yextent_file = lat_file(1)-lat_file(jjm_file)
1628  xres_file = xextent_file/REAL(iim_file-1)
1629  yres_file = yextent_file/REAL(jjm_file-1)
1630!-
1631  IF (xres_file > zonal_res) THEN
1632    WRITE(numout,*) 'Zonal resolution of model grid too fine.'
1633    WRITE(numout,*) 'Resolution of original data (deg): ', xres_file
1634    STOP
1635  ENDIF
1636!-
1637  IF (yres_file > merid_res) THEN
1638    WRITE(numout,*) 'Meridional resolution of model grid too fine.'
1639    WRITE(numout,*) 'Resolution of original data (deg): ', yres_file
1640    STOP
1641  ENDIF
1642!-
1643! 3. On verifie la coherence des coordonnees de depart et d'arrivee.
1644!    Sinon, il faut deplacer une partie du monde (rien que ca).
1645!-
1646  i_cut = 0
1647!-
1648
1649  ALLOC_ERR=-1
1650  ALLOCATE(lon_temp(iim_file), STAT=ALLOC_ERR)
1651  IF (ALLOC_ERR/=0) THEN
1652    WRITE(numout,*) "ERROR IN ALLOCATION of lon_temp : ",ALLOC_ERR
1653    STOP
1654  ENDIF
1655
1656  ALLOC_ERR=-1
1657  ALLOCATE(lat_temp(jjm_file), STAT=ALLOC_ERR)
1658  IF (ALLOC_ERR/=0) THEN
1659    WRITE(numout,*) "ERROR IN ALLOCATION of lat_temp : ",ALLOC_ERR
1660    STOP
1661  ENDIF
1662!-
1663  IF (lon(iim,1) > lon_file(iim_file)) THEN
1664!-- A l'Est de la region d'interet, il n'y a pas de donnees
1665!-- le bout a l'Ouest de la region d'interet est deplace de 360 deg
1666!-- vers l'Est
1667    x_cut = lon(1,1)
1668    DO i=1,iim_file
1669      IF (lon_file(i) < x_cut) i_cut = i
1670    ENDDO
1671    IF ((i_cut < 1).OR.(i_cut >= iim_file)) THEN
1672        STOP 'Cannot find longitude for domain shift'
1673    ENDIF
1674!---
1675    lon_temp(1:iim_file-i_cut-1) = lon_file(i_cut:iim_file)
1676    lon_temp(iim_file-i_cut:iim_file) = lon_file(1:i_cut+1)+360.
1677    lon_file(:) = lon_temp(:)
1678  ELSEIF (lon(1,1) < lon_file(1)) THEN
1679!-- A l'Ouest de la region d'interet, il n'y a pas de donnees
1680!-- le bout a l'Est de la region d'interet est deplace de 360 deg
1681!-- vers l'Ouest
1682    x_cut = lon(iim,1)
1683    DO i=1,iim_file
1684      IF (lon_file(i) < x_cut) i_cut = i
1685    ENDDO
1686    IF ( ( i_cut < 1 ) .OR. ( i_cut >= iim_file ) ) THEN
1687        STOP 'Cannot find longitude for domain shift'
1688    ENDIF
1689!---
1690    lon_temp(1:iim_file-i_cut-1) = lon_file(i_cut:iim_file) -360.
1691    lon_temp(iim_file-i_cut:iim_file) = lon_file(1:i_cut+1)
1692    lon_file(:) = lon_temp(:)
1693  ENDIF
1694!-
1695  DEALLOCATE (lon_temp)
1696  DEALLOCATE (lat_temp)
1697!-
1698  IF (    (lon(1,1) < lon_file(1)) &
1699 &    .OR.(     (lon(iim,1) > lon_file(iim_file)) &
1700 &         .AND.(lon(iim,1) > lon_file(1)+360.) ) ) THEN
1701    WRITE(numout,*) lon(:,1)
1702    WRITE(numout,*)
1703    WRITE(numout,*) lon_file(:)
1704    STOP 'weathgen_init: cannot find coherent x-coordinates'
1705  ENDIF
1706!-
1707  IF (i_cut /= 0) THEN
1708    CALL shift_field (iim_file,jjm_file,i_cut,lsm_file)
1709  ENDIF
1710!-
1711! 4. Verification
1712!-
1713  WRITE(numout,*)
1714  WRITE(numout,*) 'Input File: (Shifted) Global Land-Sea Mask'
1715  WRITE(numout,*)
1716  maskchar(0) = '-'
1717  maskchar(1) = 'X'
1718  plotstep = INT(REAL(iim_file-1)/termcol)+1
1719  DO j=1,jjm_file,plotstep
1720    DO i=1,iim_file,plotstep
1721      WRITE(numout,'(a1,$)') maskchar(NINT(lsm_file(i,j)))
1722    ENDDO
1723    WRITE(numout,*)
1724  ENDDO
1725  WRITE(numout,*)
1726!-
1727! 5. Prepare interpolation from fine grid land points to model grid
1728!-
1729! 5.1 how many grid points of the original grid fall into one grid
1730!     box of the model grid?
1731!-
1732  n_agg = NINT((zonal_res/xres_file*merid_res/yres_file )+1.)
1733!-
1734! au diable l'avarice !
1735!-
1736  n_agg = n_agg*2
1737!-
1738! 5.2 Allocate arrays where we store information about which
1739!     (and how many) points on the original grid fall
1740!     into which box on the model grid
1741!-
1742
1743  ALLOC_ERR=-1
1744  ALLOCATE(ncorr(iim,jjm), STAT=ALLOC_ERR)
1745  IF (ALLOC_ERR/=0) THEN
1746    WRITE(numout,*) "ERROR IN ALLOCATION of ncorr : ",ALLOC_ERR
1747    STOP
1748  ENDIF
1749
1750  ALLOC_ERR=-1
1751  ALLOCATE(icorr(iim,jjm,n_agg), STAT=ALLOC_ERR)
1752  IF (ALLOC_ERR/=0) THEN
1753    WRITE(numout,*) "ERROR IN ALLOCATION of icorr : ",ALLOC_ERR
1754    STOP
1755  ENDIF
1756
1757  ALLOC_ERR=-1
1758  ALLOCATE(jcorr(iim,jjm,n_agg), STAT=ALLOC_ERR)
1759  IF (ALLOC_ERR/=0) THEN
1760    WRITE(numout,*) "ERROR IN ALLOCATION of jcorr : ",ALLOC_ERR
1761    STOP
1762  ENDIF
1763!-
1764! 6. Land-Ocean Mask on model grid
1765!-
1766  tmp_lon = lon(:,1)
1767  tmp_lat = lat(1,:)
1768
1769  CALL mask_c_o &
1770 &  (iim_file, jjm_file, lon_file, lat_file, lsm_file, fcrit, &
1771 &   iim, jjm, zonal_res, merid_res, n_agg, tmp_lon, tmp_lat, &
1772! &   iim, jjm, zonal_res, merid_res, n_agg, lon(:,1), lat(1,:), &
1773 &   mask, ncorr, icorr, jcorr)
1774!-
1775  WRITE(numout,*) 'Land-Sea Mask on Model Grid'
1776  WRITE(numout,*)
1777  plotstep = INT(REAL(iim-1)/termcol)+1
1778  DO j=1,jjm,plotstep
1779    DO i=1,iim,plotstep
1780      WRITE(numout,'(a1,$)') maskchar(NINT(mask(i,j)))
1781    ENDDO
1782    WRITE(numout,*)
1783  ENDDO
1784  WRITE(numout,*)
1785!-
1786! 7. kindex table.
1787!-
1788  nbindex = 0
1789  DO j=1,jjm
1790    DO i=1,iim
1791      IF (NINT(mask(i,j)) == 1) THEN
1792        nbindex = nbindex+1
1793        kindex(nbindex) = (j-1)*iim+i
1794      ENDIF
1795    ENDDO
1796  ENDDO
1797  nbindex_w = nbindex
1798  ALLOC_ERR=-1
1799  ALLOCATE(kindex_w(nbindex_w), STAT=ALLOC_ERR)
1800  IF (ALLOC_ERR/=0) THEN
1801    WRITE(numout,*) "ERROR IN ALLOCATION of kindex_w : ",ALLOC_ERR
1802    STOP
1803  ENDIF
1804  kindex_w(:)=kindex(1:nbindex)
1805!-
1806  IF ( nbindex == 0 ) THEN
1807    WRITE(numout,*) 'Couillon! On est au plein milieu de l''ocean.'
1808    STOP 'Ou est-ce un bug?'
1809  ELSE
1810    WRITE(numout,*) 'Number of continental points: ',nbindex
1811  ENDIF
1812
1813!-
1814! 10. clean up
1815!-
1816  DEALLOCATE (lon_file)
1817  DEALLOCATE (lat_file)
1818  DEALLOCATE (lsm_file)
1819
1820END SUBROUTINE weathgen_init
1821
1822!! ================================================================================================================================
1823!! SUBROUTINE   : weathgen_read_file
1824!!
1825!>\BRIEF         This subroutine allocates variables and reads files. 
1826!!
1827!! DESCRIPTION  : 
1828!!
1829!! RECENT CHANGE(S): None
1830!!
1831!! MAIN OUTPUT VARIABLE(S):
1832!!
1833!! REFERENCE(S) :
1834!!
1835!! FLOWCHART    : None
1836!! \n
1837!_ ================================================================================================================================
1838
1839SUBROUTINE weathgen_read_file &
1840     & (force_id,iim,jjm)
1841  !---------------------------------------------------------------------
1842  IMPLICIT NONE
1843  !-
1844
1845  !! 0. Variables and parameters declaration
1846
1847  REAL,PARAMETER  :: fcrit = .5
1848
1849  !! 0.1 Input variables
1850
1851  INTEGER,INTENT(IN)                  :: force_id
1852  INTEGER,INTENT(IN)                  :: iim, jjm
1853
1854  !! 0.4 Local variables
1855
1856  CHARACTER(LEN=30)               :: var_name
1857
1858  INTEGER,DIMENSION(iim*jjm)  :: kindex
1859  INTEGER                     :: nbindex
1860
1861  REAL,DIMENSION(iim*jjm)     :: xchamp
1862  REAL,DIMENSION(iim*jjm,nmon)  :: xchampm
1863
1864!_ ================================================================================================================================
1865
1866  kindex(:)=0
1867
1868#ifdef CPP_PARA
1869  nbindex=nbp_loc
1870  CALL scatter(index_g,kindex)
1871  kindex(1:nbindex)=kindex(1:nbindex)-(jj_begin-1)*iim_g
1872#else
1873  ! Copy saved land points index
1874  nbindex = nbindex_w
1875  kindex(1:nbindex_w) = kindex_w(:)
1876#endif
1877
1878!-
1879
1880  ALLOC_ERR=-1
1881  ALLOCATE(lat_land(nbindex), STAT=ALLOC_ERR)
1882  IF (ALLOC_ERR/=0) THEN
1883    WRITE(numout,*) "ERROR IN ALLOCATION of lat_land : ",ALLOC_ERR
1884    STOP
1885  ENDIF
1886
1887!-
1888! 8 topography
1889!-
1890
1891  ALLOC_ERR=-1
1892  ALLOCATE(xintopo(nbindex), STAT=ALLOC_ERR)
1893  IF (ALLOC_ERR/=0) THEN
1894    WRITE(numout,*) "ERROR IN ALLOCATION of xintopo : ",ALLOC_ERR
1895    STOP
1896  ENDIF
1897!-
1898  var_name='altitude'
1899  CALL weather_read (force_id,var_name,iim_file,jjm_file,1,i_cut, &
1900                     iim,jjm,n_agg,ncorr,icorr,jcorr,xchamp)
1901  xintopo(:)=xchamp(kindex(1:nbindex))
1902!-
1903! 9. Allocate and read the monthly fields
1904!-
1905
1906  ALLOC_ERR=-1
1907  ALLOCATE(xinwet(nbindex,nmon), STAT=ALLOC_ERR)
1908  IF (ALLOC_ERR/=0) THEN
1909    WRITE(numout,*) "ERROR IN ALLOCATION of xinwet : ",ALLOC_ERR
1910    STOP
1911  ENDIF
1912  var_name='prs'
1913  CALL weather_read (force_id,var_name,iim_file,jjm_file,nmon,i_cut, &
1914                     iim,jjm,n_agg,ncorr,icorr,jcorr,xchampm)
1915  xinwet(:,:)=xchampm(kindex(1:nbindex),:)
1916  !-
1917
1918  ALLOC_ERR=-1
1919  ALLOCATE(xinprec(nbindex,nmon), STAT=ALLOC_ERR)
1920  IF (ALLOC_ERR/=0) THEN
1921    WRITE(numout,*) "ERROR IN ALLOCATION of xinprec : ",ALLOC_ERR
1922    STOP
1923  ENDIF
1924  var_name='prm'
1925  CALL weather_read (force_id,var_name,iim_file,jjm_file,nmon,i_cut, &
1926                     iim,jjm,n_agg,ncorr,icorr,jcorr,xchampm)
1927  xinprec(:,:)=xchampm(kindex(1:nbindex),:)
1928!-
1929 
1930  ALLOC_ERR=-1
1931  ALLOCATE(xint(nbindex,nmon), STAT=ALLOC_ERR)
1932  IF (ALLOC_ERR/=0) THEN
1933    WRITE(numout,*) "ERROR IN ALLOCATION of xint : ",ALLOC_ERR
1934    STOP
1935  ENDIF
1936  var_name='t2m'
1937  CALL weather_read (force_id,var_name,iim_file,jjm_file,nmon,i_cut, &
1938                     iim,jjm,n_agg,ncorr,icorr,jcorr,xchampm)
1939  xint(:,:)=xchampm(kindex(1:nbindex),:)
1940!-
1941
1942  ALLOC_ERR=-1
1943  ALLOCATE(xinq(nbindex,nmon), STAT=ALLOC_ERR)
1944  IF (ALLOC_ERR/=0) THEN
1945    WRITE(numout,*) "ERROR IN ALLOCATION of xinq : ",ALLOC_ERR
1946    STOP
1947  ENDIF
1948  var_name='r2m'
1949  CALL weather_read (force_id,var_name,iim_file,jjm_file,nmon,i_cut, &
1950                     iim,jjm,n_agg,ncorr,icorr,jcorr,xchampm)
1951  xinq(:,:)=xchampm(kindex(1:nbindex),:)
1952!-
1953
1954  ALLOC_ERR=-1
1955  ALLOCATE(xinwind(nbindex,nmon), STAT=ALLOC_ERR)
1956  IF (ALLOC_ERR/=0) THEN
1957    WRITE(numout,*) "ERROR IN ALLOCATION of xinwind : ",ALLOC_ERR
1958    STOP
1959  ENDIF
1960  var_name='uv10m'
1961  CALL weather_read (force_id,var_name,iim_file,jjm_file,nmon,i_cut, &
1962                     iim,jjm,n_agg,ncorr,icorr,jcorr,xchampm)
1963  xinwind(:,:)=xchampm(kindex(1:nbindex),:)
1964!-
1965
1966  ALLOC_ERR=-1
1967  ALLOCATE(xincld(nbindex,nmon), STAT=ALLOC_ERR)
1968  IF (ALLOC_ERR/=0) THEN
1969    WRITE(numout,*) "ERROR IN ALLOCATION of xincld : ",ALLOC_ERR
1970    STOP
1971  ENDIF
1972  var_name='tc'
1973  CALL weather_read (force_id,var_name,iim_file,jjm_file,nmon,i_cut, &
1974                       iim,jjm,n_agg,ncorr,icorr,jcorr,xchampm)
1975  xincld(:,:)=xchampm(kindex(1:nbindex),:)
1976!-
1977
1978  ALLOC_ERR=-1
1979  ALLOCATE(xintrng(nbindex,nmon), STAT=ALLOC_ERR)
1980  IF (ALLOC_ERR/=0) THEN
1981    WRITE(numout,*) "ERROR IN ALLOCATION of xintrng : ",ALLOC_ERR
1982    STOP
1983  ENDIF
1984  var_name='t2a'
1985  CALL weather_read (force_id,var_name,iim_file,jjm_file,nmon,i_cut, &
1986                       iim,jjm,n_agg,ncorr,icorr,jcorr,xchampm)
1987  xintrng(:,:)=xchampm(kindex(1:nbindex),:)
1988!-
1989! 10. clean up
1990!-
1991  IF (is_root_prc) THEN
1992     DEALLOCATE (ncorr)
1993     DEALLOCATE (icorr)
1994     DEALLOCATE (jcorr)
1995  ENDIF
1996
1997!-
1998! 12. Allocate space for daily mean values
1999!-
2000
2001  ALLOC_ERR=-1
2002  ALLOCATE(iwet(nbindex), STAT=ALLOC_ERR)
2003  IF (ALLOC_ERR/=0) THEN
2004    WRITE(numout,*) "ERROR IN ALLOCATION of iwet : ",ALLOC_ERR
2005    STOP
2006  ENDIF
2007!-
2008
2009  ALLOC_ERR=-1
2010  ALLOCATE(psurfm0(nbindex), STAT=ALLOC_ERR)
2011  IF (ALLOC_ERR/=0) THEN
2012    WRITE(numout,*) "ERROR IN ALLOCATION of psurfm0 : ",ALLOC_ERR
2013    STOP
2014  ENDIF
2015
2016  ALLOC_ERR=-1
2017  ALLOCATE(cloudm0(nbindex), STAT=ALLOC_ERR)
2018  IF (ALLOC_ERR/=0) THEN
2019    WRITE(numout,*) "ERROR IN ALLOCATION of cloudm0 : ",ALLOC_ERR
2020    STOP
2021  ENDIF
2022
2023  ALLOC_ERR=-1
2024  ALLOCATE(tmaxm0(nbindex), STAT=ALLOC_ERR)
2025  IF (ALLOC_ERR/=0) THEN
2026    WRITE(numout,*) "ERROR IN ALLOCATION of tmaxm0 : ",ALLOC_ERR
2027    STOP
2028  ENDIF
2029
2030  ALLOC_ERR=-1
2031  ALLOCATE(tminm0(nbindex), STAT=ALLOC_ERR)
2032  IF (ALLOC_ERR/=0) THEN
2033    WRITE(numout,*) "ERROR IN ALLOCATION of tminm0 : ",ALLOC_ERR
2034    STOP
2035  ENDIF
2036
2037  ALLOC_ERR=-1
2038  ALLOCATE(qdm0(nbindex), STAT=ALLOC_ERR)
2039  IF (ALLOC_ERR/=0) THEN
2040    WRITE(numout,*) "ERROR IN ALLOCATION of qdm0 : ",ALLOC_ERR
2041    STOP
2042  ENDIF
2043
2044  ALLOC_ERR=-1
2045  ALLOCATE(udm0(nbindex), STAT=ALLOC_ERR)
2046  IF (ALLOC_ERR/=0) THEN
2047    WRITE(numout,*) "ERROR IN ALLOCATION of udm0 : ",ALLOC_ERR
2048    STOP
2049  ENDIF
2050
2051  ALLOC_ERR=-1
2052  ALLOCATE(precipm0(nbindex), STAT=ALLOC_ERR)
2053  IF (ALLOC_ERR/=0) THEN
2054    WRITE(numout,*) "ERROR IN ALLOCATION of precipm0 : ",ALLOC_ERR
2055    STOP
2056  ENDIF
2057!-
2058
2059  ALLOC_ERR=-1
2060  ALLOCATE(psurfm1(nbindex), STAT=ALLOC_ERR)
2061  IF (ALLOC_ERR/=0) THEN
2062    WRITE(numout,*) "ERROR IN ALLOCATION of psurfm1 : ",ALLOC_ERR
2063    STOP
2064  ENDIF
2065
2066  ALLOC_ERR=-1
2067  ALLOCATE(cloudm1(nbindex), STAT=ALLOC_ERR)
2068  IF (ALLOC_ERR/=0) THEN
2069    WRITE(numout,*) "ERROR IN ALLOCATION of cloudm1 : ",ALLOC_ERR
2070    STOP
2071  ENDIF
2072
2073  ALLOC_ERR=-1
2074  ALLOCATE(tmaxm1(nbindex), STAT=ALLOC_ERR)
2075  IF (ALLOC_ERR/=0) THEN
2076    WRITE(numout,*) "ERROR IN ALLOCATION of tmaxm1 : ",ALLOC_ERR
2077    STOP
2078  ENDIF
2079
2080  ALLOC_ERR=-1
2081  ALLOCATE(tminm1(nbindex), STAT=ALLOC_ERR)
2082  IF (ALLOC_ERR/=0) THEN
2083    WRITE(numout,*) "ERROR IN ALLOCATION of tminm1 : ",ALLOC_ERR
2084    STOP
2085  ENDIF
2086
2087  ALLOC_ERR=-1
2088  ALLOCATE(qdm1(nbindex), STAT=ALLOC_ERR)
2089  IF (ALLOC_ERR/=0) THEN
2090    WRITE(numout,*) "ERROR IN ALLOCATION of qdm1 : ",ALLOC_ERR
2091    STOP
2092  ENDIF
2093
2094  ALLOC_ERR=-1
2095  ALLOCATE(udm1(nbindex), STAT=ALLOC_ERR)
2096  IF (ALLOC_ERR/=0) THEN
2097    WRITE(numout,*) "ERROR IN ALLOCATION of udm1 : ",ALLOC_ERR
2098    STOP
2099  ENDIF
2100
2101  ALLOC_ERR=-1
2102  ALLOCATE(precipm1(nbindex), STAT=ALLOC_ERR)
2103  IF (ALLOC_ERR/=0) THEN
2104    WRITE(numout,*) "ERROR IN ALLOCATION of precipm1 : ",ALLOC_ERR
2105    STOP
2106  ENDIF
2107END SUBROUTINE weathgen_read_file
2108!
2109!=
2110!
2111
2112!! ================================================================================================================================
2113!! SUBROUTINE   : weathgen_begin
2114!!
2115!>\BRIEF         This subroutines initializes variables or reads restart values.
2116!!
2117!! DESCRIPTION  : None
2118!!
2119!! RECENT CHANGE(S): None
2120!!
2121!! MAIN OUTPUT VARIABLE(S): ::nbindex, ::tair, ::pb, ::qair, ::kindex
2122!!
2123!! REFERENCE(S) :
2124!!
2125!! FLOWCHART    : None
2126!! \n
2127!_ ================================================================================================================================
2128
2129SUBROUTINE weathgen_begin ( &
2130     & dt_force,itau, date0, &
2131     & rest_id,iim,jjm, &
2132     & lon,lat,tair,pb,qair,kindex,nbindex)
2133  !---------------------------------------------------------------------
2134  IMPLICIT NONE
2135
2136  !-
2137
2138  !! 0. Variables and parameters declaration
2139
2140  !! 0.1 Input variables
2141
2142  REAL,INTENT(IN)                     :: dt_force, date0
2143  INTEGER,INTENT(IN)                  :: itau
2144  INTEGER,INTENT(IN)                  :: rest_id
2145  INTEGER,INTENT(IN)                  :: iim, jjm
2146  REAL,DIMENSION(iim,jjm),INTENT(IN)  :: lon,lat
2147
2148  !! 0.2 Output variables
2149
2150  INTEGER,INTENT(OUT)                     :: nbindex
2151  INTEGER,DIMENSION(iim*jjm),INTENT(OUT)  :: kindex
2152  REAL,DIMENSION(iim,jjm),INTENT(OUT)     :: tair,pb,qair
2153
2154  !! 0.4 Local variables
2155
2156  INTEGER  :: i, j, ij
2157  REAL     :: val_exp
2158  REAL,DIMENSION(iim*jjm)               :: xchamp
2159  REAL,DIMENSION(iim_g*jjm_g)           :: xchamp_g
2160  CHARACTER(LEN=30)                     :: var_name
2161  REAL,DIMENSION(1)                     :: jullasttab
2162  REAL,DIMENSION(seedsize_max)          :: seed_in_file
2163  INTEGER,DIMENSION(:), ALLOCATABLE     :: seed_in_proc
2164  INTEGER  :: seedsize, iret
2165  INTEGER  :: nlonid, nlatid, nlonid1, nlatid1, tdimid1, varid
2166  INTEGER  :: ndim, dims(4)
2167  CHARACTER(LEN=30) :: assoc
2168  CHARACTER(LEN=70) :: str70
2169  CHARACTER(LEN=80) :: stamp
2170  INTEGER  :: yy_b, mm_b, dd_b, hh, mm
2171  REAL     :: ss
2172  CHARACTER(LEN=10) :: today, att
2173  INTEGER  :: nlandid1, nlandid, nlevid, nlevid1
2174  REAL     :: lev_max, lev_min
2175  REAL     :: height_lev1
2176  INTEGER  :: imois
2177  REAL     :: xx, td
2178
2179!_ ================================================================================================================================
2180
2181  kindex(:)=0
2182
2183#ifdef CPP_PARA
2184  nbindex=nbp_loc
2185  CALL scatter(index_g,kindex)
2186  kindex(1:nbindex)=kindex(1:nbindex)-(jj_begin-1)*iim_g
2187#else
2188  ! Copy saved land points index
2189  nbindex = nbindex_w
2190  kindex(1:nbindex_w) = kindex_w(:)
2191#endif
2192!-
2193! 13. Prescribed or statistical values?
2194!-
2195  !Config  Key  = IPPREC
2196  !Config  Desc = Use prescribed values
2197  !Config  If = ALLOW_WEATHERGEN
2198  !Config  Def  = 0
2199  !Config  Help = If this is set to 1, the weather generator
2200  !Config         uses the monthly mean values for daily means.
2201  !Config         If it is set to 0, the weather generator
2202  !Config         uses statistical relationships to derive daily
2203  !Config         values from monthly means.
2204  ipprec = 0
2205  CALL getin_p ('IPPREC',ipprec)
2206  WRITE(numout,*) 'IPPREC: ',ipprec
2207!-
2208! 14. Do we want exact monthly precipitations even with ipprec=0 ?
2209!-
2210  !Config  Key  = WEATHGEN_PRECIP_EXACT
2211  !Config  Desc = Exact monthly precipitation
2212  !Config  If = ALLOW_WEATHERGEN
2213  !Config  Def  = n
2214  !Config  Help = If this is set to y, the weather generator
2215  !Config         will generate pseudo-random precipitations
2216  !Config         whose monthly mean is exactly the prescribed one.
2217  !Config         In this case, the daily precipitation (for rainy
2218  !Config         days) is constant (that is, some days have 0 precip,
2219  !Config         the other days have precip=Precip_month/n_precip,
2220  !Config         where n_precip is the prescribed number of rainy days
2221  !Config         per month).
2222  precip_exact = .FALSE.
2223  CALL getin_p ('WEATHGEN_PRECIP_EXACT',precip_exact)
2224  WRITE(numout,*) 'PRECIP_EXACT: ',precip_exact
2225!-
2226  IF (precip_exact) THEN
2227!---
2228!-- preparer un tableau utilise pour determiner s'il pleut ou pas
2229!-- (en fct. du nombre de jours de pluie par mois).
2230!---
2231     IF (is_root_prc) THEN
2232        DO imois=1,12
2233           CALL permute (ndaypm(imois),jour_precip(:,imois))
2234        ENDDO
2235     ENDIF
2236     CALL bcast(jour_precip)
2237  ENDIF
2238!-
2239! Read Orbital Parameters
2240!-
2241  !Config  Key  = ECCENTRICITY
2242  !Config  Desc = Use prescribed values
2243  !Config  If = ALLOW_WEATHERGEN
2244  !Config  Def  = 0.016724
2245  ecc = 0.016724
2246  CALL getin_p ('ECCENTRICITY',ecc)
2247  WRITE(numout,*) 'ECCENTRICITY: ',ecc
2248!
2249  !Config  Key  = PERIHELIE
2250  !Config  Desc = Use prescribed values
2251  !Config  If = ALLOW_WEATHERGEN
2252  !Config  Def  = 102.04
2253  perh = 102.04
2254  CALL getin_p ('PERIHELIE',perh)
2255  WRITE(numout,*) 'PERIHELIE: ',perh
2256!
2257  !Config  Key  = OBLIQUITY
2258  !Config  Desc = Use prescribed values
2259  !Config  If = ALLOW_WEATHERGEN
2260  !Config  Def  = 23.446
2261  xob = 23.446
2262  CALL getin_p ('OBLIQUITY',xob)
2263  WRITE(numout,*) 'OBLIQUITY: ',xob
2264!-
2265! 15. Read restart file
2266!-
2267  CALL ioget_expval (val_exp)
2268!-
2269  var_name= 'julian'
2270  IF (is_root_prc) THEN
2271     CALL restget (rest_id,var_name,1,1,1,itau,.TRUE.,jullasttab)
2272     IF (jullasttab(1) == val_exp) THEN
2273        jullasttab(1) = itau2date(itau-1, date0, dt_force)
2274     ENDIF
2275  ENDIF
2276  CALL bcast(jullasttab)
2277  julian_last = jullasttab(1)
2278!-
2279  var_name= 'seed'
2280  IF (is_root_prc) &
2281       CALL restget (rest_id,var_name,seedsize_max, &
2282 &              1,1,itau,.TRUE.,seed_in_file)
2283  CALL bcast(seed_in_file)
2284  IF (ALL(seed_in_file(:) == val_exp)) THEN
2285!---
2286!-- there is no need to reinitialize the random number generator as
2287!-- this does not seem to be a restart
2288!---
2289    CONTINUE
2290  ELSE
2291!---
2292!-- reinitialize the random number generator
2293!---
2294     IF (is_root_prc) &
2295          CALL RANDOM_SEED( SIZE = seedsize )
2296     CALL bcast(seedsize)
2297    IF (seedsize > seedsize_max) THEN
2298        STOP 'weathgen_begin: increase seedsize_max'
2299    ENDIF
2300 
2301    ALLOC_ERR=-1
2302    ALLOCATE(seed_in_proc(seedsize), STAT=ALLOC_ERR)
2303    IF (ALLOC_ERR/=0) THEN
2304      WRITE(numout,*) "ERROR IN ALLOCATION of seed_in_proc : ",ALLOC_ERR
2305      STOP
2306    ENDIF
2307    seed_in_proc(1:seedsize) = NINT( seed_in_file(1:seedsize) )
2308    CALL RANDOM_SEED (PUT = seed_in_proc)
2309    DEALLOCATE( seed_in_proc )
2310  ENDIF
2311!-
2312  var_name= 'iwet'
2313  IF (is_root_prc) THEN
2314    CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2315    IF (ALL(xchamp_g(:) == val_exp)) THEN
2316      xchamp_g(:) = 0.
2317    ENDIF
2318  ENDIF
2319  CALL scatter2D(xchamp_g,xchamp)
2320  iwet(:) = NINT(xchamp(kindex(1:nbindex)))
2321!-
2322  var_name= 'psurfm0'
2323  IF (is_root_prc) THEN
2324     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2325     IF (ALL(xchamp_g(:) == val_exp)) THEN
2326        xchamp_g(:) = 100000.
2327     ENDIF
2328  ENDIF
2329  CALL scatter2D(xchamp_g,xchamp)
2330  psurfm0(:) = xchamp(kindex(1:nbindex))
2331!-
2332  var_name= 'cloudm0'
2333  IF (is_root_prc) THEN
2334     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2335     IF (ALL(xchamp_g(:) == val_exp)) THEN
2336        xchamp_g(:) = .5
2337     ENDIF
2338  ENDIF
2339  CALL scatter2D(xchamp_g,xchamp)
2340  cloudm0(:) = xchamp(kindex(1:nbindex))
2341!-
2342  var_name= 'tmaxm0'
2343  IF (is_root_prc) THEN
2344     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2345     IF (ALL(xchamp_g(:) == val_exp)) THEN
2346        xchamp_g(:) = 285.
2347     ENDIF
2348  ENDIF
2349  CALL scatter2D(xchamp_g,xchamp)
2350  tmaxm0(:) = xchamp(kindex(1:nbindex))
2351!-
2352  var_name= 'tminm0'
2353  IF (is_root_prc) THEN
2354     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2355     IF (ALL(xchamp_g(:) == val_exp)) THEN
2356        xchamp_g(:) = 275.
2357     ENDIF
2358  ENDIF
2359  CALL scatter2D(xchamp_g,xchamp)
2360  tminm0(:) = xchamp(kindex(1:nbindex))
2361!-
2362  var_name= 'qdm0'
2363  IF (is_root_prc) THEN
2364     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2365     IF (ALL(xchamp_g(:) == val_exp)) THEN
2366        xchamp_g(:) = 1.E-03
2367     ENDIF
2368  ENDIF
2369  CALL scatter2D(xchamp_g,xchamp)
2370  qdm0(:) = xchamp(kindex(1:nbindex))
2371!-
2372  var_name= 'udm0'
2373  IF (is_root_prc) THEN
2374     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2375     IF (ALL(xchamp_g(:) == val_exp)) THEN
2376        xchamp_g(:) = 2.
2377     ENDIF
2378  ENDIF
2379  CALL scatter2D(xchamp_g,xchamp)
2380  udm0(:) = xchamp(kindex(1:nbindex))
2381!-
2382  var_name= 'precipm0'
2383  IF (is_root_prc) THEN
2384     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2385     IF (ALL(xchamp_g(:) == val_exp)) THEN
2386        xchamp_g(:) = 1.
2387     ENDIF
2388  ENDIF
2389  CALL scatter2D(xchamp_g,xchamp)
2390  precipm0(:) = xchamp(kindex(1:nbindex))
2391!-
2392  var_name= 'psurfm1'
2393  IF (is_root_prc) THEN
2394     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2395     IF (ALL(xchamp_g(:) == val_exp)) THEN
2396        xchamp_g(:) = 100000.
2397     ENDIF
2398  ENDIF
2399  CALL scatter2D(xchamp_g,xchamp)
2400  psurfm1(:) = xchamp(kindex(1:nbindex))
2401!-
2402  var_name= 'cloudm1'
2403  IF (is_root_prc) THEN
2404     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2405     IF (ALL(xchamp_g(:) == val_exp)) THEN
2406        xchamp_g(:) = .5
2407     ENDIF
2408  ENDIF
2409  CALL scatter2D(xchamp_g,xchamp)
2410  cloudm1(:) = xchamp(kindex(1:nbindex))
2411!-
2412  var_name= 'tmaxm1'
2413  IF (is_root_prc) THEN
2414     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2415     IF (ALL(xchamp_g(:) == val_exp)) THEN
2416        xchamp_g(:) = 285.
2417     ENDIF
2418  ENDIF
2419  CALL scatter2D(xchamp_g,xchamp)
2420  tmaxm1(:) = xchamp(kindex(1:nbindex))
2421!-
2422  var_name= 'tminm1'
2423  IF (is_root_prc) THEN
2424     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2425     IF (ALL(xchamp_g(:) == val_exp)) THEN
2426        xchamp_g(:) = 275.
2427     ENDIF
2428  ENDIF
2429  CALL scatter2D(xchamp_g,xchamp)
2430  tminm1(:) = xchamp(kindex(1:nbindex))
2431!-
2432  var_name= 'qdm1'
2433  IF (is_root_prc) THEN
2434     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2435     IF (ALL(xchamp_g(:) == val_exp)) THEN
2436        xchamp_g(:) = 1.E-03
2437     ENDIF
2438  ENDIF
2439  CALL scatter2D(xchamp_g,xchamp)
2440  qdm1(:) = xchamp(kindex(1:nbindex))
2441!-
2442  var_name= 'udm1'
2443  IF (is_root_prc) THEN
2444     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2445     IF (ALL(xchamp_g(:) == val_exp)) THEN
2446        xchamp_g(:) = 2.
2447     ENDIF
2448  ENDIF
2449  CALL scatter2D(xchamp_g,xchamp)
2450  udm1(:) = xchamp(kindex(1:nbindex))
2451!-
2452  var_name= 'precipm1'
2453  IF (is_root_prc) THEN
2454     CALL restget (rest_id, var_name, iim_g, jjm_g, 1, itau, .TRUE., xchamp_g)
2455     IF (ALL(xchamp_g(:) == val_exp)) THEN
2456        xchamp_g(:) = 1.
2457     ENDIF
2458  ENDIF
2459  CALL scatter2D(xchamp_g,xchamp)
2460  precipm1(:) = xchamp(kindex(1:nbindex))
2461!-
2462! 16. We still need instantaneous tair, qair, and the surface pressure
2463!     We take daily mean values read from the restart file
2464!-
2465!!$  tair(:,:)=280.
2466!!$  qair(:,:)=1.E-03
2467!!$  pb(:,:)=101325
2468  tair(:,:)=val_exp
2469  qair(:,:)=val_exp
2470  pb(:,:)=val_exp
2471  xx = 9.81/287./0.0065
2472  DO ij=1,nbindex
2473     j = ((kindex(ij)-1)/iim) + 1
2474     i = kindex(ij) - (j-1)*iim
2475     
2476     lat_land(ij) = lat(i,j)
2477     
2478     td =  (tmaxm0(ij)+tminm0(ij))/2.
2479     tair(i,j) = td
2480     qair(i,j) = qdm1(ij)
2481     pb(i,j) = 101325.*(td/(td+0.0065*xintopo(ij)))**xx
2482  ENDDO
2483!-
2484! 17. We can write a forcing file for Orchidee
2485!     from this weather Generator run.
2486!-
2487  !Config  Key  = DUMP_WEATHER
2488  !Config  Desc = Write weather from generator into a forcing file
2489  !Config  Def  = n
2490  !Config  Help = This flag makes the weather generator dump its
2491  !               generated weather into a forcing file which can
2492  !               then be used to get the same forcing on different
2493  !               machines. This only works correctly if there is
2494  !               a restart file (otherwise the forcing at the first
2495  !               time step is slightly wrong).
2496  dump_weather = .FALSE.
2497  CALL getin_p ('DUMP_WEATHER',dump_weather)
2498!-
2499  IF (dump_weather .AND. is_root_prc) THEN
2500!---
2501!-- Initialize the file
2502!---
2503    !Config  Key  = DUMP_WEATHER_FILE
2504    !Config  Desc = Name of the file that contains
2505    !               the weather from generator
2506    !Config  Def  = 'weather_dump.nc'
2507    !Config  If = DUMP_WEATHER
2508    !Config  Help =
2509    dump_weather_file = 'weather_dump.nc'
2510    CALL getin ('DUMP_WEATHER_FILE',dump_weather_file)
2511!---
2512    !Config  Key  = DUMP_WEATHER_GATHERED
2513    !Config  Desc = Dump weather data on gathered grid
2514    !Config  Def  = y
2515    !Config  If = DUMP_WEATHER
2516    !Config  Help = If 'y', the weather data are gathered
2517    !               for all land points.
2518    gathered = .TRUE.
2519    CALL getin ('DUMP_WEATHER_GATHERED',gathered)
2520!---
2521    iret = NF90_CREATE (TRIM(dump_weather_file),NF90_CLOBBER,dump_id)
2522!---
2523!-- Dimensions
2524!---
2525    iret = NF90_DEF_DIM (dump_id,'x',iim_g,nlonid1)
2526    iret = NF90_DEF_DIM (dump_id,'y',jjm_g,nlatid1)
2527    iret = NF90_DEF_DIM (dump_id,'z',  1,nlevid1)
2528!---
2529    IF (gathered) THEN
2530      iret = NF90_DEF_DIM (dump_id,'land',nbp_glo,nlandid1)
2531    ENDIF
2532    iret = NF90_DEF_DIM (dump_id,'tstep',NF90_UNLIMITED,tdimid1)
2533!---
2534!-- Coordinate variables
2535!---
2536    dims(1:2) = (/ nlonid1, nlatid1 /)
2537!---
2538    iret = NF90_DEF_VAR (dump_id,'nav_lon',n_rtp,dims(1:2),nlonid)
2539    iret = NF90_PUT_ATT (dump_id,nlonid,'units',"degrees_east")
2540    iret = NF90_PUT_ATT (dump_id,nlonid,'valid_min',MINVAL(lon_g))
2541    iret = NF90_PUT_ATT (dump_id,nlonid,'valid_max',MAXVAL(lon_g))
2542    iret = NF90_PUT_ATT (dump_id,nlonid,'long_name',"Longitude")
2543!---
2544    iret = NF90_DEF_VAR (dump_id,'nav_lat',n_rtp,dims(1:2),nlatid)
2545    iret = NF90_PUT_ATT (dump_id,nlatid,'units',"degrees_north")
2546    iret = NF90_PUT_ATT (dump_id,nlatid,'valid_min',MINVAL(lat_g))
2547    iret = NF90_PUT_ATT (dump_id,nlatid,'valid_max',MAXVAL(lat_g))
2548    iret = NF90_PUT_ATT (dump_id,nlatid,'long_name',"Latitude")
2549!---
2550    height_lev1 = 10.
2551    CALL getin ('HEIGHT_LEV1',height_lev1)
2552    lev_min = height_lev1
2553    lev_max = height_lev1
2554!---
2555    iret = NF90_DEF_VAR (dump_id,'level',n_rtp,(/ nlevid1 /),nlevid)
2556    iret = NF90_PUT_ATT (dump_id,nlevid,'units',"m")
2557    iret = NF90_PUT_ATT (dump_id,nlevid,'valid_min',lev_min)
2558    iret = NF90_PUT_ATT (dump_id,nlevid,'valid_max',lev_max)
2559    iret = NF90_PUT_ATT (dump_id,nlevid,'long_name',"Vertical levels")
2560!---
2561    IF (gathered) THEN
2562      iret = NF90_DEF_VAR (dump_id,'land',NF90_INT,(/ nlandid1 /),nlandid)
2563      iret = NF90_PUT_ATT (dump_id,nlandid,'compress',"y x")
2564    ENDIF
2565!---
2566!-- Store the time axes.
2567!---
2568    iret = NF90_DEF_VAR (dump_id,'time',n_rtp,tdimid1,time_id)
2569
2570    yy_b=0
2571    mm_b=1
2572    dd_b=1
2573    hh=00
2574    mm=00
2575    ss=0.
2576
2577    WRITE (str70,7000) yy_b, mm_b, dd_b, hh, mm, INT(ss)
2578    iret = NF90_PUT_ATT (dump_id,time_id,'units',TRIM(str70))
2579    iret = NF90_PUT_ATT (dump_id,time_id,'calendar',TRIM(calendar_str))
2580    iret = NF90_PUT_ATT (dump_id,time_id,'title','Time')
2581    iret = NF90_PUT_ATT (dump_id,time_id,'long_name','Time axis')
2582    WRITE(str70,7001) yy_b, cal(mm_b), dd_b, hh, mm, INT(ss)
2583    iret = NF90_PUT_ATT (dump_id,time_id,'time_origin',TRIM(str70))
2584!---
2585!-- Time steps
2586!---
2587    iret = NF90_DEF_VAR (dump_id,'timestp',NF90_INT,tdimid1,timestp_id)
2588    WRITE(str70,7002) yy_b, mm_b, dd_b, hh, mm, INT(ss)
2589    iret = NF90_PUT_ATT (dump_id,timestp_id,'units',TRIM(str70))
2590    iret = NF90_PUT_ATT (dump_id,timestp_id,'title','Time steps')
2591    iret = NF90_PUT_ATT (dump_id,timestp_id,'tstep_sec',dt_force)
2592    iret = NF90_PUT_ATT &
2593 &           (dump_id,timestp_id,'long_name','Time step axis')
2594    WRITE(str70,7001) yy_b, cal(mm_b), dd_b, hh, mm, INT(ss)
2595    iret = NF90_PUT_ATT (dump_id,timestp_id,'time_origin',TRIM(str70))
2596!---
25977000 FORMAT('seconds since ',I4.4,'-',I2.2,'-',I2.2,' ',I2.2,':',I2.2,':',I2.2)
25987001 FORMAT(' ',I4.4,'-',A3,'-',I2.2,' ',I2.2,':',I2.2,':',I2.2)
25997002 FORMAT('timesteps since ', I4.4,'-',I2.2,'-',I2.2,' ',I2.2,':',I2.2,':',I2.2)
2600!---
2601!-- The variables in the file are declared and their attributes
2602!-- written.
2603!---
2604    IF (gathered) THEN
2605      ndim = 2
2606      dims(1:2) = (/ nlandid1, tdimid1 /)
2607      assoc = 'time (nav_lat nav_lon)'
2608    ELSE
2609      ndim = 3
2610      dims(1:3) = (/ nlonid1, nlatid1, tdimid1 /)
2611      assoc = 'time nav_lat nav_lon'
2612    ENDIF
2613!---
2614    iret = NF90_DEF_VAR (dump_id,'SWdown',n_rtp,dims(1:ndim),varid)
2615    iret = NF90_PUT_ATT (dump_id,varid,'axis','TYX')
2616    iret = NF90_PUT_ATT (dump_id,varid,'units','W/m^2')
2617    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2618 &                       'Surface incident shortwave radiation')
2619    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2620    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2621    soldownid = varid
2622!---
2623    iret = NF90_DEF_VAR (dump_id,'Rainf',n_rtp,dims(1:ndim),varid)
2624    iret = NF90_PUT_ATT (dump_id,varid,'axis','TYX')
2625    iret = NF90_PUT_ATT (dump_id,varid,'units','kg/m^2s')
2626    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2627 &                       'Rainfall rate')
2628    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2629    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2630    rainfid = varid
2631!---
2632    iret = NF90_DEF_VAR (dump_id,'Snowf',n_rtp,dims(1:ndim),varid)
2633    iret = NF90_PUT_ATT (dump_id,varid,'axis','TYX')
2634    iret = NF90_PUT_ATT (dump_id,varid,'units','kg/m^2s')
2635    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2636 &                       'Snowfall rate')
2637    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2638    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2639    snowfid = varid
2640!---
2641    iret = NF90_DEF_VAR (dump_id,'LWdown',n_rtp,dims(1:ndim),varid)
2642    iret = NF90_PUT_ATT (dump_id,varid,'axis','TYX')
2643    iret = NF90_PUT_ATT (dump_id,varid,'units','W/m^2')
2644    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2645 &                       'Surface incident longwave radiation')
2646    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2647    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2648    lwradid = varid
2649!---
2650    iret = NF90_DEF_VAR (dump_id,'PSurf',n_rtp,dims(1:ndim),varid)
2651    iret = NF90_PUT_ATT (dump_id,varid,'axis','TYX')
2652    iret = NF90_PUT_ATT (dump_id,varid,'units','Pa')
2653    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2654 &                       'Surface pressure')
2655    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2656    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2657    psolid = varid
2658!---
2659!-- 3D Variables to be written
2660!---
2661    IF (gathered) THEN
2662      ndim = 3
2663      dims(1:3) = (/ nlandid1, nlevid1, tdimid1 /)
2664      assoc = 'time level (nav_lat nav_lon)'
2665    ELSE
2666      ndim = 4
2667      dims(1:4) = (/ nlonid1, nlatid1, nlevid1, tdimid1 /)
2668      assoc = 'time level nav_lat nav_lon'
2669    ENDIF
2670!---
2671    iret = NF90_DEF_VAR (dump_id,'Tair',n_rtp,dims(1:ndim),varid)
2672    iret = NF90_PUT_ATT (dump_id,varid,'axis','TZYX')
2673    iret = NF90_PUT_ATT (dump_id,varid,'units','K')
2674    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2675 &                       'Near surface air temperature')
2676    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2677    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2678    tairid = varid
2679!---
2680    iret = NF90_DEF_VAR (dump_id,'Qair',n_rtp,dims(1:ndim),varid)
2681    iret = NF90_PUT_ATT (dump_id,varid,'axis','TZYX')
2682    iret = NF90_PUT_ATT (dump_id,varid,'units','kg/kg')
2683    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2684 &                       'Near surface specific humidity')
2685    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2686    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2687    qairid = varid
2688!---
2689    iret = NF90_DEF_VAR (dump_id,'Wind_N',n_rtp,dims(1:ndim),varid)
2690    iret = NF90_PUT_ATT (dump_id,varid,'axis','TZYX')
2691    iret = NF90_PUT_ATT (dump_id,varid,'units','m/s')
2692    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2693 &                       'Near surface northward wind component')
2694    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2695    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2696    uid = varid
2697!---
2698    iret = NF90_DEF_VAR (dump_id,'Wind_E',n_rtp,dims(1:ndim),varid)
2699    iret = NF90_PUT_ATT (dump_id,varid,'axis','TZYX')
2700    iret = NF90_PUT_ATT (dump_id,varid,'units','m/s')
2701    iret = NF90_PUT_ATT (dump_id,varid,'long_name', &
2702 &                       'Near surface eastward wind component')
2703    iret = NF90_PUT_ATT (dump_id,varid,'associate',TRIM(assoc))
2704    iret = NF90_PUT_ATT (dump_id,varid,'missing_value',undef)
2705    vid = varid
2706!---
2707!-- Global attributes
2708!---
2709    CALL DATE_AND_TIME (today, att)
2710    stamp = "WG, date: "//TRIM(today)//" at "//TRIM(att)
2711    iret = NF90_PUT_ATT (dump_id,NF90_GLOBAL,'Conventions',"GDT 1.2")
2712    iret = NF90_PUT_ATT (dump_id,NF90_GLOBAL,'file_name', &
2713 &                       TRIM(dump_weather_file))
2714    iret = NF90_PUT_ATT (dump_id,NF90_GLOBAL,'production',TRIM(stamp))
2715!---
2716!-- Finish the definition phase
2717!---
2718    iret = NF90_ENDDEF (dump_id)
2719!---
2720!--    Write coordinates
2721!---
2722    iret = NF90_PUT_VAR (dump_id,nlonid,lon_g)
2723    IF (iret /= NF90_NOERR) THEN
2724       WRITE(numout,*) iret
2725       CALL ipslerr (3,'weathgen_begin', &
2726 &          'Could not put variable nav_lon in the file : ', &
2727 &          TRIM(dump_weather_file),'(Solution ?)')
2728    ENDIF
2729    iret = NF90_PUT_VAR (dump_id,nlatid,lat_g)
2730    IF (iret /= NF90_NOERR) THEN
2731       WRITE(numout,*) iret
2732       CALL ipslerr (3,'weathgen_begin', &
2733 &          'Could not put variable nav_lat in the file : ', &
2734 &          TRIM(dump_weather_file),'(Solution ?)')
2735    ENDIF
2736    iret = NF90_PUT_VAR (dump_id,nlevid,height_lev1)
2737    IF (iret /= NF90_NOERR) THEN
2738       WRITE(numout,*) iret
2739       CALL ipslerr (3,'weathgen_begin', &
2740 &          'Could not put variable level in the file : ', &
2741 &          TRIM(dump_weather_file),'(Solution ?)')
2742    ENDIF
2743!---
2744    IF (gathered) THEN
2745       iret = NF90_PUT_VAR (dump_id,nlandid,index_g(1:nbp_glo))
2746       IF (iret /= NF90_NOERR) THEN
2747          WRITE(numout,*) iret
2748          CALL ipslerr (3,'weathgen_begin', &
2749 &          'Could not put variable land in the file : ', &
2750 &          TRIM(dump_weather_file),'(Solution ?)')
2751       ENDIF
2752    ENDIF
2753!---
2754 ENDIF ! dump_weather
2755!-----------------------------
2756END SUBROUTINE weathgen_begin
2757!-
2758!===
2759!-
2760!! ================================================================================================================================
2761!! SUBROUTINE   : weathgen_get
2762!!
2763!>\BRIEF        This subroutine initializes forcing values.
2764!!
2765!! DESCRIPTION  : None
2766!!
2767!! RECENT CHANGE(S): None
2768!!
2769!! MAIN OUTPUT VARIABLE(S): ::swdown, ::raina, ::snowa, ::tair, ::u, ::v, ::qair, ::psurf, ::lwdown
2770!!
2771!! REFERENCE(S) :
2772!!
2773!! FLOWCHART    : None
2774!! \n
2775!_ ================================================================================================================================
2776
2777SUBROUTINE weathgen_get &
2778& (itau, date0, dt_force, nbindex, nband, lat, &
2779&  swdown, raina, snowa, tair, u, v, qair, psurf, lwdown)
2780!---------------------------------------------------------------------
2781  IMPLICIT NONE
2782
2783  !! 0. Variables and parameters declaration
2784
2785  !! 0.1 Input variables
2786
2787  INTEGER,INTENT(IN)               :: itau      !! number of time step
2788  REAL,INTENT(IN)                  :: date0     !! date when itau was 0
2789  REAL,INTENT(IN)                  :: dt_force  !! time step (s)
2790  INTEGER,INTENT(IN)               :: nbindex   !! number of land points
2791  INTEGER,INTENT(IN)               :: nband     !! number of visible bands
2792  REAL,DIMENSION(nbindex),INTENT(IN)  :: lat    !! latitude (deg)
2793
2794  !! 0.2 Output variables 
2795
2796  REAL,DIMENSION(nbindex,nband),INTENT(OUT) :: swdown        !! Downward solar radiation @tex $(W.m^{-2})$ @endtex
2797  REAL,DIMENSION(nbindex),INTENT(OUT)       :: raina, snowa  !! precipitations @tex $(mm.day^{-1})$ @endtex
2798  REAL,DIMENSION(nbindex),INTENT(OUT)       :: tair          !! air temperature (K)
2799  REAL,DIMENSION(nbindex),INTENT(OUT)       :: u,v           !! wind speed @tex $(m.s^{-1})$ @endtex
2800  REAL,DIMENSION(nbindex),INTENT(OUT)       :: qair          !! air humidity @tex $(kg_h2o.kg_air^{-1})$ @endtex
2801  REAL,DIMENSION(nbindex),INTENT(OUT)       :: psurf         !! Surface pressure (Pa)
2802  REAL,DIMENSION(nbindex),INTENT(OUT)       :: lwdown        !! Downward long wave radiation @tex $(W.m^{-2})$ @endtex
2803
2804  !! 0.4 Local variables
2805
2806  REAL,DIMENSION(nbindex)        :: cloud, tmax, tmin, precipd, qd, ud
2807  REAL,DIMENSION(nbindex)        :: rh
2808  REAL,DIMENSION(nbindex,nband)  :: solai, solad
2809  REAL                        :: julian, jur
2810  REAL                        :: x
2811  INTEGER                     :: yy, mm, dd
2812  REAL                        :: ss, plens, time
2813
2814!_ ================================================================================================================================
2815
2816!-
2817! 1. get a reduced julian day
2818!-
2819  julian = itau2date(itau-1, date0, dt_force)
2820!SZ, test: solar noon at 12 o'clock!
2821!  julian = itau2date(itau, date0, dt_force)
2822  CALL ju2ymds (julian, yy, mm, dd, ss)
2823  CALL ymds2ju (yy,1,1,0.0, jur)
2824  julian = julian-jur
2825  CALL ju2ymds (julian, yy, mm, dd, ss)
2826!-
2827! 2. daily values
2828!-
2829  IF (INT(julian_last) /= INT(julian)) THEN
2830!-- today's values become yesterday's values
2831    cloudm1(:) = cloudm0(:)
2832    tmaxm1(:) = tmaxm0(:)
2833    tminm1(:) = tminm0(:)
2834    precipm1(:) = precipm0(:)
2835    qdm1(:) = qdm0(:)
2836    udm1(:) = udm0(:)
2837    psurfm1(:) = psurfm0(:)
2838!-- we have to get new daily values
2839!!$    WRITE(*,*) mpi_rank, "weathgen_get : date ",yy, mm, dd, ss
2840!!$    WRITE(*,*) mpi_rank, "weathgen_get : grid date ",year, month, day, sec
2841    CALL daily (nbindex, mm, dd, cloudm0, tmaxm0, tminm0, &
2842 &              precipm0, qdm0, udm0, psurfm0)
2843  ENDIF
2844!-
2845! 3. interpolate daily values
2846!    (otherwise we get ugly temperature jumps at midnight)
2847!-
2848  x = (julian-INT(julian))
2849!-
2850  cloud(:) = (1.-x)*cloudm1(:)+x*cloudm0(:)
2851  tmax(:) = (1.-x)*tmaxm1(:)+x*tmaxm0(:)
2852  tmin(:) = (1.-x)*tminm1(:)+x*tminm0(:)
2853  precipd(:) = (1.-x)*precipm1(:)+x*precipm0(:)
2854  qd(:) = (1.-x)*qdm1(:)+x*qdm0(:)
2855  ud(:) = (1.-x)*udm1(:)+x*udm0(:)
2856  psurf(:) = (1.-x)*psurfm1(:)+x*psurfm0(:)
2857!-
2858! 4. read instantaneous values
2859!-
2860  plens = one_day/dt_force
2861  time = (julian-REAL(INT(julian)))*one_day
2862!-
2863  CALL diurnal (nbindex, nband, time, NINT(julian), plens, 0., one_day, &
2864 &              lat, cloud, tmax, tmin, precipd, qd, ud, psurf, &
2865 &              lwdown, solad, solai, u, tair, qair, raina, snowa, rh)
2866!-
2867  raina(:) = raina(:)/dt_force
2868  snowa(:) = snowa(:)/dt_force
2869!-
2870  swdown(:,:) = solad(:,:)+solai(:,:)
2871!-
2872  v(:) = 0.
2873!-
2874! 5. Store date
2875!-
2876  julian_last = julian
2877!--------------------------
2878END SUBROUTINE weathgen_get
2879!-
2880!===
2881!-
2882!! ================================================================================================================================
2883!! SUBROUTINE   : weathgen_restwrite
2884!!
2885!>\BRIEF         This subroutine writes data in the restart file.
2886!!
2887!! DESCRIPTION  : None
2888!!
2889!! RECENT CHANGE(S): None
2890!!
2891!! MAIN OUTPUT VARIABLE(S): None
2892!!
2893!! REFERENCE(S) :
2894!!
2895!! FLOWCHART    : None
2896!! \n
2897!_ ================================================================================================================================
2898
2899SUBROUTINE weathgen_restwrite (rest_id,itau,iim,jjm,nbindex,kindex)
2900!---------------------------------------------------------------------
2901  IMPLICIT NONE
2902!-
2903
2904  !! 0. Variables and parameters declaration
2905
2906  !! 0.1 Input variables
2907
2908  INTEGER,INTENT(IN)  :: rest_id,itau,iim,jjm,nbindex
2909  INTEGER,DIMENSION(iim*jjm),INTENT(IN) :: kindex
2910
2911  !! 0.4 Local variables
2912
2913  CHARACTER(LEN=30)                 :: var_name
2914  INTEGER                           :: i,j,ij
2915  REAL,DIMENSION(1)                 :: jullasttab
2916  REAL,DIMENSION(seedsize_max)      :: seed_in_file
2917  INTEGER,DIMENSION(:),ALLOCATABLE  :: seed_in_proc
2918  INTEGER                           :: seedsize
2919  REAL                              :: rndnum
2920  REAL,DIMENSION(iim*jjm)           :: xchamp
2921  REAL,DIMENSION(iim_g*jjm_g)       :: xchamp_g
2922
2923!_ ================================================================================================================================
2924
2925  var_name= 'julian'
2926  jullasttab(:) = julian_last
2927  IF (is_root_prc) CALL restput (rest_id, var_name, 1, 1, 1, itau, jullasttab)
2928!-
2929  IF (is_root_prc) THEN
2930     CALL RANDOM_SEED( SIZE = seedsize )
2931     IF (seedsize > seedsize_max) THEN
2932        STOP 'weathgen_restwrite: increase seedsize_max'
2933     ENDIF
2934  ENDIF
2935  CALL bcast(seedsize)
2936
2937  IF (is_root_prc) THEN
2938     ALLOC_ERR=-1
2939     ALLOCATE(seed_in_proc(seedsize), STAT=ALLOC_ERR)
2940     IF (ALLOC_ERR/=0) THEN
2941        WRITE(numout,*) "ERROR IN ALLOCATION of seed_in_proc : ",ALLOC_ERR
2942        STOP
2943     ENDIF
2944!-
2945     CALL RANDOM_SEED (GET = seed_in_proc)
2946!-
2947     seed_in_file(1:seedsize) = REAL(seed_in_proc(1:seedsize))
2948!-
2949! fill in the seed up to seedsize_max
2950! (useful in the case we restart on
2951!  a machine with a longer seed vector:
2952!  we do not want a degenerated seed)
2953!-
2954     DO i=seedsize+1,seedsize_max
2955        CALL RANDOM_NUMBER( rndnum )
2956        seed_in_file(i) = 100000.*rndnum
2957     ENDDO
2958  ENDIF
2959  CALL bcast (seed_in_file)
2960!-
2961  IF (is_root_prc) THEN
2962     DEALLOCATE( seed_in_proc )
2963!-
2964     var_name= 'seed'
2965     CALL restput (rest_id,var_name,seedsize_max,1,1,itau,seed_in_file)
2966  ENDIF
2967!-
2968
2969  xchamp(:) = val_exp
2970 
2971!!$  DO j=1,jjm
2972!!$    DO i=1,iim
2973!!$      ij = (j-1)*iim+i
2974!!$      xchamp(i,j) = REAL(iwet(ij))
2975!!$    ENDDO
2976!!$  ENDDO
2977  DO ij=1,nbindex
2978     xchamp(kindex(ij)) = REAL(iwet(ij))
2979  ENDDO
2980  var_name= 'iwet'
2981  CALL gather2D(xchamp,xchamp_g)
2982  IF (is_root_prc) THEN
2983     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
2984  ENDIF
2985!-
2986  DO ij=1,nbindex
2987    xchamp(kindex(ij)) = psurfm0(ij)
2988  ENDDO
2989  var_name= 'psurfm0'
2990  CALL gather2D(xchamp,xchamp_g)
2991  IF (is_root_prc) THEN
2992     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
2993  ENDIF
2994!-
2995  DO ij=1,nbindex
2996    xchamp(kindex(ij)) = cloudm0(ij)
2997  ENDDO
2998  var_name= 'cloudm0'
2999  CALL gather2D(xchamp,xchamp_g)
3000  IF (is_root_prc) THEN
3001     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3002  ENDIF
3003!-
3004  DO ij=1,nbindex
3005    xchamp(kindex(ij)) = tmaxm0(ij)
3006  ENDDO
3007  var_name= 'tmaxm0'
3008  CALL gather2D(xchamp,xchamp_g)
3009  IF (is_root_prc) THEN
3010     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3011  ENDIF
3012!-
3013  DO ij=1,nbindex
3014    xchamp(kindex(ij)) = tminm0(ij)
3015  ENDDO
3016  var_name= 'tminm0'
3017  CALL gather2D(xchamp,xchamp_g)
3018  IF (is_root_prc) THEN
3019     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3020  ENDIF
3021!-
3022  DO ij=1,nbindex
3023    xchamp(kindex(ij)) = qdm0(ij)
3024  ENDDO
3025  var_name= 'qdm0'
3026  CALL gather2D(xchamp,xchamp_g)
3027  IF (is_root_prc) THEN
3028     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3029  ENDIF
3030!-
3031  DO ij=1,nbindex
3032    xchamp(kindex(ij)) = udm0(ij)
3033  ENDDO
3034  var_name= 'udm0'
3035  CALL gather2D(xchamp,xchamp_g)
3036  IF (is_root_prc) THEN
3037     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3038  ENDIF
3039!-
3040  DO ij=1,nbindex
3041    xchamp(kindex(ij)) = precipm0(ij)
3042  ENDDO
3043  var_name= 'precipm0'
3044  CALL gather2D(xchamp,xchamp_g)
3045  IF (is_root_prc) THEN
3046     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3047  ENDIF
3048!-
3049  DO ij=1,nbindex
3050    xchamp(kindex(ij)) = psurfm1(ij)
3051  ENDDO
3052  var_name= 'psurfm1'
3053  CALL gather2D(xchamp,xchamp_g)
3054  IF (is_root_prc) THEN
3055     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3056  ENDIF
3057!-
3058  DO ij=1,nbindex
3059    xchamp(kindex(ij)) = cloudm1(ij)
3060  ENDDO
3061  var_name= 'cloudm1'
3062  CALL gather2D(xchamp,xchamp_g)
3063  IF (is_root_prc) THEN
3064     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3065  ENDIF
3066!-
3067  DO ij=1,nbindex
3068    xchamp(kindex(ij)) = tmaxm1(ij)
3069  ENDDO
3070  var_name= 'tmaxm1'
3071  CALL gather2D(xchamp,xchamp_g)
3072  IF (is_root_prc) THEN
3073     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3074  ENDIF
3075!-
3076  DO ij=1,nbindex
3077    xchamp(kindex(ij)) = tminm1(ij)
3078  ENDDO
3079  var_name= 'tminm1'
3080  CALL gather2D(xchamp,xchamp_g)
3081  IF (is_root_prc) THEN
3082     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3083  ENDIF
3084!-
3085  DO ij=1,nbindex
3086    xchamp(kindex(ij)) = qdm1(ij)
3087  ENDDO
3088  var_name= 'qdm1'
3089  CALL gather2D(xchamp,xchamp_g)
3090  IF (is_root_prc) THEN
3091     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3092  ENDIF
3093!-
3094  DO ij=1,nbindex
3095    xchamp(kindex(ij)) = udm1(ij)
3096  ENDDO
3097  var_name= 'udm1'
3098  CALL gather2D(xchamp,xchamp_g)
3099  IF (is_root_prc) THEN
3100     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3101  ENDIF
3102!-
3103  DO ij=1,nbindex
3104    xchamp(kindex(ij)) = precipm1(ij)
3105  ENDDO
3106  var_name= 'precipm1'
3107  CALL gather2D(xchamp,xchamp_g)
3108  IF (is_root_prc) THEN
3109     CALL restput (rest_id, var_name, iim_g, jjm_g, 1, itau, xchamp_g)
3110  ENDIF
3111!--------------------------------
3112END SUBROUTINE weathgen_restwrite
3113!-
3114!===
3115!-
3116!! ================================================================================================================================
3117!! SUBROUTINE   : weathgen_data
3118!!
3119!>\BRIEF         This subroutine reads data from an netcdf file.
3120!!
3121!! DESCRIPTION  : None
3122!!
3123!! RECENT CHANGE(S): None
3124!!
3125!! MAIN OUTPUT VARIABLE(S): ::champout
3126!!
3127!! REFERENCE(S) :
3128!!
3129!! FLOWCHART    : None
3130!! \n
3131!_ ================================================================================================================================
3132
3133SUBROUTINE weather_read &
3134& (force_id,nomvar,iim_file,jjm_file,n3,i_cut, &
3135&  iim,jjm,n_agg,ncorr,icorr,jcorr,champout)
3136!---------------------------------------------------------------------
3137  IMPLICIT NONE
3138!-
3139
3140  !! 0. Variables and parameters declaration
3141 
3142  !! 0.1 Input variables
3143
3144  INTEGER,INTENT(IN)                          :: force_id
3145  CHARACTER(LEN=*),INTENT(IN)                 :: nomvar
3146  INTEGER,INTENT(IN)                          :: iim_file,jjm_file
3147  INTEGER,INTENT(IN)                          :: n3
3148  INTEGER,INTENT(IN)                          :: i_cut
3149  INTEGER,INTENT(IN)                          :: iim,jjm
3150  INTEGER,INTENT(IN)                          :: n_agg
3151  INTEGER,DIMENSION(:,:),INTENT(IN)           :: ncorr
3152  INTEGER,DIMENSION(:,:,:),INTENT(IN)         :: icorr,jcorr
3153
3154  !! 0.2 Output variables
3155
3156  REAL,DIMENSION(iim*jjm,n3),INTENT(OUT)      :: champout
3157
3158  !! 0.4 Local variables
3159
3160  REAL,DIMENSION(iim_file,jjm_file,n3)        :: champ_file
3161  REAL,ALLOCATABLE,DIMENSION(:,:)             :: champout_g
3162  INTEGER                                     :: i,j,ij,l,m
3163
3164!_ ================================================================================================================================
3165
3166  WRITE(numout,*) 'Lecture ',TRIM(nomvar)
3167!-
3168  IF (is_root_prc) THEN
3169     ALLOCATE(champout_g(iim_g*jjm_g,n3))
3170     IF ( n3 == 1 ) THEN
3171        CALL flinget (force_id,nomvar(1:LEN_TRIM(nomvar)), &
3172             &                iim_file, jjm_file, 0, 0,  1, 1, champ_file)
3173     ELSE
3174        DO l=1,n3
3175           CALL flinget &
3176                &      (force_id,nomvar(1:LEN_TRIM(nomvar)), &
3177                &       iim_file, jjm_file, 0, n3,  l, l, champ_file(:,:,l))
3178        ENDDO
3179     ENDIF
3180     ! shift if necessary
3181     IF (i_cut /= 0) THEN
3182        DO l=1,n3
3183           CALL shift_field (iim_file,jjm_file,i_cut,champ_file(:,:,l))
3184        ENDDO
3185     ENDIF
3186     ! interpolate onto the model grid
3187     DO l=1,n3
3188        DO j=1,jjm_g
3189           DO i=1,iim_g
3190              ij = i+(j-1)*iim_g
3191              champout_g(ij,l) = 0.
3192              DO m=1,ncorr(i,j)
3193                 champout_g(ij,l) = champout_g(ij,l) &
3194        &                        +champ_file(icorr(i,j,m),jcorr(i,j,m),l)
3195              ENDDO
3196              champout_g(ij,l) = champout_g(ij,l)/REAL(ncorr(i,j))
3197           ENDDO
3198        ENDDO
3199     ENDDO
3200!$     DO l=1,n3
3201!$        DO j=1,jjm_g
3202!$           WRITE(numout,*) j,(/ ( champout_g((j-1)*iim_g+i,l), i=1,iim_g ) /)
3203!$        ENDDO
3204!$     ENDDO
3205  ELSE
3206     ALLOCATE(champout_g(1,1))
3207  ENDIF
3208!!$  CALL scatter2D(champout_g,champout)
3209#ifndef CPP_PARA
3210  champout(:,:)=champout_g(:,:)
3211#else
3212  CALL scatter2D_rgen(champout_g,champout,n3)
3213#endif
3214
3215!$  DO l=1,n3
3216!$     DO j=1,jjm
3217!$        WRITE(numout,*) j,(/ ( champout((j-1)*iim_g+i,l), i=1,iim_g ) /)
3218!$     ENDDO
3219!$  ENDDO
3220  !----------------------------
3221END SUBROUTINE weather_read
3222!-
3223!===
3224!-
3225!! ================================================================================================================================
3226!! SUBROUTINE   : weathgen_dump
3227!!
3228!>\BRIEF        This subroutine "dumps" data before writing an netcdf file.
3229!!
3230!! DESCRIPTION  : None
3231!!
3232!! RECENT CHANGE(S): None
3233!!
3234!! MAIN OUTPUT VARIABLE(S):
3235!!
3236!! REFERENCE(S) :
3237!!
3238!! FLOWCHART    : None
3239!! \n
3240!_ ================================================================================================================================
3241
3242SUBROUTINE weathgen_dump &
3243& (itau, dt_force, iim, jjm, nbindex, kindex, lrstwrite, &
3244&  swdown, rainf, snowf, tair, u, v, qair, pb, lwdown )
3245!---------------------------------------------------------------------
3246  IMPLICIT NONE
3247!-
3248
3249  !! 0. Variables and parameters declaration
3250
3251  !! 0.1 Input variables
3252
3253  INTEGER,INTENT(IN)                     :: itau
3254  REAL,INTENT(IN)                        :: dt_force
3255  INTEGER,INTENT(IN)                     :: iim,jjm
3256  INTEGER,INTENT(IN)                     :: nbindex
3257  LOGICAL,INTENT(IN)                     :: lrstwrite
3258  INTEGER,DIMENSION(iim*jjm),INTENT(IN)  :: kindex
3259  REAL,DIMENSION(iim*jjm),INTENT(IN)     :: &
3260 &  swdown, rainf, snowf, tair, u, v, qair, pb, lwdown
3261
3262  !! 0.4 Local variables
3263
3264  INTEGER                 :: iret,ndim
3265  INTEGER,DIMENSION(4)    :: corner,edges
3266  REAL,DIMENSION(iim*jjm) :: var_gather
3267
3268!_ ================================================================================================================================
3269
3270!-
3271! time dimension
3272!-
3273  iret = NF90_PUT_VAR (dump_id,timestp_id,(/ REAL(itau) /), &
3274 &                     start=(/ itau /),count=(/ 1 /))
3275  iret = NF90_PUT_VAR (dump_id,time_id,(/ REAL(itau)*dt_force /), &
3276 &                     start=(/ itau /),count=(/ 1 /))
3277!-
3278! 2D variables: pas de dimension verticale
3279!-
3280  IF (gathered) THEN
3281    ndim = 2
3282    corner(1:2) = (/ 1, itau /)
3283    edges(1:2) = (/ nbindex, 1 /)
3284  ELSE
3285    ndim = 3
3286    corner(1:3) = (/ 1, 1, itau /)
3287    edges(1:3) = (/ iim, jjm, 1 /)
3288  ENDIF
3289!-
3290  CALL gather_weather (iim*jjm,nbindex,kindex,swdown, var_gather)
3291  iret = NF90_PUT_VAR (dump_id,soldownid, var_gather, &
3292 &         start=corner(1:ndim), count=edges(1:ndim))
3293  CALL gather_weather (iim*jjm,nbindex,kindex,rainf,  var_gather)
3294  iret = NF90_PUT_VAR (dump_id,rainfid,   var_gather, &
3295 &         start=corner(1:ndim), count=edges(1:ndim))
3296  CALL gather_weather (iim*jjm,nbindex,kindex,snowf,  var_gather)
3297  iret = NF90_PUT_VAR (dump_id,snowfid,   var_gather, &
3298 &         start=corner(1:ndim), count=edges(1:ndim))
3299  CALL gather_weather (iim*jjm,nbindex,kindex,pb,     var_gather)
3300  iret = NF90_PUT_VAR (dump_id,psolid,    var_gather, &
3301 &         start=corner(1:ndim), count=edges(1:ndim))
3302  CALL gather_weather (iim*jjm,nbindex,kindex,lwdown, var_gather)
3303  iret = NF90_PUT_VAR (dump_id,lwradid,   var_gather, &
3304 &         start=corner(1:ndim), count=edges(1:ndim))
3305!-
3306! 3D variables
3307!-
3308  IF (gathered) THEN
3309    ndim = 3
3310    corner(1:3) = (/ 1, 1, itau /)
3311    edges(1:3) = (/ nbindex, 1, 1 /)
3312  ELSE
3313    ndim = 4
3314    corner(1:4) = (/ 1, 1, 1, itau /)
3315    edges(1:4) = (/ iim, jjm, 1, 1 /)
3316  ENDIF
3317!-
3318  CALL gather_weather (iim*jjm,nbindex,kindex,u,    var_gather)
3319  iret = NF90_PUT_VAR (dump_id,uid,    var_gather, &
3320 &         start=corner(1:ndim), count=edges(1:ndim))
3321  CALL gather_weather (iim*jjm,nbindex,kindex,v,    var_gather)
3322  iret = NF90_PUT_VAR (dump_id,vid,    var_gather, &
3323 &         start=corner(1:ndim), count=edges(1:ndim))
3324  CALL gather_weather (iim*jjm,nbindex,kindex,tair, var_gather)
3325  iret = NF90_PUT_VAR (dump_id,tairid, var_gather, &
3326 &         start=corner(1:ndim), count=edges(1:ndim))
3327  CALL gather_weather (iim*jjm,nbindex,kindex,qair, var_gather)
3328  iret = NF90_PUT_VAR (dump_id,qairid, var_gather, &
3329 &         start=corner(1:ndim), count=edges(1:ndim))
3330!-
3331  IF (lrstwrite) THEN
3332    iret = NF90_CLOSE (dump_id)
3333  ENDIF
3334!---------------------------
3335END SUBROUTINE weathgen_dump
3336!-
3337!===
3338!-
3339
3340!! ================================================================================================================================
3341!! SUBROUTINE   : gather_weather
3342!!
3343!>\BRIEF        This subroutine determines which points are not in the computational domain and
3344!! creates a mask for these points.
3345!!
3346!! DESCRIPTION  : None
3347!!
3348!! RECENT CHANGE(S): None
3349!!
3350!! MAIN OUTPUT VARIABLE(S): ::var_out
3351!!
3352!! REFERENCE(S) :
3353!!
3354!! FLOWCHART    : None
3355!! \n
3356!_ ================================================================================================================================
3357
3358SUBROUTINE gather_weather (iimjjm, nbindex, kindex, var_in, var_out)
3359!---------------------------------------------------------------------
3360  IMPLICIT NONE
3361!-
3362
3363  !! 0. Variables and parameters declaration
3364
3365  !! 0.1 Input variables
3366
3367  INTEGER,INTENT(IN)                     :: iimjjm,nbindex
3368  INTEGER,DIMENSION(iimjjm),INTENT(IN)   :: kindex
3369  REAL,DIMENSION(iimjjm),INTENT(IN)      :: var_in
3370
3371  !! 0.2 Output variables 
3372
3373  REAL,DIMENSION(iimjjm),INTENT(OUT)     :: var_out
3374
3375  !! 0.4 Local variables
3376
3377  INTEGER                                :: i
3378  LOGICAL,SAVE                           :: firstcall = .TRUE.
3379  INTEGER,SAVE                           :: nb_outside
3380  INTEGER,ALLOCATABLE,SAVE,DIMENSION(:)  :: outside
3381
3382!_ ================================================================================================================================
3383
3384  IF (firstcall) THEN
3385!---
3386!-- determine which points are not in the computational domain and
3387!-- create a mask for these points
3388!---
3389    firstcall = .FALSE.
3390 
3391    ALLOC_ERR=-1
3392    ALLOCATE(outside(iimjjm), STAT=ALLOC_ERR)
3393    IF (ALLOC_ERR/=0) THEN
3394      WRITE(numout,*) "ERROR IN ALLOCATION of outside : ",ALLOC_ERR
3395      STOP
3396    ENDIF
3397    outside(:) = 0.
3398    nb_outside = 0
3399    DO i=1,iimjjm
3400      IF ( ALL( kindex(:) /= i ) ) THEN
3401        nb_outside = nb_outside+1
3402        outside(nb_outside) = i
3403      ENDIF
3404    ENDDO
3405  ENDIF
3406!-
3407  IF ( gathered ) THEN
3408    DO i=1,nbindex
3409      var_out(i) = var_in(kindex(i))
3410    ENDDO
3411  ELSE
3412    var_out(:) = var_in(:)
3413    DO i=1,nb_outside
3414      var_out(outside(i)) = undef
3415    ENDDO
3416  ENDIF
3417!--------------------
3418END SUBROUTINE gather_weather
3419!-
3420!===
3421!-
3422
3423!! ================================================================================================================================
3424!! SUBROUTINE   : shift_shield
3425!!
3426!>\BRIEF       
3427!!
3428!! DESCRIPTION  : None
3429!!
3430!! RECENT CHANGE(S): None
3431!!
3432!! MAIN OUTPUT VARIABLE(S): ::champ
3433!!
3434!! REFERENCE(S) :
3435!!
3436!! FLOWCHART    : None
3437!! \n
3438!_ ================================================================================================================================
3439
3440SUBROUTINE shift_field (im,jm,i_cut,champ)
3441!---------------------------------------------------------------------
3442
3443  !! 0. Variables and parameters declaration
3444
3445  !! 0.1 Input variables
3446
3447  INTEGER,INTENT(IN)                  :: im,jm,i_cut
3448
3449  !! 0.3 Modified variables
3450
3451  REAL,DIMENSION(im,jm),INTENT(INOUT) :: champ
3452
3453  !! 0.4 Local variables
3454
3455  REAL,DIMENSION(im,jm)               :: champ_temp
3456
3457!_ ================================================================================================================================
3458
3459  IF ( (i_cut >= 1).AND.(i_cut <= im) ) THEN
3460    champ_temp(1:im-i_cut-1,:) = champ(i_cut:im,:)
3461    champ_temp(im-i_cut:im,:)  = champ(1:i_cut+1,:)
3462    champ(:,:) = champ_temp(:,:)
3463  ENDIF
3464!-------------------------
3465END SUBROUTINE shift_field
3466!-
3467!===
3468!-
3469!! ================================================================================================================================
3470!! SUBROUTINE   : weathgen_domain_size
3471!!
3472!>\BRIEF        This subroutine determines the size of the domain.
3473!!
3474!! DESCRIPTION  : None
3475!!
3476!! RECENT CHANGE(S): None
3477!!
3478!! MAIN OUTPUT VARIABLE(S): ::iim, ::jjm, ::limit_west, ::limit_east, ::limit_north, ::limit_south
3479!!
3480!! REFERENCE(S) :
3481!!
3482!! FLOWCHART    : None
3483!! \n
3484!_ ================================================================================================================================
3485
3486SUBROUTINE weathgen_domain_size &
3487& (limit_west,limit_east,limit_north,limit_south, &
3488&  zonal_res,merid_res,iim,jjm)
3489!---------------------------------------------------------------------
3490  IMPLICIT NONE
3491!-
3492  !! 0. Variables and parameters declaration
3493
3494  !! 0.1 Input variables
3495
3496  REAL,INTENT(IN)     :: zonal_res,merid_res
3497
3498  !! 0.2 Output variables
3499
3500  INTEGER,INTENT(OUT) :: iim,jjm
3501
3502  !! 0.3 Modified variables
3503
3504  REAL,INTENT(INOUT)  :: limit_west,limit_east,limit_north,limit_south
3505
3506!_ ================================================================================================================================
3507
3508  IF (limit_west > limit_east)  limit_east = limit_east+360.
3509!-
3510  IF (    (limit_west >= limit_east) &
3511 &    .OR.(limit_east > 360.) &
3512 &    .OR.(limit_west < -180.) &
3513 &    .OR.(limit_east-limit_west > 360.) ) THEN
3514    WRITE(numout,*) 'PROBLEME longitudes.'
3515    WRITE(numout,*) 'Limites Ouest, Est: ',limit_west,limit_east
3516    STOP
3517  ENDIF
3518!-
3519  IF (    (limit_south < -90.) &
3520 &    .OR.(limit_north > 90.) &
3521 &    .OR.(limit_south >= limit_north ) ) THEN
3522    WRITE(numout,*) 'PROBLEME latitudes.'
3523    WRITE(numout,*) 'Limites Nord, Sud: ',limit_north,limit_south
3524    STOP
3525  ENDIF
3526!-
3527  IF (    (zonal_res <= 0. ) &
3528 &    .OR.(zonal_res > limit_east-limit_west) ) THEN
3529    WRITE(numout,*) 'PROBLEME resolution zonale.'
3530    WRITE(numout,*) 'Limites Ouest, Est, Resolution: ', &
3531 &             limit_west,limit_east,zonal_res
3532    STOP
3533  ENDIF
3534!-
3535  IF (    (merid_res <= 0.) &
3536 &    .OR.(merid_res > limit_north-limit_south) ) THEN
3537    WRITE(numout,*) 'PROBLEME resolution meridionale.'
3538    WRITE(numout,*) 'Limites Nord, Sud, Resolution: ', &
3539 &             limit_north,limit_south,merid_res
3540    STOP
3541  ENDIF
3542!-
3543  iim = NINT(MAX((limit_east-limit_west)/zonal_res,1.))
3544  jjm = NINT(MAX((limit_north-limit_south)/merid_res,1.))
3545!-
3546  WRITE(numout,*) 'Domain size: iim, jjm = ', iim, jjm
3547!----------------------------------
3548END SUBROUTINE weathgen_domain_size
3549!-
3550!===
3551!-
3552
3553!! ================================================================================================================================
3554!! FUNCTION     : tsat1
3555!!
3556!>\BRIEF         This function computes the saturated temperature for vapor.
3557!!
3558!! DESCRIPTION :  functions tsatl,tsati are used below so that Lowe's
3559!!                polyomial for liquid is used if t gt 273.16, or for ice if
3560!!                t lt 273.16. also impose range of validity for Lowe's polys.\n
3561!!
3562!! RECENT CHANGE(S): None
3563!!
3564!! RETURN VALUE : tsat
3565!!
3566!! REFERENCE(S) :
3567!! - Lowe PR, 1977, An Approximating Polynomial for the Computation of Saturation
3568!! Vapor Pressure, Journal of Applied Meteorology.16,101-103.
3569!!
3570!! FLOWCHART    : None
3571!! \n
3572!_ ================================================================================================================================
3573
3574FUNCTION tsatl (t) RESULT (tsat)
3575
3576  !! 0. Variables and parameters declaration
3577 
3578  !! 0.1 Input variables
3579
3580  REAL,INTENT(IN) :: t
3581
3582  !! 0.2 Result
3583  REAL            :: tsat
3584
3585!_ ================================================================================================================================
3586
3587  tsat = MIN(100.,MAX(t-zero_t,0.))
3588!-----------------
3589END FUNCTION tsatl
3590!-
3591!===
3592!-
3593!! ================================================================================================================================
3594!! FUNCTION     : tsati
3595!!
3596!>\BRIEF         This function computes the saturated temperature for ice.
3597!!
3598!! DESCRIPTION :  functions tsatl,tsati are used below so that Lowe's
3599!!                polyomial for liquid is used if t gt 273.16, or for ice if
3600!!                t lt 273.16. also impose range of validity for Lowe's polys.\n
3601!!
3602!! RECENT CHANGE(S): None
3603!!
3604!! RETURN VALUE : tsat
3605!!
3606!! REFERENCE(S) :
3607!! - Lowe PR, 1977, An Approximating Polynomial for the Computation of Saturation
3608!! Vapor Pressure, Journal of Applied Meteorology.16,101-103.
3609!!
3610!! FLOWCHART    : None
3611!! \n
3612!_ ================================================================================================================================
3613
3614FUNCTION tsati (t) RESULT (tsat)
3615
3616  !! 0. Variables and parameters declaration
3617 
3618  !! 0.1 Input variables
3619
3620  REAL,INTENT(IN) :: t
3621
3622  !! 0.2 Result
3623  REAL            :: tsat
3624
3625!_ ================================================================================================================================
3626
3627  tsat = MAX(-60.,MIN(t-zero_t,0.))
3628!-----------------
3629END FUNCTION tsati
3630!-
3631!===
3632!-
3633
3634!! ================================================================================================================================
3635!! FUNCTION     : esat
3636!!
3637!>\BRIEF         This function computes specific humidity with the polynomials of Lowe.
3638!!
3639!! DESCRIPTION : The function esat is svp in n/m**2, with t in deg k.
3640!!               (100 * lowe's poly since 1 mb = 100 n/m**2.). \n
3641!!               Polynomials for svp(t), d(svp)/dt over water and ice
3642!!
3643!! RECENT CHANGE(S): None
3644!!
3645!! RETURN VALUE : esatout
3646!!
3647!! REFERENCE(S) :
3648!! - Lowe PR, 1977, An Approximating Polynomial for the Computation of Saturation
3649!! Vapor Pressure, Journal of Applied Meteorology.16,101-103.
3650!!
3651!! FLOWCHART    : None
3652!! \n
3653!_ ================================================================================================================================
3654
3655FUNCTION esat (t) RESULT (esatout)
3656
3657  !! 0. Variables and parameters declaration
3658
3659  REAL,PARAMETER :: &                                                    !! polynomials for svp(t), d(svp)/dt over water and ice are from
3660 & asat0 = 6.1078000,    asat1 = 4.4365185e-1, asat2 = 1.4289458e-2, &   !! lowe(1977),jam,16,101-103.
3661 & asat3 = 2.6506485e-4, asat4 = 3.0312404e-6, asat5 = 2.0340809e-8, &
3662 & asat6 = 6.1368209e-11, &
3663 & bsat0 = 6.1091780,    bsat1 = 5.0346990e-1, bsat2 = 1.8860134e-2, &
3664 & bsat3 = 4.1762237e-4, bsat4 = 5.8247203e-6, bsat5 = 4.8388032e-8, &
3665 & bsat6 = 1.8388269e-10
3666
3667  !! 0.1 Input variables
3668
3669  REAL,INTENT(IN) :: t
3670
3671  !! 0.2 Result
3672
3673  REAL             :: esatout
3674
3675  !! 0.4 Local variables
3676
3677  REAL             :: x
3678
3679!_ ================================================================================================================================
3680
3681  IF (t >= zero_t) THEN
3682    x = asat0
3683  ELSE
3684    x = bsat0
3685  ENDIF
3686!-
3687  esatout = 100.* &
3688    ( x &
3689     +tsatl(t)*(asat1+tsatl(t)*(asat2+tsatl(t)*(asat3 &
3690     +tsatl(t)*(asat4+tsatl(t)*(asat5+tsatl(t)* asat6))))) &
3691     +tsati(t)*(bsat1+tsati(t)*(bsat2+tsati(t)*(bsat3 &
3692     +tsati(t)*(bsat4+tsati(t)*(bsat5+tsati(t)* bsat6)))))  )
3693!----------------
3694END FUNCTION esat
3695!-
3696!===
3697!-
3698! ================================================================================================================================
3699!! FUNCTION     : qsat
3700!!
3701!>\BRIEF         This function computes the saturation specific humidity.
3702!!
3703!! DESCRIPTION :  statement function qsat is saturation specific humidity,
3704!! with svp e and ambient pressure p in n/m**2. impose an upper
3705!! limit of 1 to avoid spurious values for very high svp
3706!! and/or small p
3707!!
3708!! RECENT CHANGE(S): None
3709!!
3710!! RETURN VALUE : qsatout
3711!!
3712!! REFERENCE(S) :
3713!! - Lowe PR, 1977, An Approximating Polynomial for the Computation of Saturation
3714!! Vapor Pressure, Journal of Applied Meteorology.16,101-103.
3715!!
3716!! FLOWCHART    : None
3717!! \n
3718!_ ================================================================================================================================
3719
3720FUNCTION qsat (e,p) RESULT (qsatout)
3721
3722  !! 0. Variables and parameters declaration
3723
3724  !! 0.1 Input variables
3725
3726  REAL, INTENT(IN) :: e,p
3727
3728  !! 0.2 Result
3729  REAL             :: qsatout
3730
3731!_ ================================================================================================================================
3732
3733  qsatout = 0.622*e/MAX(p-(1.0-0.622)*e,0.622*e)
3734!----------------
3735END FUNCTION qsat
3736!-
3737!===
3738!-
3739
3740!! ================================================================================================================================
3741!! SUBROUTINE   : weathgen_qsat
3742!!
3743!>\BRIEF        This subroutine calculates the saturation vapor pressure with the polynomials of Lowe.
3744!!
3745!! DESCRIPTION  : Vectorized version of functions esat and qsat.
3746!!                statement function esat is svp in n/m**2, with t in deg K.\n
3747!!               (100 * lowe's poly since 1 mb = 100 n/m**2.)\n
3748!!               Polynomials for svp(t), d(svp)/dt over water
3749!!               and ice are from Lowe(1977),jam,16,101-103 \n
3750!!
3751!! RECENT CHANGE(S): None
3752!!
3753!! MAIN OUTPUT VARIABLE(S): ::qsat
3754!!
3755!! REFERENCE(S) :
3756!! - Lowe PR, 1977, An Approximating Polynomial for the Computation of Saturation
3757!! Vapor Pressure, Journal of Applied Meteorology.16,101-103.
3758!!
3759!! FLOWCHART    : None
3760!! \n
3761!_ ================================================================================================================================
3762
3763SUBROUTINE weathgen_qsat (npoi,t,p,qsat)
3764
3765
3766  !! 0. Variables and parameters declaration
3767
3768 !-
3769 ! polynomials for svp(t), d(svp)/dt over water and ice
3770 ! are from lowe(1977),ja
3771  REAL,PARAMETER :: &
3772 & asat0 = 6.1078000,    asat1 = 4.4365185e-1, asat2 = 1.4289458e-2, &   !! polynomials for svp(t), d(svp)/dt over water and ice
3773 & asat3 = 2.6506485e-4, asat4 = 3.0312404e-6, asat5 = 2.0340809e-8, &
3774 & asat6 = 6.1368209e-11, &
3775 & bsat0 = 6.1091780,    bsat1 = 5.0346990e-1, bsat2 = 1.8860134e-2, &
3776 & bsat3 = 4.1762237e-4, bsat4 = 5.8247203e-6, bsat5 = 4.8388032e-8, &
3777 & bsat6 = 1.8388269e-10
3778
3779  !! 0.1 Input variables
3780
3781  INTEGER,INTENT(IN)              :: npoi
3782  REAL,DIMENSION(npoi),INTENT(IN) :: t,p
3783
3784  !! 0.2 Output variables
3785
3786  REAL,DIMENSION(npoi),INTENT(OUT):: qsat
3787
3788  !! 0.4 Local variables
3789
3790  REAL,DIMENSION(npoi) :: x, tl, ti, e
3791
3792!_ ================================================================================================================================
3793
3794  WHERE (t(:) > zero_t)
3795    x(:) = asat0
3796  ELSEWHERE
3797    x(:) = bsat0
3798  ENDWHERE
3799!-
3800  tl(:) = MIN(100.,MAX(t(:)-zero_t,0.))
3801  ti(:) = MAX(-60.,MIN(t(:)-zero_t,0.))
3802!-
3803  e(:) =  100.* &
3804    ( x(:) &
3805     +tl(:)*(asat1+tl(:)*(asat2+tl(:)*(asat3 &
3806     +tl(:)*(asat4+tl(:)*(asat5+tl(:)* asat6))))) &
3807     +ti(:)*(bsat1+ti(:)*(bsat2+ti(:)*(bsat3 &
3808     +ti(:)*(bsat4+ti(:)*(bsat5+ti(:)* bsat6)))))  )
3809!-
3810  qsat(:) = 0.622*e(:)/MAX(p(:)-(1.0-0.622)*e(:),0.622*e(:))
3811!---------------------------
3812END SUBROUTINE weathgen_qsat
3813!-
3814!===
3815!-
3816
3817!! ================================================================================================================================
3818!! SUBROUTINE   : mask_c_o
3819!!
3820!>\BRIEF        This subroutine computes a field which indicated if the point is terrestrial or oceanic.
3821!!
3822!! DESCRIPTION  : From a mask field, we make an indicator mask Earth/ocean. Earth : 1 ; ocean : 0.
3823!!
3824!! RECENT CHANGE(S): z.x.li,01/04/1994 : creation of the subroutine
3825!!
3826!! MAIN OUTPUT VARIABLE(S): ::mask, ::ncorr, ::icorr
3827!!
3828!! REFERENCE(S) :
3829!!
3830!! FLOWCHART    : None
3831!! \n
3832!_ ================================================================================================================================
3833
3834SUBROUTINE mask_c_o &
3835& (imdep, jmdep, xdata, ydata, mask_in, fcrit, &
3836&  imar, jmar, zonal_res, merid_res, n_agg, x, y, mask, &
3837&  ncorr, icorr, jcorr)
3838
3839  !! 0. Variables and parameters declaration
3840
3841  !! 0.1 Input variables
3842
3843  INTEGER :: imdep,jmdep
3844  REAL :: xdata(imdep),ydata(jmdep)
3845  REAL :: mask_in(imdep,jmdep)
3846  REAL :: fcrit
3847  INTEGER :: imar,jmar
3848  REAL :: zonal_res,merid_res
3849  INTEGER :: n_agg
3850  REAL :: x(imar),y(jmar)
3851
3852  !! 0.2 Output variables
3853
3854  REAL, INTENT(OUT) :: mask(imar,jmar)
3855  INTEGER :: ncorr(imar,jmar)
3856  INTEGER,DIMENSION(imar,jmar,n_agg) :: icorr,jcorr
3857
3858  !! 0.4 Local variables
3859
3860  INTEGER i, j, ii, jj
3861  REAL a(imar),b(imar),c(jmar),d(jmar)
3862  INTEGER num_tot(imar,jmar), num_oce(imar,jmar)
3863  REAL,ALLOCATABLE :: distans(:)
3864  INTEGER ij_proche(1),i_proche,j_proche
3865!-
3866  INTEGER,DIMENSION(imar,jmar) :: ncorr_oce , ncorr_land
3867  INTEGER,DIMENSION(imar,jmar,n_agg) :: &
3868 &  icorr_oce, jcorr_oce , icorr_land, jcorr_land
3869!-
3870  INTEGER imdepp
3871  REAL,ALLOCATABLE :: xdatap(:)
3872  REAL,ALLOCATABLE :: mask_inp(:,:)
3873  LOGICAL :: extend
3874
3875!_ ================================================================================================================================
3876
3877  ncorr(:,:) = 0
3878  icorr(:,:,:) = -1; jcorr(:,:,:) = -1
3879  ncorr_land(:,:) = 0
3880  icorr_land(:,:,:) = -1; jcorr_land(:,:,:) = -1
3881  ncorr_oce(:,:) = 0
3882  icorr_oce(:,:,:) = -1; jcorr_oce(:,:,:) = -1
3883! do we have to extend the domain (-x...-x+360)?
3884  IF ( xdata(1)+360.-xdata(imdep) > 0.01 ) THEN
3885    extend = .TRUE.
3886    imdepp = imdep+1
3887  ELSE
3888    extend = .FALSE.
3889    imdepp = imdep
3890  ENDIF
3891!-
3892
3893  ALLOC_ERR=-1
3894  ALLOCATE(xdatap(imdepp), STAT=ALLOC_ERR)
3895  IF (ALLOC_ERR/=0) THEN
3896    WRITE(numout,*) "ERROR IN ALLOCATION of xdatap : ",ALLOC_ERR
3897    STOP
3898  ENDIF
3899
3900  ALLOC_ERR=-1
3901  ALLOCATE(mask_inp(imdepp,jmdep), STAT=ALLOC_ERR)
3902  IF (ALLOC_ERR/=0) THEN
3903    WRITE(numout,*) "ERROR IN ALLOCATION of mask_inp : ",ALLOC_ERR
3904    STOP
3905  ENDIF
3906!-
3907  xdatap(1:imdep) = xdata(1:imdep)
3908  mask_inp(1:imdep,:) = mask_in(1:imdep,:)
3909!-
3910  IF (extend) THEN
3911    xdatap(imdepp) = xdatap(1)+360.
3912    mask_inp(imdepp,:) = mask_inp(1,:)
3913  ENDIF
3914!-
3915
3916  ALLOC_ERR=-1
3917  ALLOCATE(distans(imdepp*jmdep), STAT=ALLOC_ERR)
3918  IF (ALLOC_ERR/=0) THEN
3919    WRITE(numout,*) "ERROR IN ALLOCATION of distans : ",ALLOC_ERR
3920    STOP
3921  ENDIF
3922! Definition des limites des boites de la grille d'arrivee.
3923  IF (imar > 1) THEN
3924    a(1) = x(1)-(x(2)-x(1))/2.0
3925    b(1) = (x(1)+x(2))/2.0
3926    DO i=2,imar-1
3927      a(i) = b(i-1)
3928      b(i) = (x(i)+x(i+1))/2.0
3929    ENDDO
3930    a(imar) = b(imar-1)
3931    b(imar) = x(imar)+(x(imar)-x(imar-1))/2.0
3932  ELSE
3933    a(1) = x(1)-zonal_res/2.
3934    b(1) = x(1)+zonal_res/2.
3935  ENDIF
3936!-
3937  IF (jmar > 1) THEN
3938    c(1) = y(1)-(y(2)-y(1))/2.0
3939    d(1) = (y(1)+y(2))/2.0
3940    DO j=2,jmar-1
3941      c(j) = d(j-1)
3942      d(j) = (y(j)+y(j+1))/2.0
3943    ENDDO
3944    c(jmar) = d(jmar-1)
3945    d(jmar) = y(jmar)+(y(jmar)-y(jmar-1))/2.0
3946  ELSE
3947    c(1) = y(1)-merid_res/2.
3948    d(1) = y(1)+merid_res/2.
3949  ENDIF
3950!-
3951  num_oce(1:imar,1:jmar) = 0
3952  num_tot(1:imar,1:jmar) = 0
3953!-
3954!  .....  Modif  P. Le Van ( 23/08/95 )  ....
3955!-
3956  DO ii=1,imar
3957    DO jj=1,jmar
3958      DO i=1,imdepp
3959        IF (    (     (xdatap(i)-a(ii) >= 1.e-5) &
3960 &               .AND.(xdatap(i)-b(ii) <= 1.e-5) ) &
3961 &          .OR.(     (xdatap(i)-a(ii) <= 1.e-5) &
3962 &               .AND.(xdatap(i)-b(ii) >= 1.e-5) ) ) THEN
3963          DO j=1,jmdep
3964            IF (    (     (ydata(j)-c(jj) >= 1.e-5) &
3965 &                   .AND.(ydata(j)-d(jj) <= 1.e-5) ) &
3966 &              .OR.(     (ydata(j)-c(jj) <= 1.e-5) &
3967 &                   .AND.(ydata(j)-d(jj) >= 1.e-5) ) ) THEN
3968              num_tot(ii,jj) = num_tot(ii,jj)+1
3969              IF (mask_inp(i,j) < 0.5) THEN
3970                num_oce(ii,jj) = num_oce(ii,jj)+1
3971!-------------- on a trouve un point oceanique. On le memorise.
3972                ncorr_oce(ii,jj) = ncorr_oce(ii,jj)+1
3973                IF ((i == imdepp).AND.extend) THEN
3974                  icorr_oce(ii,jj,ncorr_oce(ii,jj)) = 1
3975                ELSE
3976                  icorr_oce(ii,jj,ncorr_oce(ii,jj)) = i
3977                ENDIF
3978                jcorr_oce(ii,jj,ncorr_oce(ii,jj)) = j
3979              ELSE
3980!-------------- on a trouve un point continental. On le memorise.
3981                ncorr_land(ii,jj) = ncorr_land(ii,jj)+1
3982                IF ((i == imdepp).AND.extend) THEN
3983                  icorr_land(ii,jj,ncorr_land(ii,jj)) = 1
3984                ELSE
3985                  icorr_land(ii,jj,ncorr_land(ii,jj)) = i
3986                ENDIF
3987                jcorr_land(ii,jj,ncorr_land(ii,jj)) = j
3988              ENDIF
3989            ENDIF
3990          ENDDO
3991        ENDIF
3992      ENDDO
3993    ENDDO
3994  ENDDO
3995!-
3996  DO i=1,imar
3997    DO j=1,jmar
3998      IF (num_tot(i,j) > 0) THEN
3999        IF (    (     (num_oce(i,j) == 0) &
4000 &               .AND.(num_tot(i,j) > 0) ) &
4001 &          .OR.(     (num_oce(i,j) > 0) &
4002 &               .AND.(   REAL(num_oce(i,j)) &
4003 &                     <= REAL(num_tot(i,j))*(1.-fcrit) ) ) ) THEN
4004          mask(i,j) = 1.
4005          ncorr(i,j) = ncorr_land(i,j)
4006          icorr(i,j,:) = icorr_land(i,j,:)
4007          jcorr(i,j,:) = jcorr_land(i,j,:)
4008        ELSE
4009          mask(i,j) = 0.
4010          ncorr(i,j) = ncorr_oce(i,j)
4011          icorr(i,j,:) = icorr_oce(i,j,:)
4012          jcorr(i,j,:) = jcorr_oce(i,j,:)
4013        ENDIF
4014      ELSE
4015        CALL dist_sphe(x(i),y(j),xdatap,ydata,imdepp,jmdep,distans)
4016        ij_proche(:) = MINLOC(distans)
4017        j_proche = (ij_proche(1)-1)/imdepp+1
4018        i_proche = ij_proche(1)-(j_proche-1)*imdepp
4019        mask(i,j) = mask_inp(i_proche,j_proche)
4020        IF ( (i_proche == imdepp).AND.extend)  i_proche=1
4021        ncorr(i,j) = 1
4022        icorr(i,j,1) = i_proche
4023        jcorr(i,j,1) = j_proche
4024      ENDIF
4025    ENDDO
4026  ENDDO
4027!----------------------
4028END SUBROUTINE mask_c_o
4029!-
4030!===
4031!-
4032!! ================================================================================================================================
4033!! SUBROUTINE   : dist_sphe
4034!!
4035!>\BRIEF        This subroutine computes the minimum distance between two points on Earth
4036!! according the great circle. \n
4037!!
4038!! DESCRIPTION  : None
4039!!
4040!! RECENT CHANGE(S): Laurent Li, 30/12/1996 : creation of this subroutine
4041!!
4042!! MAIN OUTPUT VARIABLE(S): ::distance
4043!!
4044!! REFERENCE(S) :
4045!!
4046!! FLOWCHART    : None
4047!! \n
4048!_ ================================================================================================================================
4049
4050SUBROUTINE dist_sphe (rf_lon,rf_lat,rlon,rlat,im,jm,distance)
4051
4052
4053  !! 0. Variables and parameters declaration
4054
4055  REAL radius                !! Earth radius (m)
4056  PARAMETER (radius=6371229.)
4057
4058  !! 0.1 Input variables
4059
4060  INTEGER im, jm    !! dimensions
4061  REAL rf_lon       !! longitude of the referenced point (degrees)
4062  REAL rf_lat       !! latitude of the referenced point (degrees)
4063  REAL rlon(im), rlat(jm) !! longitude and latitude of points
4064
4065  !! 0.2 Output variables
4066
4067  REAL distance(im,jm) !! distances in meters (m)
4068
4069  !! 0.4 Local variables
4070
4071  REAL rlon1, rlat1
4072  REAL rlon2, rlat2
4073  REAL dist
4074  REAL pa, pb, p, pi
4075  INTEGER i,j
4076
4077!_ ================================================================================================================================
4078
4079  pi = 4.0*ATAN(1.0)
4080!-
4081  DO j=1,jm
4082    DO i=1,im
4083      rlon1=rf_lon
4084      rlat1=rf_lat
4085      rlon2=rlon(i)
4086      rlat2=rlat(j)
4087      pa = pi/2.0-rlat1*pi/180.0 ! dist. entre pole n et point a
4088      pb = pi/2.0-rlat2*pi/180.0 ! dist. entre pole n et point b
4089!-----
4090      p = (rlon1-rlon2)*pi/180.0 ! angle entre a et b (leurs meridiens)
4091!-----
4092      dist = ACOS( COS(pa)*COS(pb)+SIN(pa)*SIN(pb)*COS(p))
4093      dist = radius*dist
4094      distance(i,j) = dist
4095    ENDDO
4096  ENDDO
4097!-----------------------
4098END SUBROUTINE dist_sphe
4099!-
4100!===
4101!-
4102
4103!! ================================================================================================================================
4104!! SUBROUTINE   : permute
4105!!
4106!>\BRIEF         This subroutine initializes an array of size n by random integers between 1 and n. 
4107!!
4108!! DESCRIPTION  : None
4109!!
4110!! RECENT CHANGE(S): None
4111!!
4112!! MAIN OUTPUT VARIABLE(S): ::ordre
4113!!
4114!! REFERENCE(S) :
4115!!
4116!! FLOWCHART    : None
4117!! \n
4118!_ ================================================================================================================================
4119
4120SUBROUTINE permute (n,ordre)
4121!---------------------------------------------------------------------
4122
4123  !! 0. Variables and parameters declaration
4124
4125  !! 0.1 Input variables
4126
4127  INTEGER,INTENT(IN) :: n   !! size of the array
4128
4129  !! 0.2 Output variables
4130
4131  INTEGER,DIMENSION(n),INTENT(OUT) :: ordre
4132
4133  !! 0.4 Local variables
4134
4135  INTEGER,DIMENSION(n) :: restant
4136  INTEGER :: ipique, i, n_rest
4137  REAL    :: rndnum
4138
4139!_ ================================================================================================================================
4140
4141  n_rest = n
4142  restant(:) = (/ (i, i=1,n) /)
4143!-
4144  DO i=1,n
4145    CALL random_number (rndnum)
4146    ipique = INT(rndnum*n_rest)+1
4147    ordre(i) = restant(ipique)
4148    restant(ipique:n_rest-1) = restant(ipique+1:n_rest)
4149    n_rest = n_rest-1
4150  ENDDO
4151!---------------------
4152END SUBROUTINE permute
4153!-
4154!===
4155!-----------------
4156END MODULE weather
Note: See TracBrowser for help on using the repository browser.