Changeset 4186 for trunk/LMDZ.MARS/libf/phymars
- Timestamp:
- Apr 14, 2026, 10:31:30 AM (4 weeks ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.MARS/libf/phymars/improvedclouds_mod.F90
r4161 r4186 9 9 SUBROUTINE improvedclouds(ngrid,nlay,ptimestep,pplay,pt,pdt,pq,pdq,nq,tauscaling,imicro,zt,zq) 10 10 11 use updaterad, only: updaterice_micro, updaterccn12 use watersat_mod, only: watersat13 use tracer_mod, only: rho_ice, nuice_sed, igcm_h2o_vap, igcm_h2o_ice, igcm_dust_mass, &14 igcm_dust_number, igcm_ccn_mass, igcm_ccn_number, igcm_hdo_vap, &15 igcm_hdo_ice,qperemin16 use conc_mod, only: mmean17 use comcstfi_h, only: pi, cpp18 use microphys_h, only: nbin_cld, rad_cld, mteta, kbz, nav, rgp19 use microphys_h, only: mco2, vo1, mh2o, mhdo, molco2, molhdo, To20 use nuclea_mod, only: nuclea21 use sig_h2o_mod, only: sig_h2o22 use growthrate_mod, only: growthrate11 use updaterad, only: updaterice_micro, updaterccn 12 use watersat_mod, only: watersat 13 use tracer_mod, only: rho_ice, nuice_sed, igcm_h2o_vap, igcm_h2o_ice, igcm_dust_mass, & 14 igcm_dust_number, igcm_ccn_mass, igcm_ccn_number, igcm_hdo_vap, & 15 igcm_hdo_ice, qperemin 16 use conc_mod, only: mmean 17 use comcstfi_h, only: pi, cpp 18 use microphys_h, only: nbin_cld, rad_cld, mteta, kbz, nav, rgp 19 use microphys_h, only: mco2, vo1, mh2o, mhdo, molco2, molhdo, To 20 use nuclea_mod, only: nuclea 21 use sig_h2o_mod, only: sig_h2o 22 use growthrate_mod, only: growthrate 23 23 use write_output_mod, only: write_output 24 use callkeys_mod, only: activice, scavenging, cloud_adapt_ts, hdo, hdofrac24 use callkeys_mod, only: activice, scavenging, cloud_adapt_ts, hdo, hdofrac 25 25 26 26 implicit none … … 50 50 !------------------------------------------------------------------ 51 51 ! Inputs/outputs: 52 INTEGER, INTENT(IN) :: ngrid,nlay53 INTEGER, INTENT(IN) :: nq! nombre de traceurs54 REAL, INTENT(IN) :: ptimestep! pas de temps physique (s)55 REAL, dimension(ngrid,nlay), INTENT(IN) :: pplay ! pression au milieu des couches (Pa)56 REAL, dimension(ngrid,nlay), INTENT(IN) :: pt! temperature at the middle of the layers (K)57 REAL, dimension(ngrid,nlay), INTENT(IN) :: pdt! temperature tendency (K/s)58 REAL, dimension(ngrid,nlay,nq), INTENT(IN) :: pq ! tracer (kg/kg)59 REAL, dimension(ngrid,nlay,nq), INTENT(IN) :: pdq ! tracer tendency (kg/kg/s)60 REAL, dimension(ngrid), INTENT(IN) :: tauscaling ! Convertion factor for qdust and Ndust61 INTEGER, INTENT(IN) :: imicro! nb. microphy calls(retrocompatibility)62 63 REAL, dimension(ngrid,nlay,nq), INTENT(OUT) :: zq ! tracers post microphy (kg/kg) 64 REAL, dimension(ngrid,nlay), INTENT(OUT) :: zt ! temperature post microphy (K)52 INTEGER, INTENT(IN) :: ngrid,nlay 53 INTEGER, INTENT(IN) :: nq ! nombre de traceurs 54 REAL, INTENT(IN) :: ptimestep ! pas de temps physique (s) 55 REAL, dimension(ngrid,nlay), INTENT(IN) :: pplay ! pression au milieu des couches (Pa) 56 REAL, dimension(ngrid,nlay), INTENT(IN) :: pt ! temperature at the middle of the layers (K) 57 REAL, dimension(ngrid,nlay), INTENT(IN) :: pdt ! temperature tendency (K/s) 58 REAL, dimension(ngrid,nlay,nq), INTENT(IN) :: pq ! tracer (kg/kg) 59 REAL, dimension(ngrid,nlay,nq), INTENT(IN) :: pdq ! tracer tendency (kg/kg/s) 60 REAL, dimension(ngrid), INTENT(IN) :: tauscaling ! Convertion factor for qdust and Ndust 61 INTEGER, INTENT(IN) :: imicro ! nb. microphy calls(retrocompatibility) 62 63 REAL, dimension(ngrid,nlay,nq), INTENT(OUT) :: zq ! tracers post microphy (kg/kg) 64 REAL, dimension(ngrid,nlay), INTENT(OUT) :: zt ! temperature post microphy (K) 65 65 66 66 !------------------------------------------------------------------ 67 67 ! Local variables: 68 LOGICAL, SAVE :: firstcall = .true.68 LOGICAL, SAVE :: firstcall = .true. 69 69 !$OMP THREADPRIVATE(firstcall) 70 REAL*8 :: derf ! Error function70 REAL*8 :: derf ! Error function 71 71 !external derf 72 INTEGER :: ig,l,i73 REAL, dimension(ngrid,nlay) :: zqsat ! saturation74 REAL :: lw ! Latent heat of sublimation (J.kg-1)75 REAL :: cste76 REAL :: dMice! mass of condensed ice77 REAL :: dMicetot ! JN78 REAL :: dMice_hdo! mass of condensed HDO ice79 REAL, dimension(ngrid,nlay) :: alpha ! HDO equilibrium fractionation coefficient (Saturation=1)80 REAL, dimension(ngrid,nlay) :: alpha_c ! HDO real fractionation coefficient81 REAL*8 :: ph2o! Water vapor partial pressure (Pa)82 REAL*8 :: satu! Water vapor saturation ratio over ice83 REAL*8 :: Mo,No, Rn, Rm, dev2, n_derf, m_derf84 REAL*8, dimension(nbin_cld) :: n_aer ! number conc. of particle/each size bin85 REAL*8, dimension(nbin_cld) :: m_aer ! mass mixing ratio of particle/each size bin72 INTEGER :: ig, l, i 73 REAL, dimension(ngrid,nlay) :: zqsat ! Saturation 74 REAL :: lw ! Latent heat of sublimation (J.kg-1) 75 REAL :: cste 76 REAL :: dMice ! mass of condensed ice 77 REAL :: dMicetot 78 REAL :: dMice_hdo ! mass of condensed HDO ice 79 REAL, dimension(ngrid,nlay) :: alpha ! HDO equilibrium fractionation coefficient (Saturation=1) 80 REAL, dimension(ngrid,nlay) :: alpha_c ! HDO real fractionation coefficient 81 REAL*8 :: ph2o ! Water vapor partial pressure (Pa) 82 REAL*8 :: satu ! Water vapor saturation ratio over ice 83 REAL*8 :: Mo, No, Rn, Rm, dev2, n_derf, m_derf 84 REAL*8, dimension(nbin_cld) :: n_aer ! number conc. of particle/each size bin 85 REAL*8, dimension(nbin_cld) :: m_aer ! mass mixing ratio of particle/each size bin 86 86 REAL :: dN, dM, seq 87 REAL, dimension(nbin_cld) :: rate ! nucleation rate88 REAL, dimension(ngrid,nlay) :: rice ! Ice mass mean radius (m) (r_c in montmessin_2004)89 REAL, dimension(ngrid,nlay) :: rhocloud ! Cloud density (kg.m-3)90 REAL, dimension(ngrid,nlay) :: rdust ! Dust geometric mean radius (m)91 REAL :: res! Resistance growth92 REAL :: Dv,Dv_hdo ! Water/HDO vapor diffusion coefficient87 REAL, dimension(nbin_cld) :: rate ! Nucleation rate 88 REAL, dimension(ngrid,nlay) :: rice ! Ice mass mean radius (m) (r_c in montmessin_2004) 89 REAL, dimension(ngrid,nlay) :: rhocloud ! Cloud density (kg.m-3) 90 REAL, dimension(ngrid,nlay) :: rdust ! Dust geometric mean radius (m) 91 REAL :: res ! Resistance growth 92 REAL :: Dv, Dv_hdo ! Water/HDO vapor diffusion coefficient 93 93 94 94 ! Parameters of the size discretization used by the microphysical scheme 95 DOUBLE PRECISION, PARAMETER :: rmin_cld = 0.1e-6! Minimum radius (m)96 DOUBLE PRECISION, PARAMETER :: rmax_cld = 10.e-6! Maximum radius (m)97 DOUBLE PRECISION, PARAMETER :: rbmin_cld = 0.0001e-6 ! Minimum boundary radius (m)98 DOUBLE PRECISION, PARAMETER :: rbmax_cld = 1.e-2! Maximum boundary radius (m)99 DOUBLE PRECISION :: vrat_cld! Volume ratio100 DOUBLE PRECISION, dimension(nbin_cld +1), SAVE :: rb_cld ! boundary values of each rad_cld bin (m)95 DOUBLE PRECISION, PARAMETER :: rmin_cld = 0.1e-6 ! Minimum radius (m) 96 DOUBLE PRECISION, PARAMETER :: rmax_cld = 10.e-6 ! Maximum radius (m) 97 DOUBLE PRECISION, PARAMETER :: rbmin_cld = 0.0001e-6 ! Minimum boundary radius (m) 98 DOUBLE PRECISION, PARAMETER :: rbmax_cld = 1.e-2 ! Maximum boundary radius (m) 99 DOUBLE PRECISION :: vrat_cld ! Volume ratio 100 DOUBLE PRECISION, dimension(nbin_cld + 1), SAVE :: rb_cld ! Boundary values of each rad_cld bin (m) 101 101 !$OMP THREADPRIVATE(rb_cld) 102 DOUBLE PRECISION, dimension(nbin_cld) :: dr_cld ! width of each rad_cld bin (m)103 DOUBLE PRECISION, dimension(nbin_cld) :: vol_cld ! particle volume for each bin (m3)104 REAL, SAVE :: sigma_ice ! Variance of the ice and CCN distributions102 DOUBLE PRECISION, dimension(nbin_cld) :: dr_cld ! Width of each rad_cld bin (m) 103 DOUBLE PRECISION, dimension(nbin_cld) :: vol_cld ! Particle volume for each bin (m3) 104 REAL, SAVE :: sigma_ice ! Variance of the ice and CCN distributions 105 105 !$OMP THREADPRIVATE(sigma_ice) 106 106 107 !---------------------------------- 108 ! JN : used in subtimestep109 REAL :: microtimestep! subdivision of ptimestep (s)110 REAL, dimension(ngrid,nlay) :: subpdtcloud! Temperature variation due to latent heat111 REAL, dimension(ngrid,nlay,nq) :: zq0 ! local initial value of tracers112 INTEGER, dimension(ngrid,nlay) :: zimicro! Subdivision of ptimestep113 INTEGER, dimension(ngrid,nlay) :: count_micro! Number of microphys calls114 REAL, dimension(ngrid,nlay) :: zpotcond ! maximal condensable water (previous two)115 REAL, dimension(1) :: zqsat_tmp ! maximal condensable water (previous two)116 REAL :: spenttime ! time spent in while loop117 REAL :: zdq ! used to compute adaptative timestep118 LOGICAL :: ending_ts! Condition to end while loop119 120 !---------------------------------- 107 !---------------------------------- 108 ! JN: used in subtimestep 109 REAL :: microtimestep ! Subdivision of ptimestep (s) 110 REAL, dimension(ngrid,nlay) :: subpdtcloud ! Temperature variation due to latent heat 111 REAL, dimension(ngrid,nlay,nq) :: zq0 ! Local initial value of tracers 112 INTEGER, dimension(ngrid,nlay) :: zimicro ! Subdivision of ptimestep 113 INTEGER, dimension(ngrid,nlay) :: count_micro ! Number of microphys calls 114 REAL, dimension(ngrid,nlay) :: zpotcond ! Maximal condensable water (previous two) 115 REAL, dimension(1) :: zqsat_tmp ! Maximal condensable water (previous two) 116 REAL :: spenttime ! Time spent in while loop 117 REAL :: zdq ! Used to compute adaptative timestep 118 LOGICAL :: ending_ts ! Condition to end while loop 119 120 !---------------------------------- 121 121 ! TESTS 122 INTEGER :: countcells123 LOGICAL, SAVE :: test_flag ! flag for test/debuging outputs122 INTEGER :: countcells 123 LOGICAL, SAVE :: test_flag ! Flag for test/debuging outputs 124 124 !$OMP THREADPRIVATE(test_flag) 125 REAL, dimension(ngrid,nlay) :: satubf, satuaf, res_out125 REAL, dimension(ngrid,nlay) :: satubf, satuaf, res_out 126 126 127 127 !------------------------------------------------------------------ … … 133 133 !============================================================= 134 134 ! rad_cld is the primary radius grid used for microphysics computation. 135 ! The grid spacing is computed assuming a constant volume ratio 136 ! between two consecutive bins; i.e. vrat_cld. 137 ! vrat_cld is determined from the boundary values of the size grid: 138 ! rmin_cld and rmax_cld. 135 ! The grid spacing is computed assuming a constant volume ratio between two consecutive bins; i.e. vrat_cld. 136 ! vrat_cld is determined from the boundary values of the size grid: rmin_cld and rmax_cld. 139 137 ! The rb_cld array contains the boundary values of each rad_cld bin. 140 138 ! dr_cld is the width of each rad_cld bin. 141 139 142 ! Volume ratio between two adjacent bins143 ! vrat_cld = log(rmax_cld/rmin_cld) / float(nbin_cld-1) *3.144 ! vrat_cld = exp(vrat_cld)145 vrat_cld = log(rmax_cld/rmin_cld) / float(nbin_cld-1) *3.146 vrat_cld = exp(vrat_cld)147 write(*,*) "vrat_cld", vrat_cld148 149 rb_cld(1) = rbmin_cld150 rad_cld(1) = rmin_cld151 vol_cld(1) = 4./3. * dble(pi) * rmin_cld*rmin_cld*rmin_cld152 153 do i=1,nbin_cld-1154 rad_cld(i+1)= rad_cld(i) * vrat_cld**(1./3.)155 vol_cld(i+1)= vol_cld(i) * vrat_cld156 enddo157 158 do i=1,nbin_cld159 rb_cld(i+1)= ( (2.*vrat_cld) / (vrat_cld+1.) )**(1./3.) * rad_cld(i)160 dr_cld(i) = rb_cld(i+1) - rb_cld(i)161 enddo162 rb_cld(nbin_cld+1) = rbmax_cld163 dr_cld(nbin_cld) = rb_cld(nbin_cld+1) - rb_cld(nbin_cld)164 165 print*,' '166 print*,'Microphysics: size bin information:'167 print*,'i,rb_cld(i), rad_cld(i),dr_cld(i)'168 print*,'-----------------------------------'169 do i=1,nbin_cld170 write(*,'(i2,3x,3(e12.6,4x))') i,rb_cld(i), rad_cld(i), dr_cld(i)171 enddo172 write(*,'(i2,3x,e12.6)') nbin_cld+1,rb_cld(nbin_cld+1)173 print*,'-----------------------------------'174 175 ! we save that so that it is not computed at each timestep and gridpoint176 rb_cld(:) = log(rb_cld(:))177 178 ! Contact parameter of water ice on dust ( m=cos(theta) )179 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~180 !mteta is initialized in conf_phys181 write(*,*) 'water_param contact parameter:', mteta182 183 ! Volume of a water molecule (m3)184 vo1 = mh2o / dble(rho_ice)185 ! Variance of the ice and CCN distributions186 sigma_ice = sqrt(log(1.+nuice_sed))187 188 write(*,*) 'Variance of ice & CCN distribs:', sigma_ice189 write(*,*) 'nuice for sedimentation:', nuice_sed190 write(*,*) 'Volume of a water molecule:', vo1191 192 test_flag = .false.193 firstcall=.false.140 ! Volume ratio between two adjacent bins 141 ! vrat_cld = log(rmax_cld/rmin_cld) / float(nbin_cld-1) *3. 142 ! vrat_cld = exp(vrat_cld) 143 vrat_cld = log(rmax_cld/rmin_cld) / float(nbin_cld-1) *3. 144 vrat_cld = exp(vrat_cld) 145 write(*,*) "vrat_cld", vrat_cld 146 147 rb_cld(1) = rbmin_cld 148 rad_cld(1) = rmin_cld 149 vol_cld(1) = 4./3. * dble(pi) * rmin_cld*rmin_cld*rmin_cld 150 151 do i=1,nbin_cld-1 152 rad_cld(i+1) = rad_cld(i) * vrat_cld**(1./3.) 153 vol_cld(i+1) = vol_cld(i) * vrat_cld 154 enddo 155 156 do i=1,nbin_cld 157 rb_cld(i+1)= ( (2.*vrat_cld) / (vrat_cld+1.) )**(1./3.) * rad_cld(i) 158 dr_cld(i) = rb_cld(i+1) - rb_cld(i) 159 enddo 160 rb_cld(nbin_cld+1) = rbmax_cld 161 dr_cld(nbin_cld) = rb_cld(nbin_cld+1) - rb_cld(nbin_cld) 162 163 write(*,*) ' ' 164 write(*,*)'Microphysics: size bin information:' 165 write(*,*)'i,rb_cld(i), rad_cld(i),dr_cld(i)' 166 write(*,*)'-----------------------------------' 167 do i=1,nbin_cld 168 write(*,'(i2,3x,3(e12.6,4x))') i,rb_cld(i), rad_cld(i), dr_cld(i) 169 enddo 170 write(*,'(i2,3x,e12.6)') nbin_cld+1,rb_cld(nbin_cld+1) 171 write(*,*)'-----------------------------------' 172 173 ! we save that so that it is not computed at each timestep and gridpoint 174 rb_cld(:) = log(rb_cld(:)) 175 176 ! Contact parameter of water ice on dust ( m=cos(theta) ) 177 ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 178 ! mteta is initialized in conf_phys 179 write(*,*) 'water_param contact parameter:', mteta 180 181 ! Volume of a water molecule (m3) 182 vo1 = mh2o / dble(rho_ice) 183 ! Variance of the ice and CCN distributions 184 sigma_ice = sqrt(log(1.+nuice_sed)) 185 186 write(*,*) 'Variance of ice & CCN distribs:', sigma_ice 187 write(*,*) 'nuice for sedimentation :', nuice_sed 188 write(*,*) 'Volume of a water molecule :', vo1 189 190 test_flag = .false. 191 firstcall = .false. 194 192 ENDIF 195 193 … … 197 195 ! 1. Initialisation 198 196 !============================================================= 199 200 197 res_out(:,:) = 0 201 198 rice(:,:) = 1.e-8 … … 235 232 ! 2. Compute saturation 236 233 !============================================================= 237 238 234 dev2 = 1. / ( sqrt(2.) * sigma_ice ) 239 235 … … 248 244 ! Main loop over the GCM's grid 249 245 DO l=1,nlay 250 DO ig=1,ngrid251 ! Subtimestep: here we go252 IF (cloud_adapt_ts) call adapt_imicro(ptimestep,zpotcond(ig,l),zimicro(ig,l))253 spenttime = 0.254 dMicetot= 0.255 ending_ts=.false.256 DO while (.not.ending_ts)257 call watersat(1,(/zt(ig,l)/),(/pplay(ig,l)/),zqsat_tmp)258 zqsat(ig,l)=zqsat_tmp(1)259 ! Get the partial pressure of water vapor and its saturation ratio260 ph2o = zq(ig,l,igcm_h2o_vap) * (mmean(ig,l)/18.) * pplay(ig,l)261 satu = zq(ig,l,igcm_h2o_vap) / zqsat(ig,l)262 microtimestep=ptimestep/real(zimicro(ig,l))263 264 ! Initialize tracers for scavenging + hdo computations (JN)265 zq0(ig,l,:)=zq(ig,l,:)266 267 ! Check if we are integrating over ptimestep268 if (spenttime+microtimestep.ge.ptimestep) then269 microtimestep=ptimestep-spenttime270 ! If so: last call !271 ending_ts=.true.272 endif! (spenttime+microtimestep.ge.ptimestep) then246 DO ig=1,ngrid 247 ! Subtimestep: here we go 248 IF (cloud_adapt_ts) call adapt_imicro(ptimestep,zpotcond(ig,l),zimicro(ig,l)) 249 spenttime = 0. 250 dMicetot= 0. 251 ending_ts=.false. 252 DO while (.not.ending_ts) 253 call watersat(1,(/zt(ig,l)/),(/pplay(ig,l)/),zqsat_tmp) 254 zqsat(ig,l)=zqsat_tmp(1) 255 ! Get the partial pressure of water vapor and its saturation ratio 256 ph2o = zq(ig,l,igcm_h2o_vap) * (mmean(ig,l)/18.) * pplay(ig,l) 257 satu = zq(ig,l,igcm_h2o_vap) / zqsat(ig,l) 258 microtimestep=ptimestep/real(zimicro(ig,l)) 259 260 ! Initialize tracers for scavenging + hdo computations (JN) 261 zq0(ig,l,:) = zq(ig,l,:) 262 263 ! Check if we are integrating over ptimestep 264 if (spenttime+microtimestep >= ptimestep) then 265 microtimestep = ptimestep-spenttime 266 ! If so: last call ! 267 ending_ts = .true. 268 endif! (spenttime+microtimestep.ge.ptimestep) then 273 269 274 270 !============================================================= 275 271 ! 3. Nucleation 276 272 !============================================================= 277 278 IF ( satu .ge. 1. ) THEN ! if there is condensation 279 call updaterccn(zq(ig,l,igcm_dust_mass),zq(ig,l,igcm_dust_number),rdust(ig,l),tauscaling(ig)) 280 281 ! Expand the dust moments into a binned distribution 282 Mo = zq(ig,l,igcm_dust_mass)* tauscaling(ig) + 1.e-30 283 No = zq(ig,l,igcm_dust_number)* tauscaling(ig) + 1.e-30 284 Rn = rdust(ig,l) 285 Rn = -log(Rn) 286 Rm = Rn - 3. * sigma_ice*sigma_ice 287 n_derf = derf( (rb_cld(1)+Rn) *dev2) 288 m_derf = derf( (rb_cld(1)+Rm) *dev2) 289 do i = 1, nbin_cld 290 n_aer(i) = -0.5 * No * n_derf !! this ith previously computed 291 m_aer(i) = -0.5 * Mo * m_derf !! this ith previously computed 292 n_derf = derf( (rb_cld(i+1)+Rn) *dev2) 293 m_derf = derf( (rb_cld(i+1)+Rm) *dev2) 294 n_aer(i) = n_aer(i) + 0.5 * No * n_derf 295 m_aer(i) = m_aer(i) + 0.5 * Mo * m_derf 296 enddo 297 298 ! Get the rates of nucleation 299 call nuclea(ph2o,zt(ig,l),satu,n_aer,rate) 300 301 dN = 0. 302 dM = 0. 303 do i = 1, nbin_cld 304 dN = dN + n_aer(i)*(exp(-rate(i)*microtimestep)-1.) 305 dM = dM + m_aer(i)*(exp(-rate(i)*microtimestep)-1.) 306 enddo 307 308 ! Update Dust particles 309 zq(ig,l,igcm_dust_mass) = zq(ig,l,igcm_dust_mass) + dM/ tauscaling(ig) !max(tauscaling(ig),1.e-10) 310 zq(ig,l,igcm_dust_number) = zq(ig,l,igcm_dust_number) + dN/ tauscaling(ig) !max(tauscaling(ig),1.e-10) 311 ! Update CCNs 312 zq(ig,l,igcm_ccn_mass) = zq(ig,l,igcm_ccn_mass) - dM/ tauscaling(ig) !max(tauscaling(ig),1.e-10) 313 zq(ig,l,igcm_ccn_number) = zq(ig,l,igcm_ccn_number) - dN/ tauscaling(ig) !max(tauscaling(ig),1.e-10) 314 315 ENDIF ! of is satu >1 273 IF ( satu >= 1. ) THEN ! if there is condensation 274 call updaterccn(zq(ig,l,igcm_dust_mass),zq(ig,l,igcm_dust_number),rdust(ig,l),tauscaling(ig)) 275 276 ! Expand the dust moments into a binned distribution 277 Mo = zq(ig,l,igcm_dust_mass) *tauscaling(ig) + 1.e-30 278 No = zq(ig,l,igcm_dust_number)*tauscaling(ig) + 1.e-30 279 Rn = rdust(ig,l) 280 Rn = -log(Rn) 281 Rm = Rn - 3. * sigma_ice*sigma_ice 282 n_derf = derf( (rb_cld(1)+Rn) *dev2) 283 m_derf = derf( (rb_cld(1)+Rm) *dev2) 284 do i = 1, nbin_cld 285 n_aer(i) = -0.5 * No * n_derf ! this ith previously computed 286 m_aer(i) = -0.5 * Mo * m_derf ! this ith previously computed 287 n_derf = derf( (rb_cld(i+1)+Rn) *dev2) 288 m_derf = derf( (rb_cld(i+1)+Rm) *dev2) 289 n_aer(i) = n_aer(i) + 0.5 * No * n_derf 290 m_aer(i) = m_aer(i) + 0.5 * Mo * m_derf 291 enddo 292 293 ! Get the rates of nucleation 294 call nuclea(ph2o,zt(ig,l),satu,n_aer,rate) 295 296 dN = 0. 297 dM = 0. 298 do i = 1, nbin_cld 299 dN = dN + n_aer(i)*(exp(-rate(i)*microtimestep)-1.) 300 dM = dM + m_aer(i)*(exp(-rate(i)*microtimestep)-1.) 301 enddo 302 303 ! Update Dust particles 304 zq(ig,l,igcm_dust_mass) = zq(ig,l,igcm_dust_mass) + dM/ tauscaling(ig) !max(tauscaling(ig),1.e-10) 305 zq(ig,l,igcm_dust_number) = zq(ig,l,igcm_dust_number) + dN/ tauscaling(ig) !max(tauscaling(ig),1.e-10) 306 ! Update CCNs 307 zq(ig,l,igcm_ccn_mass) = zq(ig,l,igcm_ccn_mass) - dM/ tauscaling(ig) !max(tauscaling(ig),1.e-10) 308 zq(ig,l,igcm_ccn_number) = zq(ig,l,igcm_ccn_number) - dN/ tauscaling(ig) !max(tauscaling(ig),1.e-10) 309 ENDIF ! of is satu >1 316 310 317 311 !============================================================= … … 321 315 ! Indeed, if we are supersaturated and still don't have at least one nuclei, we should better wait 322 316 ! to avoid unrealistic value for nuclei radius and so on for cases that remain negligible. 323 IF ( zq(ig,l,igcm_ccn_number)*tauscaling(ig).ge. 1.) THEN ! we trigger crystal growth324 call updaterice_micro(zq(ig,l,igcm_h2o_ice),zq(ig,l,igcm_ccn_mass),zq(ig,l,igcm_ccn_number),tauscaling(ig),rice(ig,l),rhocloud(ig,l))325 326 No= zq(ig,l,igcm_ccn_number)* tauscaling(ig) + 1.e-30327 328 ! saturation at equilibrium329 ! rice should not be too small, otherwise seq value is not valid330 seq = exp(2.*sig_h2o(zt(ig,l))*mh2o / (rho_ice*rgp*zt(ig,l)*max(rice(ig,l),1.e-7)))331 332 ! get resistance growth333 call growthrate(zt(ig,l),pplay(ig,l),real(ph2o/satu),rice(ig,l),res,Dv)334 335 res_out(ig,l) = res336 337 ! implicit scheme of mass growth338 ! cste here must be computed at each step339 cste = 4*pi*rho_ice*microtimestep340 341 dMice = (zq(ig,l,igcm_h2o_vap)-seq*zqsat(ig,l))/(res*zqsat(ig,l)/(cste*No*rice(ig,l)) + 1.)342 343 ! With the above scheme, dMice cannot be bigger than vapor, but can be bigger than all available ice.344 dMice = max(dMice,-zq(ig,l,igcm_h2o_ice))345 dMice = min(dMice,zq(ig,l,igcm_h2o_vap))346 347 zq(ig,l,igcm_h2o_ice) = zq(ig,l,igcm_h2o_ice)+dMice348 zq(ig,l,igcm_h2o_vap) = zq(ig,l,igcm_h2o_vap)-dMice349 350 countcells = countcells + 1351 352 ! latent heat release353 lw=(2834.3-0.28*(zt(ig,l)-To)-0.004*(zt(ig,l)-To)*(zt(ig,l)-To))*1.e+3354 subpdtcloud(ig,l)= dMice*lw/cpp/microtimestep355 356 ! DIFF: trend is enforce in a range, stabilize the scheme?357 if (subpdtcloud(ig,l)*microtimestep.gt.5.0) then358 subpdtcloud(ig,l)=5./microtimestep359 endif! (subpdtcloud(ig,l)*microtimestep.gt.5.0) then360 if (subpdtcloud(ig,l)*microtimestep.lt.-5.0) then361 subpdtcloud(ig,l)=-5./microtimestep362 endif! (subpdtcloud(ig,l)*microtimestep.gt.5.0) then363 364 ! Special case of the isotope of water HDO365 if (hdo) then366 ! condensation367 if (dMice.gt.0.0) then368 ! do we use fractionation?369 if (hdofrac) then370 ! Calculation of the HDO vapor coefficient371 Dv_hdo = 1./3. * sqrt( 8*kbz*zt(ig,l)/(pi*mhdo/nav) ) * kbz * zt(ig,l) / (pi * pplay(ig,l) * (molco2+molhdo)*(molco2+molhdo) * sqrt(1.+mhdo/mco2) )372 ! Calculation of the fractionnation coefficient at equilibrium373 alpha(ig,l) = exp(16288./zt(ig,l)**2.-9.34d-2)374 ! Calculation of the 'real' fractionnation coefficient375 alpha_c(ig,l) = (alpha(ig,l)*satu)/((alpha(ig,l)*(Dv/Dv_hdo)*(satu-1.)) + 1.)376 else377 alpha_c(ig,l) = 1.d0378 endif379 if (zq0(ig,l,igcm_h2o_vap).gt.qperemin) then380 dMice_hdo = dMice*alpha_c(ig,l)*( zq0(ig,l,igcm_hdo_vap)/zq0(ig,l,igcm_h2o_vap) )381 else382 dMice_hdo=0.383 endif384 !! sublimation385 else386 if (zq0(ig,l,igcm_h2o_ice).gt.qperemin) then387 dMice_hdo=dMice*( zq0(ig,l,igcm_hdo_ice)/zq0(ig,l,igcm_h2o_ice) )388 else389 dMice_hdo=0.390 endif391 endif !if (dMice.gt.0.0)392 393 dMice_hdo = max(dMice_hdo,-zq(ig,l,igcm_hdo_ice))394 dMice_hdo = min(dMice_hdo,zq(ig,l,igcm_hdo_vap))395 396 zq(ig,l,igcm_hdo_ice) = zq(ig,l,igcm_hdo_ice)+dMice_hdo397 zq(ig,l,igcm_hdo_vap) = zq(ig,l,igcm_hdo_vap)-dMice_hdo398 399 endif ! if (hdo)317 IF ( zq(ig,l,igcm_ccn_number)*tauscaling(ig) >= 1.) THEN ! we trigger crystal growth 318 call updaterice_micro(zq(ig,l,igcm_h2o_ice),zq(ig,l,igcm_ccn_mass),zq(ig,l,igcm_ccn_number),tauscaling(ig),rice(ig,l),rhocloud(ig,l)) 319 320 No = zq(ig,l,igcm_ccn_number)* tauscaling(ig) + 1.e-30 321 322 ! saturation at equilibrium 323 ! rice should not be too small, otherwise seq value is not valid 324 seq = exp(2.*sig_h2o(zt(ig,l))*mh2o / (rho_ice*rgp*zt(ig,l)*max(rice(ig,l),1.e-7))) 325 326 ! get resistance growth 327 call growthrate(zt(ig,l),pplay(ig,l),real(ph2o/satu),rice(ig,l),res,Dv) 328 329 res_out(ig,l) = res 330 331 ! implicit scheme of mass growth 332 ! cste here must be computed at each step 333 cste = 4*pi*rho_ice*microtimestep 334 335 dMice = (zq(ig,l,igcm_h2o_vap)-seq*zqsat(ig,l))/(res*zqsat(ig,l)/(cste*No*rice(ig,l)) + 1.) 336 337 ! With the above scheme, dMice cannot be bigger than vapor, but can be bigger than all available ice. 338 dMice = max(dMice,-zq(ig,l,igcm_h2o_ice)) 339 dMice = min(dMice,zq(ig,l,igcm_h2o_vap)) 340 341 zq(ig,l,igcm_h2o_ice) = zq(ig,l,igcm_h2o_ice) + dMice 342 zq(ig,l,igcm_h2o_vap) = zq(ig,l,igcm_h2o_vap) - dMice 343 344 countcells = countcells + 1 345 346 ! latent heat release 347 lw = (2834.3-0.28*(zt(ig,l)-To)-0.004*(zt(ig,l)-To)*(zt(ig,l)-To))*1.e+3 348 subpdtcloud(ig,l) = dMice*lw/cpp/microtimestep 349 350 ! DIFF: trend is enforce in a range, stabilize the scheme? 351 if (subpdtcloud(ig,l)*microtimestep > 5.0) then 352 subpdtcloud(ig,l) = 5./microtimestep 353 endif 354 if (subpdtcloud(ig,l)*microtimestep < -5.0) then 355 subpdtcloud(ig,l) = -5./microtimestep 356 endif 357 358 ! Special case of the isotope of water HDO 359 if (hdo) then 360 ! condensation 361 if (dMice > 0.) then 362 ! do we use fractionation? 363 if (hdofrac) then 364 ! Calculation of the HDO vapor coefficient 365 Dv_hdo = 1./3. * sqrt( 8*kbz*zt(ig,l)/(pi*mhdo/nav) )* kbz * zt(ig,l) / (pi * pplay(ig,l) * (molco2+molhdo)*(molco2+molhdo) * sqrt(1.+mhdo/mco2) ) 366 ! Calculation of the fractionnation coefficient at equilibrium 367 alpha(ig,l) = exp(16288./zt(ig,l)**2.-9.34d-2) 368 ! Calculation of the 'real' fractionnation coefficient 369 alpha_c(ig,l) = (alpha(ig,l)*satu) / ((alpha(ig,l)*(Dv/Dv_hdo)*(satu-1.)) + 1.) 370 else 371 alpha_c(ig,l) = 1.d0 372 endif 373 if (zq0(ig,l,igcm_h2o_vap) > qperemin) then 374 dMice_hdo = dMice*alpha_c(ig,l)*( zq0(ig,l,igcm_hdo_vap)/zq0(ig,l,igcm_h2o_vap) ) 375 else 376 dMice_hdo = 0. 377 endif 378 ! sublimation 379 else 380 if (zq0(ig,l,igcm_h2o_ice) > qperemin) then 381 dMice_hdo = dMice*( zq0(ig,l,igcm_hdo_ice)/zq0(ig,l,igcm_h2o_ice) ) 382 else 383 dMice_hdo = 0. 384 endif 385 endif ! if (dMice > 0.) 386 387 dMice_hdo = max(dMice_hdo,-zq(ig,l,igcm_hdo_ice)) 388 dMice_hdo = min(dMice_hdo,zq(ig,l,igcm_hdo_vap)) 389 390 zq(ig,l,igcm_hdo_ice) = zq(ig,l,igcm_hdo_ice) + dMice_hdo 391 zq(ig,l,igcm_hdo_vap) = zq(ig,l,igcm_hdo_vap) - dMice_hdo 392 393 endif ! if (hdo) 400 394 401 395 !============================================================= 402 396 ! 5. Dust cores released, tendancies, latent heat, etc ... 403 397 !============================================================= 404 405 ! If all the ice particles sublimate, all the condensation 406 ! nuclei are released: 407 if (zq(ig,l,igcm_h2o_ice).le.1.e-28) then 408 ! Water 409 zq(ig,l,igcm_h2o_vap) = zq(ig,l,igcm_h2o_vap) + zq(ig,l,igcm_h2o_ice) 410 zq(ig,l,igcm_h2o_ice) = 0. 411 if (hdo) then 412 zq(ig,l,igcm_hdo_vap) = zq(ig,l,igcm_hdo_vap) + zq(ig,l,igcm_hdo_ice) 413 zq(ig,l,igcm_hdo_ice) = 0. 414 endif 415 ! Dust particles 416 zq(ig,l,igcm_dust_mass) = zq(ig,l,igcm_dust_mass) + zq(ig,l,igcm_ccn_mass) 417 zq(ig,l,igcm_dust_number) = zq(ig,l,igcm_dust_number) + zq(ig,l,igcm_ccn_number) 418 ! CCNs 419 zq(ig,l,igcm_ccn_mass) = 0. 420 zq(ig,l,igcm_ccn_number) = 0. 421 endif 422 423 ELSE 424 ! Initialization of dMice when it's not computed 425 dMice=0 ! no condensation/sublimation to account for 426 subpdtcloud(ig,l)=0 ! no condensation/sublimation to account for 427 ENDIF !of if Nccn>1 428 429 ! No more getting tendency : we increment tracers & temp directly 430 431 ! If not activice, the tendency from latent heat release is set to zero 432 IF (.not.activice) subpdtcloud(ig,l)=0. 433 434 ! Temperature change as a feedback from latent heat release 435 zt(ig,l) = zt(ig,l)+subpdtcloud(ig,l)*microtimestep 436 437 ! Prevent negative tracers ! JN 438 WHERE (zq(ig,l,:) < 1.e-30) zq(ig,l,:) = 1.e-30 439 440 IF (cloud_adapt_ts) then 441 ! Estimation of how much is actually condensing/subliming 442 dMicetot=dMicetot+abs(dMice) ! total accumulated ice formation since the beginning 443 IF (spenttime.ne.0) then 444 zdq=(dMicetot/spenttime)!*(ptimestep-spenttime) 445 ELSE 446 ! Initialization for spenttime=0 447 zdq=zpotcond(ig,l)*((ptimestep-spenttime)/ptimestep) 448 ENDIF 449 zdq=abs(zdq) 450 call adapt_imicro(ptimestep,zdq,zimicro(ig,l)) 451 ENDIF! (cloud_adapt_ts) then 452 ! Increment time spent in here 453 spenttime=spenttime+microtimestep 454 count_micro(ig,l)=count_micro(ig,l)+1 455 ENDDO ! while (.not. ending_ts) 456 ENDDO ! of ig loop 398 ! If all the ice particles sublimate, all the condensation 399 ! nuclei are released: 400 if (zq(ig,l,igcm_h2o_ice) <= 1.e-28) then 401 ! Water 402 zq(ig,l,igcm_h2o_vap) = zq(ig,l,igcm_h2o_vap) + zq(ig,l,igcm_h2o_ice) 403 zq(ig,l,igcm_h2o_ice) = 0. 404 if (hdo) then 405 zq(ig,l,igcm_hdo_vap) = zq(ig,l,igcm_hdo_vap) + zq(ig,l,igcm_hdo_ice) 406 zq(ig,l,igcm_hdo_ice) = 0. 407 endif 408 ! Dust particles 409 zq(ig,l,igcm_dust_mass) = zq(ig,l,igcm_dust_mass) + zq(ig,l,igcm_ccn_mass) 410 zq(ig,l,igcm_dust_number) = zq(ig,l,igcm_dust_number) + zq(ig,l,igcm_ccn_number) 411 ! CCNs 412 zq(ig,l,igcm_ccn_mass) = 0. 413 zq(ig,l,igcm_ccn_number) = 0. 414 endif 415 416 ELSE 417 ! Initialization of dMice when it's not computed 418 dMice = 0 ! no condensation/sublimation to account for 419 subpdtcloud(ig,l) = 0 ! no condensation/sublimation to account for 420 ENDIF ! of if Nccn>1 421 422 ! No more getting tendency: we increment tracers & temp directly 423 424 ! If not activice, the tendency from latent heat release is set to zero 425 IF (.not.activice) subpdtcloud(ig,l)=0. 426 427 ! Temperature change as a feedback from latent heat release 428 zt(ig,l) = zt(ig,l) + subpdtcloud(ig,l)*microtimestep 429 430 ! Prevent negative tracers ! JN 431 WHERE (zq(ig,l,:) < 1.e-30) zq(ig,l,:) = 1.e-30 432 433 IF (cloud_adapt_ts) then 434 ! Estimation of how much is actually condensing/subliming 435 dMicetot=dMicetot+abs(dMice) ! total accumulated ice formation since the beginning 436 IF (spenttime /= 0) then 437 zdq = (dMicetot/spenttime)!*(ptimestep-spenttime) 438 ELSE 439 ! Initialization for spenttime=0 440 zdq = zpotcond(ig,l)*((ptimestep-spenttime)/ptimestep) 441 ENDIF 442 zdq = abs(zdq) 443 call adapt_imicro(ptimestep,zdq,zimicro(ig,l)) 444 ENDIF ! (cloud_adapt_ts) then 445 ! Increment time spent in here 446 spenttime = spenttime + microtimestep 447 count_micro(ig,l) = count_micro(ig,l) + 1 448 ENDDO ! while (.not. ending_ts) 449 ENDDO ! of ig loop 457 450 ENDDO ! of nlayer loop 458 451 … … 461 454 call write_output("count_micro","count_micro after microphysics","integer",count_micro(:,:)) 462 455 463 !!!!!!!!!!!!!! TESTS OUTPUTS TESTS OUTPUTS TESTS OUTPUTS TESTS OUTPUTS 456 !!!!!!!!!!!!!! TESTS OUTPUTS TESTS OUTPUTS TESTS OUTPUTS TESTS OUTPUTS 464 457 IF (test_flag) then 465 DO l=1,nlay 466 DO ig=1,ngrid 467 satubf(ig,l) = zq0(ig,l,igcm_h2o_vap)/zqsat(ig,l) 468 satuaf(ig,l) = zq(ig,l,igcm_h2o_vap)/zqsat(ig,l) 458 DO l=1,nlay 459 DO ig=1,ngrid 460 satubf(ig,l) = zq0(ig,l,igcm_h2o_vap)/zqsat(ig,l) 461 satuaf(ig,l) = zq(ig,l,igcm_h2o_vap)/zqsat(ig,l) 462 ENDDO 469 463 ENDDO 470 ENDDO 471 print*, 'count is ',countcells, ' i.e. ', countcells*100/(nlay*ngrid), '% for microphys computation' 464 write(*,*) 'count is ',countcells, ' i.e. ', countcells*100/(nlay*ngrid), '% for microphys computation' 472 465 ENDIF ! endif test_flag 473 466 … … 483 476 ! efficiency. 484 477 485 real, intent(in) :: ptimestep ! total duration of physics (sec)486 real, intent(in) :: potcond ! condensible vapor / sublimable ice(kg/kg)487 real :: alpha, beta ! Coefficients for power law 488 real :: defstep,coef ! Default ptimestep of 7.5 mins (iphysiq=5)489 integer,intent(out) :: zimicro ! number of ptimestep division 490 491 ! Default ptimestep : defstep (7.5 mins)492 defstep =88775.*5./960.493 coef =ptimestep/defstep478 real, intent(in) :: ptimestep ! Total duration of physics (sec) 479 real, intent(in) :: potcond ! Condensible vapor / sublimable ice(kg/kg) 480 integer, intent(out) :: zimicro ! Number of ptimestep division 481 real :: alpha, beta ! Coefficients for power law 482 real :: defstep, coef ! Default ptimestep of 7.5 mins (iphysiq=5) 483 484 ! Default ptimestep: defstep (7.5 mins) 485 defstep = 88775.*5./960. 486 coef = ptimestep/defstep 494 487 ! Conservative coefficients : 495 ! alpha=1.81846504e+11496 ! beta=1.54550140e+00497 alpha =1.88282793e+05 ! Latest values for high obliquity498 beta =4.57764370e-01 ! Latest values for high obliquity499 !alpha =1.72198978e+10 ! Present day Mars500 !beta =1.88473210e+00501 zimicro =ceiling(coef*min(max(alpha*abs(potcond)**beta,5.),7000.))502 !zimicro =2*zimicro ! Prediction times two, allow to complete year at high obliquity488 !alpha = 1.81846504e+11 489 !beta = 1.54550140e+00 490 alpha = 1.88282793e+05 ! Latest values for high obliquity 491 beta = 4.57764370e-01 ! Latest values for high obliquity 492 !alpha = 1.72198978e+10 ! Present day Mars 493 !beta = 1.88473210e+00 494 zimicro = ceiling(coef*min(max(alpha*abs(potcond)**beta,5.),7000.)) 495 !zimicro = 2*zimicro ! Prediction times two, allow to complete year at high obliquity 503 496 504 497 END SUBROUTINE adapt_imicro
Note: See TracChangeset
for help on using the changeset viewer.
