[3] | 1 | ! |
---|
| 2 | ! $Header: /home/cvsroot/LMDZ4/libf/phylmd/interface_surf.F90,v 1.6 2005/02/24 09:58:18 fairhead Exp $ |
---|
| 3 | ! |
---|
| 4 | |
---|
| 5 | MODULE interface_surf |
---|
| 6 | |
---|
| 7 | ! Ce module regroupe toutes les routines gerant l'interface entre le modele |
---|
| 8 | ! atmospherique et les modeles de surface (sols continentaux, oceans, glaces) |
---|
| 9 | ! Les routines sont les suivantes: |
---|
| 10 | ! |
---|
| 11 | ! interfsurf_*: routines d'aiguillage vers les interfaces avec les |
---|
| 12 | ! differents modeles de surface |
---|
| 13 | ! |
---|
| 14 | ! L. Fairhead, LMD, 02/2000 |
---|
| 15 | |
---|
| 16 | USE ioipsl |
---|
| 17 | |
---|
| 18 | IMPLICIT none |
---|
| 19 | |
---|
| 20 | PRIVATE |
---|
| 21 | PUBLIC :: interfsurf,interfsurf_hq |
---|
| 22 | |
---|
| 23 | INTERFACE interfsurf |
---|
| 24 | module procedure interfsurf_hq |
---|
| 25 | END INTERFACE |
---|
| 26 | |
---|
[97] | 27 | #include "YOMCST.h" |
---|
[3] | 28 | |
---|
| 29 | CONTAINS |
---|
| 30 | ! |
---|
| 31 | !############################################################################ |
---|
| 32 | ! |
---|
| 33 | ! ADAPTATION GCM POUR CP(T) |
---|
| 34 | SUBROUTINE interfsurf_hq(itime, dtime, rmu0, & |
---|
| 35 | & klon, iim, jjm, knon, & |
---|
| 36 | & rlon, rlat, cufi, cvfi, & |
---|
| 37 | & debut, lafin, soil_model, nsoilmx, tsoil, & |
---|
| 38 | & zlev, u1_lay, v1_lay, temp_air, epot_air, & |
---|
| 39 | & tq_cdrag, petAcoef, petBcoef, & |
---|
| 40 | & sollw, sollwdown, swnet, swdown, & |
---|
| 41 | & fder, taux, tauy, & |
---|
| 42 | & albedo, & |
---|
| 43 | & tsurf, pkh1, p1lay, radsol, & |
---|
| 44 | & fluxsens, dflux_s, & |
---|
| 45 | & tsol_rad, tsurf_new, alb_new) |
---|
| 46 | |
---|
[973] | 47 | use write_field_phy |
---|
[3] | 48 | |
---|
[973] | 49 | IMPLICIT none |
---|
| 50 | |
---|
[3] | 51 | ! Cette routine sert d'aiguillage entre l'atmosphere et la surface en general |
---|
| 52 | ! (sols continentaux, oceans, glaces) pour les fluxs de chaleur et d'humidite. |
---|
| 53 | ! En pratique l'interface se fait entre la couche limite du modele |
---|
| 54 | ! atmospherique (clmain.F) et les routines de surface (sechiba, oasis, ...) |
---|
| 55 | ! |
---|
| 56 | ! |
---|
| 57 | ! L.Fairhead 02/2000 |
---|
| 58 | ! |
---|
| 59 | ! input: |
---|
| 60 | ! itime numero du pas de temps |
---|
| 61 | ! klon nombre total de points de grille |
---|
| 62 | ! iim, jjm nbres de pts de grille |
---|
| 63 | ! dtime pas de temps de la physique (en s) |
---|
| 64 | ! rmu0 cosinus de l'angle solaire zenithal |
---|
| 65 | ! knon nombre de points de la surface a traiter |
---|
| 66 | ! rlon longitudes |
---|
| 67 | ! rlat latitudes |
---|
| 68 | ! cufi,cvfi resolution des mailles en x et y (m) |
---|
| 69 | ! debut logical: 1er appel a la physique |
---|
| 70 | ! lafin logical: dernier appel a la physique |
---|
| 71 | ! zlev hauteur de la premiere couche |
---|
| 72 | ! u1_lay vitesse u 1ere couche |
---|
| 73 | ! v1_lay vitesse v 1ere couche |
---|
| 74 | ! temp_air temperature de l'air 1ere couche |
---|
| 75 | ! epot_air temp potentielle de l'air |
---|
| 76 | ! tq_cdrag cdrag |
---|
| 77 | ! petAcoef coeff. A de la resolution de la CL pour t |
---|
| 78 | ! petBcoef coeff. B de la resolution de la CL pour t |
---|
| 79 | ! sollw flux IR net a la surface |
---|
| 80 | ! sollwdown flux IR descendant a la surface |
---|
| 81 | ! swnet flux solaire net |
---|
| 82 | ! swdown flux solaire entrant a la surface |
---|
| 83 | ! albedo albedo de la surface |
---|
| 84 | ! tsurf temperature de surface |
---|
| 85 | ! pkh1 fct Exner à la surface: RCPD*(paprs(1)/preff)**RKAPPA |
---|
| 86 | ! p1lay pression 1er niveau (milieu de couche) |
---|
| 87 | ! radsol rayonnement net aus sol (LW + SW) |
---|
| 88 | ! fder derivee des flux (pour le couplage) |
---|
| 89 | ! taux, tauy tension de vents |
---|
| 90 | ! |
---|
| 91 | ! output: |
---|
| 92 | ! fluxsens flux de chaleur sensible |
---|
| 93 | ! tsol_rad |
---|
| 94 | ! tsurf_new temperature au sol |
---|
| 95 | ! alb_new albedo |
---|
| 96 | |
---|
| 97 | #include "iniprint.h" |
---|
| 98 | |
---|
| 99 | |
---|
| 100 | ! Parametres d'entree |
---|
| 101 | integer, intent(IN) :: itime |
---|
| 102 | integer, intent(IN) :: iim, jjm |
---|
| 103 | integer, intent(IN) :: klon |
---|
| 104 | real, intent(IN) :: dtime |
---|
| 105 | real, intent(IN) :: rmu0(klon) |
---|
| 106 | integer, intent(IN) :: knon |
---|
| 107 | logical, intent(IN) :: debut, lafin |
---|
| 108 | real, dimension(klon), intent(IN) :: rlon, rlat |
---|
| 109 | real, dimension(klon), intent(IN) :: cufi, cvfi |
---|
| 110 | real, dimension(klon), intent(INOUT) :: tq_cdrag |
---|
| 111 | real, dimension(klon), intent(IN) :: zlev |
---|
| 112 | real, dimension(klon), intent(IN) :: u1_lay, v1_lay |
---|
| 113 | real, dimension(klon), intent(IN) :: temp_air |
---|
| 114 | real, dimension(klon), intent(IN) :: epot_air |
---|
| 115 | real, dimension(klon), intent(IN) :: petAcoef |
---|
| 116 | real, dimension(klon), intent(IN) :: petBcoef |
---|
| 117 | real, dimension(klon), intent(IN) :: sollw, sollwdown, swnet, swdown |
---|
| 118 | real, dimension(klon), intent(IN) :: albedo |
---|
| 119 | real, dimension(klon), intent(IN) :: tsurf, pkh1, p1lay |
---|
| 120 | REAL, DIMENSION(klon), INTENT(INOUT) :: radsol,fder |
---|
| 121 | real, dimension(klon), intent(IN) :: taux, tauy |
---|
| 122 | !! PB ajout pour soil |
---|
| 123 | logical :: soil_model |
---|
| 124 | integer :: nsoilmx |
---|
| 125 | REAL, DIMENSION(klon, nsoilmx) :: tsoil |
---|
| 126 | REAL, dimension(klon) :: soilcap |
---|
| 127 | REAL, dimension(klon) :: soilflux |
---|
| 128 | ! Parametres de sortie |
---|
| 129 | real, dimension(klon), intent(OUT):: fluxsens |
---|
| 130 | real, dimension(klon), intent(OUT):: tsol_rad, tsurf_new, alb_new |
---|
| 131 | real, dimension(klon), intent(OUT):: dflux_s |
---|
| 132 | |
---|
| 133 | ! Local |
---|
| 134 | character (len = 20),save :: modname = 'interfsurf_hq' |
---|
| 135 | character (len = 80) :: abort_message |
---|
| 136 | integer, save :: error |
---|
| 137 | integer :: ii, index |
---|
| 138 | logical,save :: check = .false. |
---|
| 139 | real, dimension(klon):: cal, beta, capsol |
---|
| 140 | real, dimension(klon):: tsurf_temp, zcp |
---|
| 141 | INTEGER,dimension(1) :: iloc |
---|
| 142 | INTEGER :: isize |
---|
| 143 | real, dimension(klon):: fder_prev |
---|
| 144 | |
---|
| 145 | if (check) write(*,*) 'Entree ', modname |
---|
[973] | 146 | |
---|
[3] | 147 | ! Initialisations diverses |
---|
| 148 | ! |
---|
| 149 | cal = 999999. ; beta = 999999. ; capsol = 999999. |
---|
| 150 | alb_new = albedo |
---|
| 151 | tsurf_new = 999999. |
---|
| 152 | |
---|
| 153 | ! ADAPTATION GCM POUR CP(T) |
---|
[973] | 154 | do ii=1,klon |
---|
| 155 | zcp(ii)=cpdet(tsurf(ii)) |
---|
| 156 | enddo |
---|
[3] | 157 | |
---|
| 158 | IF (soil_model) THEN |
---|
| 159 | CALL soil(dtime, knon, tsurf, tsoil,soilcap, soilflux) |
---|
| 160 | cal(1:knon) = zcp(1:knon) / soilcap(1:knon) |
---|
[973] | 161 | ! for tests: |
---|
| 162 | ! call writefield_phy('interfsurf_hq_zcp',zcp,1) |
---|
| 163 | ! call writefield_phy('interfsurf_hq_cal',cal,1) |
---|
| 164 | ! call writefield_phy('interfsurf_hq_soilcap',soilcap,1) |
---|
[3] | 165 | ! print*,"DIAGNOSTIC SOIL" |
---|
| 166 | ! print*,"soilcap=",soilcap |
---|
| 167 | ! print*,"soilflux=",soilflux |
---|
| 168 | ! print*,"radsol=",radsol(knon/2) |
---|
| 169 | radsol(1:knon) = radsol(1:knon) + soilflux(1:knon) |
---|
| 170 | ELSE |
---|
| 171 | ! abort_message = "PAS DE MODELE DE SOL: CALCUL SOILCAP!!" |
---|
| 172 | ! call abort_gcm(modname,abort_message,1) |
---|
| 173 | ! VENUS: Valeur pour inertie = 200: |
---|
| 174 | soilcap = 14735. |
---|
| 175 | print*,"PAS DE MODELE DE SOL, soilcap=",soilcap |
---|
| 176 | cal(1:knon) = zcp(1:knon) / soilcap(1:knon) |
---|
| 177 | ENDIF |
---|
| 178 | ! ADAPTATION GCM POUR CP(T) |
---|
| 179 | CALL calcul_fluxs( klon, knon, dtime, & |
---|
| 180 | & tsurf, zcp, pkh1, p1lay, cal, beta, tq_cdrag, & |
---|
| 181 | & radsol, temp_air, u1_lay, v1_lay, & |
---|
| 182 | & petAcoef, petBcoef, & |
---|
| 183 | & tsurf_new, fluxsens, dflux_s ) |
---|
| 184 | |
---|
| 185 | END SUBROUTINE interfsurf_hq |
---|
| 186 | |
---|
| 187 | ! |
---|
| 188 | !######################################################################### |
---|
| 189 | ! |
---|
| 190 | SUBROUTINE calcul_fluxs( klon, knon, dtime, & |
---|
| 191 | ! ADAPTATION GCM POUR CP(T) |
---|
| 192 | & tsurf, zcp, pkh1, p1lay, cal, beta, coef1lay, & |
---|
| 193 | & radsol, t1lay, u1lay, v1lay, & |
---|
| 194 | & petAcoef, petBcoef, & |
---|
| 195 | & tsurf_new, fluxsens, dflux_s) |
---|
| 196 | |
---|
[973] | 197 | use write_field_phy |
---|
| 198 | |
---|
| 199 | IMPLICIT none |
---|
| 200 | |
---|
[3] | 201 | ! Cette routine calcule les fluxs en h a l'interface et eventuellement |
---|
| 202 | ! une temperature de surface (au cas ou ok_veget = false) |
---|
| 203 | ! |
---|
| 204 | ! L. Fairhead 4/2000 |
---|
| 205 | ! |
---|
| 206 | ! input: |
---|
| 207 | ! knon nombre de points a traiter |
---|
| 208 | ! tsurf temperature de surface |
---|
| 209 | ! zcp Cp(Tsurf) |
---|
| 210 | ! pkh1 fct Exner à la surface: RCPD*(paprs(1)/preff)**RKAPPA |
---|
| 211 | ! p1lay pression 1er niveau (milieu de couche) |
---|
| 212 | ! cal capacite calorifique du sol |
---|
| 213 | ! beta evap reelle |
---|
| 214 | ! coef1lay coefficient d'echange |
---|
| 215 | ! petAcoef coeff. A de la resolution de la CL pour t |
---|
| 216 | ! petBcoef coeff. B de la resolution de la CL pour t |
---|
| 217 | ! radsol rayonnement net aus sol (LW + SW) |
---|
| 218 | ! |
---|
| 219 | ! output: |
---|
| 220 | ! tsurf_new temperature au sol |
---|
| 221 | ! fluxsens flux de chaleur sensible |
---|
| 222 | ! dflux_s derivee du flux de chaleur sensible / Ts |
---|
| 223 | ! |
---|
| 224 | |
---|
| 225 | ! Parametres d'entree |
---|
| 226 | integer, intent(IN) :: knon, klon |
---|
| 227 | real , intent(IN) :: dtime |
---|
| 228 | real, dimension(klon), intent(IN) :: petAcoef |
---|
| 229 | real, dimension(klon), intent(IN) :: petBcoef |
---|
| 230 | ! ADAPTATION GCM POUR CP(T) |
---|
| 231 | real, dimension(klon), intent(IN) :: tsurf,pkh1,zcp |
---|
| 232 | real, dimension(klon), intent(IN) :: p1lay, cal, beta, coef1lay |
---|
| 233 | real, dimension(klon), intent(IN) :: radsol |
---|
| 234 | real, dimension(klon), intent(IN) :: t1lay, u1lay, v1lay |
---|
| 235 | |
---|
| 236 | ! Parametres sorties |
---|
| 237 | real, dimension(klon), intent(OUT):: tsurf_new, fluxsens |
---|
| 238 | real, dimension(klon), intent(OUT):: dflux_s |
---|
| 239 | |
---|
| 240 | ! Variables locales |
---|
| 241 | integer :: i |
---|
| 242 | real, dimension(klon) :: zx_mh, zx_nh, zx_oh |
---|
| 243 | real, dimension(klon) :: zx_coef |
---|
| 244 | real, dimension(klon) :: ztetasurf,ztetasurf_new |
---|
| 245 | real, dimension(klon) :: zx_k1 |
---|
| 246 | real, dimension(klon) :: zx_q_0 , d_ts |
---|
| 247 | real :: zdelta, zcvm5, zcor |
---|
| 248 | ! |
---|
| 249 | logical, save :: check = .false. |
---|
| 250 | character (len = 20) :: modname = 'calcul_fluxs' |
---|
| 251 | character (len = 80) :: abort_message |
---|
| 252 | logical,save :: first = .true.,second=.false. |
---|
| 253 | |
---|
| 254 | if (check) write(*,*)'Entree ', modname |
---|
| 255 | |
---|
| 256 | IF (check) THEN |
---|
| 257 | WRITE(*,*)' radsol (min, max)' & |
---|
| 258 | & , MINVAL(radsol(1:knon)), MAXVAL(radsol(1:knon)) |
---|
| 259 | CALL flush(6) |
---|
| 260 | ENDIF |
---|
| 261 | |
---|
| 262 | ! |
---|
| 263 | ! Initialisation |
---|
| 264 | ! |
---|
| 265 | fluxsens=0. |
---|
| 266 | dflux_s = 0. |
---|
| 267 | ! |
---|
| 268 | DO i = 1, knon |
---|
| 269 | |
---|
| 270 | zx_coef(i) = coef1lay(i) & |
---|
[892] | 271 | & * SQRT(u1lay(i)**2+v1lay(i)**2) & |
---|
[3] | 272 | & * p1lay(i)/(RD*t1lay(i)) |
---|
| 273 | |
---|
| 274 | ENDDO |
---|
| 275 | |
---|
| 276 | |
---|
| 277 | ! === Calcul de la temperature de surface === |
---|
| 278 | ! |
---|
| 279 | ! MODIF VENUS: |
---|
| 280 | ! Le calcul se fait en temperature potentielle |
---|
| 281 | |
---|
| 282 | call t2tpot(knon,tsurf,ztetasurf,pkh1) |
---|
| 283 | |
---|
| 284 | do i = 1, knon |
---|
| 285 | zx_k1(i) = zx_coef(i) |
---|
| 286 | enddo |
---|
| 287 | |
---|
| 288 | |
---|
| 289 | do i = 1, knon |
---|
| 290 | |
---|
| 291 | ! H |
---|
| 292 | zx_oh(i) = 1. - (zx_k1(i) * petBcoef(i) * dtime) |
---|
| 293 | zx_mh(i) = zx_k1(i) * petAcoef(i) / zx_oh(i) |
---|
| 294 | ! Derives des flux dF/d(teta)s: |
---|
| 295 | zx_nh(i) = - (zx_k1(i) * zcp(i))/ zx_oh(i) |
---|
| 296 | ! Derives des flux dF/dTs (W m-2 K-1): version Terre |
---|
| 297 | ! zx_nh(i) = - (zx_k1(i) * RCPD * zx_pkh(i))/ zx_oh(i) |
---|
| 298 | |
---|
| 299 | ! Tsurface Version Terre |
---|
| 300 | ! |
---|
| 301 | ! tsurf_new(i) = (tsurf(i) + cal(i)/(RCPD * zx_pkh(i)) * dtime * & |
---|
| 302 | ! & (radsol(i) + zx_mh(i)) & |
---|
| 303 | ! & + dif_grnd(i) * t_grnd * dtime)/ & |
---|
| 304 | ! & ( 1. - dtime * cal(i)/(RCPD * zx_pkh(i)) * & |
---|
| 305 | ! & zx_nh(i) & |
---|
| 306 | ! & + dtime * dif_grnd(i)) |
---|
| 307 | ! |
---|
| 308 | ! d_ts(i) = tsurf_new(i) - tsurf(i) |
---|
| 309 | ! fluxsens(i) = zx_mh(i) + zx_nh(i) * tsurf_new(i) |
---|
| 310 | ! Derives des flux dF/dTs (W m-2 K-1): |
---|
| 311 | ! dflux_s(i) = zx_nh(i) |
---|
| 312 | |
---|
| 313 | ! MODIF VENUS : on vire dif_grnd (=0) et t_grnd |
---|
| 314 | ! et on travaille en teta |
---|
| 315 | |
---|
| 316 | ztetasurf_new(i) = (ztetasurf(i) + cal(i)/zcp(i) * dtime * & |
---|
| 317 | & (radsol(i) + zx_mh(i)) & |
---|
| 318 | & ) / & |
---|
| 319 | & ( 1. - cal(i)/zcp(i) * dtime * & |
---|
| 320 | & zx_nh(i) ) |
---|
| 321 | ENDDO |
---|
| 322 | |
---|
| 323 | call tpot2t(knon,ztetasurf_new,tsurf_new,pkh1) |
---|
| 324 | |
---|
| 325 | do i = 1, knon |
---|
| 326 | d_ts(i) = tsurf_new(i) - tsurf(i) |
---|
| 327 | fluxsens(i) = zx_mh(i) + zx_nh(i) * ztetasurf_new(i) |
---|
| 328 | ! Derives des flux dF/dTs (W m-2 K-1): |
---|
| 329 | dflux_s(i) = zx_nh(i)*ztetasurf(i)/tsurf(i) |
---|
| 330 | ENDDO |
---|
| 331 | |
---|
[973] | 332 | ! for tests: write output fields... |
---|
| 333 | ! call writefield_phy('calcul_fluxs_d_ts',d_ts,1) |
---|
| 334 | ! call writefield_phy('calcul_fluxs_fluxsens',fluxsens,1) |
---|
| 335 | ! call writefield_phy('calcul_fluxs_dflux_s',dflux_s,1) |
---|
| 336 | |
---|
[3] | 337 | END SUBROUTINE calcul_fluxs |
---|
| 338 | ! |
---|
| 339 | !######################################################################### |
---|
| 340 | ! |
---|
| 341 | END MODULE interface_surf |
---|