SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
sso_z0_frictionn.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
5 ! ################################################################################
6 SUBROUTINE sso_z0_friction_n (USS, &
7  psea,puref,prhoa,pu,pv,ppew_a_coef,ppew_b_coef,psfu,psfv)
8 ! ################################################################################
9 !
10 !!**** *SSO_Z0_FRICTION_n * - Computes subgrid-scale orography friction
11 ! according to several options:
12 ! CROUGH='Z01D' : orographic roughness length
13 ! CROUGH='Z04D' : orographic roughness length
14 ! variable with wind direction
15 !!
16 !! PURPOSE
17 !! -------
18 !
19 !!** METHOD
20 !! ------
21 !!
22 !! REFERENCE
23 !! ---------
24 !!
25 !!
26 !! AUTHOR
27 !! ------
28 !! V. Masson
29 !!
30 !! MODIFICATIONS
31 !! -------------
32 !! Original 05/2010
33 !! E. Martin 01/2012 Correction masque (compatibilité XUNDEF)
34 !! B. Decharme 09/2012 new wind implicitation and sea fraction
35 !! B. Decharme 06/2013 CIMPLICIT_WIND in MODD_REPROD_OPER
36 !! J. Escobar 05/2014 for bug with ifort/10, replace WHERE by IF
37 !! J. Escobar 06/2015 bug with gfortran ZZ0EFF to small, change with > XSURF_EPSILON
38 !----------------------------------------------------------------
39 !
40 !
42 !
43 USE modd_reprod_oper, ONLY : cimplicit_wind
44 !
45 USE modd_surf_par, ONLY : xundef, xsurf_epsilon
46 USE modd_csts, ONLY : xkarman, xpi
47 !
48 USE yomhook ,ONLY : lhook, dr_hook
49 USE parkind1 ,ONLY : jprb
50 !
51 IMPLICIT NONE
52 !
53 !* 0.1 declarations of arguments
54 !
55 !
56 TYPE(surf_atm_sso_t), INTENT(INOUT) :: uss
57 !
58 REAL, DIMENSION(:), INTENT(IN) :: psea ! Sea fraction (-)
59 REAL, DIMENSION(:), INTENT(IN) :: puref ! Wind forcing height (m)
60 REAL, DIMENSION(:), INTENT(IN) :: prhoa ! air density (kg/m3)
61 REAL, DIMENSION(:), INTENT(IN) :: pu ! zonal wind (m/s)
62 REAL, DIMENSION(:), INTENT(IN) :: pv ! meridian wind (m/s)
63 REAL, DIMENSION(:), INTENT(IN) :: ppew_a_coef! implicit coefficients (m2s/kg)
64 REAL, DIMENSION(:), INTENT(IN) :: ppew_b_coef! needed if HCOUPLING='I' (m/s)
65 REAL, DIMENSION(:), INTENT(INOUT) :: psfu ! zonal momentum flux (Pa)
66 REAL, DIMENSION(:), INTENT(INOUT) :: psfv ! meridian momentum flux (Pa)
67 !
68 !* 0.2 declarations of local variables
69 !
70 REAL, DIMENSION(SIZE(PU)) :: zwind ! wind strength (m/s)
71 REAL, DIMENSION(SIZE(PU)) :: zwork ! work array
72 REAL, DIMENSION(SIZE(PU)) :: zdir ! wind direction (rad., clockwise)
73 REAL, DIMENSION(SIZE(PU)) :: zalfa ! angle between z0eff J axis and wind direction (rad., clockwise)
74 REAL, DIMENSION(SIZE(PU)) :: zcos2, zsin2
75 REAL, DIMENSION(SIZE(PU)) :: zz0eff ! Momentum Roughness length
76 REAL, DIMENSION(SIZE(PU)) :: zcd ! drag coefficient
77 REAL, DIMENSION(SIZE(PU)) :: zustar2 ! square of friction velocity
78 REAL, DIMENSION(SIZE(PU)) :: zsso_sfu! zonal orographic momentum flux
79 REAL, DIMENSION(SIZE(PU)) :: zsso_sfv! meridian orographic momentum flux
80 LOGICAL, DIMENSION(SIZE(PU)) :: gmask ! mask where SSO exists
81 INTEGER :: ii
82 REAL(KIND=JPRB) :: zhook_handle
83 
84 !-------------------------------------------------------------------------------------
85 !
86 IF (lhook) CALL dr_hook('SSO_Z0_FRICTION_N',0,zhook_handle)
87 !
88 zwork(:) = xundef
89 !
90 !* 1. roughness length formalism
91 ! --------------------------
92 !
93 !* wind strength
94 !
95 zwind(:) = sqrt(pu(:)**2+pv(:)**2)
96 !
97 !* wind direction
98 !
99 zdir(:) = 0.
100 WHERE (zwind(:)>0.) zdir(:)=atan2(pu(:),pv(:))
101 !
102 !* default value
103 !
104 gmask(:)=(psea(:)/=1..AND. uss%XZ0REL(:)/=0.)
105 zz0eff(:) = xundef
106 !
107 !* 2. Constant orographic roughness length
108 ! ------------------------------------
109 !
110 IF (uss%CROUGH=="Z01D") zz0eff(:) = uss%XZ0REL(:)
111 !
112 !* 3. Directionnal roughness length
113 ! -----------------------------
114 !
115 IF (uss%CROUGH=="Z04D") THEN
116  DO ii=1,SIZE(gmask)
117  IF (gmask(ii)) THEN
118  !
119  zalfa(ii) = zdir(ii) - uss%XZ0EFFJPDIR(ii) * xpi/180.
120  !
121  IF (zalfa(ii)<=-xpi) THEN
122  zalfa(ii) = zalfa(ii) + 2.*xpi
123  ELSEIF(zalfa(ii)> xpi) THEN
124  zalfa(ii) = zalfa(ii) - 2.*xpi
125  END IF
126  !
127  IF (zalfa(ii)>=-xpi.AND.zalfa(ii)<=xpi) THEN
128  !
129  zsin2(ii) = sin(zalfa(ii))**2
130  zcos2(ii) = cos(zalfa(ii))**2
131  !
132  IF (zalfa(ii)<0.) THEN
133  zz0eff(ii)=uss%XZ0EFFIM(ii)*zsin2(ii)
134  ELSE
135  zz0eff(ii)=uss%XZ0EFFIP(ii)*zsin2(ii)
136  END IF
137  !
138  IF (zalfa(ii)>=-xpi/2. .AND. zalfa(ii)<xpi/2.) THEN
139  zz0eff(ii) = zz0eff(ii) + uss%XZ0EFFJP(ii)*zcos2(ii)
140  ELSE
141  zz0eff(ii) = zz0eff(ii) + uss%XZ0EFFJM(ii)*zcos2(ii)
142  END IF
143  !
144  END IF
145  !
146  END IF
147  END DO
148 ENDIF
149 !
150 !* 4. Friction coefficient
151 ! --------------------
152 !
153 zcd(:) = 0.
154 zustar2(:) = 0.
155 !
156 gmask(:)=(gmask(:).AND.zz0eff(:)>xsurf_epsilon)
157 !
158 DO ii=1,SIZE(gmask)
159  !
160  IF (gmask(ii)) THEN
161  !
162  !* sets a limit to roughness length
163  zz0eff(ii) = min(zz0eff(ii),puref(ii)/uss%XFRACZ0)
164  !
165  ! neutral case
166  zcd(ii) = (xkarman/log(puref(ii)/zz0eff(ii)))**2
167  END IF
168  !
169 END DO
170 !
171 !* 5. Friction due to orography
172 ! -------------------------
173 !
174 ! Modify flux-form implicit coupling coefficients:
175 !
176 IF(cimplicit_wind=='OLD')THEN
177 ! old implicitation
178  zustar2(:) = zcd(:)*zwind(:)*ppew_b_coef(:) &
179  / (1.0-prhoa(:)*zcd(:)*zwind(:)*ppew_a_coef(:))
180 ELSE
181 ! new implicitation
182  zustar2(:) = (zcd(:)*zwind(:)*(2.*ppew_b_coef(:)-zwind(:)) ) &
183  / (1.0-2.0*prhoa(:)*zcd(:)*zwind(:)*ppew_a_coef(:))
184 ENDIF
185 !
186 WHERE (gmask(:))
187 !
188  zwork(:) = prhoa(:)*ppew_a_coef(:)*zustar2(:) + ppew_b_coef(:)
189  zwork(:) = max(zwork(:),0.)
190 !
191  WHERE(ppew_a_coef(:)/= 0.)
192  zustar2(:) = max( ( zwork(:) - ppew_b_coef(:) ) / (prhoa(:)*ppew_a_coef(:)), 0.)
193  ENDWHERE
194 !
195 END WHERE
196 !
197 !* 6. Projection of friction on wind components
198 ! -----------------------------------------
199 !
200 zsso_sfu(:) = 0.
201 zsso_sfv(:) = 0.
202 WHERE (zwind(:)>0.)
203  zsso_sfu(:) = - pu(:)/zwind(:) * zustar2(:) * prhoa(:)
204  zsso_sfv(:) = - pv(:)/zwind(:) * zustar2(:) * prhoa(:)
205 END WHERE
206 !
207 !* 7. Adds orographic friction to other sources of friction
208 ! -----------------------------------------------------
209 !
210 psfu(:) = psfu(:) + zsso_sfu(:) * (1.0-psea(:))
211 psfv(:) = psfv(:) + zsso_sfv(:) * (1.0-psea(:))
212 !
213 IF (lhook) CALL dr_hook('SSO_Z0_FRICTION_N',1,zhook_handle)
214 !
215 !-------------------------------------------------------------------------------------
216 !
217 END SUBROUTINE sso_z0_friction_n
subroutine sso_z0_friction_n(USS, PSEA, PUREF, PRHOA, PU, PV, PPEW_A_COEF, PPEW_B_COEF, PSFU, PSFV)