[1191] | 1 | !$Id $ |
---|
[5099] | 2 | |
---|
[1191] | 3 | MODULE traclmdz_mod |
---|
[1742] | 4 | |
---|
[5111] | 5 | ! In this module all tracers specific to LMDZ are treated. This module is used |
---|
| 6 | ! only if running without any other chemestry model as INCA or REPROBUS. |
---|
| 7 | USE lmdz_abort_physic, ONLY: abort_physic |
---|
[1403] | 8 | IMPLICIT NONE |
---|
| 9 | |
---|
[5111] | 10 | REAL, DIMENSION(:, :), ALLOCATABLE, SAVE :: masktr ! Masque reservoir de sol traceur |
---|
| 11 | !$OMP THREADPRIVATE(masktr) ! Masque de l'echange avec la surface (1 = reservoir) ou (possible >= 1 ) |
---|
| 12 | REAL, DIMENSION(:, :), ALLOCATABLE, SAVE :: fshtr ! Flux surfacique dans le reservoir de sol |
---|
| 13 | !$OMP THREADPRIVATE(fshtr) |
---|
| 14 | REAL, DIMENSION(:), ALLOCATABLE, SAVE :: hsoltr ! Epaisseur equivalente du reservoir de sol |
---|
| 15 | !$OMP THREADPRIVATE(hsoltr) |
---|
[5099] | 16 | |
---|
[5111] | 17 | !Radioelements: |
---|
| 18 | !-------------- |
---|
[5099] | 19 | |
---|
[5111] | 20 | REAL, DIMENSION(:), ALLOCATABLE, SAVE :: tautr ! Constante de decroissance radioactive |
---|
| 21 | !$OMP THREADPRIVATE(tautr) |
---|
| 22 | REAL, DIMENSION(:), ALLOCATABLE, SAVE :: vdeptr ! Vitesse de depot sec dans la couche Brownienne |
---|
| 23 | !$OMP THREADPRIVATE(vdeptr) |
---|
| 24 | REAL, DIMENSION(:), ALLOCATABLE, SAVE :: scavtr ! Coefficient de lessivage |
---|
| 25 | !$OMP THREADPRIVATE(scavtr) |
---|
| 26 | REAL, DIMENSION(:, :), ALLOCATABLE, SAVE :: srcbe ! Production du beryllium7 dans l atmosphere (U/s/kgA) |
---|
| 27 | !$OMP THREADPRIVATE(srcbe) |
---|
[1191] | 28 | |
---|
[5111] | 29 | LOGICAL, DIMENSION(:), ALLOCATABLE, SAVE :: radio ! radio(it) = true => decroisssance radioactive |
---|
| 30 | !$OMP THREADPRIVATE(radio) |
---|
[1191] | 31 | |
---|
[5111] | 32 | REAL, DIMENSION(:, :), ALLOCATABLE, SAVE :: trs ! Conc. radon ds le sol |
---|
| 33 | !$OMP THREADPRIVATE(trs) |
---|
[1191] | 34 | |
---|
[5111] | 35 | INTEGER, SAVE :: id_aga ! Identification number for tracer : Age of stratospheric air |
---|
| 36 | !$OMP THREADPRIVATE(id_aga) |
---|
| 37 | INTEGER, SAVE :: lev_1p5km ! Approximative vertical layer number at 1.5km above surface, used for calculation of the age of air. The result shouldn't be that sensible to the exactness of this value as long as it is in the lower troposphere. |
---|
| 38 | !$OMP THREADPRIVATE(lev_1p5km) |
---|
[1409] | 39 | |
---|
[5111] | 40 | INTEGER, SAVE :: id_rn, id_pb ! Identification number for tracer : radon (Rn222), lead (Pb210) |
---|
| 41 | !$OMP THREADPRIVATE(id_rn, id_pb) |
---|
[1409] | 42 | |
---|
[5111] | 43 | INTEGER, SAVE :: id_be ! Activation et position du traceur Be7 [ id_be=0 -> desactive ] |
---|
| 44 | !$OMP THREADPRIVATE(id_be) |
---|
[1191] | 45 | |
---|
[5111] | 46 | INTEGER, SAVE :: id_pcsat, id_pcocsat, id_pcq ! traceurs pseudo-vapeur CL qsat, qsat_oc, q |
---|
| 47 | !$OMP THREADPRIVATE(id_pcsat, id_pcocsat, id_pcq) |
---|
| 48 | INTEGER, SAVE :: id_pcs0, id_pcos0, id_pcq0 ! traceurs pseudo-vapeur CL qsat, qsat_oc, q |
---|
| 49 | ! ! qui ne sont pas transportes par la convection |
---|
| 50 | !$OMP THREADPRIVATE(id_pcs0, id_pcos0, id_pcq0) |
---|
[1403] | 51 | |
---|
[5111] | 52 | INTEGER, SAVE :: id_o3 |
---|
| 53 | !$OMP THREADPRIVATE(id_o3) |
---|
| 54 | ! index of ozone tracer with Cariolle parameterization |
---|
| 55 | ! 0 means no ozone tracer |
---|
[1403] | 56 | |
---|
[5111] | 57 | LOGICAL, SAVE :: rnpb = .FALSE. ! Presence du couple Rn222, Pb210 |
---|
| 58 | !$OMP THREADPRIVATE(rnpb) |
---|
[1191] | 59 | |
---|
| 60 | |
---|
| 61 | CONTAINS |
---|
| 62 | |
---|
| 63 | SUBROUTINE traclmdz_from_restart(trs_in) |
---|
[5103] | 64 | ! This SUBROUTINE initialize the module saved variable trs with values from restart file (startphy.nc). |
---|
| 65 | ! This SUBROUTINE is called from phyetat0 after the field trs_in has been read. |
---|
[5111] | 66 | |
---|
[1191] | 67 | USE dimphy |
---|
[4056] | 68 | USE infotrac_phy, ONLY: nbtr |
---|
[5111] | 69 | |
---|
[1191] | 70 | ! Input argument |
---|
[5111] | 71 | REAL, DIMENSION(klon, nbtr), INTENT(IN) :: trs_in |
---|
| 72 | |
---|
[1191] | 73 | ! Local variables |
---|
| 74 | INTEGER :: ierr |
---|
[5111] | 75 | |
---|
[1191] | 76 | ! Allocate restart variables trs |
---|
[5111] | 77 | ALLOCATE(trs(klon, nbtr), stat = ierr) |
---|
| 78 | IF (ierr /= 0) CALL abort_physic('traclmdz_from_restart', 'pb in allocation 1', 1) |
---|
| 79 | |
---|
[1191] | 80 | ! Initialize trs with values read from restart file |
---|
[5111] | 81 | trs(:, :) = trs_in(:, :) |
---|
| 82 | |
---|
[1191] | 83 | END SUBROUTINE traclmdz_from_restart |
---|
| 84 | |
---|
| 85 | |
---|
[1579] | 86 | SUBROUTINE traclmdz_init(pctsrf, xlat, xlon, ftsol, tr_seri, t_seri, pplay, sh, pdtphys, aerosol, lessivage) |
---|
[5103] | 87 | ! This SUBROUTINE allocates and initialize module variables and control variables. |
---|
[1421] | 88 | ! Initialization of the tracers should be done here only for those not found in the restart file. |
---|
[1191] | 89 | USE dimphy |
---|
[4056] | 90 | USE infotrac_phy, ONLY: nbtr, nqtot, tracers, pbl_flg, conv_flg |
---|
[1403] | 91 | USE regr_pr_comb_coefoz_m, ONLY: alloc_coefoz |
---|
| 92 | USE press_coefoz_m, ONLY: press_coefoz |
---|
[5110] | 93 | USE lmdz_grid_phy |
---|
| 94 | USE lmdz_phys_para |
---|
[1785] | 95 | USE indice_sol_mod |
---|
[5112] | 96 | USE lmdz_print_control, ONLY: lunout |
---|
[1191] | 97 | |
---|
[5111] | 98 | ! Input variables |
---|
| 99 | REAL, DIMENSION(klon, nbsrf), INTENT(IN) :: pctsrf ! Pourcentage de sol f(nature du sol) |
---|
| 100 | REAL, DIMENSION(klon), INTENT(IN) :: xlat ! latitudes en degres pour chaque point |
---|
| 101 | REAL, DIMENSION(klon), INTENT(IN) :: xlon ! longitudes en degres pour chaque point |
---|
| 102 | REAL, DIMENSION(klon, nbsrf), INTENT(IN) :: ftsol ! Temperature du sol (surf)(Kelvin) |
---|
| 103 | REAL, DIMENSION(klon, klev, nbtr), INTENT(INOUT) :: tr_seri! Concentration Traceur [U/KgA] |
---|
| 104 | REAL, DIMENSION(klon, klev), INTENT(IN) :: t_seri ! Temperature |
---|
| 105 | REAL, DIMENSION(klon, klev), INTENT(IN) :: pplay ! pression pour le mileu de chaque couche (en Pa) |
---|
| 106 | REAL, DIMENSION(klon, klev), INTENT(IN) :: sh ! humidite specifique |
---|
| 107 | REAL, INTENT(IN) :: pdtphys ! Pas d'integration pour la physique (seconde) |
---|
[1227] | 108 | |
---|
[5111] | 109 | ! Output variables |
---|
| 110 | LOGICAL, DIMENSION(nbtr), INTENT(OUT) :: aerosol |
---|
| 111 | LOGICAL, INTENT(OUT) :: lessivage |
---|
| 112 | |
---|
| 113 | ! Local variables |
---|
[4056] | 114 | INTEGER :: ierr, it, iq, i, k |
---|
[5111] | 115 | REAL, DIMENSION(klon_glo, klev) :: varglo ! variable temporaire sur la grille global |
---|
| 116 | REAL, DIMENSION(klev) :: mintmp, maxtmp |
---|
| 117 | LOGICAL :: zero |
---|
| 118 | ! RomP >>> profil initial Be7 |
---|
[5117] | 119 | INTEGER ilesfil |
---|
[5111] | 120 | parameter (ilesfil = 1) |
---|
[5117] | 121 | INTEGER irr, kradio |
---|
[5111] | 122 | real beryllium(klon, klev) |
---|
| 123 | ! profil initial Pb210 |
---|
[5117] | 124 | INTEGER ilesfil2 |
---|
[5111] | 125 | parameter (ilesfil2 = 1) |
---|
[5117] | 126 | INTEGER irr2, kradio2 |
---|
[5111] | 127 | real plomb(klon, klev) |
---|
| 128 | !! RomP <<< |
---|
| 129 | ! -------------------------------------------- |
---|
| 130 | ! Allocation |
---|
| 131 | ! -------------------------------------------- |
---|
| 132 | ALLOCATE(scavtr(nbtr), stat = ierr) |
---|
| 133 | IF (ierr /= 0) CALL abort_physic('traclmdz_init', 'pb in allocation 9', 1) |
---|
| 134 | scavtr(:) = 1. |
---|
| 135 | |
---|
| 136 | ALLOCATE(radio(nbtr), stat = ierr) |
---|
| 137 | IF (ierr /= 0) CALL abort_physic('traclmdz_init', 'pb in allocation 11', 1) |
---|
[5103] | 138 | radio(:) = .FALSE. ! Par defaut pas decroissance radioactive |
---|
[5111] | 139 | |
---|
| 140 | ALLOCATE(masktr(klon, nbtr), stat = ierr) |
---|
| 141 | IF (ierr /= 0) CALL abort_physic('traclmdz_init', 'pb in allocation 2', 1) |
---|
| 142 | |
---|
| 143 | ALLOCATE(fshtr(klon, nbtr), stat = ierr) |
---|
| 144 | IF (ierr /= 0) CALL abort_physic('traclmdz_init', 'pb in allocation 3', 1) |
---|
| 145 | |
---|
| 146 | ALLOCATE(hsoltr(nbtr), stat = ierr) |
---|
| 147 | IF (ierr /= 0) CALL abort_physic('traclmdz_init', 'pb in allocation 4', 1) |
---|
| 148 | |
---|
| 149 | ALLOCATE(tautr(nbtr), stat = ierr) |
---|
| 150 | IF (ierr /= 0) CALL abort_physic('traclmdz_init', 'pb in allocation 5', 1) |
---|
| 151 | tautr(:) = 0. |
---|
| 152 | |
---|
| 153 | ALLOCATE(vdeptr(nbtr), stat = ierr) |
---|
| 154 | IF (ierr /= 0) CALL abort_physic('traclmdz_init', 'pb in allocation 6', 1) |
---|
[1191] | 155 | vdeptr(:) = 0. |
---|
| 156 | |
---|
[5111] | 157 | lessivage = .TRUE. |
---|
| 158 | !!jyg(20130206) : le choix d activation du lessivage est fait dans phytrac avec iflag_lscav |
---|
| 159 | !! CALL getin('lessivage',lessivage) |
---|
[5116] | 160 | !! IF(lessivage) THEN |
---|
[5111] | 161 | !! PRINT*,'lessivage lsc ON' |
---|
| 162 | !! else |
---|
| 163 | !! PRINT*,'lessivage lsc OFF' |
---|
| 164 | !! endif |
---|
[1191] | 165 | aerosol(:) = .FALSE. ! Tous les traceurs sont des gaz par defaut |
---|
[5099] | 166 | |
---|
[5111] | 167 | ! Recherche des traceurs connus : Be7, O3, CO2,... |
---|
| 168 | ! -------------------------------------------- |
---|
| 169 | id_rn = 0; id_pb = 0; id_aga = 0; id_be = 0; id_o3 = 0 |
---|
| 170 | id_pcsat = 0; id_pcocsat = 0; id_pcq = 0; id_pcs0 = 0; id_pcos0 = 0; id_pcq0 = 0 |
---|
[4056] | 171 | it = 0 |
---|
| 172 | DO iq = 1, nqtot |
---|
[5111] | 173 | IF(.NOT.(tracers(iq)%isInPhysics)) CYCLE |
---|
| 174 | it = it + 1 |
---|
| 175 | SELECT CASE(tracers(iq)%name) |
---|
| 176 | CASE("RN"); id_rn = it ! radon |
---|
| 177 | CASE("PB"); id_pb = it ! plomb |
---|
| 178 | CASE("Aga", "AGA"); id_aga = it ! Age of stratospheric air |
---|
| 179 | CASE("Be", "BE", "Be7", "BE7"); id_be = it ! Recherche du Beryllium 7 |
---|
| 180 | CASE("o3", "O3"); id_o3 = it ! Recherche de l'ozone |
---|
| 181 | CASE("pcsat", "Pcsat"); id_pcsat = it |
---|
| 182 | CASE("pcocsat", "Pcocsat"); id_pcocsat = it |
---|
| 183 | CASE("pcq", "Pcq"); id_pcq = it |
---|
| 184 | CASE("pcs0", "Pcs0"); id_pcs0 = it |
---|
| 185 | CASE("pcos0", "Pcos0"); id_pcos0 = it |
---|
| 186 | CASE("pcq0", "Pcq0"); id_pcq0 = it |
---|
| 187 | CASE DEFAULT |
---|
| 188 | WRITE(lunout, *) 'This is an unknown tracer in LMDZ : ', trim(tracers(iq)%name) |
---|
| 189 | END SELECT |
---|
[4046] | 190 | |
---|
[5111] | 191 | SELECT CASE(tracers(iq)%name) |
---|
| 192 | CASE("PB") !--- RomP >>> profil initial de PB210 |
---|
| 193 | OPEN(ilesfil2, file = 'prof.pb210', status = 'old', iostat = irr2) |
---|
| 194 | IF(irr2 == 0) THEN |
---|
| 195 | READ(ilesfil2, *) kradio2 |
---|
| 196 | WRITE(lunout, *)'number of levels for pb210 profile ', kradio2 |
---|
| 197 | DO k = kradio2, 1, -1; READ (ilesfil2, *) plomb(:, k); |
---|
| 198 | END DO |
---|
| 199 | CLOSE(ilesfil2) |
---|
| 200 | tr_seri(:, :, id_pb) = plomb(:, :) |
---|
| 201 | ELSE |
---|
| 202 | WRITE(lunout, *)'prof.pb210 does not exist: use restart values' |
---|
| 203 | END IF |
---|
| 204 | CASE("Aga", "AGA") |
---|
| 205 | radio(id_aga) = .FALSE. |
---|
| 206 | aerosol(id_aga) = .FALSE. |
---|
| 207 | pbl_flg(id_aga) = 0 |
---|
| 208 | ! Find the first model layer above 1.5km from the surface |
---|
| 209 | IF (klev>=30) THEN |
---|
| 210 | lev_1p5km = 6 !--- NB: This value is for klev=39 |
---|
| 211 | ELSE IF (klev>=10) THEN |
---|
| 212 | lev_1p5km = 5 !--- NB: This value is for klev=19 |
---|
| 213 | ELSE |
---|
| 214 | lev_1p5km = klev / 2 |
---|
| 215 | END IF |
---|
| 216 | CASE("Be", "BE", "Be7", "BE7") |
---|
| 217 | ALLOCATE(srcbe(klon, klev)) |
---|
| 218 | radio(id_be) = .TRUE. |
---|
| 219 | aerosol(id_be) = .TRUE. !--- Le Be est un aerosol |
---|
| 220 | CALL init_be(pctsrf, pplay, masktr(:, id_be), tautr(id_be), vdeptr(id_be), scavtr(id_be), srcbe) |
---|
| 221 | WRITE(lunout, *) 'Initialisation srcBe: OK' |
---|
| 222 | !--- RomP >>> profil initial de Be7 |
---|
| 223 | OPEN(ilesfil, file = 'prof.be7', status = 'old', iostat = irr) |
---|
| 224 | IF(irr == 0) THEN |
---|
| 225 | READ(ilesfil, *) kradio |
---|
| 226 | WRITE(lunout, *)'number of levels for Be7 profile ', kradio |
---|
| 227 | DO k = kradio, 1, -1; READ(ilesfil, *) beryllium(:, k); |
---|
| 228 | END DO |
---|
| 229 | CLOSE(ilesfil) |
---|
| 230 | tr_seri(:, :, id_be) = beryllium(:, :) |
---|
| 231 | ELSE |
---|
| 232 | WRITE(lunout, *)'Prof. Be7 does not exist: use restart values' |
---|
| 233 | END IF |
---|
| 234 | CASE("o3", "O3") !--- Parametrisation par la chimie de Cariolle |
---|
| 235 | CALL alloc_coefoz !--- Allocate ozone coefficients |
---|
| 236 | CALL press_coefoz !--- Read input pressure levels |
---|
| 237 | CASE("pcs0", "Pcs0", "pcos0", "Pcos0", "pcq0", "Pcq0") |
---|
| 238 | conv_flg(it) = 0 !--- No transport by convection for this tracer |
---|
| 239 | END SELECT |
---|
[1403] | 240 | END DO |
---|
| 241 | |
---|
[5111] | 242 | ! Valeurs specifiques pour les traceurs Rn222 et Pb210 |
---|
| 243 | ! ---------------------------------------------- |
---|
| 244 | IF (id_rn/=0 .AND. id_pb/=0) THEN |
---|
| 245 | rnpb = .TRUE. |
---|
| 246 | radio(id_rn) = .TRUE. |
---|
| 247 | radio(id_pb) = .TRUE. |
---|
| 248 | pbl_flg(id_rn) = 0 ! au lieu de clsol=true ! CL au sol calcule |
---|
| 249 | pbl_flg(id_pb) = 0 ! au lieu de clsol=true |
---|
| 250 | aerosol(id_rn) = .FALSE. |
---|
| 251 | aerosol(id_pb) = .TRUE. ! le Pb est un aerosol |
---|
| 252 | |
---|
| 253 | CALL initrrnpb (ftsol, pctsrf, masktr, fshtr, hsoltr, tautr, vdeptr, scavtr) |
---|
[1191] | 254 | END IF |
---|
| 255 | |
---|
[5111] | 256 | ! Check if all tracers have restart values |
---|
| 257 | ! ---------------------------------------------- |
---|
[4056] | 258 | it = 0 |
---|
| 259 | DO iq = 1, nqtot |
---|
[5111] | 260 | IF(.NOT.(tracers(iq)%isAdvected .AND. tracers(iq)%isInPhysics)) CYCLE |
---|
| 261 | it = it + 1 |
---|
| 262 | ! Test if tracer is zero everywhere. |
---|
| 263 | ! Done by master process MPI and master thread OpenMP |
---|
| 264 | CALL gather(tr_seri(:, :, it), varglo) |
---|
| 265 | IF (is_mpi_root .AND. is_omp_root) THEN |
---|
| 266 | mintmp = MINVAL(varglo, dim = 1) |
---|
| 267 | maxtmp = MAXVAL(varglo, dim = 1) |
---|
| 268 | IF (MINVAL(mintmp, dim = 1)==0. .AND. MAXVAL(maxtmp, dim = 1)==0.) THEN |
---|
| 269 | ! Tracer is zero everywhere |
---|
| 270 | zero = .TRUE. |
---|
| 271 | ELSE |
---|
| 272 | zero = .FALSE. |
---|
| 273 | END IF |
---|
| 274 | END IF |
---|
[1403] | 275 | |
---|
[5111] | 276 | ! Distribute variable at all processes |
---|
| 277 | CALL bcast(zero) |
---|
[1403] | 278 | |
---|
[5111] | 279 | ! Initalize tracer that was not found in restart file. |
---|
| 280 | IF (zero) THEN |
---|
| 281 | ! The tracer was not found in restart file or it was equal zero everywhere. |
---|
| 282 | WRITE(lunout, *) "The tracer ", trim(tracers(iq)%name), " will be initialized" |
---|
| 283 | IF (it==id_pcsat .OR. it==id_pcq .OR. & |
---|
| 284 | it==id_pcs0 .OR. it==id_pcq0) THEN |
---|
| 285 | tr_seri(:, :, it) = 100. |
---|
| 286 | ELSE IF (it==id_pcocsat .OR. it==id_pcos0) THEN |
---|
| 287 | DO i = 1, klon |
---|
| 288 | IF (pctsrf (i, is_oce) == 0.) THEN |
---|
| 289 | tr_seri(i, :, it) = 0. |
---|
| 290 | ELSE |
---|
| 291 | tr_seri(i, :, it) = 100. |
---|
| 292 | END IF |
---|
| 293 | END DO |
---|
| 294 | ELSE |
---|
| 295 | ! No specific initialization exist for this tracer |
---|
| 296 | tr_seri(:, :, it) = 0. |
---|
| 297 | END IF |
---|
| 298 | END IF |
---|
[1421] | 299 | END DO |
---|
[1403] | 300 | |
---|
[1191] | 301 | END SUBROUTINE traclmdz_init |
---|
| 302 | |
---|
[1403] | 303 | SUBROUTINE traclmdz(nstep, julien, gmtime, pdtphys, t_seri, paprs, pplay, & |
---|
[5111] | 304 | cdragh, coefh, yu1, yv1, ftsol, pctsrf, xlat, xlon, couchelimite, sh, & |
---|
| 305 | rh, pphi, ustar, wstar, ale_bl, ale_wake, zu10m, zv10m, & |
---|
| 306 | tr_seri, source, d_tr_cl, d_tr_dec, zmasse) !RomP |
---|
| 307 | |
---|
[1191] | 308 | USE dimphy |
---|
[4124] | 309 | USE infotrac_phy, ONLY: nbtr, pbl_flg |
---|
[5117] | 310 | USE lmdz_strings, ONLY: int2str |
---|
[1403] | 311 | USE regr_pr_comb_coefoz_m, ONLY: regr_pr_comb_coefoz |
---|
| 312 | USE o3_chem_m, ONLY: o3_chem |
---|
[1785] | 313 | USE indice_sol_mod |
---|
[5117] | 314 | USE lmdz_q_sat, ONLY: q_sat |
---|
[5144] | 315 | USE lmdz_yomcst |
---|
[1785] | 316 | |
---|
[5144] | 317 | IMPLICIT NONE |
---|
[1191] | 318 | |
---|
[5111] | 319 | !========================================================================== |
---|
| 320 | ! -- DESCRIPTION DES ARGUMENTS -- |
---|
| 321 | !========================================================================== |
---|
[1191] | 322 | |
---|
[5111] | 323 | ! Input arguments |
---|
[5099] | 324 | |
---|
[5111] | 325 | !Configuration grille,temps: |
---|
| 326 | INTEGER, INTENT(IN) :: nstep ! nombre d'appels de la physiq |
---|
| 327 | INTEGER, INTENT(IN) :: julien ! Jour julien |
---|
| 328 | REAL, INTENT(IN) :: gmtime |
---|
| 329 | REAL, INTENT(IN) :: pdtphys ! Pas d'integration pour la physique (seconde) |
---|
| 330 | REAL, DIMENSION(klon), INTENT(IN) :: xlat ! latitudes pour chaque point |
---|
| 331 | REAL, INTENT(IN) :: xlon(:) ! dim(klon) longitude |
---|
[1191] | 332 | |
---|
[5111] | 333 | !Physique: |
---|
| 334 | !-------- |
---|
| 335 | REAL, DIMENSION(klon, klev), INTENT(IN) :: t_seri ! Temperature |
---|
| 336 | REAL, DIMENSION(klon, klev + 1), INTENT(IN) :: paprs ! pression pour chaque inter-couche (en Pa) |
---|
| 337 | REAL, DIMENSION(klon, klev), INTENT(IN) :: pplay ! pression pour le mileu de chaque couche (en Pa) |
---|
[5117] | 338 | REAL, INTENT(IN) :: zmasse (:, :) ! dim(klon,klev) density of air, in kg/m2 |
---|
[1191] | 339 | |
---|
| 340 | |
---|
[5111] | 341 | !Couche limite: |
---|
| 342 | !-------------- |
---|
[5099] | 343 | |
---|
[5111] | 344 | REAL, DIMENSION(klon), INTENT(IN) :: cdragh ! coeff drag pour T et Q |
---|
| 345 | REAL, DIMENSION(klon, klev), INTENT(IN) :: coefh ! coeff melange CL (m**2/s) |
---|
| 346 | REAL, DIMENSION(klon), INTENT(IN) :: yu1 ! vents au premier niveau |
---|
| 347 | REAL, DIMENSION(klon), INTENT(IN) :: yv1 ! vents au premier niveau |
---|
| 348 | LOGICAL, INTENT(IN) :: couchelimite |
---|
| 349 | REAL, DIMENSION(klon, klev), INTENT(IN) :: sh ! humidite specifique |
---|
| 350 | REAL, DIMENSION(klon, klev), INTENT(IN) :: rh ! Humidite relative |
---|
| 351 | REAL, DIMENSION(klon, klev), INTENT(IN) :: pphi ! geopotentie |
---|
| 352 | REAL, DIMENSION(klon), INTENT(IN) :: ustar ! ustar (m/s) |
---|
| 353 | REAL, DIMENSION(klon), INTENT(IN) :: wstar, ale_bl, ale_wake ! wstar (m/s) and Avail. Lifti. Energ. |
---|
| 354 | REAL, DIMENSION(klon), INTENT(IN) :: zu10m ! vent zonal 10m (m/s) |
---|
| 355 | REAL, DIMENSION(klon), INTENT(IN) :: zv10m ! vent zonal 10m (m/s) |
---|
[1191] | 356 | |
---|
[5111] | 357 | ! Arguments necessaires pour les sources et puits de traceur: |
---|
| 358 | REAL, DIMENSION(klon, nbsrf), INTENT(IN) :: ftsol ! Temperature du sol (surf)(Kelvin) |
---|
| 359 | REAL, DIMENSION(klon, nbsrf), INTENT(IN) :: pctsrf ! Pourcentage de sol f(nature du sol) |
---|
[1191] | 360 | |
---|
[5111] | 361 | ! InOutput argument |
---|
| 362 | REAL, DIMENSION(klon, klev, nbtr), INTENT(INOUT) :: tr_seri ! Concentration Traceur [U/KgA] |
---|
[1191] | 363 | |
---|
[5111] | 364 | ! Output argument |
---|
| 365 | REAL, DIMENSION(klon, nbtr), INTENT(OUT) :: source ! a voir lorsque le flux de surface est prescrit |
---|
| 366 | REAL, DIMENSION(klon, klev, nbtr), INTENT(OUT) :: d_tr_cl ! Td couche limite/traceur |
---|
[1191] | 367 | |
---|
[5111] | 368 | !======================================================================================= |
---|
| 369 | ! -- VARIABLES LOCALES TRACEURS -- |
---|
| 370 | !======================================================================================= |
---|
[1191] | 371 | |
---|
| 372 | INTEGER :: i, k, it |
---|
[1421] | 373 | INTEGER :: lmt_pas ! number of time steps of "physics" per day |
---|
[1191] | 374 | |
---|
[5111] | 375 | REAL, DIMENSION(klon) :: d_trs ! Td dans le reservoir |
---|
| 376 | REAL, DIMENSION(klon, klev) :: qsat ! pression de la vapeur a saturation |
---|
| 377 | REAL, DIMENSION(klon, klev, nbtr) :: d_tr_dec ! Td radioactive |
---|
| 378 | REAL :: zrho ! Masse Volumique de l'air KgA/m3 |
---|
| 379 | REAL :: amn, amx |
---|
[5099] | 380 | |
---|
[5111] | 381 | !================================================================= |
---|
| 382 | ! Ajout de la production en Be7 (Beryllium) srcbe U/s/kgA |
---|
| 383 | !================================================================= |
---|
[5099] | 384 | |
---|
[5111] | 385 | IF (id_be /= 0) THEN |
---|
| 386 | DO k = 1, klev |
---|
| 387 | DO i = 1, klon |
---|
| 388 | tr_seri(i, k, id_be) = tr_seri(i, k, id_be) + srcbe(i, k) * pdtphys |
---|
| 389 | END DO |
---|
| 390 | END DO |
---|
| 391 | WRITE(*, *) 'Ajout srcBe dans tr_seri: OK' |
---|
[1191] | 392 | END IF |
---|
[1421] | 393 | |
---|
| 394 | |
---|
[5111] | 395 | !================================================================= |
---|
| 396 | ! Update pseudo-vapor tracers |
---|
| 397 | !================================================================= |
---|
[1421] | 398 | |
---|
[5111] | 399 | CALL q_sat(klon * klev, t_seri, pplay, qsat) |
---|
| 400 | |
---|
| 401 | IF (id_pcsat /= 0) THEN |
---|
| 402 | DO k = 1, klev |
---|
| 403 | DO i = 1, klon |
---|
| 404 | IF (pplay(i, k)>=85000.) THEN |
---|
| 405 | tr_seri(i, k, id_pcsat) = qsat(i, k) |
---|
| 406 | ELSE |
---|
| 407 | tr_seri(i, k, id_pcsat) = MIN (qsat(i, k), tr_seri(i, k, id_pcsat)) |
---|
| 408 | END IF |
---|
| 409 | END DO |
---|
| 410 | END DO |
---|
[1403] | 411 | END IF |
---|
[1191] | 412 | |
---|
[5111] | 413 | IF (id_pcocsat /= 0) THEN |
---|
| 414 | DO k = 1, klev |
---|
| 415 | DO i = 1, klon |
---|
| 416 | IF (pplay(i, k)>=85000.) THEN |
---|
| 417 | IF (pctsrf (i, is_oce) > 0.) THEN |
---|
| 418 | tr_seri(i, k, id_pcocsat) = qsat(i, k) |
---|
[1421] | 419 | ELSE |
---|
[5111] | 420 | tr_seri(i, k, id_pcocsat) = 0. |
---|
| 421 | END IF |
---|
| 422 | ELSE |
---|
| 423 | tr_seri(i, k, id_pcocsat) = MIN (qsat(i, k), tr_seri(i, k, id_pcocsat)) |
---|
[1421] | 424 | END IF |
---|
[5111] | 425 | END DO |
---|
[1403] | 426 | END DO |
---|
| 427 | END IF |
---|
| 428 | |
---|
[5111] | 429 | IF (id_pcq /= 0) THEN |
---|
| 430 | DO k = 1, klev |
---|
| 431 | DO i = 1, klon |
---|
| 432 | IF (pplay(i, k)>=85000.) THEN |
---|
| 433 | tr_seri(i, k, id_pcq) = sh(i, k) |
---|
| 434 | ELSE |
---|
| 435 | tr_seri(i, k, id_pcq) = MIN (qsat(i, k), tr_seri(i, k, id_pcq)) |
---|
| 436 | END IF |
---|
| 437 | END DO |
---|
[1403] | 438 | END DO |
---|
| 439 | END IF |
---|
| 440 | |
---|
[5111] | 441 | IF (id_pcs0 /= 0) THEN |
---|
| 442 | DO k = 1, klev |
---|
| 443 | DO i = 1, klon |
---|
| 444 | IF (pplay(i, k)>=85000.) THEN |
---|
| 445 | tr_seri(i, k, id_pcs0) = qsat(i, k) |
---|
| 446 | ELSE |
---|
| 447 | tr_seri(i, k, id_pcs0) = MIN (qsat(i, k), tr_seri(i, k, id_pcs0)) |
---|
| 448 | END IF |
---|
| 449 | END DO |
---|
[1403] | 450 | END DO |
---|
| 451 | END IF |
---|
| 452 | |
---|
[5111] | 453 | IF (id_pcos0 /= 0) THEN |
---|
| 454 | DO k = 1, klev |
---|
| 455 | DO i = 1, klon |
---|
| 456 | IF (pplay(i, k)>=85000.) THEN |
---|
| 457 | IF (pctsrf (i, is_oce) > 0.) THEN |
---|
| 458 | tr_seri(i, k, id_pcos0) = qsat(i, k) |
---|
[1421] | 459 | ELSE |
---|
[5111] | 460 | tr_seri(i, k, id_pcos0) = 0. |
---|
[1421] | 461 | END IF |
---|
[5111] | 462 | ELSE |
---|
| 463 | tr_seri(i, k, id_pcos0) = MIN (qsat(i, k), tr_seri(i, k, id_pcos0)) |
---|
| 464 | END IF |
---|
| 465 | END DO |
---|
[1403] | 466 | END DO |
---|
| 467 | END IF |
---|
| 468 | |
---|
[5111] | 469 | IF (id_pcq0 /= 0) THEN |
---|
| 470 | DO k = 1, klev |
---|
| 471 | DO i = 1, klon |
---|
| 472 | IF (pplay(i, k)>=85000.) THEN |
---|
| 473 | tr_seri(i, k, id_pcq0) = sh(i, k) |
---|
| 474 | ELSE |
---|
| 475 | tr_seri(i, k, id_pcq0) = MIN (qsat(i, k), tr_seri(i, k, id_pcq0)) |
---|
| 476 | END IF |
---|
| 477 | END DO |
---|
[1403] | 478 | END DO |
---|
| 479 | END IF |
---|
| 480 | |
---|
[5111] | 481 | !================================================================= |
---|
| 482 | ! Update tracer : Age of stratospheric air |
---|
| 483 | !================================================================= |
---|
[1409] | 484 | IF (id_aga/=0) THEN |
---|
[5111] | 485 | |
---|
| 486 | ! Bottom layers |
---|
| 487 | DO k = 1, lev_1p5km |
---|
| 488 | tr_seri(:, k, id_aga) = 0.0 |
---|
| 489 | END DO |
---|
| 490 | |
---|
| 491 | ! Layers above 1.5km |
---|
| 492 | DO k = lev_1p5km + 1, klev - 1 |
---|
| 493 | tr_seri(:, k, id_aga) = tr_seri(:, k, id_aga) + pdtphys |
---|
| 494 | END DO |
---|
| 495 | |
---|
| 496 | ! Top layer |
---|
| 497 | tr_seri(:, klev, id_aga) = tr_seri(:, klev - 1, id_aga) |
---|
| 498 | |
---|
[1409] | 499 | END IF |
---|
| 500 | |
---|
[5111] | 501 | !====================================================================== |
---|
| 502 | ! -- Calcul de l'effet de la couche limite -- |
---|
| 503 | !====================================================================== |
---|
[1191] | 504 | |
---|
[5111] | 505 | IF (couchelimite) THEN |
---|
| 506 | source(:, :) = 0.0 |
---|
[1212] | 507 | |
---|
[5111] | 508 | IF (id_be /=0) THEN |
---|
| 509 | DO i = 1, klon |
---|
| 510 | zrho = pplay(i, 1) / t_seri(i, 1) / RD |
---|
| 511 | source(i, id_be) = - vdeptr(id_be) * tr_seri(i, 1, id_be) * zrho |
---|
| 512 | END DO |
---|
| 513 | END IF |
---|
[1212] | 514 | |
---|
[1191] | 515 | END IF |
---|
[5111] | 516 | |
---|
| 517 | DO it = 1, nbtr |
---|
| 518 | IF (couchelimite .AND. pbl_flg(it) == 0 .AND. (it==id_rn .OR. it==id_pb)) THEN |
---|
| 519 | ! couche limite avec quantite dans le sol calculee |
---|
| 520 | CALL cltracrn(it, pdtphys, yu1, yv1, & |
---|
| 521 | cdragh, coefh, t_seri, ftsol, pctsrf, & |
---|
| 522 | tr_seri(:, :, it), trs(:, it), & |
---|
| 523 | paprs, pplay, zmasse * rg, & |
---|
| 524 | masktr(:, it), fshtr(:, it), hsoltr(it), & |
---|
| 525 | tautr(it), vdeptr(it), & |
---|
| 526 | xlat, d_tr_cl(:, :, it), d_trs) |
---|
| 527 | |
---|
| 528 | DO k = 1, klev |
---|
[1191] | 529 | DO i = 1, klon |
---|
[5111] | 530 | tr_seri(i, k, it) = tr_seri(i, k, it) + d_tr_cl(i, k, it) |
---|
[1191] | 531 | END DO |
---|
[5111] | 532 | END DO |
---|
| 533 | |
---|
| 534 | ! Traceur dans le reservoir sol |
---|
| 535 | DO i = 1, klon |
---|
| 536 | trs(i, it) = trs(i, it) + d_trs(i) |
---|
| 537 | END DO |
---|
| 538 | END IF |
---|
[1191] | 539 | END DO |
---|
[1403] | 540 | |
---|
[1421] | 541 | |
---|
[5111] | 542 | !====================================================================== |
---|
| 543 | ! Calcul de l'effet du puits radioactif |
---|
| 544 | !====================================================================== |
---|
| 545 | CALL radio_decay (radio, rnpb, pdtphys, tautr, tr_seri, d_tr_dec) |
---|
| 546 | |
---|
| 547 | DO it = 1, nbtr |
---|
[5116] | 548 | IF(radio(it)) THEN |
---|
[5111] | 549 | DO k = 1, klev |
---|
| 550 | DO i = 1, klon |
---|
| 551 | tr_seri(i, k, it) = tr_seri(i, k, it) + d_tr_dec(i, k, it) |
---|
[1191] | 552 | END DO |
---|
[5111] | 553 | END DO |
---|
| 554 | CALL minmaxqfi(tr_seri(:, :, it), 0., 1.e33, 'puits rn it=' // TRIM(int2str(it))) |
---|
| 555 | END IF |
---|
[1191] | 556 | END DO |
---|
| 557 | |
---|
[5111] | 558 | !====================================================================== |
---|
| 559 | ! Parameterization of ozone chemistry |
---|
| 560 | !====================================================================== |
---|
[1403] | 561 | |
---|
[5116] | 562 | IF (id_o3 /= 0) THEN |
---|
[5111] | 563 | lmt_pas = NINT(86400. / pdtphys) |
---|
| 564 | IF (MOD(nstep - 1, lmt_pas) == 0) THEN |
---|
| 565 | ! Once per day, update the coefficients for ozone chemistry: |
---|
| 566 | CALL regr_pr_comb_coefoz(julien, xlat, paprs, pplay) |
---|
| 567 | END IF |
---|
| 568 | CALL o3_chem(julien, gmtime, t_seri, zmasse, pdtphys, xlat, & |
---|
| 569 | xlon, tr_seri(:, :, id_o3)) |
---|
[1403] | 570 | END IF |
---|
| 571 | |
---|
[1191] | 572 | END SUBROUTINE traclmdz |
---|
| 573 | |
---|
| 574 | |
---|
| 575 | SUBROUTINE traclmdz_to_restart(trs_out) |
---|
[5103] | 576 | ! This SUBROUTINE is called from phyredem.F where the module |
---|
[1191] | 577 | ! variable trs is written to restart file (restartphy.nc) |
---|
| 578 | USE dimphy |
---|
[4050] | 579 | USE infotrac_phy, ONLY: nbtr |
---|
[5111] | 580 | |
---|
| 581 | REAL, DIMENSION(klon, nbtr), INTENT(OUT) :: trs_out |
---|
[1203] | 582 | INTEGER :: ierr |
---|
[1212] | 583 | |
---|
[5111] | 584 | IF (ALLOCATED(trs)) THEN |
---|
| 585 | trs_out(:, :) = trs(:, :) |
---|
[1203] | 586 | ELSE |
---|
[5111] | 587 | ! No previous allocate of trs. This is the case for create_etat0_limit. |
---|
| 588 | trs_out(:, :) = 0.0 |
---|
[1203] | 589 | END IF |
---|
[5111] | 590 | |
---|
[1191] | 591 | END SUBROUTINE traclmdz_to_restart |
---|
| 592 | |
---|
[5111] | 593 | |
---|
[1191] | 594 | END MODULE traclmdz_mod |
---|