source: trunk/LMDZ.VENUS/libf/phyvenus/flott_gwd_ran.F90 @ 2203

Last change on this file since 2203 was 2198, checked in by flefevre, 5 years ago

reglages Diogo Quirino & Gabriella Gilli pour la haute atmosphere

File size: 19.7 KB
Line 
1      SUBROUTINE FLOTT_GWD_RAN(NLON,NLEV,DTIME, pp, pn2,  &
2                  tt,uu,vv, plevmoy, &
3                  zustr,zvstr,d_t, d_u, d_v)
4
5    !----------------------------------------------------------------------
6    ! Parametrization of the momentum flux deposition due to a discrete
7    ! number of gravity waves.
8    ! F. Lott
9    ! Version 14, Gaussian distribution of the source
10    ! LMDz model online version     
11    ! ADAPTED FOR VENUS /  F. LOTT + S. LEBONNOIS
12    ! Version adapted on 03/04/2013:
13    !      - input flux compensated in the deepest layers
14    !---------------------------------------------------------------------
15
16      use dimphy
17      implicit none
18
19#include "YOEGWD.h"
20#include "YOMCST.h"
21
22    ! 0. DECLARATIONS:
23
24    ! 0.1 INPUTS
25    INTEGER, intent(in):: NLON, NLEV
26    REAL, intent(in):: DTIME ! Time step of the Physics
27    REAL, intent(in):: pp(NLON, NLEV)   ! Pressure at full levels
28! VENUS ATTENTION: CP VARIABLE PN2 CALCULE EN AMONT DES PARAMETRISATIONS
29    REAL, intent(in):: pn2(NLON,NLEV)   ! N2 (BV^2) at 1/2 levels
30    REAL, intent(in):: TT(NLON, NLEV)   ! Temp at full levels
31
32    REAL, intent(in):: UU(NLON, NLEV) , VV(NLON, NLEV)
33    ! Hor winds at full levels
34    REAL, intent(in) :: plevmoy(NLEV+1) ! press (Pa) at interlayers, at klon/2+1
35
36    ! 0.2 OUTPUTS
37    REAL, intent(out):: zustr(NLON), zvstr(NLON) ! Surface Stresses
38    REAL, intent(inout):: d_t(NLON, NLEV)        ! Tendency on Temp.
39
40    REAL, intent(inout):: d_u(NLON, NLEV), d_v(NLON, NLEV)
41    ! Tendencies on winds
42
43    ! O.3 INTERNAL ARRAYS
44
45    INTEGER II, LL
46
47    ! 0.3.0 TIME SCALE OF THE LIFE CYCLE OF THE WAVES PARAMETERIZED
48
49    REAL DELTAT
50
51    ! 0.3.1 GRAVITY-WAVES SPECIFICATIONS
52
53!VENUS
54    INTEGER, PARAMETER:: NK = 2, NP = 2, NO = 2, NW = NK * NP * NO
55    !Online output: change NO
56!    INTEGER, PARAMETER:: NK = 1, NP = 2, NO = 11, NW = NK * NP * NO
57    INTEGER JK, JP, JO, JW
58    REAL KMIN, KMAX ! Min and Max horizontal wavenumbers
59    REAL CMIN, CMAX ! Min and Max absolute ph. vel.
60    REAL CPHA ! absolute PHASE VELOCITY frequency
61    REAL ZK(NW, KLON) ! Horizontal wavenumber amplitude
62    REAL ZP(NW)       ! Horizontal wavenumber angle       
63    REAL ZO(NW, KLON) ! Absolute frequency      !
64
65    ! Waves Intr. freq. at the 1/2 lev surrounding the full level
66    REAL ZOM(NW, KLON), ZOP(NW, KLON)
67
68    ! Wave EP-fluxes at the 2 semi levels surrounding the full level
69    REAL WWM(NW, KLON), WWP(NW, KLON)
70    ! Fluxes X and Y for each waves at 1/2 Levels
71    REAL RUWP(NW, KLON), RVWP(NW, KLON)
72    REAL RUW(KLON, KLEV + 1) ! Flux x at semi levels
73    REAL RVW(KLON, KLEV + 1) ! Flux y at semi levels
74
75    REAL RUW0(NW, KLON) ! Fluxes at launching level
76    REAL RUWMAX         ! Max value
77    INTEGER LAUNCH      ! Launching altitude
78    REAL XLAUNCH        ! Control the launching altitude
79
80    ! 0.3.2 PARAMETERS OF WAVES DISSIPATIONS
81
82    REAL SAT  ! saturation parameter
83    REAL RDISS, ZOISEC ! COEFF DE DISSIPATION, SECURITY FOR INTRINSIC FREQ
84
85    ! 0.3.3 BACKGROUND FLOW AT 1/2 LEVELS AND VERTICAL COORDINATE
86
87    REAL H0bis(KLON, KLEV) ! Characteristic Height of the atmosphere
88    REAL H0 ! Characteristic Height of the atmosphere
89    REAL PR, TR ! Reference Pressure and Temperature
90
91    REAL ZH(KLON, KLEV + 1) ! Log-pressure altitude (constant H0)
92    REAL ZHbis(KLON, KLEV + 1) ! Log-pressure altitude (varying H)
93
94    REAL UH(KLON, KLEV + 1), VH(KLON, KLEV + 1) ! Winds at 1/2 levels
95    REAL PH(KLON, KLEV + 1) ! Pressure at 1/2 levels
96    REAL PSEC ! Security to avoid division by 0 pressure
97    REAL BV(KLON, KLEV + 1) ! Brunt Vaisala freq. (BVF) at 1/2 levels
98    REAL BVSEC ! Security to avoid negative BVF
99
100! COSMETICS TO DIAGNOSE EACH WAVES CONTRIBUTION.
101    logical output
102    data output/.false./
103!    data output/.true./
104 ! CAUTION ! IF output is .true. THEN change NO to 10 at least !
105    character*14 outform
106    character*2  str2
107    integer      ieq
108
109! ON CONSERVE LA MEMOIRE un certain temps AVEC UN SAVE
110    real,save,allocatable :: d_u_sav(:,:),d_v_sav(:,:)
111    LOGICAL firstcall
112    SAVE firstcall
113    DATA firstcall/.true./
114
115      REAL ALEAS
116      EXTERNAL ALEAS
117
118    !-----------------------------------------------------------------
119    !  1. INITIALISATIONS
120
121      IF (firstcall) THEN
122        allocate(d_u_sav(NLON,NLEV),d_v_sav(NLON,NLEV))
123        d_u_sav = 0.
124        d_v_sav = 0.
125        firstcall=.false.
126      ENDIF
127   
128    !    1.1 Basic parameter
129
130    !  PARAMETERS CORRESPONDING TO V3:
131    RUWMAX = 0.005      ! Max EP-Flux at Launch altitude
132    SAT    = 0.85       ! Saturation parameter: Sc in (12)
133    RDISS  = 0.1        ! Diffusion parameter
134
135    DELTAT=24.*3600.    ! Time scale of the waves (first introduced in 9b)
136
137!!!! TEST GG Values corresponding to min/max horizontal wavel 50-500 km
138!(similar to observations)
139    KMIN = 1.E-5        ! Min horizontal wavenumber
140!    KMIN = 6.3E-6       ! Min horizontal wavenumber
141    KMAX = 1.E-4        ! Max horizontal wavenumber
142    !Online output: one value only
143    if (output) then
144      KMIN = 3E-5
145      KMAX = 3E-5
146    endif
147    CMIN = 1.           ! Min phase velocity
148    CMAX = 61.          ! Max phase speed velocity
149!    XLAUNCH=0.6         ! Parameter that control launching altitude
150    XLAUNCH=5e-3        ! Value for top of cloud convective region
151
152!    PR = 9.2e6          ! Reference pressure    ! VENUS!!
153    PR = 5e5            ! Reference pressure    ! VENUS: cloud layer
154    TR = 300.           ! Reference Temperature ! VENUS: cloud layer
155    H0 = RD * TR / RG   ! Characteristic vertical scale height
156
157    BVSEC  = 1.E-5      ! Security to avoid negative BVF 
158    PSEC   = 1.E-8      ! Security to avoid division by 0 pressure
159    ZOISEC = 1.E-8      ! Security FOR 0 INTRINSIC FREQ
160
161    IF(DELTAT.LT.DTIME)THEN
162       PRINT *,'GWD RANDO: DELTAT LT DTIME!'
163       STOP
164    ENDIF
165
166
167    IF (NLEV < NW) THEN
168       PRINT *, 'YOU WILL HAVE PROBLEM WITH RANDOM NUMBERS'
169       PRINT *, 'FLOTT GWD STOP'
170       STOP 1
171    ENDIF
172
173    !  2. EVALUATION OF THE BACKGROUND FLOW AT SEMI-LEVELS
174    !-------------------------------------------------------------
175
176    !Online output
177    if (output) OPEN(11,file="impact-gwno.dat")
178
179    ! Pressure and Inv of pressure, Temperature / at 1/2 level
180    DO LL = 2, KLEV
181       PH(:, LL) = EXP((LOG(PP(:, LL)) + LOG(PP(:, LL - 1))) / 2.)
182    end DO
183
184    PH(:, KLEV + 1) = 0.
185    PH(:, 1) = 2. * PP(:, 1) - PH(:, 2)
186
187    ! Launching altitude
188
189    DO LL = 1, NLEV
190       IF (plevmoy(LL) / plevmoy(1) > XLAUNCH) LAUNCH = LL
191    ENDDO
192! test
193!    print*,"launch=",LAUNCH
194!    print*,"launch p,N2=",plevmoy(LAUNCH),pn2(nlon/2+1,LAUNCH)
195
196    ! Log pressure vert. coordinate
197    DO LL = 1, KLEV + 1
198       ZH(:, LL) = H0 * LOG(PR / (PH(:, LL) + PSEC))
199    end DO
200
201    if (output) then
202    ! altitude above surface
203       ZHbis(:,1) = 0.   
204       DO LL = 2, KLEV + 1
205          H0bis(:, LL-1) = RD * TT(:, LL-1) / RG
206          ZHbis(:, LL) = ZHbis(:, LL-1) &
207           + H0bis(:, LL-1)*(PH(:, LL-1)-PH(:,LL))/PP(:, LL-1)
208       end DO
209    endif
210
211    ! Winds and BV frequency
212    DO LL = 2, KLEV
213       UH(:, LL) = 0.5 * (UU(:, LL) + UU(:, LL - 1)) ! Zonal wind
214       VH(:, LL) = 0.5 * (VV(:, LL) + VV(:, LL - 1)) ! Meridional wind
215       ! BVSEC: BV Frequency
216! VENUS ATTENTION: CP VARIABLE PSTAB CALCULE EN AMONT DES PARAMETRISATIONS
217       BV(:, LL) = MAX(BVSEC,SQRT(pn2(:,LL)))
218    end DO
219    BV(:, 1) = BV(:, 2)
220    UH(:, 1) = 0.
221    VH(:, 1) = 0.
222    BV(:, KLEV + 1) = BV(:, KLEV)
223    UH(:, KLEV + 1) = UU(:, KLEV)
224    VH(:, KLEV + 1) = VV(:, KLEV)
225
226
227    ! 3. WAVES CHARACTERISTICS CHOSEN RANDOMLY
228    !-------------------------------------------
229
230    ! The mod function of here a weird arguments
231    ! are used to produce the waves characteristics
232    ! in a stochastic way
233
234!! A REVOIR:
235!! - utilisation de MOD ou bien de aleas ?
236!! - distribution gaussienne des CPHA ? (avec signe ZP qui est ajuste apres)
237
238    JW = 0
239    DO JP = 1, NP
240       DO JK = 1, NK
241          DO JO = 1, NO
242             JW = JW + 1
243             !  Angle
244             ZP(JW) = 2. * RPI * REAL(JP - 1) / REAL(NP)
245             DO II = 1, KLON
246                ! Horizontal wavenumber amplitude
247!                ZK(JW, II) = KMIN + (KMAX - KMIN) * MOD(TT(II, JW) * 100., 1.)
248                ZK(JW, II) = KMIN + (KMAX - KMIN) * ALEAS(0.)
249                ! Horizontal phase speed
250!                CPHA = CMIN + (CMAX - CMIN) * MOD(TT(II, JW)**2, 1.)
251                CPHA = CMIN + (CMAX - CMIN) * ALEAS(0.)
252       !Online output: linear
253                if (output) CPHA = CMIN + (CMAX - CMIN) * (JO-1)/(NO-1)
254                ! Intrinsic frequency
255                ZO(JW, II) = CPHA * ZK(JW, II)
256                ! Intrinsic frequency  is imposed
257                    ZO(JW, II) = ZO(JW, II)      &
258                  + ZK(JW, II) * COS(ZP(JW)) * UH(II, LAUNCH) &
259                  + ZK(JW, II) * SIN(ZP(JW)) * VH(II, LAUNCH)
260                ! Momentum flux at launch lev
261                ! RUW0(JW, II) = RUWMAX / REAL(NW) &
262                RUW0(JW, II) = RUWMAX &
263!                     * MOD(100. * (UU(II, JW)**2 + VV(II, JW)**2), 1.)
264                     * ALEAS(0.)
265       !Online output: fixed to max
266                if (output) RUW0(JW, II) = RUWMAX
267             ENDDO
268          end DO
269       end DO
270    end DO
271
272    ! 4. COMPUTE THE FLUXES
273    !--------------------------
274
275    !  4.1  Vertical velocity at launching altitude to ensure
276    !       the correct value to the imposed fluxes.
277    !
278    DO JW = 1, NW
279
280       ! Evaluate intrinsic frequency at launching altitude:
281       ZOP(JW, :) = ZO(JW, :) &
282            - ZK(JW, :) * COS(ZP(JW)) * UH(:, LAUNCH) &
283            - ZK(JW, :) * SIN(ZP(JW)) * VH(:, LAUNCH)
284       ! WW is directly a flux, here, not vertical velocity anymore
285       WWP(JW, :) = RUW0(JW,:)
286       RUWP(JW, :) = COS(ZP(JW)) * SIGN(1., ZOP(JW, :)) * RUW0(JW, :)
287       RVWP(JW, :) = SIN(ZP(JW)) * SIGN(1., ZOP(JW, :)) * RUW0(JW, :)
288
289    end DO
290
291    !  4.2 Initial flux at launching altitude
292
293    RUW(:, LAUNCH) = 0
294    RVW(:, LAUNCH) = 0
295    DO JW = 1, NW
296       RUW(:, LAUNCH) = RUW(:, LAUNCH) + RUWP(JW, :)
297       RVW(:, LAUNCH) = RVW(:, LAUNCH) + RVWP(JW, :)
298    end DO
299
300    !  4.3 Loop over altitudes, with passage from one level to the
301    !      next done by i) conserving the EP flux, ii) dissipating
302    !      a little, iii) testing critical levels, and vi) testing
303    !      the breaking.
304
305    !Online output
306    if (output) then
307        ieq=nlon/2+1
308        write(str2,'(i2)') NW+2
309        outform="("//str2//"(E12.4,1X))"
310        WRITE(11,outform) ZH(IEQ, 1) / 1000., ZHbis(IEQ, 1) / 1000., &
311               (ZO(JW, IEQ)/ZK(JW, IEQ)*COS(ZP(JW)), JW = 1, NW)
312    endif
313
314    DO LL = LAUNCH, KLEV - 1
315
316
317       !  W(KB)ARNING: ALL THE PHYSICS IS HERE (PASSAGE FROM ONE LEVEL
318       ! TO THE NEXT)
319       DO JW = 1, NW
320          ZOM(JW, :) = ZOP(JW, :)
321          WWM(JW, :) = WWP(JW, :)
322          ! Intrinsic Frequency
323          ZOP(JW, :) = ZO(JW, :) - ZK(JW, :) * COS(ZP(JW)) * UH(:, LL + 1) &
324               - ZK(JW, :) * SIN(ZP(JW)) * VH(:, LL + 1)
325
326          WWP(JW, :) = MIN( &
327       ! No breaking (Eq.6)
328               WWM(JW, :) &
329       ! Dissipation (Eq. 8):
330               * EXP(- RDISS * PR / (PH(:, LL + 1) + PH(:, LL)) &
331               * ((BV(:, LL + 1) + BV(:, LL)) / 2.)**3 &
332               / MAX(ABS(ZOP(JW, :) + ZOM(JW, :)) / 2., ZOISEC)**4 &
333               * ZK(JW, :)**3 * (ZH(:, LL + 1) - ZH(:, LL))), &
334       ! Critical levels (forced to zero if intrinsic frequency changes sign)
335               MAX(0., SIGN(1., ZOP(JW, :) * ZOM(JW, :))) &
336       ! Saturation (Eq. 12)
337               * ABS(ZOP(JW, :))**3 /BV(:, LL+1) &
338               * EXP(-ZH(:, LL + 1)/H0) * SAT**2*KMIN**2/ZK(JW, :)**4) 
339       end DO
340
341       ! END OF W(KB)ARNING
342       ! Evaluate EP-flux from Eq. 7 and
343       ! Give the right orientation to the stress
344
345       DO JW = 1, NW
346          RUWP(JW, :) = SIGN(1.,ZOP(JW, :))*COS(ZP(JW))*WWP(JW, :)
347          RVWP(JW, :) = SIGN(1.,ZOP(JW, :))*SIN(ZP(JW))*WWP(JW, :)
348       end DO
349       !
350       RUW(:, LL + 1) = 0.
351       RVW(:, LL + 1) = 0.
352
353       DO JW = 1, NW
354          RUW(:, LL + 1) = RUW(:, LL + 1) + RUWP(JW, :)
355          RVW(:, LL + 1) = RVW(:, LL + 1) + RVWP(JW, :)
356       end DO
357       !Online output
358       if (output) then
359         do JW=1,NW
360            if(RUWP(JW, IEQ).gt.0.) then
361              RUWP(JW, IEQ) = max(RUWP(JW, IEQ), 1.e-99)
362            else
363              RUWP(JW, IEQ) = min(RUWP(JW, IEQ), -1.e-99)
364            endif
365         enddo
366                   WRITE(11,outform) ZH(IEQ, LL+1) / 1000., &
367                                  ZHbis(IEQ, LL+1) / 1000., &
368                                  (RUWP(JW, IEQ), JW = 1, NW)
369       endif
370
371    end DO
372
373    ! 5 CALCUL DES TENDANCES:
374    !------------------------
375
376    ! 5.1 Rectification des flux au sommet et dans les basses couches:
377! MODIF SL
378 
379! Attention, ici c'est le total sur toutes les ondes...
380
381    RUW(:, KLEV + 1) = 0.
382    RVW(:, KLEV + 1) = 0.
383
384    ! Here, big change compared to FLott version:
385    ! We compensate (RUW(:, LAUNCH), ie total emitted upward flux
386    !  over the layers max(1,LAUNCH-3) to LAUNCH-1
387    DO LL = 1, max(1,LAUNCH-3)
388      RUW(:, LL) = 0.
389      RVW(:, LL) = 0.
390    end DO
391    DO LL = max(2,LAUNCH-2), LAUNCH-1
392       RUW(:, LL) = RUW(:, LL - 1) + RUW(:, LAUNCH) * &
393            (PH(:,LL)-PH(:,LL-1)) / (PH(:,LAUNCH)-PH(:,max(1,LAUNCH-3)))
394       RVW(:, LL) = RVW(:, LL - 1) + RVW(:, LAUNCH) * &
395            (PH(:,LL)-PH(:,LL-1)) / (PH(:,LAUNCH)-PH(:,max(1,LAUNCH-3)))
396    end DO
397    ! This way, the total flux from GW is zero, but there is a net transport
398    ! (upward) that should be compensated by circulation
399    ! and induce additional friction at the surface
400
401    !Online output
402    if (output) then
403       DO LL = 1, KLEV - 1
404           WRITE(11,*) ZHbis(IEQ, LL)/1000.,RUW(IEQ,LL)
405       end DO
406       CLOSE(11)
407       stop
408    endif
409
410    ! AR-1 RECURSIVE FORMULA (13) IN VERSION 4
411    DO LL = 1, KLEV
412       d_u(:, LL) = RG * (RUW(:, LL + 1) - RUW(:, LL)) &
413            / (PH(:, LL + 1) - PH(:, LL)) * DTIME
414       d_v(:, LL) = RG * (RVW(:, LL + 1) - RVW(:, LL)) &
415            / (PH(:, LL + 1) - PH(:, LL)) * DTIME
416    ENDDO
417        d_t = 0.
418    ! ON CONSERVE LA MEMOIRE un certain temps AVEC UN SAVE
419        d_u = DTIME/DELTAT/REAL(NW) * d_u + (1.-DTIME/DELTAT) * d_u_sav
420        d_v = DTIME/DELTAT/REAL(NW) * d_v + (1.-DTIME/DELTAT) * d_v_sav
421        d_u_sav = d_u
422        d_v_sav = d_v
423
424    ! Cosmetic: evaluation of the cumulated stress
425
426    ZUSTR(:) = 0.
427    ZVSTR(:) = 0.
428    DO LL = 1, KLEV
429       ZUSTR(:) = ZUSTR(:) + D_U(:, LL) / RG * (PH(:, LL + 1) - PH(:, LL))
430       ZVSTR(:) = ZVSTR(:) + D_V(:, LL) / RG * (PH(:, LL + 1) - PH(:, LL))
431    ENDDO
432
433  END SUBROUTINE FLOTT_GWD_RAN
434
435!===================================================================
436!===================================================================
437!===================================================================
438!===================================================================
439
440      FUNCTION ALEAS (R)
441!***BEGIN PROLOGUE  ALEAS
442!***PURPOSE  Generate a uniformly distributed random number.
443!***LIBRARY   SLATEC (FNLIB)
444!***CATEGORY  L6A21
445!***TYPE      SINGLE PRECISION (ALEAS-S)
446!***KEYWORDS  FNLIB, ALEAS NUMBER, SPECIAL FUNCTIONS, UNIFORM
447!***AUTHOR  Fullerton, W., (LANL)
448!***DESCRIPTION
449!
450!      This pseudo-random number generator is portable among a wide
451! variety of computers.  RAND(R) undoubtedly is not as good as many
452! readily available installation dependent versions, and so this
453! routine is not recommended for widespread usage.  Its redeeming
454! feature is that the exact same random numbers (to within final round-
455! off error) can be generated from machine to machine.  Thus, programs
456! that make use of random numbers can be easily transported to and
457! checked in a new environment.
458!
459!      The random numbers are generated by the linear congruential
460! method described, e.g., by Knuth in Seminumerical Methods (p.9),
461! Addison-Wesley, 1969.  Given the I-th number of a pseudo-random
462! sequence, the I+1 -st number is generated from
463!             X(I+1) = (A*X(I) + C) MOD M,
464! where here M = 2**22 = 4194304, C = 1731 and several suitable values
465! of the multiplier A are discussed below.  Both the multiplier A and
466! random number X are represented in double precision as two 11-bit
467! words.  The constants are chosen so that the period is the maximum
468! possible, 4194304.
469!
470!      In order that the same numbers be generated from machine to
471! machine, it is necessary that 23-bit integers be reducible modulo
472! 2**11 exactly, that 23-bit integers be added exactly, and that 11-bit
473! integers be multiplied exactly.  Furthermore, if the restart option
474! is used (where R is between 0 and 1), then the product R*2**22 =
475! R*4194304 must be correct to the nearest integer.
476!
477!      The first four random numbers should be .0004127026,
478! .6750836372, .1614754200, and .9086198807.  The tenth random number
479! is .5527787209, and the hundredth is .3600893021 .  The thousandth
480! number should be .2176990509 .
481!
482!      In order to generate several effectively independent sequences
483! with the same generator, it is necessary to know the random number
484! for several widely spaced calls.  The I-th random number times 2**22,
485! where I=K*P/8 and P is the period of the sequence (P = 2**22), is
486! still of the form L*P/8.  In particular we find the I-th random
487! number multiplied by 2**22 is given by
488! I   =  0  1*P/8  2*P/8  3*P/8  4*P/8  5*P/8  6*P/8  7*P/8  8*P/8
489! RAND=  0  5*P/8  2*P/8  7*P/8  4*P/8  1*P/8  6*P/8  3*P/8  0
490! Thus the 4*P/8 = 2097152 random number is 2097152/2**22.
491!
492!      Several multipliers have been subjected to the spectral test
493! (see Knuth, p. 82).  Four suitable multipliers roughly in order of
494! goodness according to the spectral test are
495!    3146757 = 1536*2048 + 1029 = 2**21 + 2**20 + 2**10 + 5
496!    2098181 = 1024*2048 + 1029 = 2**21 + 2**10 + 5
497!    3146245 = 1536*2048 +  517 = 2**21 + 2**20 + 2**9 + 5
498!    2776669 = 1355*2048 + 1629 = 5**9 + 7**7 + 1
499!
500!      In the table below LOG10(NU(I)) gives roughly the number of
501! random decimal digits in the random numbers considered I at a time.
502! C is the primary measure of goodness.  In both cases bigger is better.
503!
504!                   LOG10 NU(I)              C(I)
505!       A       I=2  I=3  I=4  I=5    I=2  I=3  I=4  I=5
506!
507!    3146757    3.3  2.0  1.6  1.3    3.1  1.3  4.6  2.6
508!    2098181    3.3  2.0  1.6  1.2    3.2  1.3  4.6  1.7
509!    3146245    3.3  2.2  1.5  1.1    3.2  4.2  1.1  0.4
510!    2776669    3.3  2.1  1.6  1.3    2.5  2.0  1.9  2.6
511!   Best
512!    Possible   3.3  2.3  1.7  1.4    3.6  5.9  9.7  14.9
513!
514!             Input Argument --
515! R      If R=0., the next random number of the sequence is generated.
516!        If R .LT. 0., the last generated number will be returned for
517!          possible use in a restart procedure.
518!        If R .GT. 0., the sequence of random numbers will start with
519!          the seed R mod 1.  This seed is also returned as the value of
520!          RAND provided the arithmetic is done exactly.
521!
522!             Output Value --
523! RAND   a pseudo-random number between 0. and 1.
524!
525!***REFERENCES  (NONE)
526!***ROUTINES CALLED  (NONE)
527!***REVISION HISTORY  (YYMMDD)
528!   770401  DATE WRITTEN
529!   890531  Changed all specific intrinsics to generic.  (WRB)
530!   890531  REVISION DATE from Version 3.2
531!   891214  Prologue converted to Version 4.0 format.  (BAB)
532!***END PROLOGUE  RAND
533      SAVE IA1, IA0, IA1MA0, IC, IX1, IX0
534      DATA IA1, IA0, IA1MA0 /1536, 1029, 507/
535      DATA IC /1731/
536      DATA IX1, IX0 /0, 0/
537!***FIRST EXECUTABLE STATEMENT  RAND
538!
539!           A*X = 2**22*IA1*IX1 + 2**11*(IA1*IX1 + (IA1-IA0)*(IX0-IX1)
540!                   + IA0*IX0) + IA0*IX0
541!
542      IF (R.EQ.0.) THEN
543       IY0 = IA0*IX0
544       IY1 = IA1*IX1 + IA1MA0*(IX0-IX1) + IY0
545       IY0 = IY0 + IC
546       IX0 = MOD (IY0, 2048)
547       IY1 = IY1 + (IY0-IX0)/2048
548       IX1 = MOD (IY1, 2048)
549      ENDIF
550
551      IF (R.GT.0.) THEN
552       IX1 = MOD(R,1.)*4194304. + 0.5
553       IX0 = MOD (IX1, 2048)
554       IX1 = (IX1-IX0)/2048
555      ENDIF
556
557      ALEAS = IX1*2048 + IX0
558      ALEAS = ALEAS / 4194304.
559      RETURN
560
561      END
562
563
Note: See TracBrowser for help on using the repository browser.