source: LMDZ6/trunk/libf/phylmd/lmdz_ratqs_main.f90 @ 5821

Last change on this file since 5821 was 5820, checked in by rkazeroni, 2 months ago

For GPU porting of ratqs_main routine:

  • Add "horizontal" comment to specify possible names of horizontal variables
  • Move computation of maxval into an initialization routine as this cannot be GPU ported
  • Fix wrong dimensionality of wake_s in the argument declaration
  • Change problematic variable initializations at declaration (SAVE attribute implied) by either adding a PARAMETER attribute or moving the initialization
  • 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
File size: 10.9 KB
RevLine 
[5820]1!$gpum horizontal klon ngrid
[4613]2MODULE lmdz_ratqs_main
[5820]3  PRIVATE
[4613]4
[5820]5  LOGICAL, SAVE :: first=.TRUE.  ! fisrt call to ratqs_main
6  !$OMP THREADPRIVATE(first)
7
8  REAL, SAVE :: resolmax
9
10  REAL, SAVE, ALLOCATABLE :: resol(:)
11  !$OMP THREADPRIVATE(resol)
12
13  PUBLIC ratqs_main_first, ratqs_main
14
[4613]15CONTAINS
16
[5820]17SUBROUTINE ratqs_main_first(klon, cell_area)
18
19  IMPLICIT NONE
20  INTEGER, INTENT(in) :: klon
21  REAL, DIMENSION(klon), INTENT(in) :: cell_area
22  INTEGER :: i
23
24  IF (first) THEN
25     ALLOCATE(resol(klon))
26     resolmax=sqrt(maxval(cell_area))
27     DO i=1,klon
28        resol(i) = sqrt(cell_area(i))
29     END DO
30     first = .FALSE.
31  END IF
32
33END SUBROUTINE ratqs_main_first
34
[4613]35SUBROUTINE ratqs_main(klon,klev,nbsrf,prt_level,lunout,       &
[2236]36           iflag_ratqs,iflag_con,iflag_cld_th,pdtphys, &
[2534]37           ratqsbas,ratqshaut,ratqsp0,ratqsdp, &
[4613]38           pctsrf,s_pblh,zstd, &
[3856]39           tau_ratqs,fact_cldcon,wake_s, wake_deltaq,   &
[4009]40           ptconv,ptconvth,clwcon0th, rnebcon0th,       &
41           paprs,pplay,t_seri,q_seri,                   &
[4613]42           qtc_cv, sigt_cv,detrain_cv,fm_cv,fqd,fqcomp,sigd,zqsat,             &
43           omega,tke,tke_dissip,lmix,wprime, &
44           t2m,q2m,fm_therm,entr_therm,detr_therm,cell_area,&
[5208]45           ratqs,ratqsc,ratqs_inter_,sigma_qtherm)
[1689]46
[4009]47
[5816]48USE clouds_gno_mod,     ONLY: clouds_gno
[4613]49USE lmdz_ratqs_multi,   ONLY: ratqs_inter, ratqs_oro, ratqs_hetero, ratqs_tke
[4009]50
[1689]51implicit none
52
53!========================================================================
54! Computation of ratqs, the width of the subrid scale water distribution
55! (normalized by the mean value)
56! Various options controled by flags iflag_con and iflag_ratqs
57! F Hourdin 2012/12/06
58!========================================================================
59
60! Declarations
61
62! Input
[4613]63integer,intent(in) :: klon,klev,nbsrf,prt_level,lunout
[2236]64integer,intent(in) :: iflag_con,iflag_cld_th,iflag_ratqs
[1689]65real,intent(in) :: pdtphys,ratqsbas,ratqshaut,fact_cldcon,tau_ratqs
[2534]66real,intent(in) :: ratqsp0, ratqsdp
[4613]67real, dimension(klon,klev),intent(in) :: omega
[4009]68real, dimension(klon,klev+1),intent(in) :: paprs,tke,tke_dissip,lmix,wprime
[4613]69real, dimension(klon,klev),intent(in) :: pplay,t_seri,q_seri,zqsat
70real, dimension(klon,klev),intent(in) :: entr_therm,detr_therm,qtc_cv, sigt_cv
71real, dimension(klon,klev) :: detrain_cv,fm_cv,fqd,fqcomp
72real, dimension(klon) :: sigd
73
74real, dimension(klon,klev+1),intent(in) :: fm_therm
[1689]75logical, dimension(klon,klev),intent(in) :: ptconv
76real, dimension(klon,klev),intent(in) :: rnebcon0th,clwcon0th
[5820]77real, dimension(klon,klev),intent(in) :: wake_deltaq
78real, dimension(klon),intent(in) :: wake_s
[4009]79real, dimension(klon,nbsrf),intent(in) :: t2m,q2m
[4519]80real, dimension(klon), intent(in) :: cell_area
[4613]81real, dimension(klon,nbsrf),intent(in) :: pctsrf
82real, dimension(klon),intent(in) :: s_pblh
83real, dimension(klon),intent(in) :: zstd
84
[1689]85! Output
[5208]86real, dimension(klon,klev),intent(inout) :: ratqs,ratqsc,ratqs_inter_,sigma_qtherm
[4009]87
[1689]88logical, dimension(klon,klev),intent(inout) :: ptconvth
89
90! local
91integer i,k
92real, dimension(klon,klev) :: ratqss
93real facteur,zfratqs1,zfratqs2
[4613]94real, dimension(klon,klev) :: ratqs_hetero_,ratqs_oro_,ratqs_tke_
[5820]95real, dimension(klon) :: fact
[1689]96
97!-------------------------------------------------------------------------
98!  Caclul des ratqs
99!-------------------------------------------------------------------------
100
101!      print*,'calcul des ratqs'
102!   ratqs convectifs a l'ancienne en fonction de q(z=0)-q / q
103!   ----------------
104!   on ecrase le tableau ratqsc calcule par clouds_gno
[2236]105      if (iflag_cld_th.eq.1) then
[1689]106         do k=1,klev
107         do i=1,klon
108            if(ptconv(i,k)) then
109              ratqsc(i,k)=ratqsbas &
110              +fact_cldcon*(q_seri(i,1)-q_seri(i,k))/q_seri(i,k)
111            else
112               ratqsc(i,k)=0.
113            endif
114         enddo
115         enddo
116
117!-----------------------------------------------------------------------
118!  par nversion de la fonction log normale
119!-----------------------------------------------------------------------
[2236]120      else if (iflag_cld_th.eq.4) then
[1689]121         ptconvth(:,:)=.false.
122         ratqsc(:,:)=0.
123         if(prt_level.ge.9) print*,'avant clouds_gno thermique'
124         call clouds_gno &
125         (klon,klev,q_seri,zqsat,clwcon0th,ptconvth,ratqsc,rnebcon0th)
126         if(prt_level.ge.9) print*,' CLOUDS_GNO OK'
127       
128       endif
129
130!   ratqs stables
131!   -------------
132
133      if (iflag_ratqs.eq.0) then
134
135! Le cas iflag_ratqs=0 correspond a la version IPCC 2005 du modele.
136         do k=1,klev
137            do i=1, klon
138               ratqss(i,k)=ratqsbas+(ratqshaut-ratqsbas)* &
139               min((paprs(i,1)-pplay(i,k))/(paprs(i,1)-30000.),1.)
140            enddo
141         enddo
142
143! Pour iflag_ratqs=1 ou 2, le ratqs est constant au dessus de
144! 300 hPa (ratqshaut), varie lineariement en fonction de la pression
145! entre 600 et 300 hPa et est soit constant (ratqsbas) pour iflag_ratqs=1
146! soit lineaire (entre 0 a la surface et ratqsbas) pour iflag_ratqs=2
147! Il s'agit de differents tests dans la phase de reglage du modele
148! avec thermiques.
149
150      else if (iflag_ratqs.eq.1) then
151
152         do k=1,klev
153            do i=1, klon
154               if (pplay(i,k).ge.60000.) then
155                  ratqss(i,k)=ratqsbas
156               else if ((pplay(i,k).ge.30000.).and.(pplay(i,k).lt.60000.)) then
157                  ratqss(i,k)=ratqsbas+(ratqshaut-ratqsbas)*(60000.-pplay(i,k))/(60000.-30000.)
158               else
159                  ratqss(i,k)=ratqshaut
160               endif
161            enddo
162         enddo
163
164      else if (iflag_ratqs.eq.2) then
165
166         do k=1,klev
167            do i=1, klon
168               if (pplay(i,k).ge.60000.) then
169                  ratqss(i,k)=ratqsbas*(paprs(i,1)-pplay(i,k))/(paprs(i,1)-60000.)
170               else if ((pplay(i,k).ge.30000.).and.(pplay(i,k).lt.60000.)) then
171                    ratqss(i,k)=ratqsbas+(ratqshaut-ratqsbas)*(60000.-pplay(i,k))/(60000.-30000.)
172               else
173                    ratqss(i,k)=ratqshaut
174               endif
175            enddo
176         enddo
177
178      else if (iflag_ratqs==3) then
179         do k=1,klev
180           ratqss(:,k)=ratqsbas+(ratqshaut-ratqsbas) &
181           *min( ((paprs(:,1)-pplay(:,k))/70000.)**2 , 1. )
182         enddo
183
[3856]184      else if (iflag_ratqs==4) then
[1689]185         do k=1,klev
186           ratqss(:,k)=ratqsbas+0.5*(ratqshaut-ratqsbas) &
[2534]187!          *( tanh( (50000.-pplay(:,k))/20000.) + 1.)
188           *( tanh( (ratqsp0-pplay(:,k))/ratqsdp) + 1.)
[1689]189         enddo
190
[4519]191
192      else if (iflag_ratqs==5) then
193! Dependency of ratqs on model resolution
194! Audran, Meryl, Lea, Gwendal and Etienne
195! April 2023
196         do k=1,klev
197            do i=1,klon
[5820]198              fact(i) = sqrt(resol(i)/resolmax)
199              ratqss(i,k)=ratqsbas*fact(i)+0.5*(ratqshaut-ratqsbas)*fact(i) &
[4519]200              *( tanh( (ratqsp0-pplay(i,k))/ratqsdp) + 1.)
201           enddo
202         enddo
203
204
[4009]205       else if (iflag_ratqs .GT. 9) then
206 
207       ! interactive ratqs calculations that depend on cold pools, orography, surface heterogeneity and small-scale turbulence
208       ! This should help getting a more realistic ratqs in the low and mid troposphere
209       ! We however need a "background" ratqs to account for subgrid distribution of qt (or qt/qs)
210       ! in the high troposphere
211       
212       ! background ratqs and initialisations
213          do k=1,klev
214             do i=1,klon
215              ratqss(i,k)=ratqsbas+0.5*(ratqshaut-ratqsbas) &
216              *( tanh( (ratqsp0-pplay(i,k))/ratqsdp) + 1.)
217              ratqss(i,k)=max(ratqss(i,k),0.0)
[4613]218              ratqs_hetero_(i,k)=0.
219              ratqs_oro_(i,k)=0.
220              ratqs_tke_(i,k)=0.
221              ratqs_inter_(i,k)=0
[4009]222             enddo
223          enddo
224     
225          if (iflag_ratqs .EQ. 10) then
[5208]226             print*,'avant ratqs_inter'
227            ! interactive ratqs with several sources
[4613]228             call ratqs_inter(klon,klev,iflag_ratqs,pdtphys,paprs, &
229                       ratqsbas,wake_deltaq,wake_s,q_seri,qtc_cv, sigt_cv, &
230                       fm_therm,entr_therm,detr_therm,detrain_cv,fm_cv,fqd,fqcomp,sigd, &
[5208]231                       ratqs_inter_,sigma_qtherm)
[4613]232             ratqss=ratqss+ratqs_inter_
[4009]233          else if (iflag_ratqs .EQ. 11) then
[4613]234            print*,'avant ratqs_inter'
[4009]235            ! interactive ratqs with several sources
[4613]236             call ratqs_inter(klon,klev,iflag_ratqs,pdtphys,paprs, &
237                       ratqsbas,wake_deltaq,wake_s,q_seri,qtc_cv, sigt_cv, &
238                       fm_therm,entr_therm,detr_therm,detrain_cv,fm_cv,fqd,fqcomp,sigd, &
[5208]239                       ratqs_inter_,sigma_qtherm)
[4613]240             ratqss=ratqss+ratqs_inter_
[4009]241          else if (iflag_ratqs .EQ. 12) then
242             ! contribution of surface heterogeneities to ratqs
[4613]243             call ratqs_hetero(klon,klev,pctsrf,s_pblh,t2m,q2m,t_seri,q_seri,pplay,paprs,ratqs_hetero_)
244             ratqss=ratqss+ratqs_hetero_
[4009]245          else if (iflag_ratqs .EQ. 13) then
246             ! contribution of ubgrid orography to ratqs
[4613]247             call ratqs_oro(klon,klev,pctsrf,zstd,zqsat,t_seri,pplay,paprs,ratqs_oro_)
248             ratqss=ratqss+ratqs_oro_
[4009]249          else if (iflag_ratqs .EQ. 14) then
250             ! effect of subgrid-scale TKE on ratqs (in development)
[4613]251             call ratqs_tke(klon,klev,pdtphys,t_seri,q_seri,zqsat,pplay,paprs,omega,tke,tke_dissip,lmix,wprime,ratqs_tke_)     
252             ratqss=ratqss+ratqs_tke_
[4009]253          endif
254         
255     
[1689]256      endif
257
258
259!  ratqs final
260!  -----------
261
[2236]262      if (iflag_cld_th.eq.1 .or.iflag_cld_th.eq.2.or.iflag_cld_th.eq.4) then
[1689]263
264! On ajoute une constante au ratqsc*2 pour tenir compte de
265! fluctuations turbulentes de petite echelle
266
267         do k=1,klev
268            do i=1,klon
[4613]269               if ((fm_therm(i,k)>1.e-10)) then
[1689]270                  ratqsc(i,k)=sqrt(ratqsc(i,k)**2+0.05**2)
271               endif
272            enddo
273         enddo
274
275!   les ratqs sont une combinaison de ratqss et ratqsc
276       if(prt_level.ge.9) write(lunout,*)'PHYLMD NOUVEAU TAU_RATQS ',tau_ratqs
277
278         if (tau_ratqs>1.e-10) then
279            facteur=exp(-pdtphys/tau_ratqs)
280         else
281            facteur=0.
282         endif
283         ratqs(:,:)=ratqsc(:,:)*(1.-facteur)+ratqs(:,:)*facteur
284!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
285! FH 22/09/2009
286! La ligne ci-dessous faisait osciller le modele et donnait une solution
[4812]287! assymptotique bidon et d??pendant fortement du pas de temps.
[1689]288!        ratqs(:,:)=sqrt(ratqs(:,:)**2+ratqss(:,:)**2)
289!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
290         ratqs(:,:)=max(ratqs(:,:),ratqss(:,:))
[2236]291      else if (iflag_cld_th<=6) then
[1689]292!   on ne prend que le ratqs stable pour fisrtilp
293         ratqs(:,:)=ratqss(:,:)
294      else
295          zfratqs1=exp(-pdtphys/10800.)
296          zfratqs2=exp(-pdtphys/10800.)
297          do k=1,klev
298             do i=1,klon
299                if (ratqsc(i,k).gt.1.e-10) then
[2236]300                   ratqs(i,k)=ratqs(i,k)*zfratqs2+(iflag_cld_th/100.)*ratqsc(i,k)*(1.-zfratqs2)
[1689]301                endif
302                ratqs(i,k)=min(ratqs(i,k)*zfratqs1+ratqss(i,k)*(1.-zfratqs1),0.5)
303             enddo
304          enddo
305      endif
306
307
308return
[4613]309END SUBROUTINE ratqs_main
310
311END MODULE lmdz_ratqs_main
Note: See TracBrowser for help on using the repository browser.