source: LMDZ6/branches/PBLSURF_GPUPORT/libf/phylmd/flott_gwd_rando_m.f90 @ 5880

Last change on this file since 5880 was 5767, checked in by rkazeroni, 5 months ago

For GPU porting of gravity waves params:

  • Add "horizontal" comment to specify possible names of horizontal variables
  • Remove "fake_call" utility which is no longer needed by GPU-Morphosis (bug fixed in the tool)
  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory.
  • Property svn:keywords set to Id
File size: 15.5 KB
Line 
1!
2! $Id: flott_gwd_rando_m.f90 5767 2025-07-10 10:04:51Z ymeurdesoif $
3!
4!$gpum horizontal klon
5module FLOTT_GWD_rando_m
6
7  USE clesphys_mod_h
8      implicit none
9    INTEGER, PARAMETER:: NK = 2, NP = 2, NO = 2, NW = NK * NP * NO
10    INTEGER, PARAMETER:: NA = 5  !number of realizations to get the phase speed
11    LOGICAL, SAVE :: gwd_reproductibilite_mpiomp=.true.
12    LOGICAL, SAVE :: firstcall = .TRUE.
13   !$OMP THREADPRIVATE(firstcall,gwd_reproductibilite_mpiomp)
14
15contains
16
17  SUBROUTINE FLOTT_GWD_rando_first
18  use dimphy, only: klev
19  USE ioipsl_getin_p_mod, ONLY : getin_p
20  IMPLICIT NONE
21    CHARACTER (LEN=20),PARAMETER :: modname='acama_gwd_rando_m'
22    CHARACTER (LEN=80) :: abort_message
23 
24    IF (firstcall) THEN
25    ! Cle introduite pour resoudre un probleme de non reproductibilite
26    ! Le but est de pouvoir tester de revenir a la version precedenete
27    ! A eliminer rapidement
28    CALL getin_p('gwd_reproductibilite_mpiomp',gwd_reproductibilite_mpiomp)
29    IF (NW+3*NA>=KLEV) THEN
30       abort_message = 'NW+3*NA>=KLEV Probleme pour generation des ondes'
31       CALL abort_physic (modname,abort_message,1)
32    ENDIF
33    firstcall=.false.
34  ENDIF
35  END SUBROUTINE FLOTT_GWD_rando_first
36
37
38  SUBROUTINE FLOTT_GWD_rando(DTIME, PP, tt, uu, vv, prec, zustr, zvstr, d_u, &
39       d_v,east_gwstress,west_gwstress)
40
41    ! Parametrization of the momentum flux deposition due to a discrete
42    ! number of gravity waves.
43    ! Author: F. Lott
44    ! July, 12th, 2012
45    ! Gaussian distribution of the source, source is precipitation
46    ! Reference: Lott (JGR, vol 118, page 8897, 2013)
47
48    !ONLINE:
49      USE yomcst_mod_h
50use dimphy, only: klon, klev
51      use assert_m, only: assert
52      USE ioipsl_getin_p_mod, ONLY : getin_p
53      USE vertical_layers_mod, ONLY : presnivs
54      USE yoegwd_mod_h
55
56      CHARACTER (LEN=20),PARAMETER :: modname='flott_gwd_rando'
57      CHARACTER (LEN=80) :: abort_message
58
59    ! OFFLINE:
60    ! include "dimensions_mod.f90"
61    ! include "dimphy.h"
62    ! END OF DIFFERENCE ONLINE-OFFLINE
63
64    ! 0. DECLARATIONS:
65
66    ! 0.1 INPUTS
67    REAL, intent(in)::DTIME ! Time step of the Physics
68    REAL, intent(in):: pp(KLON, KLEV) ! (KLON, KLEV) Pressure at full levels
69    REAL, intent(in):: prec(KLON) ! (klon) Precipitation (kg/m^2/s)
70    REAL, intent(in):: TT(KLON, KLEV) ! (KLON, KLEV) Temp at full levels
71    REAL, intent(in):: UU(KLON, KLEV) ! (KLON, KLEV) Zonal wind at full levels
72    REAL, intent(in):: VV(KLON, KLEV) ! (KLON, KLEV) Merid wind at full levels
73
74    ! 0.2 OUTPUTS
75    REAL, intent(out):: zustr(KLON), zvstr(KLON) ! (KLON) Surface Stresses
76
77    REAL, intent(inout):: d_u(KLON, KLEV), d_v(KLON, KLEV)
78    REAL, intent(inout):: east_gwstress(KLON, KLEV) !  Profile of eastward stress
79    REAL, intent(inout):: west_gwstress(KLON, KLEV) !  Profile of westward stress
80
81    ! (KLON, KLEV) tendencies on winds
82
83    ! O.3 INTERNAL ARRAYS
84    REAL BVLOW(klon)
85    REAL DZ   !  Characteristic depth of the Source
86
87    INTEGER II, JJ, LL
88
89    ! 0.3.0 TIME SCALE OF THE LIFE CYCLE OF THE WAVES PARAMETERIZED
90
91    REAL DELTAT
92
93    ! 0.3.1 GRAVITY-WAVES SPECIFICATIONS
94
95    INTEGER JK, JP, JO, JW
96    REAL KMIN, KMAX ! Min and Max horizontal wavenumbers
97    REAL CMAX ! standard deviation of the phase speed distribution
98    REAL RUWMAX,SAT  ! ONLINE SPECIFIED IN run.def
99    REAL CPHA ! absolute PHASE VELOCITY frequency
100    REAL ZK(KLON, NW) ! Horizontal wavenumber amplitude
101    REAL ZP(KLON, NW) ! Horizontal wavenumber angle
102    REAL ZO(KLON, NW) ! Absolute frequency !
103
104    ! Waves Intr. freq. at the 1/2 lev surrounding the full level
105    REAL ZOM(KLON, NW), ZOP(KLON, NW)
106
107    ! Wave EP-fluxes at the 2 semi levels surrounding the full level
108    REAL WWM(KLON, NW), WWP(KLON, NW)
109
110    REAL RUW0(KLON, NW) ! Fluxes at launching level
111
112    REAL RUWP(KLON, NW), RVWP(KLON, NW)
113    ! Fluxes X and Y for each waves at 1/2 Levels
114
115    INTEGER LAUNCH, LTROP ! Launching altitude and tropo altitude
116
117    REAL XLAUNCH ! Controle the launching altitude
118    REAL XTROP ! SORT of Tropopause altitude
119    REAL RUW(KLON, KLEV + 1) ! Flux x at semi levels
120    REAL RVW(KLON, KLEV + 1) ! Flux y at semi levels
121
122    REAL PRMAX ! Maximum value of PREC, and for which our linear formula
123    ! for GWs parameterisation apply
124
125    ! 0.3.2 PARAMETERS OF WAVES DISSIPATIONS
126
127    REAL RDISS, ZOISEC ! COEFF DE DISSIPATION, SECURITY FOR INTRINSIC FREQ
128
129    ! 0.3.3 BACKGROUND FLOW AT 1/2 LEVELS AND VERTICAL COORDINATE
130
131    REAL H0 ! Characteristic Height of the atmosphere
132    REAL PR, TR ! Reference Pressure and Temperature
133
134    REAL ZH(KLON, KLEV + 1) ! Log-pressure altitude
135
136    REAL UH(KLON, KLEV + 1), VH(KLON, KLEV + 1) ! Winds at 1/2 levels
137    REAL PH(KLON, KLEV + 1) ! Pressure at 1/2 levels
138    REAL PSEC ! Security to avoid division by 0 pressure
139    REAL BV(KLON, KLEV + 1) ! Brunt Vaisala freq. (BVF) at 1/2 levels
140    REAL BVSEC ! Security to avoid negative BVF
141    REAL RAN_NUM_1,RAN_NUM_2,RAN_NUM_3
142
143    REAL, DIMENSION(klev+1) ::HREF
144
145
146    !-----------------------------------------------------------------
147
148    ! 1. INITIALISATIONS
149
150    ! 1.1 Basic parameter
151
152    ! Are provided from elsewhere (latent heat of vaporization, dry
153    ! gaz constant for air, gravity constant, heat capacity of dry air
154    ! at constant pressure, earth rotation rate, pi).
155
156    ! 1.2 Tuning parameters of V14
157
158   
159    RDISS = 0.5 ! Diffusion parameter
160    ! ONLINE
161      RUWMAX=GWD_RANDO_RUWMAX
162      SAT=gwd_rando_sat
163    !END ONLINE
164    ! OFFLINE
165    ! RUWMAX= 1.75    ! Launched flux
166    ! SAT=0.25     ! Saturation parameter
167    ! END OFFLINE
168
169    PRMAX = 20. / 24. /3600.
170    ! maximum of rain for which our theory applies (in kg/m^2/s)
171
172 ! Characteristic depth of the source
173    DZ = 1000.
174    XLAUNCH=0.5 ! Parameter that control launching altitude
175    XTROP=0.2 ! Parameter that control tropopause altitude
176    DELTAT=24.*3600. ! Time scale of the waves (first introduced in 9b)
177    !  OFFLINE
178    !  DELTAT=DTIME
179    !  END OFFLINE
180
181    KMIN = 2.E-5
182    ! minimum horizontal wavenumber (inverse of the subgrid scale resolution)
183
184    KMAX = 1.E-3 ! Max horizontal wavenumber
185    CMAX = 30. ! Max phase speed velocity
186
187    TR = 240. ! Reference Temperature
188    PR = 101300. ! Reference pressure
189    H0 = RD * TR / RG ! Characteristic vertical scale height
190
191    BVSEC = 5.E-3 ! Security to avoid negative BVF
192    PSEC = 1.E-6 ! Security to avoid division by 0 pressure
193    ZOISEC = 1.E-6 ! Security FOR 0 INTRINSIC FREQ
194
195IF (1==0) THEN
196    !ONLINE
197        call assert(klon == (/size(pp, 1), size(tt, 1), size(uu, 1), &
198         size(vv, 1), size(zustr), size(zvstr), size(d_u, 1), &
199         size(d_v, 1), &
200         size(east_gwstress, 1), size(west_gwstress, 1) /), &
201         "FLOTT_GWD_RANDO klon")
202     call assert(klev == (/size(pp, 2), size(tt, 2), size(uu, 2), &
203          size(vv, 2), size(d_u, 2), size(d_v, 2), &
204          size(east_gwstress,2), size(west_gwstress,2) /), &
205          "FLOTT_GWD_RANDO klev")
206    !END ONLINE
207ENDIF
208   
209    IF(DELTAT < DTIME)THEN
210       abort_message='flott_gwd_rando: deltat < dtime!'
211       CALL abort_physic(modname,abort_message,1)
212    ENDIF
213
214    IF (KLEV < NW) THEN
215       abort_message='flott_gwd_rando: you will have problem with random numbers'
216       CALL abort_physic(modname,abort_message,1)
217    ENDIF
218   
219    ! 2. EVALUATION OF THE BACKGROUND FLOW AT SEMI-LEVELS
220
221    ! Pressure and Inv of pressure
222    DO LL = 2, KLEV
223       PH(:, LL) = EXP((LOG(PP(:, LL)) + LOG(PP(:, LL - 1))) / 2.)
224    end DO
225    PH(:, KLEV + 1) = 0.
226    PH(:, 1) = 2. * PP(:, 1) - PH(:, 2)
227
228    ! Launching altitude
229
230    !Pour revenir a la version non reproductible en changeant le nombre de process
231    IF (gwd_reproductibilite_mpiomp) THEN
232       ! Reprend la formule qui calcule PH en fonction de PP=play
233       DO LL = 2, KLEV
234          HREF(LL) = EXP((LOG(presnivs(LL)) + LOG(presnivs(LL - 1))) / 2.)
235       end DO
236       HREF(KLEV + 1) = 0.
237       HREF(1) = 2. * presnivs(1) - HREF(2)
238    ELSE
239       HREF(1:KLEV)=PH(KLON/2,1:KLEV)
240    ENDIF
241
242    LAUNCH=0
243    LTROP =0
244    DO LL = 1, KLEV
245       IF (HREF(LL) / HREF(1) > XLAUNCH) LAUNCH = LL
246    ENDDO
247    DO LL = 1, KLEV
248       IF (HREF(LL) / HREF(1) > XTROP) LTROP = LL
249    ENDDO
250    !LAUNCH=22 ; LTROP=33
251!   print*,'LAUNCH=',LAUNCH,'LTROP=',LTROP
252
253    ! Log pressure vert. coordinate
254    DO LL = 1, KLEV + 1
255       ZH(:, LL) = H0 * LOG(PR / (PH(:, LL) + PSEC))
256    end DO
257
258    ! BV frequency
259    DO LL = 2, KLEV
260       ! BVSEC: BV Frequency (UH USED IS AS A TEMPORARY ARRAY DOWN TO WINDS)
261       UH(:, LL) = 0.5 * (TT(:, LL) + TT(:, LL - 1)) &
262            * RD**2 / RCPD / H0**2 + (TT(:, LL) &
263            - TT(:, LL - 1)) / (ZH(:, LL) - ZH(:, LL - 1)) * RD / H0
264    end DO
265    BVLOW(:) = 0.5 * (TT(:, LTROP )+ TT(:, LAUNCH)) &
266         * RD**2 / RCPD / H0**2 + (TT(:, LTROP ) &
267         - TT(:, LAUNCH))/(ZH(:, LTROP )- ZH(:, LAUNCH)) * RD / H0
268
269    UH(:, 1) = UH(:, 2)
270    UH(:, KLEV + 1) = UH(:, KLEV)
271    BV(:, 1) = UH(:, 2)
272    BV(:, KLEV + 1) = UH(:, KLEV)
273    ! SMOOTHING THE BV HELPS
274    DO LL = 2, KLEV
275       BV(:, LL)=(UH(:, LL+1)+2.*UH(:, LL)+UH(:, LL-1))/4.
276    end DO
277
278    BV=MAX(SQRT(MAX(BV, 0.)), BVSEC)
279    BVLOW=MAX(SQRT(MAX(BVLOW, 0.)), BVSEC)
280
281
282    ! WINDS
283    DO LL = 2, KLEV
284       UH(:, LL) = 0.5 * (UU(:, LL) + UU(:, LL - 1)) ! Zonal wind
285       VH(:, LL) = 0.5 * (VV(:, LL) + VV(:, LL - 1)) ! Meridional wind
286    end DO
287    UH(:, 1) = 0.
288    VH(:, 1) = 0.
289    UH(:, KLEV + 1) = UU(:, KLEV)
290    VH(:, KLEV + 1) = VV(:, KLEV)
291
292    ! 3 WAVES CHARACTERISTICS CHOSEN RANDOMLY AT THE LAUNCH ALTITUDE
293
294    ! The mod functions of weird arguments are used to produce the
295    ! waves characteristics in an almost stochastic way
296
297    DO JW = 1, NW
298             ! Angle
299             DO II = 1, KLON
300                ! Angle (0 or PI so far)
301                RAN_NUM_1=MOD(TT(II, JW) * 10., 1.)
302                RAN_NUM_2= MOD(TT(II, JW) * 100., 1.)
303                ZP(II, JW) = (SIGN(1., 0.5 - RAN_NUM_1) + 1.) &
304                     * RPI / 2.
305                ! Horizontal wavenumber amplitude
306                ZK(II, JW) = KMIN + (KMAX - KMIN) *RAN_NUM_2
307                ! Horizontal phase speed
308                CPHA = 0.
309                DO JJ = 1, NA
310                    RAN_NUM_3=MOD(TT(II, JW+3*JJ)**2, 1.)
311                    CPHA = CPHA + &
312                    CMAX*2.*(RAN_NUM_3 -0.5)*SQRT(3.)/SQRT(NA*1.)
313                END DO
314                IF (CPHA.LT.0.)  THEN
315                   CPHA = -1.*CPHA
316                   ZP(II, JW) = ZP(II, JW) + RPI
317                ENDIF
318                ! Absolute frequency is imposed
319                ZO(II, JW) = CPHA * ZK(II, JW)
320                ! Intrinsic frequency is imposed
321                ZO(II, JW) = ZO(II, JW) &
322                     + ZK(II, JW) * COS(ZP(II, JW)) * UH(II, LAUNCH) &
323                     + ZK(II, JW) * SIN(ZP(II, JW)) * VH(II, LAUNCH)
324                ! Momentum flux at launch lev
325                RUW0(II, JW) = RUWMAX
326             ENDDO
327    ENDDO
328
329    ! 4. COMPUTE THE FLUXES
330
331    ! 4.1 Vertical velocity at launching altitude to ensure
332    ! the correct value to the imposed fluxes.
333
334    DO JW = 1, NW
335
336       ! Evaluate intrinsic frequency at launching altitude:
337       ZOP(:,JW) = ZO(:, JW) &
338            - ZK(:, JW) * COS(ZP(:, JW)) * UH(:, LAUNCH) &
339            - ZK(:, JW) * SIN(ZP(:, JW)) * VH(:, LAUNCH)
340
341       ! VERSION WITH CONVECTIVE SOURCE
342
343       ! Vertical velocity at launch level, value to ensure the
344       ! imposed factor related to the convective forcing:
345       ! precipitations.
346
347       ! tanh limitation to values above prmax:
348       WWP(:, JW) = RUW0(:, JW) &
349            * (RD / RCPD / H0 * RLVTT * PRMAX * TANH(PREC(:) / PRMAX))**2
350
351       ! Factor related to the characteristics of the waves:
352       WWP(:, JW) = WWP(:, JW) * ZK(:, JW)**3 / KMIN / BVLOW(:)  &
353            / MAX(ABS(ZOP(:, JW)), ZOISEC)**3
354
355       ! Moderation by the depth of the source (dz here):
356       WWP(:, JW) = WWP(:, JW) &
357            * EXP(- BVLOW(:)**2 / MAX(ABS(ZOP(:, JW)), ZOISEC)**2 * ZK(:, JW)**2 &
358            * DZ**2)
359
360       ! Put the stress in the right direction:
361       RUWP(:, JW) = ZOP(:, JW) / MAX(ABS(ZOP(:, JW)), ZOISEC)**2 &
362            * BV(:, LAUNCH) * COS(ZP(:, JW)) * WWP(:, JW)**2
363       RVWP(:, JW) = ZOP(:, JW) / MAX(ABS(ZOP(:, JW)), ZOISEC)**2 &
364            * BV(:, LAUNCH) * SIN(ZP(:, JW)) * WWP(:, JW)**2
365    end DO
366
367
368    ! 4.2 Uniform values below the launching altitude
369
370    DO LL = 1, LAUNCH
371       RUW(:, LL) = 0
372       RVW(:, LL) = 0
373       DO JW = 1, NW
374          RUW(:, LL) = RUW(:, LL) + RUWP(:, JW)
375          RVW(:, LL) = RVW(:, LL) + RVWP(:, JW)
376       end DO
377    end DO
378
379    ! 4.3 Loop over altitudes, with passage from one level to the next
380    ! done by i) conserving the EP flux, ii) dissipating a little,
381    ! iii) testing critical levels, and vi) testing the breaking.
382
383    DO LL = LAUNCH, KLEV - 1
384       ! Warning: all the physics is here (passage from one level
385       ! to the next)
386       DO JW = 1, NW
387          ZOM(:, JW) = ZOP(:,JW)
388          WWM(:, JW) = WWP(:, JW)
389          ! Intrinsic Frequency
390          ZOP(:, JW) = ZO(:, JW) - ZK(:, JW) * COS(ZP(:, JW)) * UH(:, LL + 1) &
391               - ZK(:, JW) * SIN(ZP(:, JW)) * VH(:, LL + 1)
392
393          ! No breaking (Eq.6)
394          ! Dissipation (Eq. 8)
395          WWP(:, JW) = WWM(:, JW) * EXP(- 4. * RDISS * PR / (PH(:, LL + 1) &
396               + PH(:, LL)) * ((BV(:, LL + 1) + BV(:, LL)) / 2.)**3 &
397               / MAX(ABS(ZOP(:, JW) + ZOM(:, JW)) / 2., ZOISEC)**4 &
398               * ZK(:, JW)**3 * (ZH(:, LL + 1) - ZH(:, LL)))
399
400          ! Critical levels (forced to zero if intrinsic frequency changes sign)
401          ! Saturation (Eq. 12)
402          WWP(:, JW) = min(WWP(:, JW), MAX(0., &
403               SIGN(1., ZOP(:, JW) * ZOM(:, JW))) * ABS(ZOP(:, JW))**3 &
404               / BV(:, LL + 1) * EXP(- ZH(:, LL + 1) / H0) * KMIN**2  &
405               * SAT**2 / ZK(:, JW)**4)
406       end DO
407
408       ! Evaluate EP-flux from Eq. 7 and give the right orientation to
409       ! the stress
410
411       DO JW = 1, NW
412          RUWP(:, JW) = SIGN(1., ZOP(:, JW))*COS(ZP(:, JW)) * WWP(:, JW)
413          RVWP(:, JW) = SIGN(1., ZOP(:, JW))*SIN(ZP(:, JW)) * WWP(:, JW)
414       end DO
415
416       RUW(:, LL + 1) = 0.
417       RVW(:, LL + 1) = 0.
418
419       DO JW = 1, NW
420          RUW(:, LL + 1) = RUW(:, LL + 1) + RUWP(:, JW)
421          RVW(:, LL + 1) = RVW(:, LL + 1) + RVWP(:, JW)
422          EAST_GWSTRESS(:, LL)=EAST_GWSTRESS(:, LL)+MAX(0.,RUWP(:, JW))/REAL(NW)
423          WEST_GWSTRESS(:, LL)=WEST_GWSTRESS(:, LL)+MIN(0.,RUWP(:, JW))/REAL(NW)
424       end DO
425    end DO
426! OFFLINE ONLY
427!   PRINT *,'SAT PROFILE:'
428!   DO LL=1,KLEV
429!   PRINT *,ZH(KLON/2,LL)/1000.,SAT*(2.+TANH(ZH(KLON/2,LL)/H0-8.))
430!   ENDDO
431
432    ! 5 CALCUL DES TENDANCES:
433
434    ! 5.1 Rectification des flux au sommet et dans les basses couches
435
436    RUW(:, KLEV + 1) = 0.
437    RVW(:, KLEV + 1) = 0.
438    RUW(:, 1) = RUW(:, LAUNCH)
439    RVW(:, 1) = RVW(:, LAUNCH)
440    DO LL = 1, LAUNCH
441       RUW(:, LL) = RUW(:, LAUNCH+1)
442       RVW(:, LL) = RVW(:, LAUNCH+1)
443       EAST_GWSTRESS(:, LL)  = EAST_GWSTRESS(:, LAUNCH)
444       WEST_GWSTRESS(:, LL)  = WEST_GWSTRESS(:, LAUNCH)
445    end DO
446
447    ! AR-1 RECURSIVE FORMULA (13) IN VERSION 4
448    DO LL = 1, KLEV
449       D_U(:, LL) = (1.-DTIME/DELTAT) * D_U(:, LL) + DTIME/DELTAT/REAL(NW) * &
450            RG * (RUW(:, LL + 1) - RUW(:, LL)) &
451            / (PH(:, LL + 1) - PH(:, LL)) * DTIME
452       ! NO AR-1 FOR MERIDIONAL TENDENCIES
453       D_V(:, LL) =                                            1./REAL(NW) * &
454            RG * (RVW(:, LL + 1) - RVW(:, LL)) &
455            / (PH(:, LL + 1) - PH(:, LL)) * DTIME
456    ENDDO
457
458    ! Cosmetic: evaluation of the cumulated stress
459    ZUSTR = 0.
460    ZVSTR = 0.
461    DO LL = 1, KLEV
462       ZUSTR = ZUSTR + D_U(:, LL) / RG * (PH(:, LL + 1) - PH(:, LL))/DTIME
463       ZVSTR = ZVSTR + D_V(:, LL) / RG * (PH(:, LL + 1) - PH(:, LL))/DTIME
464    ENDDO
465
466
467  END SUBROUTINE FLOTT_GWD_RANDO
468
469end module FLOTT_GWD_rando_m
Note: See TracBrowser for help on using the repository browser.