- Timestamp:
- Sep 4, 2023, 10:17:16 AM (10 months ago)
- Location:
- LMDZ6/branches/LMDZ_cdrag_LSCE
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/branches/LMDZ_cdrag_LSCE
- Property svn:mergeinfo changed
-
LMDZ6/branches/LMDZ_cdrag_LSCE/libf/phylmd/lscp_tools_mod.F90
r4072 r4669 16 16 ! 3212–3234. https://doi.org/10.1029/2019MS001642 17 17 18 18 use lscp_ini_mod, only: iflag_vice, ffallv_con, ffallv_lsc 19 use lscp_ini_mod, only: cice_velo, dice_velo 20 19 21 IMPLICIT NONE 20 21 INCLUDE "nuage.h"22 INCLUDE "fisrtilp.h"23 22 24 23 INTEGER, INTENT(IN) :: klon … … 33 32 34 33 INTEGER i 35 REAL logvm,iwcg,tempc,phpa, cvel,dvel,fallv_tun34 REAL logvm,iwcg,tempc,phpa,fallv_tun 36 35 REAL m2ice, m2snow, vmice, vmsnow 37 36 REAL aice, bice, asnow, bsnow … … 62 61 63 62 velo(i)=fallv_tun*velo(i)/100.0 ! from cm/s to m/s 64 dvel=0.265 cvel=fallv_tun*65.0*(rho(i)**0.2)*(150./phpa)**0.1566 63 67 64 ELSE IF (iflag_vice .EQ. 2) THEN … … 94 91 vmsnow=vmsnow*((1000./phpa)**0.35) 95 92 velo(i)=fallv_tun*min(vmsnow,vmice)/100. ! to m/s 96 dvel=0.297 cvel=velo(i)/((iwcg/1000.*rho(i))**dvel)98 93 99 94 ELSE 100 95 ! By default, fallspeed velocity of ice crystals according to Heymsfield & Donner 1990 101 velo(i) = fallv_tun*3.29/2.0*((iwcg/1000.)**0.16) 102 dvel=0.16 103 cvel=fallv_tun*3.29/2.0*(rho(i)**0.16) 96 velo(i) = fallv_tun*cice_velo*((iwcg/1000.)**dice_velo) 104 97 ENDIF 105 98 ENDDO … … 109 102 110 103 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 111 SUBROUTINE ICEFRAC_LSCP(klon, temp, sig, icefrac, dicefracdT)104 SUBROUTINE ICEFRAC_LSCP(klon, temp, iflag_ice_thermo, distcltop, icefrac, dicefracdT) 112 105 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 113 106 … … 120 113 121 114 USE print_control_mod, ONLY: lunout, prt_level 115 USE lscp_ini_mod, ONLY: t_glace_min, t_glace_max, exposant_glace, iflag_t_glace 116 USE lscp_ini_mod, ONLY : RTT, dist_liq 122 117 123 118 IMPLICIT NONE 124 119 125 126 INCLUDE "YOMCST.h"127 INCLUDE "nuage.h"128 INCLUDE "clesphys.h"129 130 131 ! nuage.h contains:132 ! t_glace_min: if T < Tmin, the cloud is only made of water ice133 ! t_glace_max: if T > Tmax, the cloud is only made of liquid water134 ! exposant_glace: controls the sharpness of the transition135 120 136 121 INTEGER, INTENT(IN) :: klon ! number of horizontal grid points 137 122 REAL, INTENT(IN), DIMENSION(klon) :: temp ! temperature 138 REAL, INTENT(IN), DIMENSION(klon) :: sig 123 REAL, INTENT(IN), DIMENSION(klon) :: distcltop ! distance to cloud top 124 INTEGER, INTENT(IN) :: iflag_ice_thermo 139 125 REAL, INTENT(OUT), DIMENSION(klon) :: icefrac 140 126 REAL, INTENT(OUT), DIMENSION(klon) :: dicefracdT … … 142 128 143 129 INTEGER i 144 REAL sig0,www,tmin_tmp,liqfrac_tmp130 REAL liqfrac_tmp, dicefrac_tmp 145 131 REAL Dv, denomdep,beta,qsi,dqsidt 146 INTEGER exposant_glace_old147 REAL t_glace_min_old148 132 LOGICAL ice_thermo 149 133 150 sig0=0.8 151 t_glace_min_old = RTT - 15.0 152 ice_thermo = (iflag_ice_thermo .EQ. 1).OR.(iflag_ice_thermo .GE. 3) 153 IF (ice_thermo) THEN 154 exposant_glace_old = 2 155 ELSE 156 exposant_glace_old = 6 134 CHARACTER (len = 20) :: modname = 'lscp_tools' 135 CHARACTER (len = 80) :: abort_message 136 137 IF ((iflag_t_glace.LT.2) .OR. (iflag_t_glace.GT.6)) THEN 138 abort_message = 'lscp cannot be used if iflag_t_glace<2 or >6' 139 CALL abort_physic(modname,abort_message,1) 157 140 ENDIF 158 141 159 160 ! calculation of icefrac and dicefrac/dT 142 IF (.NOT.((iflag_ice_thermo .EQ. 1).OR.(iflag_ice_thermo .GE. 3))) THEN 143 abort_message = 'lscp cannot be used without ice thermodynamics' 144 CALL abort_physic(modname,abort_message,1) 145 ENDIF 146 161 147 162 148 DO i=1,klon 163 164 IF (iflag_t_glace.EQ.1) THEN 165 ! Transition to ice close to surface for T<Tmax 166 ! w=1 at the surface and 0 for sig < sig0 167 www=(max(sig(i)-sig0,0.))/(1.-sig0) 168 ELSEIF (iflag_t_glace.GE.2) THEN 169 ! No convertion to ice close to surface 170 www = 0. 171 ENDIF 172 173 tmin_tmp=www*t_glace_max+(1.-www)*t_glace_min 174 liqfrac_tmp= (temp(i)-tmin_tmp) / (t_glace_max-tmin_tmp) 175 liqfrac_tmp = MIN(MAX(liqfrac_tmp,0.0),1.0) 176 177 IF (iflag_t_glace.GE.3) THEN 178 icefrac(i) = 1.0-liqfrac_tmp**exposant_glace 179 IF ((icefrac(i) .GT.0.) .AND. (liqfrac_tmp .GT. 0)) THEN 180 dicefracdT(i)= exposant_glace * ((liqfrac_tmp)**(exposant_glace-1.)) & 181 / (t_glace_min - t_glace_max) 182 ELSE 183 184 dicefracdT(i)=0. 185 ENDIF 186 187 ELSE 149 150 ! old function with sole dependence upon temperature 151 IF (iflag_t_glace .EQ. 2) THEN 152 liqfrac_tmp = (temp(i)-t_glace_min) / (t_glace_max-t_glace_min) 153 liqfrac_tmp = MIN(MAX(liqfrac_tmp,0.0),1.0) 188 154 icefrac(i) = (1.0-liqfrac_tmp)**exposant_glace 189 155 IF (icefrac(i) .GT.0.) THEN … … 196 162 ENDIF 197 163 198 ENDIF 199 200 ENDDO 201 202 203 RETURN 204 164 ENDIF 165 166 ! function of temperature used in CMIP6 physics 167 IF (iflag_t_glace .EQ. 3) THEN 168 liqfrac_tmp = (temp(i)-t_glace_min) / (t_glace_max-t_glace_min) 169 liqfrac_tmp = MIN(MAX(liqfrac_tmp,0.0),1.0) 170 icefrac(i) = 1.0-liqfrac_tmp**exposant_glace 171 IF ((icefrac(i) .GT.0.) .AND. (liqfrac_tmp .GT. 0.)) THEN 172 dicefracdT(i)= exposant_glace * ((liqfrac_tmp)**(exposant_glace-1.)) & 173 / (t_glace_min - t_glace_max) 174 ELSE 175 dicefracdT(i)=0. 176 ENDIF 177 ENDIF 178 179 ! for iflag_t_glace .GE. 4, the liquid fraction depends upon temperature at cloud top 180 ! and then decreases with decreasing height 181 182 !with linear function of temperature at cloud top 183 IF (iflag_t_glace .EQ. 4) THEN 184 liqfrac_tmp = (temp(i)-t_glace_min) / (t_glace_max-t_glace_min) 185 liqfrac_tmp = MIN(MAX(liqfrac_tmp,0.0),1.0) 186 icefrac(i) = MAX(MIN(1.,1.0 - liqfrac_tmp*exp(-distcltop(i)/dist_liq)),0.) 187 dicefrac_tmp = - temp(i)/(t_glace_max-t_glace_min) 188 dicefracdT(i) = dicefrac_tmp*exp(-distcltop(i)/dist_liq) 189 IF ((liqfrac_tmp .LE.0) .OR. (liqfrac_tmp .GE. 1)) THEN 190 dicefracdT(i) = 0. 191 ENDIF 192 ENDIF 193 194 ! with CMIP6 function of temperature at cloud top 195 IF (iflag_t_glace .EQ. 5) THEN 196 liqfrac_tmp = (temp(i)-t_glace_min) / (t_glace_max-t_glace_min) 197 liqfrac_tmp = MIN(MAX(liqfrac_tmp,0.0),1.0) 198 liqfrac_tmp = liqfrac_tmp**exposant_glace 199 icefrac(i) = MAX(MIN(1.,1.0 - liqfrac_tmp*exp(-distcltop(i)/dist_liq)),0.) 200 IF ((liqfrac_tmp .LE.0) .OR. (liqfrac_tmp .GE. 1)) THEN 201 dicefracdT(i) = 0. 202 ELSE 203 dicefracdT(i) = exposant_glace*((liqfrac_tmp)**(exposant_glace-1.))/(t_glace_min- t_glace_max) & 204 *exp(-distcltop(i)/dist_liq) 205 ENDIF 206 ENDIF 207 208 ! with modified function of temperature at cloud top 209 ! to get largere values around 260 K, works well with t_glace_min = 241K 210 IF (iflag_t_glace .EQ. 6) THEN 211 IF (temp(i) .GT. t_glace_max) THEN 212 liqfrac_tmp = 1. 213 ELSE 214 liqfrac_tmp = -((temp(i)-t_glace_max) / (t_glace_max-t_glace_min))**2+1. 215 ENDIF 216 liqfrac_tmp = MIN(MAX(liqfrac_tmp,0.0),1.0) 217 icefrac(i) = MAX(MIN(1.,1.0 - liqfrac_tmp*exp(-distcltop(i)/dist_liq)),0.) 218 IF ((liqfrac_tmp .LE.0) .OR. (liqfrac_tmp .GE. 1)) THEN 219 dicefracdT(i) = 0. 220 ELSE 221 dicefracdT(i) = 2*((temp(i)-t_glace_max) / (t_glace_max-t_glace_min))/(t_glace_max-t_glace_min) & 222 *exp(-distcltop(i)/dist_liq) 223 ENDIF 224 ENDIF 225 226 227 228 ENDDO ! klon 229 230 RETURN 231 205 232 END SUBROUTINE ICEFRAC_LSCP 206 233 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ … … 276 303 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 277 304 305 use lscp_ini_mod, only: iflag_gammasat, t_glace_min, RTT 278 306 279 307 IMPLICIT NONE 280 308 281 include "YOMCST.h"282 include "YOETHF.h"283 include "FCTTRE.h"284 include "nuage.h"285 309 286 310 INTEGER, INTENT(IN) :: klon ! number of horizontal grid points … … 348 372 349 373 END SUBROUTINE CALC_GAMMASAT 350 351 374 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 375 376 377 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 378 SUBROUTINE DISTANCE_TO_CLOUD_TOP(klon,klev,k,temp,pplay,paprs,rneb,distcltop1D) 379 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 380 381 USE lscp_ini_mod, ONLY : rd,rg,tresh_cl 382 383 IMPLICIT NONE 384 385 INTEGER, INTENT(IN) :: klon,klev !number of horizontal and vertical grid points 386 INTEGER, INTENT(IN) :: k ! vertical index 387 REAL, INTENT(IN), DIMENSION(klon,klev) :: temp ! temperature in K 388 REAL, INTENT(IN), DIMENSION(klon,klev) :: pplay ! pressure middle layer in Pa 389 REAL, INTENT(IN), DIMENSION(klon,klev+1) :: paprs ! pressure interfaces in Pa 390 REAL, INTENT(IN), DIMENSION(klon,klev) :: rneb ! cloud fraction 391 392 REAL, INTENT(OUT), DIMENSION(klon) :: distcltop1D ! distance from cloud top 393 394 REAL dzlay(klon,klev) 395 REAL zlay(klon,klev) 396 REAL dzinterf 397 INTEGER i,k_top, kvert 398 LOGICAL bool_cl 399 400 401 DO i=1,klon 402 ! Initialization height middle of first layer 403 dzlay(i,1) = Rd * temp(i,1) / rg * log(paprs(i,1)/paprs(i,2)) 404 zlay(i,1) = dzlay(i,1)/2 405 406 DO kvert=2,klev 407 IF (kvert.EQ.klev) THEN 408 dzlay(i,kvert) = 2*(rd * temp(i,kvert) / rg * log(paprs(i,kvert)/pplay(i,kvert))) 409 ELSE 410 dzlay(i,kvert) = rd * temp(i,kvert) / rg * log(paprs(i,kvert)/paprs(i,kvert+1)) 411 ENDIF 412 dzinterf = rd * temp(i,kvert) / rg * log(pplay(i,kvert-1)/pplay(i,kvert)) 413 zlay(i,kvert) = zlay(i,kvert-1) + dzinterf 414 ENDDO 415 ENDDO 416 417 k_top = k 418 DO i=1,klon 419 IF (rneb(i,k) .LE. tresh_cl) THEN 420 bool_cl = .FALSE. 421 ELSE 422 bool_cl = .TRUE. 423 ENDIF 424 425 DO WHILE ((bool_cl) .AND. (k_top .LE. klev)) 426 ! find cloud top 427 IF (rneb(i,k_top) .GT. tresh_cl) THEN 428 k_top = k_top + 1 429 ELSE 430 bool_cl = .FALSE. 431 k_top = k_top - 1 432 ENDIF 433 ENDDO 434 k_top=min(k_top,klev) 435 436 !dist to top is dist between current layer and layer of cloud top (from middle to middle) + dist middle to 437 !interf for layer of cloud top 438 distcltop1D(i) = zlay(i,k_top) - zlay(i,k) + dzlay(i,k_top)/2 439 ENDDO ! klon 440 441 END SUBROUTINE DISTANCE_TO_CLOUD_TOP 352 442 !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 353 443
Note: See TracChangeset
for help on using the changeset viewer.