source: LMDZ6/branches/LMDZ_cdrag_LSCE/libf/phylmd/cdrag_mod.F90 @ 4661

Last change on this file since 4661 was 4661, checked in by Laurent Fairhead, 10 months ago

Inclusion and merge of Olivier's modifications

  • Property svn:executable set to *
File size: 24.8 KB
Line 
1!
2MODULE cdrag_mod
3!
4! This module contains some procedures for calculation of the cdrag
5! coefficients for turbulent diffusion at surface
6!
7  IMPLICIT NONE
8
9CONTAINS
10!
11!****************************************************************************************
12!
13!r original routine svn3623
14!
15 SUBROUTINE cdrag(knon,  nsrf,   &
16     speed, t1,    q1,    zgeop1, &
17     psol, pblh,  tsurf, qsurf, z0m, z0h,  &
18     ri_in, iri_in, &
19     cdm,  cdh,  zri,   pref, prain, tsol , pat1)
20
21  USE dimphy
22  USE indice_sol_mod
23  USE print_control_mod, ONLY: lunout, prt_level
24  USE ioipsl_getin_p_mod, ONLY : getin_p
25  USE atke_turbulence_ini_mod, ONLY : ric, cinf, cepsilon, pr_slope, pr_asym, pr_neut
26
27  IMPLICIT NONE
28! ================================================================= c
29!
30! Objet : calcul des cdrags pour le moment (pcfm) et
31!         les flux de chaleur sensible et latente (pcfh) d'apr??s
32!         Louis 1982, Louis 1979, King et al 2001
33!         ou Zilitinkevich et al 2002  pour les cas stables, Louis 1979
34!         et 1982 pour les cas instables
35!
36! Modified history:
37!  writting on the 20/05/2016
38!  modified on the 13/12/2016 to be adapted to LMDZ6
39!
40! References:
41!   Louis, J. F., 1979: A parametric model of vertical eddy fluxes in the
42!     atmosphere. Boundary-Layer Meteorology. 01/1979; 17(2):187-202.
43!   Louis, J. F., Tiedtke, M. and Geleyn, J. F., 1982: `A short history of the
44!     operational PBL parametrization at ECMWF'. Workshop on boundary layer
45!     parametrization, November 1981, ECMWF, Reading, England.
46!     Page: 19. Equations in Table 1.
47!   Mascart P, Noilhan J, Giordani H 1995.A MODIFIED PARAMETERIZATION OF FLUX-PROFILE RELATIONSHIPS
48!    IN THE SURFACE LAYER USING DIFFERENT ROUGHNESS LENGTH VALUES FOR HEAT AND MOMENTUM
49!    Boundary-Layer Meteorology 72: 331-344
50!   Anton Beljaars. May 1992. The parametrization of the planetary boundary layer. 
51!     European Centre for Medium-Range Weather Forecasts.
52!     Equations: 110-113. Page 40.
53!   Miller,M.J., A.C.M.Beljaars, T.N.Palmer. 1992. The sensitivity of the ECMWF
54!     model to the parameterization of evaporation from the tropical oceans. J.
55!     Climate, 5:418-434.
56!   King J.C, Connolley, W.M ad Derbyshire S.H. 2001, Sensitivity of Modelled Antarctic climate
57!   to surface and boundary-layer flux parametrizations
58!   QJRMS, 127, pp 779-794
59!
60! ================================================================= c
61! ================================================================= c
62! On choisit le couple de fonctions de correction avec deux flags:
63! Un pour les cas instables, un autre pour les cas stables
64!
65! iflag_corr_insta:
66!                   1: Louis 1979 avec les modifications de Mascart 1995 (z0/= z0h)
67!                   2: Louis 1982
68!                   3: Laurent Li
69!
70! iflag_corr_sta:
71!                   1: Louis 1979 avec les modifications de Mascart 1995 (z0/= z0h)
72!                   2: Louis 1982
73!                   3: Laurent Li
74!                   4: King  2001 (SHARP)
75!                   5: MO 1st order theory (allow collapse of turbulence)
76!           
77!
78!*****************************************************************
79! Parametres d'entree
80!*****************************************************************
81 
82  INTEGER, INTENT(IN)                      :: knon, nsrf ! nombre de points de grille sur l'horizontal + type de surface
83  REAL, DIMENSION(klon), INTENT(IN)        :: speed    ! module du vent au 1er niveau du modele
84  REAL, DIMENSION(klon), INTENT(IN)        :: zgeop1   ! geopotentiel au 1er niveau du modele
85  REAL, DIMENSION(klon), INTENT(IN)        :: tsurf    ! Surface temperature (K)
86  REAL, DIMENSION(klon), INTENT(IN)        :: qsurf    ! Surface humidity (Kg/Kg)
87  REAL, DIMENSION(klon), INTENT(INOUT)     :: z0m, z0h ! Rugosity at surface (m)
88  REAL, DIMENSION(klon), INTENT(IN)        :: ri_in ! Input Richardson 1st layer for first guess calculations of screen var.
89  INTEGER, INTENT(IN)                      :: iri_in! iflag to activate cdrag calculation using ri1
90  REAL, DIMENSION(klon), INTENT(IN)        :: t1       ! Temperature au premier niveau (K)
91  REAL, DIMENSION(klon), INTENT(IN)        :: q1       ! humidite specifique au premier niveau (kg/kg)
92  REAL, DIMENSION(klon), INTENT(IN)        :: psol     ! pression au sol
93
94!------------------ Rajout pour COARE (OT2018) --------------------
95  REAL, DIMENSION(klon), INTENT(INOUT)     :: pblh  !hauteur de CL
96  REAL, DIMENSION(klon), INTENT(IN)        :: prain !rapport au precipitation
97  REAL, DIMENSION(klon), INTENT(IN)        :: tsol  !SST imposé sur la surface oceanique
98  REAL, DIMENSION(klon), INTENT(IN)        :: pat1  !pression premier lev
99
100
101
102! Parametres de sortie
103!******************************************************************
104  REAL, DIMENSION(klon), INTENT(OUT)       :: cdm   ! Drag coefficient for momentum
105  REAL, DIMENSION(klon), INTENT(OUT)       :: cdh   ! Drag coefficient for heat flux
106  REAL, DIMENSION(klon), INTENT(OUT)       :: zri   ! Richardson number
107  REAL, DIMENSION(klon), INTENT(INOUT)       :: pref  ! Pression au niveau zgeop/RG
108
109! Variables Locales
110!******************************************************************
111 
112
113  INCLUDE "YOMCST.h"
114  INCLUDE "YOETHF.h"
115  INCLUDE "clesphys.h"
116
117
118  REAL, PARAMETER       :: CKAP=0.40, CKAPT=0.42
119  REAL                   CEPDU2
120  REAL                   ALPHA
121  REAL                   CB,CC,CD,C2,C3
122  REAL                   MU, CM, CH, B, CMstar, CHstar
123  REAL                   PM, PH, BPRIME
124  REAL                   C
125  INTEGER                ng_q1                      ! Number of grids that q1 < 0.0
126  INTEGER                ng_qsurf                   ! Number of grids that qsurf < 0.0
127  INTEGER                i, k
128  REAL                   zdu2, ztsolv
129  REAL                   ztvd, zscf
130  REAL                   zucf, zcr
131  REAL                   friv, frih
132  REAL, DIMENSION(klon) :: FM, FH                   ! stability functions
133  REAL, DIMENSION(klon) :: cdmn, cdhn               ! Drag coefficient in neutral conditions
134  REAL zzzcd
135  REAL, DIMENSION(klon) :: sm, prandtl              ! Stability function from atke turbulence scheme
136  REAL                  ri0, ri1, cn                ! to have dimensionless term in sm and prandtl
137
138!------------------ Rajout (OT2018) --------------------
139!------------------ Rajout pour les appelles BULK (OT) --------------------
140  REAL, DIMENSION(klon,2) :: rugos_itm
141  REAL, DIMENSION(klon,2) :: rugos_ith
142  REAL, PARAMETER         :: tol_it_rugos=1.e-4
143  REAL, DIMENSION(3)      :: coeffs
144  LOGICAL                 :: mixte
145  REAL                    :: z_0m
146  REAL                    :: z_0h
147  REAL, DIMENSION(klon)   :: cdmm
148  REAL, DIMENSION(klon)   :: cdhh
149
150!--------- rajout pour verification --------------------
151
152  REAL, DIMENSION(klon) :: zcdn_h2
153
154
155!------------------RAJOUT POUR ECUME -------------------
156
157  REAL, DIMENSION(klon) :: PQSAT
158  REAL, DIMENSION(klon) :: PSFTH
159  REAL, DIMENSION(klon) :: PFSTQ
160  REAL, DIMENSION(klon) :: PUSTAR
161  REAL, DIMENSION(klon) :: PCD      ! Drag coefficient for momentum
162  REAL, DIMENSION(klon) :: PCDN     ! Drag coefficient for momentum
163  REAL, DIMENSION(klon) :: PCH      ! Drag coefficient for momentum
164  REAL, DIMENSION(klon) :: PCE      ! Drag coefficient for momentum
165  REAL, DIMENSION(klon) :: PRI
166  REAL, DIMENSION(klon) :: PRESA
167  REAL, DIMENSION(klon) :: PSSS
168
169  LOGICAL               :: OPRECIP
170  LOGICAL               :: OPWEBB
171  LOGICAL               :: OPERTFLUX
172  LOGICAL               :: LPRECIP
173  LOGICAL               :: LPWG
174
175
176
177  LOGICAL, SAVE :: firstcall = .TRUE.
178  !$OMP THREADPRIVATE(firstcall)
179  INTEGER, SAVE :: iflag_corr_sta
180  !$OMP THREADPRIVATE(iflag_corr_sta)
181  INTEGER, SAVE :: iflag_corr_insta
182  !$OMP THREADPRIVATE(iflag_corr_insta)
183
184!===================================================================c
185! Valeurs numeriques des constantes
186!===================================================================c
187
188
189! Minimum du carre du vent
190
191 CEPDU2 = (0.1)**2
192
193! Louis 1982
194
195  CB=5.0
196  CC=5.0
197  CD=5.0
198
199
200! King 2001
201
202  C2=0.25
203  C3=0.0625
204
205 
206! Louis 1979
207
208  BPRIME=4.7
209  B=9.4
210 
211
212!MO
213
214  ALPHA=5.0
215
216! Consistent with atke scheme
217cn=(1./sqrt(cepsilon))**(2/3)
218ri0=2./rpi*(cinf - cn)*ric/cn
219ri1=-2./rpi * (pr_asym - pr_neut)/pr_slope
220
221
222! ================================================================= c
223! Tests avant de commencer
224! Fuxing WANG, 04/03/2015
225! To check if there are negative q1, qsurf values.
226!====================================================================c
227  ng_q1 = 0     ! Initialization
228  ng_qsurf = 0  ! Initialization
229  DO i = 1, knon
230     IF (q1(i).LT.0.0)     ng_q1 = ng_q1 + 1
231     IF (qsurf(i).LT.0.0)  ng_qsurf = ng_qsurf + 1
232  ENDDO
233  IF (ng_q1.GT.0 .and. prt_level > 5) THEN
234      WRITE(lunout,*)" *** Warning: Negative q1(humidity at 1st level) values in cdrag.F90 !"
235      WRITE(lunout,*)" The total number of the grids is: ", ng_q1
236      WRITE(lunout,*)" The negative q1 is set to zero "
237!      abort_message="voir ci-dessus"
238!      CALL abort_physic(modname,abort_message,1)
239  ENDIF
240  IF (ng_qsurf.GT.0 .and. prt_level > 5) THEN
241      WRITE(lunout,*)" *** Warning: Negative qsurf(humidity at surface) values in cdrag.F90 !"
242      WRITE(lunout,*)" The total number of the grids is: ", ng_qsurf
243      WRITE(lunout,*)" The negative qsurf is set to zero "
244!      abort_message="voir ci-dessus"
245!      CALL abort_physic(modname,abort_message,1)
246  ENDIF
247
248
249
250!=============================================================================c
251! Calcul du cdrag
252!=============================================================================c
253
254! On choisit les fonctions de stabilite utilisees au premier appel
255!**************************************************************************
256  IF (firstcall) THEN
257   iflag_corr_sta=2
258   iflag_corr_insta=2
259 
260   CALL getin_p('iflag_corr_sta',iflag_corr_sta)
261   CALL getin_p('iflag_corr_insta',iflag_corr_insta)
262
263   firstcall = .FALSE.
264 ENDIF
265
266!------------------ Rajout (OT2018) --------------------
267!---------    Rajout pour itération sur rugosité     ----------------
268  rugos_itm(:,2) = z0m
269  rugos_itm(:,1) = 3.*tol_it_rugos*z0m
270
271  rugos_ith(:,2) = z0h !cp nouveau rugos_it
272  rugos_ith(:,1) = 3.*tol_it_rugos*z0h
273!--------------------------------------------------------------------
274
275!xxxxxxxxxxxxxxxxxxxxxxx
276  DO i = 1, knon        ! Boucle sur l'horizontal
277!xxxxxxxxxxxxxxxxxxxxxxx
278
279
280! calculs preliminaires:
281!***********************
282     
283     zdu2 = MAX(CEPDU2, speed(i)**2)
284     pref(i) = EXP(LOG(psol(i)) - zgeop1(i)/(RD*t1(i)* &
285          (1.+ RETV * max(q1(i),0.0))))           ! negative q1 set to zero
286     ztsolv = tsurf(i) * (1.0+RETV*max(qsurf(i),0.0))    ! negative qsurf set to zero
287     ztvd = (t1(i)+zgeop1(i)/RCPD/(1.+RVTMP2*q1(i))) &
288          *(1.+RETV*max(q1(i),0.0))                      ! negative q1 set to zero
289     
290!------------------ Rajout (OT2018) --------------------
291!--------------   ON DUPLIQUE POUR METTRE ITERATION SUR OCEAN    ------------------------     
292     IF (iri_in.EQ.1) THEN
293       zri(i) = ri_in(i)
294     ENDIF
295
296     IF (nsrf == is_oce) THEN
297       
298!------------------  Pour Core 2 choix Core Pur ou Core Mixte  --------------------
299       IF ((choix_bulk > 1 .AND. choix_bulk < 4) .AND. (nsrf .eq. is_oce)) THEN
300         IF(choix_bulk .eq. 2) THEN
301           mixte = .false.
302         ELSE
303            mixte = .true.
304         ENDIF
305         call clc_core_cp ( sqrt(zdu2),t1(i)-tsurf(i),q1(i)-qsurf(i),t1(i),q1(i),&
306             zgeop1(i)/RG, zgeop1(i)/RG,  zgeop1(i)/RG,&
307             psol(i),nit_bulk,mixte,&
308             coeffs,z_0m,z_0h)
309         cdmm(i) = coeffs(1)
310         cdhh(i) = coeffs(2)
311         cdm(i)=cdmm(i)
312         cdh(i)=cdhh(i)
313         write(*,*) "clc_core cd ch",cdmm(i),cdhh(i)
314
315!------------------                 Pour ECUME                 --------------------     
316       ELSE IF ((choix_bulk .eq. 4) .and. (nsrf .eq. is_oce)) THEN
317         OPRECIP = .false.
318         OPWEBB  = .false.
319         OPERTFLUX = .false.
320         IF (nsrf .eq. is_oce) THEN
321           PSSS = 0.0
322         ENDIF
323         call ini_csts
324         call ecumev6_flux( z_0m,t1(i),tsurf(i),&
325             q1(i),qsurf(i),sqrt(zdu2),zgeop1(i)/RG,PSSS,zgeop1(i)/RG,&
326             psol(i),pat1(i), OPRECIP, OPWEBB,&
327             PSFTH,PFSTQ,PUSTAR,PCD,PCDN,&
328             PCH,PCE,PRI,PRESA,prain,&
329             z_0h,OPERTFLUX,coeffs)
330       
331         cdmm(i) = coeffs(1)
332         cdhh(i) = coeffs(2)
333         cdm(i)=cdmm(i)
334         cdh(i)=cdhh(i)
335   
336         write(*,*) "ecume cd ch",cdmm(i),cdhh(i)
337       
338!------------------                 Pour COARE CNRM                 --------------------
339       ELSE IF ((choix_bulk .eq. 5) .and. (nsrf .eq. is_oce)) THEN
340         LPRECIP = .false.
341         LPWG    = .false.
342         call ini_csts
343         call coare30_flux_cnrm(z_0m,t1(i),tsurf(i), q1(i),  &
344             sqrt(zdu2),zgeop1(i)/RG,zgeop1(i)/RG,psol(i),qsurf(i),PQSAT, &
345             PSFTH,PFSTQ,PUSTAR,PCD,PCDN,PCH,PCE,PRI, &
346             PRESA,prain,pat1(i),z_0h, LPRECIP, LPWG, coeffs)
347         cdmm(i) = coeffs(1)
348         cdhh(i) = coeffs(2)
349         cdm(i)=cdmm(i)
350         cdh(i)=cdhh(i)
351         write(*,*) "coare CNRM cd ch",cdmm(i),cdhh(i)
352
353!------------------                 Pour COARE Maison                 --------------------
354       ELSE IF ((choix_bulk .eq. 1) .and. (nsrf .eq. is_oce)) THEN
355         IF ( pblh(i) .eq. 0. ) THEN
356           pblh(i) = 1500.
357         ENDIF
358         write(*,*) "debug size",size(coeffs)
359         call coare_cp(sqrt(zdu2),t1(i)-tsurf(i),q1(i)-qsurf(i),&
360                 t1(i),q1(i),&
361                 zgeop1(i)/RG,zgeop1(i)/RG,zgeop1(i)/RG,&
362                 psol(i), pblh(i),&
363                 nit_bulk,&
364                 coeffs,z_0m,z_0h)
365         cdmm(i) = coeffs(1)
366         cdhh(i) = coeffs(3)
367         cdm(i)=cdmm(i)
368         cdh(i)=cdhh(i)
369         write(*,*) "coare cd ch",cdmm(i),cdhh(i)
370       ELSE
371!------------------                 Pour La param LMDZ (ocean)              --------------------
372         zri(i) = zgeop1(i)*(ztvd-ztsolv)/(zdu2*ztvd)
373         IF (iri_in.EQ.1) THEN
374           zri(i) = ri_in(i)
375         ENDIF
376       ENDIF
377
378!----------------------- Rajout des itérations --------------
379       DO  k=1,nit_bulk
380
381! Coefficients CD neutres : k^2/ln(z/z0) et k^2/(ln(z/z0)*ln(z/z0h)):
382!********************************************************************
383         zzzcd=CKAP/LOG(1.+zgeop1(i)/(RG*rugos_itm(i,2)))
384         cdmn(i) = zzzcd*zzzcd
385         cdhn(i) = zzzcd*(CKAP/LOG(1.+zgeop1(i)/(RG*rugos_ith(i,2))))
386
387! Calcul des fonctions de stabilite FMs, FHs, FMi, FHi :
388!*******************************************************
389         IF (zri(i) .LT. 0.) THEN   
390           SELECT CASE (iflag_corr_insta)
391             CASE (1) ! Louis 1979 + Mascart 1995
392                  MU=LOG(MAX(z0m(i)/z0h(i),0.01))
393                  CMstar=6.8741+2.6933*MU-0.3601*(MU**2)+0.0154*(MU**3)
394                  PM=0.5233-0.0815*MU+0.0135*(MU**2)-0.001*(MU**3)
395                  CHstar=3.2165+4.3431*MU+0.536*(MU**2)-0.0781*(MU**3)
396                  PH=0.5802-0.1571*MU+0.0327*(MU**2)-0.0026*(MU**3)
397                  CH=CHstar*B*CKAP/LOG(z0m(i)+zgeop1(i)/(RG*z0m(i))) &
398                     & * CKAPT/LOG(z0h(i)+zgeop1(i)/(RG*z0h(i)))       &
399                     & * ((zgeop1(i)/(RG*z0h(i)))**PH)
400                  CM=CMstar*B*CKAP/LOG(z0m(i)+zgeop1(i)/(RG*z0m(i))) &
401                     & *CKAP/LOG(z0m(i)+zgeop1(i)/(RG*z0m(i)))         &
402                     & * ((zgeop1(i)/(RG*z0m(i)))**PM)
403                  FM(i)=1.-B*zri(i)/(1.+CM*SQRT(ABS(zri(i))))
404                  FH(i)=1.-B*zri(i)/(1.+CH*SQRT(ABS(zri(i))))
405             CASE (2) ! Louis 1982
406                  zucf = 1./(1.+3.0*CB*CC*cdmn(i)*SQRT(ABS(zri(i)) &
407                        *(1.0+zgeop1(i)/(RG*z0m(i)))))
408                  FM(i) = AMAX1((1.-2.0*CB*zri(i)*zucf),f_ri_cd_min)
409                  FH(i) = AMAX1((1.-3.0*CB*zri(i)*zucf),f_ri_cd_min)
410             CASE (3) ! Laurent Li
411                  FM(i) = MAX(SQRT(1.0-18.0*zri(i)),f_ri_cd_min)
412                  FH(i) = MAX(SQRT(1.0-18.0*zri(i)),f_ri_cd_min)
413             CASE (6) ! Consistent with turbulence scheme (in stationary case) derived in atke (2023)
414                  sm(i) = 2./rpi * (cinf - cn) * atan(-zri(i)/ri0) + cn
415                  prandtl(i) = -2./rpi * (pr_asym - pr_neut) * atan(zri(i)/ri1) + pr_neut
416                  FM(i) = MAX((sm(i)**(3/2) * sqrt(cepsilon) * (1 - zri(i) / prandtl(i))**(1/2)),f_ri_cd_min)
417                  FH(i) = MAX((FM(i) / prandtl(i)), f_ri_cd_min)
418             CASE default ! Louis 1982
419                  zucf = 1./(1.+3.0*CB*CC*cdmn(i)*SQRT(ABS(zri(i)) &
420                         *(1.0+zgeop1(i)/(RG*z0m(i)))))
421                  FM(i) = AMAX1((1.-2.0*CB*zri(i)*zucf),f_ri_cd_min)
422                  FH(i) = AMAX1((1.-3.0*CB*zri(i)*zucf),f_ri_cd_min)
423           END SELECT
424! Calcul des drags
425           cdmm(i)=cdmn(i)*FM(i)
426           cdhh(i)=f_cdrag_ter*cdhn(i)*FH(i)
427! Traitement particulier des cas oceaniques
428! on applique Miller et al 1992 en l'absence de gustiness
429           IF (nsrf == is_oce) THEN
430!            cdh(i)=f_cdrag_oce*cdhn(i)*FH(i)
431             IF (iflag_gusts==0) THEN
432               zcr = (0.0016/(cdmn(i)*SQRT(zdu2)))*ABS(ztvd-ztsolv)**(1./3.)
433               cdhh(i) =f_cdrag_oce* cdhn(i)*(1.0+zcr**1.25)**(1./1.25)
434             ENDIF
435             cdmm(i)=MIN(cdmm(i),cdmmax)
436             cdhh(i)=MIN(cdhh(i),cdhmax)
437             write(*,*) "LMDZ cd ch",cdmm(i),cdhh(i)
438           END IF
439         ELSE                         
440
441!'''''''''''''''
442! Cas stables :
443!'''''''''''''''
444           zri(i) = MIN(20.,zri(i))
445           SELECT CASE (iflag_corr_sta)
446             CASE (1) ! Louis 1979 + Mascart 1995
447                  FM(i)=MAX(1./((1+BPRIME*zri(i))**2),f_ri_cd_min)
448                  FH(i)=FM(i)
449             CASE (2) ! Louis 1982
450                  zscf = SQRT(1.+CD*ABS(zri(i)))
451                  FM(i)= AMAX1(1. / (1.+2.*CB*zri(i)/zscf), f_ri_cd_min)
452                  FH(i)= AMAX1(1./ (1.+3.*CB*zri(i)*zscf), f_ri_cd_min )
453             CASE (3) ! Laurent Li
454                  FM(i)=MAX(1.0 / (1.0+10.0*zri(i)*(1+8.0*zri(i))),f_ri_cd_min)
455                  FH(i)=FM(i)
456             CASE (4)  ! King 2001
457                  IF (zri(i) .LT. C2/2.) THEN
458                    FM(i)=MAX((1.-zri(i)/C2)**2,f_ri_cd_min)
459                    FH(i)=  FM(i)
460                  ELSE
461                    FM(i)=MAX(C3*((C2/zri(i))**2),f_ri_cd_min)
462                    FH(i)= FM(i)
463                  ENDIF
464             CASE (5) ! MO
465                  if (zri(i) .LT. 1./alpha) then
466                    FM(i)=MAX((1.-alpha*zri(i))**2,f_ri_cd_min)
467                    FH(i)=FM(i)
468                  else
469                    FM(i)=MAX(1E-7,f_ri_cd_min)
470                    FH(i)=FM(i)
471                  endif
472             CASE (6) ! Consistent with turbulence scheme (in stationary case) derived in atke (2023)
473                  sm(i) = MAX(0.,cn*(1.-zri(i)/ric))
474                  prandtl(i) = pr_neut + zri(i) * pr_slope
475                  FM(i) = MAX((sm(i)**(3/2) * sqrt(cepsilon) * (1 - zri(i) / prandtl(i))**(1/2)),f_ri_cd_min)
476                  FH(i) = MAX((FM(i) / prandtl(i)), f_ri_cd_min)
477             CASE default ! Louis 1982
478                  zscf = SQRT(1.+CD*ABS(zri(i)))
479                  FM(i)= AMAX1(1. / (1.+2.*CB*zri(i)/zscf), f_ri_cd_min)
480                  FH(i)= AMAX1(1./ (1.+3.*CB*zri(i)*zscf), f_ri_cd_min )
481           END SELECT
482! Calcul des drags
483           cdmm(i)=cdmn(i)*FM(i)
484           cdhh(i)=f_cdrag_ter*cdhn(i)*FH(i)
485           IF (nsrf.EQ.is_oce) THEN
486             cdhh(i)=f_cdrag_oce*cdhn(i)*FH(i)
487             cdmm(i)=MIN(cdm(i),cdmmax)
488             cdhh(i)=MIN(cdh(i),cdhmax)
489           ENDIF
490           rugos_itm(i,1) = rugos_itm(i,2)
491           rugos_ith(i,1) = rugos_ith(i,2)
492           rugos_itm(i,2) =  0.018*cdmm(i) * (speed(i))/RG  &
493                              +  0.11*14e-6 / SQRT(cdmm(i) * zdu2)
494
495!---------- Version SEPARATION DES Z0 ----------------------
496           IF (iflag_z0_oce==0) THEN
497             rugos_ith(i,2) = rugos_itm(i,2)
498           ELSE IF (iflag_z0_oce==1) THEN
499             rugos_ith(i,2) = 0.40*14e-6 / SQRT(cdmm(i) * zdu2)
500           ENDIF
501         ENDIF
502         rugos_itm(i,2) = MAX(1.5e-05,rugos_itm(i,2))
503         rugos_ith(i,2) = MAX(1.5e-05,rugos_ith(i,2))
504       ENDDO
505       IF (nsrf.EQ.is_oce) THEN
506         cdm(i)=MIN(cdmm(i),cdmmax)
507         cdh(i)=MIN(cdhh(i),cdhmax)
508       ENDIF
509       z0m = rugos_itm(:,2)
510       z0h = rugos_ith(:,2)
511     ELSE ! (nsrf == is_oce)
512       zri(i) = zgeop1(i)*(ztvd-ztsolv)/(zdu2*ztvd)
513       IF (iri_in.EQ.1) THEN
514         zri(i) = ri_in(i)
515       ENDIF
516
517! Coefficients CD neutres : k^2/ln(z/z0) et k^2/(ln(z/z0)*ln(z/z0h)):
518!********************************************************************
519       zzzcd=CKAP/LOG(1.+zgeop1(i)/(RG*z0m(i)))
520       cdmn(i) = zzzcd*zzzcd
521       cdhn(i) = zzzcd*(CKAP/LOG(1.+zgeop1(i)/(RG*z0h(i))))
522
523
524! Calcul des fonctions de stabilit?? FMs, FHs, FMi, FHi :
525!*******************************************************
526!''''''''''''''
527! Cas instables
528!''''''''''''''
529       IF (zri(i) .LT. 0.) THEN   
530         SELECT CASE (iflag_corr_insta)
531           CASE (1) ! Louis 1979 + Mascart 1995
532                MU=LOG(MAX(z0m(i)/z0h(i),0.01))
533                CMstar=6.8741+2.6933*MU-0.3601*(MU**2)+0.0154*(MU**3)
534                PM=0.5233-0.0815*MU+0.0135*(MU**2)-0.001*(MU**3)
535                CHstar=3.2165+4.3431*MU+0.536*(MU**2)-0.0781*(MU**3)
536                PH=0.5802-0.1571*MU+0.0327*(MU**2)-0.0026*(MU**3)
537                CH=CHstar*B*CKAP/LOG(z0m(i)+zgeop1(i)/(RG*z0m(i))) &
538                   & * CKAPT/LOG(z0h(i)+zgeop1(i)/(RG*z0h(i)))       &
539                   & * ((zgeop1(i)/(RG*z0h(i)))**PH)
540                CM=CMstar*B*CKAP/LOG(z0m(i)+zgeop1(i)/(RG*z0m(i))) &
541                   & *CKAP/LOG(z0m(i)+zgeop1(i)/(RG*z0m(i)))         &
542                   & * ((zgeop1(i)/(RG*z0m(i)))**PM)
543                FM(i)=1.-B*zri(i)/(1.+CM*SQRT(ABS(zri(i))))
544                FH(i)=1.-B*zri(i)/(1.+CH*SQRT(ABS(zri(i))))
545           CASE (2) ! Louis 1982
546                zucf = 1./(1.+3.0*CB*CC*cdmn(i)*SQRT(ABS(zri(i)) &
547                       *(1.0+zgeop1(i)/(RG*z0m(i)))))
548                FM(i) = AMAX1((1.-2.0*CB*zri(i)*zucf),f_ri_cd_min)
549                FH(i) = AMAX1((1.-3.0*CB*zri(i)*zucf),f_ri_cd_min)
550           CASE (3) ! Laurent Li
551                FM(i) = MAX(SQRT(1.0-18.0*zri(i)),f_ri_cd_min)
552                FH(i) = MAX(SQRT(1.0-18.0*zri(i)),f_ri_cd_min)
553           CASE (6) ! Consistent with turbulence scheme (in stationary case) derived in atke (2023)
554                 sm(i) = 2./rpi * (cinf - cn) * atan(-zri(i)/ri0) + cn
555                 prandtl(i) = -2./rpi * (pr_asym - pr_neut) * atan(zri(i)/ri1) + pr_neut
556                 FM(i) = MAX((sm(i)**(3/2) * sqrt(cepsilon) * (1 - zri(i) / prandtl(i))**(1/2)),f_ri_cd_min)
557                 FH(i) = MAX((FM(i) / prandtl(i)), f_ri_cd_min)
558           CASE default ! Louis 1982
559                zucf = 1./(1.+3.0*CB*CC*cdmn(i)*SQRT(ABS(zri(i)) &
560                      *(1.0+zgeop1(i)/(RG*z0m(i)))))
561                FM(i) = AMAX1((1.-2.0*CB*zri(i)*zucf),f_ri_cd_min)
562                FH(i) = AMAX1((1.-3.0*CB*zri(i)*zucf),f_ri_cd_min)
563         END SELECT
564! Calcul des drags
565         cdm(i)=cdmn(i)*FM(i)
566         cdh(i)=f_cdrag_ter*cdhn(i)*FH(i)
567       ELSE                         
568!'''''''''''''''
569! Cas stables :
570!'''''''''''''''
571         zri(i) = MIN(20.,zri(i))
572         SELECT CASE (iflag_corr_sta)
573           CASE (1) ! Louis 1979 + Mascart 1995
574                FM(i)=MAX(1./((1+BPRIME*zri(i))**2),f_ri_cd_min)
575                FH(i)=FM(i)
576           CASE (2) ! Louis 1982
577                zscf = SQRT(1.+CD*ABS(zri(i)))
578                FM(i)= AMAX1(1. / (1.+2.*CB*zri(i)/zscf), f_ri_cd_min)
579                FH(i)= AMAX1(1./ (1.+3.*CB*zri(i)*zscf), f_ri_cd_min )
580           CASE (3) ! Laurent Li
581                FM(i)=MAX(1.0 / (1.0+10.0*zri(i)*(1+8.0*zri(i))),f_ri_cd_min)
582                FH(i)=FM(i)
583           CASE (4)  ! King 2001
584                if (zri(i) .LT. C2/2.) then
585                  FM(i)=MAX((1.-zri(i)/C2)**2,f_ri_cd_min)
586                  FH(i)=  FM(i)
587                else
588                  FM(i)=MAX(C3*((C2/zri(i))**2),f_ri_cd_min)
589                  FH(i)= FM(i)
590                endif
591           CASE (5) ! MO
592                if (zri(i) .LT. 1./alpha) then
593                  FM(i)=MAX((1.-alpha*zri(i))**2,f_ri_cd_min)
594                  FH(i)=FM(i)
595                else
596                  FM(i)=MAX(1E-7,f_ri_cd_min)
597                  FH(i)=FM(i)
598                endif
599           CASE (6) ! Consistent with turbulence scheme (in stationary case) derived in atke (2023)
600                sm(i) = MAX(0.,cn*(1.-zri(i)/ric))
601                prandtl(i) = pr_neut + zri(i) * pr_slope
602                FM(i) = MAX((sm(i)**(3/2) * sqrt(cepsilon) * (1 - zri(i) / prandtl(i))**(1/2)),f_ri_cd_min)
603                FH(i) = MAX((FM(i) / prandtl(i)), f_ri_cd_min)
604           CASE default ! Louis 1982
605                zscf = SQRT(1.+CD*ABS(zri(i)))
606                FM(i)= AMAX1(1. / (1.+2.*CB*zri(i)/zscf), f_ri_cd_min)
607                FH(i)= AMAX1(1./ (1.+3.*CB*zri(i)*zscf), f_ri_cd_min )
608         END SELECT
609! Calcul des drags
610         cdm(i)=cdmn(i)*FM(i)
611         cdh(i)=f_cdrag_ter*cdhn(i)*FH(i)
612       ENDIF
613     ENDIF ! fin du if (nsrf == is_oce)
614  END DO   !  Fin de la boucle sur l'horizontal
615     
616END SUBROUTINE cdrag
617
618END MODULE cdrag_mod
Note: See TracBrowser for help on using the repository browser.