Changeset 1032 for trunk/LMDZ.MARS/libf
- Timestamp:
- Sep 6, 2013, 8:51:56 AM (12 years ago)
- Location:
- trunk/LMDZ.MARS/libf/phymars
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LMDZ.MARS/libf/phymars/calltherm_interface.F90
r1028 r1032 1 ! --------------------------------------------------------------------- 2 ! Arnaud Colaitis 2011-01-05 3 ! 4 ! Interface routine between physiq.F (driver for physics) and thermcell_main_mars (thermals model) 5 ! Handles sub-timestep for the thermals model, outputs and diagnostics 6 ! 7 ! The thermals model implemented in the Mars LMD-GCM is called after the vertical turbulent mixing scheme (Mellor and Yamada) 8 ! and surface layer scheme (Richardson-based surface layer with subgrid gustiness parameterization) 9 ! Other routines called before the thermals model are Radiative transfer scheme (Madeleine et.al) 10 ! and gravity wave and subgrid scale topography drag. 11 ! 12 ! Reference paper for the Martian thermals model is Colaitis et al. 2013 (JGR-planets) 13 ! Mentions in the routines to a "paper" points to the above reference. 14 ! 15 ! This model is based on the LMDZ thermals model from C. Rio and F. Hourdin 16 ! --------------------------------------------------------------------- 17 SUBROUTINE calltherm_interface (firstcall, & 1 ! ----------------------------------------------------------------------- 2 ! CALLTHERM_INTERFACE 3 ! ----------------------------------------------------------------------- 4 ! Main interface to the Martian thermal plume model 5 ! This interface handles sub-timesteps for this model 6 ! A call to this interface must be inserted in the main 'physics' routine 7 ! NB: for information: 8 ! In the Mars LMD-GCM, the thermal plume model is called after 9 ! the vertical turbulent mixing scheme (Mellor and Yamada) 10 ! and the surface layer scheme (Richardson-based surface layer + subgrid gustiness) 11 ! Other routines called before the thermals model are 12 ! radiative transfer and (orographic) gravity wave drag. 13 ! ----------------------------------------------------------------------- 14 ! ASSOCIATED FILES 15 ! --> thermcell_dqup.F90 16 ! --> thermcell_main_mars.F90 17 ! --> comtherm_h.F90 18 ! ----------------------------------------------------------------------- 19 ! Reference paper: 20 ! A. Colaïtis, A. Spiga, F. Hourdin, C. Rio, F. Forget, and E. Millour. 21 ! A thermal plume model for the Martian convective boundary layer. 22 ! Journal of Geophysical Research (Planets), 118:1468-1487, July 2013. 23 ! ----------------------------------------------------------------------- 24 ! Reference paper for terrestrial plume model: 25 ! C. Rio and F. Hourdin. 26 ! A thermal plume model for the convective boundary layer : Representation of cumulus clouds. 27 ! Journal of the Atmospheric Sciences, 65:407-425, 2008. 28 ! ----------------------------------------------------------------------- 29 ! Author : A. Colaitis 2011-01-05 (with updates 2011-2013) 30 ! Institution : Laboratoire de Meteorologie Dynamique (LMD) Paris, France 31 ! Corresponding author : A. Spiga aymeric.spiga_AT_upmc.fr 32 ! ----------------------------------------------------------------------- 33 34 SUBROUTINE calltherm_interface (ngrid,nlayer,nq, & 35 & tracer,igcm_co2, & 18 36 & zzlev,zzlay, & 19 37 & ptimestep,pu,pv,pt,pq,pdu,pdv,pdt,pdq,q2, & … … 22 40 & pdhdif,hfmax,wstar,sensibFlux) 23 41 24 25 USE ioipsl_getincom, only : getin ! to read options from external file "run.def" 42 use comtherm_h 26 43 implicit none 27 #include "callkeys.h" !contains logical values determining which subroutines and which options are used. 28 ! includes logical "tracer", which is .true. if tracers are present and to be transported 29 ! includes integer "iradia", frequency of calls to radiative scheme wrt calls to physics (and is typically==1) 30 #include "dimensions.h" !contains global GCM grid dimension informations 31 #include "dimphys.h" !similar to dimensions.h, and based on it; includes 32 ! "ngridmx": number of horizontal grid points 33 ! "nlayermx": number of atmospheric layers 44 45 ! SHARED VARIABLES. This needs adaptations in another climate model. 34 46 #include "comcstfi.h" !contains physical constant values such as 35 47 ! "g" : gravitational acceleration (m.s-2) 36 48 ! "r" : recuced gas constant (J.K-1.mol-1) 37 49 ! "cpp" : specific heat of the atmosphere (J.kg-1.K-1) 38 #include "tracer.h" !contains tracer information such as39 ! "nqmx": number of tracers40 ! "noms()": tracer name41 50 42 51 !-------------------------------------------------------- … … 44 53 !-------------------------------------------------------- 45 54 55 INTEGER, INTENT(IN) :: ngrid ! number of horizontal grid points 56 INTEGER, INTENT(IN) :: nlayer ! number of vertical grid points 57 INTEGER, INTENT(IN) :: nq ! number of tracer species 46 58 REAL, INTENT(IN) :: ptimestep !timestep (s) 47 REAL, INTENT(IN) :: pplev(ngridmx,nlayermx+1) !intermediate pressure levels (Pa) 48 REAL, INTENT(IN) :: pplay(ngridmx,nlayermx) !Pressure at the middle of the layers (Pa) 49 REAL, INTENT(IN) :: pphi(ngridmx,nlayermx) !Geopotential at the middle of the layers (m2s-2) 50 REAL, INTENT(IN) :: pu(ngridmx,nlayermx),pv(ngridmx,nlayermx) !u,v components of the wind (ms-1) 51 REAL, INTENT(IN) :: pt(ngridmx,nlayermx),pq(ngridmx,nlayermx,nqmx)!temperature (K) and tracer concentration (kg/kg) 52 REAL, INTENT(IN) :: zzlay(ngridmx,nlayermx) ! altitude at the middle of the layers 53 REAL, INTENT(IN) :: zzlev(ngridmx,nlayermx+1) ! altitude at layer boundaries 54 LOGICAL, INTENT(IN) :: firstcall ! =.true. if this is the first time the routine is called. 55 ! Used to detect and store which tracer is co2 56 REAL, INTENT(IN) :: pdu(ngridmx,nlayermx),pdv(ngridmx,nlayermx) ! wind velocity change from routines called 59 REAL, INTENT(IN) :: pplev(ngrid,nlayer+1) !intermediate pressure levels (Pa) 60 REAL, INTENT(IN) :: pplay(ngrid,nlayer) !Pressure at the middle of the layers (Pa) 61 REAL, INTENT(IN) :: pphi(ngrid,nlayer) !Geopotential at the middle of the layers (m2s-2) 62 REAL, INTENT(IN) :: pu(ngrid,nlayer),pv(ngrid,nlayer) !u,v components of the wind (ms-1) 63 REAL, INTENT(IN) :: pt(ngrid,nlayer),pq(ngrid,nlayer,nq)!temperature (K) and tracer concentration (kg/kg) 64 REAL, INTENT(IN) :: zzlay(ngrid,nlayer) ! altitude at the middle of the layers 65 REAL, INTENT(IN) :: zzlev(ngrid,nlayer+1) ! altitude at layer boundaries 66 LOGICAL, INTENT(IN) :: tracer ! =.true. if tracers are present and to be transported 67 INTEGER, INTENT(IN) :: igcm_co2 ! index of the CO2 tracer in mixing ratio array 68 ! --> 0 if no tracer is CO2 (or no tracer at all) 69 ! --> this prepares special treatment for polar night mixing 70 ! (see thermcell_main_mars) 71 REAL, INTENT(IN) :: pdu(ngrid,nlayer),pdv(ngrid,nlayer) ! wind velocity change from routines called 57 72 ! before thermals du/dt (m/s/s) 58 REAL, INTENT(IN) :: pdq(ngrid mx,nlayermx,nqmx) ! tracer concentration change from routines called73 REAL, INTENT(IN) :: pdq(ngrid,nlayer,nq) ! tracer concentration change from routines called 59 74 ! before thermals dq/dt (kg/kg/s) 60 REAL, INTENT(IN) :: pdt(ngrid mx,nlayermx) ! temperature change from routines called before thermals dT/dt (K/s)61 REAL, INTENT(IN) :: q2(ngrid mx,nlayermx+1) ! turbulent kinetic energy62 REAL, INTENT(IN) :: zpopsk(ngrid mx,nlayermx) ! ratio of pressure at middle of layer to surface pressure,75 REAL, INTENT(IN) :: pdt(ngrid,nlayer) ! temperature change from routines called before thermals dT/dt (K/s) 76 REAL, INTENT(IN) :: q2(ngrid,nlayer+1) ! turbulent kinetic energy 77 REAL, INTENT(IN) :: zpopsk(ngrid,nlayer) ! ratio of pressure at middle of layer to surface pressure, 63 78 ! to the power r/cp, i.e. zpopsk=(pplay(ig,l)/pplev(ig,1))**rcp 64 REAL, INTENT(IN) :: pdhdif(ngrid mx,nlayermx) ! potential temperature change from turbulent diffusion scheme dT/dt (K/s)65 REAL, INTENT(IN) :: sensibFlux(ngrid mx) ! sensible heat flux computed from surface layer scheme79 REAL, INTENT(IN) :: pdhdif(ngrid,nlayer) ! potential temperature change from turbulent diffusion scheme dT/dt (K/s) 80 REAL, INTENT(IN) :: sensibFlux(ngrid) ! sensible heat flux computed from surface layer scheme 66 81 67 82 !-------------------------------------------------------- … … 69 84 !-------------------------------------------------------- 70 85 71 REAL, INTENT(OUT) :: pdu_th(ngridmx,nlayermx) ! wind velocity change from thermals du/dt (m/s/s) 72 REAL, INTENT(OUT) :: pdv_th(ngridmx,nlayermx) ! wind velocity change from thermals dv/dt (m/s/s) 73 REAL, INTENT(OUT) :: pdt_th(ngridmx,nlayermx) ! temperature change from thermals dT/dt (K/s) 74 REAL, INTENT(OUT) :: pdq_th(ngridmx,nlayermx,nqmx) ! tracer change from thermals dq/dt (kg/kg/s) 75 INTEGER, INTENT(OUT) :: lmax(ngridmx) ! layer number reacher by thermals in grid point 76 REAL, INTENT(OUT) :: zmaxth(ngridmx) ! equivalent to lmax, but in (m), interpolated 77 REAL, INTENT(OUT) :: pbl_dtke(ngridmx,nlayermx+1) ! turbulent kinetic energy change from thermals dtke/dt 78 REAL, INTENT(OUT) :: wstar(ngridmx) ! free convection velocity (m/s) 79 80 !-------------------------------------------------------- 81 ! Control parameters of the thermal model 82 !-------------------------------------------------------- 83 ! such variables are: 84 ! - outptherm to control internal diagnostics 85 ! - qtransport_thermals to control tracer transport in thermals 86 ! - dtke_thermals to control turbulent kinetic energy transport in thermals 87 LOGICAL,SAVE :: outptherm,qtransport_thermals,dtke_thermals 86 REAL, INTENT(OUT) :: pdu_th(ngrid,nlayer) ! wind velocity change from thermals du/dt (m/s/s) 87 REAL, INTENT(OUT) :: pdv_th(ngrid,nlayer) ! wind velocity change from thermals dv/dt (m/s/s) 88 REAL, INTENT(OUT) :: pdt_th(ngrid,nlayer) ! temperature change from thermals dT/dt (K/s) 89 REAL, INTENT(OUT) :: pdq_th(ngrid,nlayer,nq) ! tracer change from thermals dq/dt (kg/kg/s) 90 INTEGER, INTENT(OUT) :: lmax(ngrid) ! layer number reacher by thermals in grid point 91 REAL, INTENT(OUT) :: zmaxth(ngrid) ! equivalent to lmax, but in (m), interpolated 92 REAL, INTENT(OUT) :: pbl_dtke(ngrid,nlayer+1) ! turbulent kinetic energy change from thermals dtke/dt 93 REAL, INTENT(OUT) :: wstar(ngrid) ! free convection velocity (m/s) 88 94 89 95 !-------------------------------------------------------- 90 96 ! Thermals local variables 91 97 !-------------------------------------------------------- 92 REAL zu(ngrid mx,nlayermx), zv(ngridmx,nlayermx)93 REAL zt(ngrid mx,nlayermx)94 REAL d_t_ajs(ngrid mx,nlayermx)95 REAL d_u_ajs(ngrid mx,nlayermx), d_q_ajs(ngridmx,nlayermx,nqmx)96 REAL d_v_ajs(ngrid mx,nlayermx)97 REAL fm_therm(ngrid mx,nlayermx+1), entr_therm(ngridmx,nlayermx)98 REAL detr_therm(ngrid mx,nlayermx),detrmod(ngridmx,nlayermx)99 REAL zw2(ngrid mx,nlayermx+1)100 REAL fraca(ngrid mx,nlayermx+1),zfraca(ngridmx,nlayermx+1)101 REAL q_therm(ngrid mx,nlayermx), pq_therm(ngridmx,nlayermx,nqmx)102 REAL q2_therm(ngrid mx,nlayermx), dq2_therm(ngridmx,nlayermx)103 REAL lmax_real(ngrid mx)104 REAL masse(ngrid mx,nlayermx)98 REAL zu(ngrid,nlayer), zv(ngrid,nlayer) 99 REAL zt(ngrid,nlayer) 100 REAL d_t_ajs(ngrid,nlayer) 101 REAL d_u_ajs(ngrid,nlayer), d_q_ajs(ngrid,nlayer,nq) 102 REAL d_v_ajs(ngrid,nlayer) 103 REAL fm_therm(ngrid,nlayer+1), entr_therm(ngrid,nlayer) 104 REAL detr_therm(ngrid,nlayer),detrmod(ngrid,nlayer) 105 REAL zw2(ngrid,nlayer+1) 106 REAL fraca(ngrid,nlayer+1),zfraca(ngrid,nlayer+1) 107 REAL q_therm(ngrid,nlayer), pq_therm(ngrid,nlayer,nq) 108 REAL q2_therm(ngrid,nlayer), dq2_therm(ngrid,nlayer) 109 REAL lmax_real(ngrid) 110 REAL masse(ngrid,nlayer) 105 111 106 112 INTEGER l,ig,iq,ii(1),k … … 111 117 !-------------------------------------------------------- 112 118 113 REAL d_t_the(ngrid mx,nlayermx), d_q_the(ngridmx,nlayermx,nqmx)119 REAL d_t_the(ngrid,nlayer), d_q_the(ngrid,nlayer,nq) 114 120 INTEGER isplit 115 INTEGER,SAVE :: nsplit_thermals116 REAL, SAVE :: r_aspect_thermals117 121 REAL fact 118 REAL zfm_therm(ngrid mx,nlayermx+1),zdt119 REAL zentr_therm(ngrid mx,nlayermx),zdetr_therm(ngridmx,nlayermx)120 REAL zheatFlux(ngrid mx,nlayermx)121 REAL zheatFlux_down(ngrid mx,nlayermx)122 REAL zbuoyancyOut(ngrid mx,nlayermx)123 REAL zbuoyancyEst(ngrid mx,nlayermx)124 REAL zzw2(ngrid mx,nlayermx+1)125 REAL zmax(ngrid mx)122 REAL zfm_therm(ngrid,nlayer+1),zdt 123 REAL zentr_therm(ngrid,nlayer),zdetr_therm(ngrid,nlayer) 124 REAL zheatFlux(ngrid,nlayer) 125 REAL zheatFlux_down(ngrid,nlayer) 126 REAL zbuoyancyOut(ngrid,nlayer) 127 REAL zbuoyancyEst(ngrid,nlayer) 128 REAL zzw2(ngrid,nlayer+1) 129 REAL zmax(ngrid) 126 130 INTEGER ndt,zlmax 127 131 … … 130 134 !-------------------------------------------------------- 131 135 132 REAL heatFlux(ngridmx,nlayermx) 133 REAL heatFlux_down(ngridmx,nlayermx) 134 REAL buoyancyOut(ngridmx,nlayermx) 135 REAL buoyancyEst(ngridmx,nlayermx) 136 REAL hfmax(ngridmx),wmax(ngridmx) 137 REAL pbl_teta(ngridmx),dteta(ngridmx,nlayermx) 138 REAL rpdhd(ngridmx,nlayermx) 139 REAL wtdif(ngridmx,nlayermx),rho(ngridmx,nlayermx) 140 REAL wtth(ngridmx,nlayermx) 141 142 !-------------------------------------------------------- 143 ! Theta_m 144 !-------------------------------------------------------- 145 146 INTEGER,SAVE :: ico2 147 148 149 if(firstcall) then 150 ico2=0 151 ! ********************************************************************** 152 ! Polar night mixing : theta_m 153 ! Get index of co2 tracer in tracer array 154 ! ********************************************************************** 155 if (tracer) then !NB: tracer==.true. if tracers are present and to be transported 156 ! Prepare Special treatment if one of the tracers is CO2 gas 157 do iq=1,nqmx 158 if (noms(iq).eq."co2") then 159 ico2=iq 160 end if 161 enddo 162 endif 163 164 ! control parameters of the thermal model: 165 qtransport_thermals=.true. !! default setting: transport tracers in thermals 166 167 dtke_thermals=.false. !! default setting 168 ! switch to transport TKE in thermals. still experimental, for testing purposes only. not used in current thermal plume models both on Earth and Mars. 169 170 outptherm=.false. !! default setting 171 ! switch to control if internal quantities ofthe thermals must be output (typically set to .false., but very useful for fine diagnostics. 172 ! get value (if set by user) of this parameter from run.def file 173 call getin("outptherm",outptherm) 174 175 endif !of if firstcall 136 REAL heatFlux(ngrid,nlayer) 137 REAL heatFlux_down(ngrid,nlayer) 138 REAL buoyancyOut(ngrid,nlayer) 139 REAL buoyancyEst(ngrid,nlayer) 140 REAL hfmax(ngrid),wmax(ngrid) 141 REAL pbl_teta(ngrid),dteta(ngrid,nlayer) 142 REAL rpdhd(ngrid,nlayer) 143 REAL wtdif(ngrid,nlayer),rho(ngrid,nlayer) 144 REAL wtth(ngrid,nlayer) 176 145 177 146 ! ********************************************************************** … … 226 195 227 196 IF(dtke_thermals) THEN 228 DO l=1,nlayer mx197 DO l=1,nlayer 229 198 q2_therm(:,l)=0.5*(q2(:,l)+q2(:,l+1)) 230 199 ENDDO 231 200 ENDIF 232 201 233 234 ! ********************************************************************** 235 ! ********************************************************************** 236 ! ********************************************************************** 237 ! CALLTHERM 238 ! ********************************************************************** 239 ! ********************************************************************** 240 ! ********************************************************************** 241 242 ! r_aspect_thermals ! Mainly control the shape of the temperature profile 243 ! in the surface layer. Decreasing it goes toward 244 ! a convective-adjustment like profile. 245 ! nsplit_thermals ! Sub-timestep for the thermals. Very dependant on the 246 ! chosen timestep for the radiative transfer. 247 ! It is recommended to run with 96 timestep per day and 248 ! call radiative transfer at each timestep, 249 ! configuration in which thermals can run 250 ! very well with a sub-timestep of 10. 251 IF (firstcall) THEN 252 r_aspect_thermals=1. ! same value is OK for GCM and mesoscale 253 ! Sub Timestep for the mesoscale model: 254 #ifdef MESOSCALE 255 !! valid for timesteps < 200s 256 nsplit_thermals=4 257 #else 258 ! Sub Timestep for the GCM: 259 ! If there is at least 96 timesteps per day in the gcm, subtimestep factor 10 260 IF ((ptimestep .le. 3699.*24./96.) .and. (iradia .eq. 1)) THEN 261 nsplit_thermals=10 262 ELSE !if there is less, subtimestep factor 35 263 nsplit_thermals=35 264 ENDIF 265 #endif 266 ENDIF 267 268 ! ********************************************************************** 202 ! ********************************************************************** 203 ! --> CALLTHERM 269 204 ! SUB-TIMESTEP LOOP 270 205 ! ********************************************************************** … … 280 215 lmax(:)=0 281 216 282 if (nq mx .ne. 0 .and. ico2 .ne. 0) then !initialize co2 tracer tendancy283 d_q_the(:,:,i co2)=0.217 if (nq .ne. 0 .and. igcm_co2 .ne. 0) then !initialize co2 tracer tendancy 218 d_q_the(:,:,igcm_co2)=0. 284 219 endif 285 220 286 221 ! CALL to main thermal routine 287 CALL thermcell_main_mars(zdt & 222 CALL thermcell_main_mars(ngrid,nlayer,nq & 223 & ,tracer,igcm_co2 & 224 & ,zdt & 288 225 & ,pplay,pplev,pphi,zzlev,zzlay & 289 226 & ,zu,zv,zt,pq_therm,q2_therm & 290 227 & ,d_t_the,d_q_the & 291 228 & ,zfm_therm,zentr_therm,zdetr_therm,lmax,zmax & 292 & ,r_aspect_thermals &293 229 & ,zzw2,fraca,zpopsk & 294 230 & ,zheatFlux,zheatFlux_down & … … 299 235 ! Update thermals tendancies 300 236 d_t_the(:,:)=d_t_the(:,:)*ptimestep*fact !temperature 301 if (i co2 .ne. 0) then302 d_q_the(:,:,i co2)=d_q_the(:,:,ico2)*ptimestep*fact !co2 mass mixing ratio237 if (igcm_co2 .ne. 0) then 238 d_q_the(:,:,igcm_co2)=d_q_the(:,:,igcm_co2)*ptimestep*fact !co2 mass mixing ratio 303 239 endif 304 240 zmaxth(:)=zmaxth(:)+zmax(:)*fact !thermals height … … 323 259 ! Save tendancies 324 260 d_t_ajs(:,:)=d_t_ajs(:,:)+d_t_the(:,:) !temperature tendancy (delta T) 325 if (i co2 .ne. 0) then326 d_q_ajs(:,:,i co2)=d_q_ajs(:,:,ico2)+d_q_the(:,:,ico2) !tracer tendancy (delta q)261 if (igcm_co2 .ne. 0) then 262 d_q_ajs(:,:,igcm_co2)=d_q_ajs(:,:,igcm_co2)+d_q_the(:,:,igcm_co2) !tracer tendancy (delta q) 327 263 endif 328 264 329 265 ! Increment temperature and co2 concentration for next pass in subtimestep loop 330 266 zt(:,:) = zt(:,:) + d_t_the(:,:) !temperature 331 if (i co2 .ne. 0) then332 pq_therm(:,:,i co2) = &333 & pq_therm(:,:,i co2) + d_q_the(:,:,ico2) !co2 tracer267 if (igcm_co2 .ne. 0) then 268 pq_therm(:,:,igcm_co2) = & 269 & pq_therm(:,:,igcm_co2) + d_q_the(:,:,igcm_co2) !co2 tracer 334 270 endif 335 271 … … 342 278 lmax(:)=nint(lmax_real(:)) 343 279 zlmax=MAXVAL(lmax(:))+2 344 if (zlmax .ge. nlayer mx) then280 if (zlmax .ge. nlayer) then 345 281 print*,'thermals have reached last layer of the model' 346 282 print*,'this is not good !' … … 356 292 357 293 ! mass of cells 358 do l=1,nlayer mx294 do l=1,nlayer 359 295 masse(:,l)=(pplev(:,l)-pplev(:,l+1))/g 360 296 enddo … … 364 300 detrmod(:,:)=0. 365 301 do l=1,zlmax 366 do ig=1,ngrid mx302 do ig=1,ngrid 367 303 detrmod(ig,l)=fm_therm(ig,l)-fm_therm(ig,l+1) & 368 304 & +entr_therm(ig,l) … … 377 313 ! result is a derivative (d_u_ajs in m/s/s) 378 314 ndt=10 379 call thermcell_dqup(ngrid mx,nlayermx,ptimestep &315 call thermcell_dqup(ngrid,nlayer,ptimestep & 380 316 & ,fm_therm,entr_therm,detrmod, & 381 317 & masse,zu,d_u_ajs,ndt,zlmax) … … 383 319 ! v component of wind velocity advection in thermals 384 320 ! result is a derivative (d_v_ajs in m/s/s) 385 call thermcell_dqup(ngrid mx,nlayermx,ptimestep &321 call thermcell_dqup(ngrid,nlayer,ptimestep & 386 322 & ,fm_therm,entr_therm,detrmod, & 387 323 & masse,zv,d_v_ajs,ndt,zlmax) … … 390 326 ! result is a derivative (d_q_ajs in kg/kg/s) 391 327 392 if (nq mx.ne. 0.) then393 DO iq=1,nq mx394 if (iq .ne. i co2) then395 call thermcell_dqup(ngrid mx,nlayermx,ptimestep &328 if (nq .ne. 0.) then 329 DO iq=1,nq 330 if (iq .ne. igcm_co2) then 331 call thermcell_dqup(ngrid,nlayer,ptimestep & 396 332 & ,fm_therm,entr_therm,detrmod, & 397 333 & masse,pq_therm(:,:,iq),d_q_ajs(:,:,iq),ndt,zlmax) … … 403 339 ! result is a tendancy (d_u_ajs in J) 404 340 if (dtke_thermals) then 405 call thermcell_dqup(ngrid mx,nlayermx,ptimestep &341 call thermcell_dqup(ngrid,nlayer,ptimestep & 406 342 & ,fm_therm,entr_therm,detrmod, & 407 343 & masse,q2_therm,dq2_therm,ndt,zlmax) … … 409 345 410 346 ! compute wmax for diagnostics 411 DO ig=1,ngrid mx347 DO ig=1,ngrid 412 348 wmax(ig)=MAXVAL(zw2(ig,:)) 413 349 ENDDO … … 434 370 if(qtransport_thermals) then 435 371 if(tracer) then 436 do iq=1,nq mx437 if (iq .ne. i co2) then372 do iq=1,nq 373 if (iq .ne. igcm_co2) then 438 374 do l=1,zlmax 439 375 pdq_th(:,l,iq)=d_q_ajs(:,l,iq) !non-co2 tracers d_q_ajs are dq/dt (kg/kg/s) … … 450 386 ! if tke is transported in thermals, update output variable, else this is 0. 451 387 IF(dtke_thermals) THEN 452 DO l=2,nlayer mx388 DO l=2,nlayer 453 389 pbl_dtke(:,l)=0.5*(dq2_therm(:,l-1)+dq2_therm(:,l)) 454 390 ENDDO 455 391 456 392 pbl_dtke(:,1)=0.5*dq2_therm(:,1) 457 pbl_dtke(:,nlayer mx+1)=0.393 pbl_dtke(:,nlayer+1)=0. 458 394 ENDIF 459 395 … … 475 411 ! Potential temperature gradient 476 412 477 dteta(:,nlayer mx)=0.478 DO l=1,nlayer mx-1479 DO ig=1, ngrid mx413 dteta(:,nlayer)=0. 414 DO l=1,nlayer-1 415 DO ig=1, ngrid 480 416 dteta(ig,l) = ((zt(ig,l+1)-zt(ig,l))/zpopsk(ig,l)) & 481 417 & /(zzlay(ig,l+1)-zzlay(ig,l)) … … 485 421 ! Computation of the PBL mixed layer temperature 486 422 487 DO ig=1, ngrid mx423 DO ig=1, ngrid 488 424 ii=MINLOC(abs(dteta(ig,1:lmax(ig)))) 489 425 pbl_teta(ig) = zt(ig,ii(1))/zpopsk(ig,ii(1)) … … 504 440 rpdhd(:,:)=0. 505 441 506 DO ig=1,ngrid mx442 DO ig=1,ngrid 507 443 DO l=1,lmax(ig) 508 444 rpdhd(ig,l)=0. … … 527 463 ! integrate -rho*pdhdif 528 464 529 DO ig=1,ngrid mx465 DO ig=1,ngrid 530 466 DO l=1,lmax(ig) 531 467 rpdhd(ig,l)=0. … … 538 474 ENDDO 539 475 ENDDO 540 rpdhd(:,nlayer mx)=0.476 rpdhd(:,nlayer)=0. 541 477 542 478 ! compute w'teta' from thermals … … 547 483 ! and compute the maximum 548 484 549 DO ig=1,ngrid mx485 DO ig=1,ngrid 550 486 hfmax(ig)=MAXVAL(wtth(ig,:)+wtdif(ig,:)) 551 487 ENDDO … … 555 491 ! ------------ 556 492 557 DO ig=1, ngrid mx493 DO ig=1, ngrid 558 494 IF (zmax(ig) .gt. 0.) THEN 559 495 wstar(ig)=(g*zmaxth(ig)*hfmax(ig)/pbl_teta(ig))**(1./3.) … … 563 499 ENDDO 564 500 565 ! **********************************************************************566 ! Diagnostics567 ! **********************************************************************568 ! THESE DIAGNOSTICS ARE WRITTEN IN THE LMD-GCM FORMAT569 ! THESE ARE LEFT AS A FURTHER INDICATION OF THE QUANTITIES DEFINED IN THIS ROUTINE570 571 ! outptherm is a logical in callkeys that controls if internal quantities of the thermals must be output.572 573 if (outptherm) then574 if (ngridmx .eq. 1) then !these are 1D outputs575 call WRITEDIAGFI(ngridmx,'entr_therm','entrainement thermique',&576 & 'kg/m-2',1,entr_therm)577 call WRITEDIAGFI(ngridmx,'detr_therm','detrainement thermique',&578 & 'kg/m-2',1,detr_therm)579 call WRITEDIAGFI(ngridmx,'fm_therm','flux masse thermique',&580 & 'kg/m-2',1,fm_therm)581 call WRITEDIAGFI(ngridmx,'zw2','vitesse verticale thermique',&582 & 'm/s',1,zw2)583 call WRITEDIAGFI(ngridmx,'heatFlux_up','heatFlux_updraft',&584 & 'SI',1,heatFlux)585 call WRITEDIAGFI(ngridmx,'heatFlux_down','heatFlux_downdraft',&586 & 'SI',1,heatFlux_down)587 call WRITEDIAGFI(ngridmx,'fraca','fraction coverage',&588 & 'percent',1,fraca)589 call WRITEDIAGFI(ngridmx,'buoyancyOut','buoyancyOut',&590 & 'm.s-2',1,buoyancyOut)591 call WRITEDIAGFI(ngridmx,'buoyancyEst','buoyancyEst',&592 & 'm.s-2',1,buoyancyEst)593 call WRITEDIAGFI(ngridmx,'d_t_th', &594 & 'tendance temp TH','K',1,d_t_ajs)595 call WRITEDIAGFI(ngridmx,'d_q_th', &596 & 'tendance traceur TH','kg/kg',1,d_q_ajs)597 call WRITEDIAGFI(ngridmx,'zmax', &598 & 'pbl height','m',0,zmaxth)599 call WRITEDIAGFI(ngridmx,'d_u_th', &600 & 'tendance moment','m/s',1,pdu_th)601 call WRITEDIAGFI(ngridmx,'wtdif', &602 & 'heat flux from diffusion','K.m/s',1,wtdif)603 call WRITEDIAGFI(ngridmx,'wtth', &604 & 'heat flux from thermals','K.m/s',1,wtth)605 call WRITEDIAGFI(ngridmx,'wttot', &606 & 'heat flux PBL','K.m/s',1,wtdif(:,:)+wtth(:,:))607 608 else !these are 3D outputs609 610 call WRITEDIAGFI(ngridmx,'entr_therm','entrainement thermique',&611 & 'kg/m-2',3,entr_therm)612 call WRITEDIAGFI(ngridmx,'detr_therm','detrainement thermique',&613 & 'kg/m-2',3,detr_therm)614 call WRITEDIAGFI(ngridmx,'fm_therm','flux masse thermique',&615 & 'kg/m-2',3,fm_therm)616 call WRITEDIAGFI(ngridmx,'zw2','vitesse verticale thermique',&617 & 'm/s',3,zw2)618 call WRITEDIAGFI(ngridmx,'heatFlux','heatFlux',&619 & 'SI',3,heatFlux)620 call WRITEDIAGFI(ngridmx,'buoyancyOut','buoyancyOut',&621 & 'SI',3,buoyancyOut)622 call WRITEDIAGFI(ngridmx,'d_t_th', &623 & 'tendance temp TH','K',3,d_t_ajs)624 625 endif626 endif ! of if (outptherm)627 628 501 END -
trunk/LMDZ.MARS/libf/phymars/physiq.F
r1013 r1032 896 896 if(calltherm) then 897 897 898 call calltherm_interface(firstcall, 898 call calltherm_interface(ngrid,nlayer,nq, 899 $ tracer,igcm_co2, 899 900 $ zzlev,zzlay, 900 901 $ ptimestep,pu,pv,pt,pq,pdu,pdv,pdt,pdq,q2, … … 2106 2107 & 'part/kg',3,ndust) 2107 2108 #ifdef MESOINI 2108 call WRITEDIAGFI(ngridmx,'dustq','Dust mass mr', 2109 & 'kg/kg',3,qdust) 2110 call WRITEDIAGFI(ngridmx,'dustN','Dust number', 2111 & 'part/kg',3,ndust) 2112 call WRITEDIAGFI(ngridmx,'ccn','Nuclei mass mr', 2113 & 'kg/kg',3,qccn) 2114 call WRITEDIAGFI(ngridmx,'ccnN','Nuclei number', 2115 & 'part/kg',3,nccn) 2109 ! !!! to initialize mesoscale we need scaled variables 2110 ! !!! because this must correspond to starting point for tracers 2111 ! call WRITEDIAGFI(ngridmx,'dustq','Dust mass mr', 2112 ! & 'kg/kg',3,pq(1:ngridmx,1:nlayermx,igcm_dust_mass)) 2113 ! call WRITEDIAGFI(ngridmx,'dustN','Dust number', 2114 ! & 'part/kg',3,pq(1:ngridmx,1:nlayermx,igcm_dust_number)) 2115 ! call WRITEDIAGFI(ngridmx,'ccn','Nuclei mass mr', 2116 ! & 'kg/kg',3,pq(1:ngridmx,1:nlayermx,igcm_ccn_mass)) 2117 ! call WRITEDIAGFI(ngridmx,'ccnN','Nuclei number', 2118 ! & 'part/kg',3,pq(1:ngridmx,1:nlayermx,igcm_ccn_number)) 2119 call WRITEDIAGFI(ngridmx,'dustq','Dust mass mr', 2120 & 'kg/kg',3,pq(1,1,igcm_dust_mass)) 2121 call WRITEDIAGFI(ngridmx,'dustN','Dust number', 2122 & 'part/kg',3,pq(1,1,igcm_dust_number)) 2123 call WRITEDIAGFI(ngridmx,'ccn','Nuclei mass mr', 2124 & 'kg/kg',3,pq(1,1,igcm_ccn_mass)) 2125 call WRITEDIAGFI(ngridmx,'ccnN','Nuclei number', 2126 & 'part/kg',3,pq(1,1,igcm_ccn_number)) 2116 2127 #endif 2117 2128 else -
trunk/LMDZ.MARS/libf/phymars/thermcell_dqup.F90
r1028 r1032 1 ! ---------------------------------------------------------------------2 ! Arnaud Colaitis 2011-01-053 ! --------------------------------------------------------------------4 1 subroutine thermcell_dqup(ngrid,nlayer,ptimestep,fm,entr,detr, & 5 2 & masse0,q_therm,dq_therm,ndt,zlmax) … … 16 13 ! 17 14 !======================================================================= 18 19 #include "dimensions.h" !contains global GCM grid dimension informations 20 #include "dimphys.h" !similar to dimensions.h, and based on it; includes 21 ! "ngridmx": number of horizontal grid points 22 ! "nlayermx": number of atmospheric layers 15 ! Arnaud Colaitis 2011-01-05 (modified 2011-2013) 16 ! SEE COMMENTS IN CALLTHERM_INTERFACE 17 !======================================================================= 23 18 24 19 ! ============================ INPUTS ============================ … … 26 21 INTEGER, INTENT(IN) :: ngrid,nlayer ! number of grid points and number of levels 27 22 REAL, INTENT(IN) :: ptimestep ! timestep (s) 28 REAL, INTENT(IN) :: fm(ngrid mx,nlayermx+1) ! upward mass flux29 REAL, INTENT(IN) :: entr(ngrid mx,nlayermx) ! entrainment mass flux30 REAL, INTENT(IN) :: detr(ngrid mx,nlayermx) ! detrainment mass flux31 REAL, INTENT(IN) :: q_therm(ngrid mx,nlayermx) ! initial profil of q32 REAL, INTENT(IN) :: masse0(ngrid mx,nlayermx) ! mass of cells23 REAL, INTENT(IN) :: fm(ngrid,nlayer+1) ! upward mass flux 24 REAL, INTENT(IN) :: entr(ngrid,nlayer) ! entrainment mass flux 25 REAL, INTENT(IN) :: detr(ngrid,nlayer) ! detrainment mass flux 26 REAL, INTENT(IN) :: q_therm(ngrid,nlayer) ! initial profil of q 27 REAL, INTENT(IN) :: masse0(ngrid,nlayer) ! mass of cells 33 28 INTEGER, INTENT(IN) :: ndt ! number of subtimesteps 34 29 INTEGER, INTENT(IN) :: zlmax ! index of maximum layer … … 36 31 ! ============================ OUTPUTS =========================== 37 32 38 REAL, INTENT(OUT) :: dq_therm(ngrid mx,nlayermx) ! dq/dt -> derivative33 REAL, INTENT(OUT) :: dq_therm(ngrid,nlayer) ! dq/dt -> derivative 39 34 40 35 ! ============================ LOCAL ============================= 41 36 42 REAL q(ngrid mx,nlayermx)43 REAL qa(ngrid mx,nlayermx)37 REAL q(ngrid,nlayer) 38 REAL qa(ngrid,nlayer) 44 39 INTEGER ig,k,i 45 REAL invflux0(ngrid mx,nlayermx)40 REAL invflux0(ngrid,nlayer) 46 41 REAL ztimestep 47 42 … … 65 60 66 61 do k=2,zlmax 67 do ig=1,ngrid mx62 do ig=1,ngrid 68 63 if ((fm(ig,k+1)+detr(ig,k))*ptimestep.gt. & 69 64 & 1.e-5*masse0(ig,k)) then -
trunk/LMDZ.MARS/libf/phymars/thermcell_main_mars.F90
r1028 r1032 1 1 !======================================================================= 2 2 ! THERMCELL_MAIN_MARS 3 ! Author : A Colaitis3 ! Author : A. Colaitis after C. Rio and F. Hourdin 4 4 ! 5 5 ! This routine is called by calltherm_interface and is inside a sub-timestep … … 7 7 ! detrainment rate as well as the source profile. 8 8 ! Mass flux are then computed and temperature and CO2 MMR are transported. 9 !10 ! This routine is based on the terrestrial version thermcell_main of the11 ! LMDZ model, written by C. Rio and F. Hourdin12 9 !======================================================================= 13 ! 14 ! 15 SUBROUTINE thermcell_main_mars(ptimestep & 10 ! SEE COMMENTS IN CALLTHERM_INTERFACE 11 !======================================================================= 12 ! 13 ! 14 SUBROUTINE thermcell_main_mars(ngrid,nlayer,nq & 15 & ,tracer,igcm_co2 & 16 & ,ptimestep & 16 17 & ,pplay,pplev,pphi,zlev,zlay & 17 18 & ,pu,pv,pt,pq,pq2 & 18 19 & ,pdtadj,pdqadj & 19 20 & ,fm,entr,detr,lmax,zmax & 20 & ,r_aspect &21 21 & ,zw2,fraca & 22 22 & ,zpopsk,heatFlux,heatFlux_down & 23 23 & ,buoyancyOut, buoyancyEst) 24 24 25 USE comtherm_h 26 25 27 IMPLICIT NONE 26 28 27 29 !======================================================================= 28 30 29 #include "callkeys.h" !contains logical values determining which subroutines and which options are used. 30 ! includes logical "tracer", which is .true. if tracers are present and to be transported 31 ! includes logical "lwrite", which is .true. if one wants more verbose outputs as GCM runs 32 #include "dimensions.h" !contains global GCM grid dimension informations 33 #include "dimphys.h" !similar to dimensions.h, and based on it; includes 34 ! "ngridmx": number of horizontal grid points 35 ! "nlayermx": number of atmospheric layers 31 ! SHARED VARIABLES. This needs adaptations in another climate model. 36 32 #include "comcstfi.h" !contains physical constant values such as 37 33 ! "g" : gravitational acceleration (m.s-2) 38 34 ! "r" : recuced gas constant (J.K-1.mol-1) 39 #include "tracer.h" !contains tracer information such as 40 ! "nqmx": number of tracers 41 ! "noms()": tracer name 35 42 36 ! ============== INPUTS ============== 43 37 38 INTEGER, INTENT(IN) :: ngrid ! number of horizontal grid points 39 INTEGER, INTENT(IN) :: nlayer ! number of vertical grid points 40 INTEGER, INTENT(IN) :: nq ! number of tracer species 41 LOGICAL, INTENT(IN) :: tracer ! =.true. if tracers are present and to be transported 42 INTEGER, INTENT(IN) :: igcm_co2 ! index of the CO2 tracer in mixing ratio array 43 ! --> 0 if no tracer is CO2 (or no tracer at all) 44 ! --> this prepares special treatment for polar night mixing 44 45 REAL, INTENT(IN) :: ptimestep !subtimestep (s) 45 REAL, INTENT(IN) :: r_aspect !aspect ratio (see paragraph 45 of paper and appendix S4) 46 REAL, INTENT(IN) :: pt(ngridmx,nlayermx) !temperature (K) 47 REAL, INTENT(IN) :: pu(ngridmx,nlayermx) !u component of the wind (ms-1) 48 REAL, INTENT(IN) :: pv(ngridmx,nlayermx) !v component of the wind (ms-1) 49 REAL, INTENT(IN) :: pq(ngridmx,nlayermx,nqmx) !tracer concentration (kg/kg) 50 REAL, INTENT(IN) :: pq2(ngridmx,nlayermx) ! Turbulent Kinetic Energy 51 REAL, INTENT(IN) :: pplay(ngridmx,nlayermx) !Pressure at the middle of the layers (Pa) 52 REAL, INTENT(IN) :: pplev(ngridmx,nlayermx+1) !intermediate pressure levels (Pa) 53 REAL, INTENT(IN) :: pphi(ngridmx,nlayermx) !Geopotential at the middle of the layers (m2s-2) 54 REAL, INTENT(IN) :: zlay(ngridmx,nlayermx) ! altitude at the middle of the layers 55 REAL, INTENT(IN) :: zlev(ngridmx,nlayermx+1) ! altitude at layer boundaries 46 REAL, INTENT(IN) :: pt(ngrid,nlayer) !temperature (K) 47 REAL, INTENT(IN) :: pu(ngrid,nlayer) !u component of the wind (ms-1) 48 REAL, INTENT(IN) :: pv(ngrid,nlayer) !v component of the wind (ms-1) 49 REAL, INTENT(IN) :: pq(ngrid,nlayer,nq) !tracer concentration (kg/kg) 50 REAL, INTENT(IN) :: pq2(ngrid,nlayer) ! Turbulent Kinetic Energy 51 REAL, INTENT(IN) :: pplay(ngrid,nlayer) !Pressure at the middle of the layers (Pa) 52 REAL, INTENT(IN) :: pplev(ngrid,nlayer+1) !intermediate pressure levels (Pa) 53 REAL, INTENT(IN) :: pphi(ngrid,nlayer) !Geopotential at the middle of the layers (m2s-2) 54 REAL, INTENT(IN) :: zlay(ngrid,nlayer) ! altitude at the middle of the layers 55 REAL, INTENT(IN) :: zlev(ngrid,nlayer+1) ! altitude at layer boundaries 56 56 57 57 ! ============== OUTPUTS ============== 58 58 59 59 ! TEMPERATURE 60 REAL, INTENT(OUT) :: pdtadj(ngrid mx,nlayermx) !temperature change from thermals dT/dt (K/s)60 REAL, INTENT(OUT) :: pdtadj(ngrid,nlayer) !temperature change from thermals dT/dt (K/s) 61 61 62 62 ! DIAGNOSTICS 63 REAL, INTENT(OUT) :: zw2(ngrid mx,nlayermx+1) ! vertical velocity (m/s)64 REAL, INTENT(OUT) :: heatFlux(ngrid mx,nlayermx) ! interface heatflux65 REAL, INTENT(OUT) :: heatFlux_down(ngrid mx,nlayermx) ! interface heat flux from downdraft63 REAL, INTENT(OUT) :: zw2(ngrid,nlayer+1) ! vertical velocity (m/s) 64 REAL, INTENT(OUT) :: heatFlux(ngrid,nlayer) ! interface heatflux 65 REAL, INTENT(OUT) :: heatFlux_down(ngrid,nlayer) ! interface heat flux from downdraft 66 66 67 67 ! ============== LOCAL ================ 68 REAL :: pdqadj(ngrid mx,nlayermx,nqmx) !tracer change from thermals dq/dt, only for CO2 (the rest can be advected outside of the loop)68 REAL :: pdqadj(ngrid,nlayer,nq) !tracer change from thermals dq/dt, only for CO2 (the rest can be advected outside of the loop) 69 69 70 70 ! dummy variables when output not needed : 71 71 72 REAL :: buoyancyOut(ngrid mx,nlayermx) ! interlayer buoyancy term73 REAL :: buoyancyEst(ngrid mx,nlayermx) ! interlayer estimated buoyancy term72 REAL :: buoyancyOut(ngrid,nlayer) ! interlayer buoyancy term 73 REAL :: buoyancyEst(ngrid,nlayer) ! interlayer estimated buoyancy term 74 74 75 75 ! ============== LOCAL ================ 76 76 77 77 INTEGER ig,k,l,ll,iq 78 INTEGER lmax(ngrid mx),lmin(ngridmx),lalim(ngridmx)79 REAL zmax(ngrid mx)80 REAL ztva(ngrid mx,nlayermx),zw_est(ngridmx,nlayermx+1),ztva_est(ngridmx,nlayermx)81 REAL zh(ngrid mx,nlayermx)82 REAL zdthladj(ngrid mx,nlayermx)83 REAL zdthladj_down(ngrid mx,nlayermx)84 REAL ztvd(ngrid mx,nlayermx)85 REAL ztv(ngrid mx,nlayermx)86 REAL zu(ngrid mx,nlayermx),zv(ngridmx,nlayermx),zo(ngridmx,nlayermx)87 REAL zva(ngrid mx,nlayermx)88 REAL zua(ngrid mx,nlayermx)89 90 REAL zta(ngrid mx,nlayermx)91 REAL fraca(ngrid mx,nlayermx+1)92 REAL q2(ngrid mx,nlayermx)93 REAL rho(ngrid mx,nlayermx),rhobarz(ngridmx,nlayermx),masse(ngridmx,nlayermx)94 REAL zpopsk(ngrid mx,nlayermx)95 96 REAL wmax(ngrid mx)97 REAL fm(ngrid mx,nlayermx+1),entr(ngridmx,nlayermx),detr(ngridmx,nlayermx)98 99 REAL fm_down(ngrid mx,nlayermx+1)100 101 REAL ztla(ngrid mx,nlayermx)102 103 REAL f_star(ngrid mx,nlayermx+1),entr_star(ngridmx,nlayermx)104 REAL detr_star(ngrid mx,nlayermx)105 REAL alim_star_tot(ngrid mx)106 REAL alim_star(ngrid mx,nlayermx)107 REAL alim_star_clos(ngrid mx,nlayermx)108 REAL f(ngrid mx)109 110 REAL detrmod(ngrid mx,nlayermx)111 112 REAL teta_th_int(ngrid mx,nlayermx)113 REAL teta_env_int(ngrid mx,nlayermx)114 REAL teta_down_int(ngrid mx,nlayermx)78 INTEGER lmax(ngrid),lmin(ngrid),lalim(ngrid) 79 REAL zmax(ngrid) 80 REAL ztva(ngrid,nlayer),zw_est(ngrid,nlayer+1),ztva_est(ngrid,nlayer) 81 REAL zh(ngrid,nlayer) 82 REAL zdthladj(ngrid,nlayer) 83 REAL zdthladj_down(ngrid,nlayer) 84 REAL ztvd(ngrid,nlayer) 85 REAL ztv(ngrid,nlayer) 86 REAL zu(ngrid,nlayer),zv(ngrid,nlayer),zo(ngrid,nlayer) 87 REAL zva(ngrid,nlayer) 88 REAL zua(ngrid,nlayer) 89 90 REAL zta(ngrid,nlayer) 91 REAL fraca(ngrid,nlayer+1) 92 REAL q2(ngrid,nlayer) 93 REAL rho(ngrid,nlayer),rhobarz(ngrid,nlayer),masse(ngrid,nlayer) 94 REAL zpopsk(ngrid,nlayer) 95 96 REAL wmax(ngrid) 97 REAL fm(ngrid,nlayer+1),entr(ngrid,nlayer),detr(ngrid,nlayer) 98 99 REAL fm_down(ngrid,nlayer+1) 100 101 REAL ztla(ngrid,nlayer) 102 103 REAL f_star(ngrid,nlayer+1),entr_star(ngrid,nlayer) 104 REAL detr_star(ngrid,nlayer) 105 REAL alim_star_tot(ngrid) 106 REAL alim_star(ngrid,nlayer) 107 REAL alim_star_clos(ngrid,nlayer) 108 REAL f(ngrid) 109 110 REAL detrmod(ngrid,nlayer) 111 112 REAL teta_th_int(ngrid,nlayer) 113 REAL teta_env_int(ngrid,nlayer) 114 REAL teta_down_int(ngrid,nlayer) 115 115 116 116 CHARACTER (LEN=80) :: abort_message … … 119 119 ! ============= PLUME VARIABLES ============ 120 120 121 REAL w_est(ngrid mx,nlayermx+1)122 REAL wa_moy(ngrid mx,nlayermx+1)123 REAL wmaxa(ngrid mx)124 REAL zdz,zbuoy(ngrid mx,nlayermx),zw2m125 LOGICAL activecell(ngrid mx),activetmp(ngridmx)121 REAL w_est(ngrid,nlayer+1) 122 REAL wa_moy(ngrid,nlayer+1) 123 REAL wmaxa(ngrid) 124 REAL zdz,zbuoy(ngrid,nlayer),zw2m 125 LOGICAL activecell(ngrid),activetmp(ngrid) 126 126 REAL a1,b1,ae,be,ad,bd,fdfu,b1inv,a1inv,omega 127 127 INTEGER tic … … 131 131 ! ============= HEIGHT VARIABLES =========== 132 132 133 REAL num(ngrid mx)134 REAL denom(ngrid mx)135 REAL zlevinter(ngrid mx)133 REAL num(ngrid) 134 REAL denom(ngrid) 135 REAL zlevinter(ngrid) 136 136 INTEGER zlmax 137 137 … … 140 140 ! ============= CLOSURE VARIABLES ========= 141 141 142 REAL zdenom(ngrid mx)143 REAL alim_star2(ngrid mx)144 REAL alim_star_tot_clos(ngrid mx)142 REAL zdenom(ngrid) 143 REAL alim_star2(ngrid) 144 REAL alim_star_tot_clos(ngrid) 145 145 INTEGER llmax 146 146 … … 159 159 ! ============== Theta_M Variables ======== 160 160 161 INTEGER ico2162 SAVE ico2163 161 REAL m_co2, m_noco2, A , B 164 162 SAVE A, B 165 LOGICAL firstcall 166 save firstcall 167 data firstcall/.true./ 168 REAL zhc(ngridmx,nlayermx) 169 REAL ratiom(ngridmx,nlayermx) 163 REAL zhc(ngrid,nlayer) 164 REAL ratiom(ngrid,nlayer) 170 165 171 166 ! ========================================= … … 181 176 ndt=1 182 177 178 !....................................................................... 179 ! Special treatment for co2: 180 !....................................................................... 183 181 ! ********************************************************************** 184 182 ! In order to take into account the effect of vertical molar mass … … 193 191 ! This is especially important for modelling polar convection. 194 192 ! ********************************************************************** 195 196 197 !....................................................................... 198 ! Special treatment for co2 at firstcall: compute coefficients and 199 ! get index of co2 tracer 200 !....................................................................... 201 202 if(firstcall) then 203 ico2=0 204 if (tracer) then 205 ! Prepare Special treatment if one of the tracers is CO2 gas 206 do iq=1,nqmx 207 if (noms(iq).eq."co2") then 208 ico2=iq 209 m_co2 = 44.01E-3 ! CO2 molecular mass (kg/mol) 210 m_noco2 = 33.37E-3 ! Non condensible mol mass (kg/mol) 211 ! Compute A and B coefficient use to compute 212 ! mean molecular mass Mair defined by 213 ! 1/Mair = q(ico2)/m_co2 + (1-q(ico2))/m_noco2 214 ! 1/Mair = A*q(ico2) + B 215 A =(1/m_co2 - 1/m_noco2) 216 B=1/m_noco2 217 end if 218 enddo 219 endif 220 221 firstcall=.false. 222 endif !of if firstcall 223 224 !....................................................................... 225 ! Special treatment for co2 226 !....................................................................... 227 228 if (ico2.ne.0) then 193 if (igcm_co2.ne.0) then 194 195 m_co2 = 44.01E-3 ! CO2 molecular mass (kg/mol) 196 m_noco2 = 33.37E-3 ! Non condensible mol mass (kg/mol) 197 ! Compute A and B coefficient use to compute 198 ! mean molecular mass Mair defined by 199 ! 1/Mair = q(igcm_co2)/m_co2 + (1-q(igcm_co2))/m_noco2 200 ! 1/Mair = A*q(igcm_co2) + B 201 A =(1/m_co2 - 1/m_noco2) 202 B=1/m_noco2 203 229 204 ! Special case if one of the tracers is CO2 gas 230 DO l=1,nlayer mx231 DO ig=1,ngrid mx232 ztv(ig,l) = zhc(ig,l)*(A*pq(ig,l,i co2)+B)205 DO l=1,nlayer 206 DO ig=1,ngrid 207 ztv(ig,l) = zhc(ig,l)*(A*pq(ig,l,igcm_co2)+B) 233 208 ENDDO 234 209 ENDDO … … 265 240 rhobarz(:,1)=rho(:,1) 266 241 267 do l=2,nlayer mx242 do l=2,nlayer 268 243 rhobarz(:,l)=pplev(:,l)/(r*0.5*(pt(:,l)+pt(:,l-1))) 269 244 enddo 270 245 271 246 ! mass computation 272 do l=1,nlayer mx247 do l=1,nlayer 273 248 masse(:,l)=(pplev(:,l)-pplev(:,l+1))/g 274 249 enddo … … 395 370 396 371 activecell(:)=ztv(:,1)>ztv(:,2) 397 do ig=1,ngrid mx372 do ig=1,ngrid 398 373 if (ztv(ig,1)>=(ztv(ig,2))) then 399 374 alim_star(ig,1)=MAX((ztv(ig,1)-ztv(ig,2)),0.) & … … 404 379 enddo 405 380 406 do l=2,nlayer mx-1407 do ig=1,ngrid mx381 do l=2,nlayer-1 382 do ig=1,ngrid 408 383 if (ztv(ig,l)>(ztv(ig,l+1)) .and. ztv(ig,1)>=ztv(ig,l) & 409 384 & .and. (alim_star(ig,l-1).ne. 0.)) then … … 415 390 enddo 416 391 enddo 417 do l=1,nlayer mx418 do ig=1,ngrid mx392 do l=1,nlayer 393 do ig=1,ngrid 419 394 if (alim_star_tot(ig) > 1.e-10 ) then 420 395 alim_star(ig,l)=alim_star(ig,l)/alim_star_tot(ig) … … 428 403 ! (f_star) in the first and second layer from the source profile. 429 404 430 do ig=1,ngrid mx405 do ig=1,ngrid 431 406 if (activecell(ig)) then 432 407 ztla(ig,1)=ztv(ig,1) … … 445 420 ! LOOP ON VERTICAL LEVELS 446 421 !============================================================================== 447 do l=2,nlayer mx-1422 do l=2,nlayer-1 448 423 !============================================================================== 449 424 !============================================================================== … … 452 427 453 428 ! is the thermal plume still active ? 454 do ig=1,ngrid mx429 do ig=1,ngrid 455 430 activecell(ig)=activecell(ig) & 456 431 & .and. zw2(ig,l)>1.e-10 & … … 470 445 !--------------------------------------------------------------------------- 471 446 472 do ig=1,ngrid mx447 do ig=1,ngrid 473 448 if(activecell(ig)) then 474 449 ztva_est(ig,l)=ztla(ig,l-1) … … 496 471 !------------------------------------------------- 497 472 498 do ig=1,ngrid mx473 do ig=1,ngrid 499 474 if (activecell(ig)) then 500 475 … … 573 548 574 549 ! If the cell is active, compute temperature inside updraft 575 do ig=1,ngrid mx550 do ig=1,ngrid 576 551 if (activetmp(ig)) then 577 552 … … 587 562 588 563 ! Compute new buoyancu and vertical velocity 589 do ig=1,ngrid mx564 do ig=1,ngrid 590 565 if (activetmp(ig)) then 591 566 ztva(ig,l) = ztla(ig,l) … … 606 581 ! ND detrainment rate, see paragraph 44 of paper 607 582 608 do ig=1,ngrid mx583 do ig=1,ngrid 609 584 if (activetmp(ig)) then 610 585 … … 664 639 !--------------------------------------------------------------------------- 665 640 666 do ig=1,ngrid mx641 do ig=1,ngrid 667 642 if (zw2(ig,l+1)>0. .and. zw2(ig,l+1).lt.1.e-10) then 668 IF ( lwrite) THEN643 IF (thermverbose) THEN 669 644 print*,'thermcell_plume, particular case in velocity profile' 670 645 ENDIF … … 695 670 ! alim_star. 696 671 697 do ig=1,ngrid mx672 do ig=1,ngrid 698 673 alim_star_tot(ig)=0. 699 674 enddo 700 do ig=1,ngrid mx675 do ig=1,ngrid 701 676 do l=1,lalim(ig)-1 702 677 alim_star_tot(ig)=alim_star_tot(ig)+alim_star(ig,l) … … 704 679 enddo 705 680 706 do l=1,nlayer mx707 do ig=1,ngrid mx681 do l=1,nlayer 682 do ig=1,ngrid 708 683 if (alim_star_tot(ig) > 1.e-10 ) then 709 684 alim_star(ig,l)=alim_star(ig,l)/alim_star_tot(ig) … … 727 702 728 703 ! Index of the thermal plume height 729 do ig=1,ngrid mx704 do ig=1,ngrid 730 705 lmax(ig)=lalim(ig) 731 706 enddo 732 do ig=1,ngrid mx733 do l=nlayer mx,lalim(ig)+1,-1707 do ig=1,ngrid 708 do l=nlayer,lalim(ig)+1,-1 734 709 if (zw2(ig,l).le.1.e-10) then 735 710 lmax(ig)=l-1 … … 739 714 740 715 ! Particular case when the thermal reached the model top, which is not a good sign 741 do ig=1,ngrid mx742 if ( zw2(ig,nlayer mx) > 1.e-10 ) then716 do ig=1,ngrid 717 if ( zw2(ig,nlayer) > 1.e-10 ) then 743 718 print*,'WARNING !!!!! W2 non-zero in last layer' 744 lmax(ig)=nlayer mx719 lmax(ig)=nlayer 745 720 endif 746 721 enddo 747 722 748 723 ! Maximum vertical velocity zw2 749 do ig=1,ngrid mx724 do ig=1,ngrid 750 725 wmax(ig)=0. 751 726 enddo 752 727 753 do l=1,nlayer mx754 do ig=1,ngrid mx728 do l=1,nlayer 729 do ig=1,ngrid 755 730 if (l.le.lmax(ig)) then 756 731 if (zw2(ig,l).lt.0.)then … … 769 744 ! zmax=Integral[z*w(z)*dz]/Integral[w(z)*dz] 770 745 ! 771 do ig=1,ngrid mx746 do ig=1,ngrid 772 747 zmax(ig)=0. 773 748 zlevinter(ig)=zlev(ig,1) … … 776 751 num(:)=0. 777 752 denom(:)=0. 778 do ig=1,ngrid mx779 do l=1,nlayer mx753 do ig=1,ngrid 754 do l=1,nlayer 780 755 num(ig)=num(ig)+zw2(ig,l)*zlev(ig,l)*(zlev(ig,l+1)-zlev(ig,l)) 781 756 denom(ig)=denom(ig)+zw2(ig,l)*(zlev(ig,l+1)-zlev(ig,l)) 782 757 enddo 783 758 enddo 784 do ig=1,ngrid mx759 do ig=1,ngrid 785 760 if (denom(ig).gt.1.e-10) then 786 761 zmax(ig)=2.*num(ig)/denom(ig) … … 793 768 794 769 zlmax=MAXVAL(lmax(:))+2 795 if (zlmax .ge. nlayer mx) then770 if (zlmax .ge. nlayer) then 796 771 print*,'thermals have reached last layer of the model' 797 772 print*,'this is not good !' … … 819 794 ! llmax is the index of the heighest thermal in the simulation domain 820 795 llmax=1 821 do ig=1,ngrid mx796 do ig=1,ngrid 822 797 if (lalim(ig)>llmax) llmax=lalim(ig) 823 798 enddo … … 826 801 827 802 do k=1,llmax-1 828 do ig=1,ngrid mx803 do ig=1,ngrid 829 804 if (k<lalim(ig)) then 830 805 alim_star2(ig)=alim_star2(ig)+alim_star_clos(ig,k)*alim_star_clos(ig,k) & … … 837 812 ! Closure mass flux, equation 13 of appendix 4.2 in paper 838 813 839 do ig=1,ngrid mx814 do ig=1,ngrid 840 815 if (alim_star2(ig)>1.e-10) then 841 816 f(ig)=wmax(ig)*alim_star_tot_clos(ig)/ & 842 & (max(500.,zmax(ig))*r_aspect *alim_star2(ig))817 & (max(500.,zmax(ig))*r_aspect_thermals*alim_star2(ig)) 843 818 844 819 endif … … 864 839 865 840 866 ! these variables allow to follow corrections made to the mass flux when lwrite=.true.841 ! these variables allow to follow corrections made to the mass flux when thermverbose=.true. 867 842 ncorecfm1=0 868 843 ncorecfm2=0 … … 887 862 888 863 do l=1,zlmax 889 do ig=1,ngrid mx864 do ig=1,ngrid 890 865 if (l.lt.lmax(ig)) then 891 866 fm(ig,l+1)=fm(ig,l)+entr(ig,l)-detr(ig,l) … … 918 893 ! Upward mass flux at level l+1 919 894 920 do ig=1,ngrid mx895 do ig=1,ngrid 921 896 if (l.lt.lmax(ig)) then 922 897 fm(ig,l+1)=fm(ig,l)+entr(ig,l)-detr(ig,l) … … 934 909 !------------------------------------------------------------------------- 935 910 936 do ig=1,ngrid mx911 do ig=1,ngrid 937 912 938 913 if (fm(ig,l+1).lt.0.) then … … 943 918 ncorecfm2=ncorecfm2+1 944 919 else 945 IF ( lwrite) THEN920 IF (thermverbose) THEN 946 921 print*,'fm(l+1)<0 : ig, l+1,lmax :',ig,l+1,lmax(ig),fm(ig,l+1) 947 922 ENDIF … … 958 933 !------------------------------------------------------------------------- 959 934 960 do ig=1,ngrid mx935 do ig=1,ngrid 961 936 if (detr(ig,l).gt.fm(ig,l)) then 962 937 ncorecfm6=ncorecfm6+1 … … 981 956 !------------------------------------------------------------------------- 982 957 983 do ig=1,ngrid mx958 do ig=1,ngrid 984 959 if (fm(ig,l+1).lt.0.) then 985 960 detr(ig,l)=detr(ig,l)+fm(ig,l+1) … … 993 968 !----------------------------------------------------------------------- 994 969 995 do ig=1,ngrid mx970 do ig=1,ngrid 996 971 if (zw2(ig,l+1).gt.1.e-10) then 997 972 zfm=rhobarz(ig,l+1)*zw2(ig,l+1)*alphamax … … 1016 991 1017 992 do l=1,zlmax 1018 do ig=1,ngrid mx993 do ig=1,ngrid 1019 994 eee0=entr(ig,l) 1020 995 ddd0=detr(ig,l) … … 1044 1019 1045 1020 ! Check again that everything cancels at zmax 1046 do ig=1,ngrid mx1021 do ig=1,ngrid 1047 1022 fm(ig,lmax(ig)+1)=0. 1048 1023 entr(ig,lmax(ig))=0. … … 1051 1026 1052 1027 !----------------------------------------------------------------------- 1053 ! Summary of the number of modifications that were necessary (if lwrite=.true.1028 ! Summary of the number of modifications that were necessary (if thermverbose=.true. 1054 1029 ! and only if there were a lot of them) 1055 1030 !----------------------------------------------------------------------- 1056 1031 1057 1032 !IM 090508 beg 1058 IF ( lwrite) THEN1059 if (ncorecfm1+ncorecfm2+ncorecfm3+ncorecfm4+ncorecfm5+ncorecalpha > ngrid mx/4. ) then1033 IF (thermverbose) THEN 1034 if (ncorecfm1+ncorecfm2+ncorecfm3+ncorecfm4+ncorecfm5+ncorecalpha > ngrid/4. ) then 1060 1035 print*,'thermcell warning : large number of corrections' 1061 1036 print*,'PB thermcell : on a du coriger ',ncorecfm1,'x fm1',& … … 1089 1064 ! Based on equation 14 in appendix 4.2 1090 1065 1091 do ig=1,ngrid mx1066 do ig=1,ngrid 1092 1067 if(lmax(ig) .gt. 1) then 1093 1068 do k=1,lmax(ig) … … 1095 1070 & fm(ig,k)*ztv(ig,k)+fm(ig,k)*ztva(ig,k)-fm(ig,k+1)*ztva(ig,k+1)) 1096 1071 if (ztv(ig,k) + ptimestep*zdthladj(ig,k) .le. 0.) then 1097 IF ( lwrite) THEN1072 IF (thermverbose) THEN 1098 1073 print*,'Teta<0 in thermcell_dTeta up: qenv .. dq : ', ztv(ig,k),ptimestep*zdthladj(ig,k) 1099 1074 ENDIF … … 1112 1087 ztvd(:,:)=ztv(:,:) 1113 1088 fm_down(:,:)=0. 1114 do ig=1,ngrid mx1089 do ig=1,ngrid 1115 1090 if (lmax(ig) .gt. 1) then 1116 1091 do l=1,lmax(ig) … … 1139 1114 zdthladj_down(:,:)=0. 1140 1115 1141 do ig=1,ngrid mx1116 do ig=1,ngrid 1142 1117 if(lmax(ig) .gt. 1) then 1143 1118 ! No downdraft in the very-near surface layer, we begin at k=3 … … 1148 1123 & fm_down(ig,k)*ztv(ig,k)+fm_down(ig,k)*ztvd(ig,k)-fm_down(ig,k+1)*ztvd(ig,k+1)) 1149 1124 if (ztv(ig,k) + ptimestep*zdthladj_down(ig,k) .le. 0.) then 1150 IF ( lwrite) THEN1125 IF (thermverbose) THEN 1151 1126 print*,'q<0 in thermcell_dTeta down: qenv .. dq : ', ztv(ig,k),ptimestep*zdthladj_down(ig,k) 1152 1127 ENDIF … … 1164 1139 fraca(:,:)=0. 1165 1140 do l=2,zlmax 1166 do ig=1,ngrid mx1141 do ig=1,ngrid 1167 1142 if (zw2(ig,l).gt.1.e-10) then 1168 1143 fraca(ig,l)=fm(ig,l)/(rhobarz(ig,l)*zw2(ig,l)) … … 1182 1157 ratiom(:,:)=1. 1183 1158 1184 if (i co2.ne.0) then1159 if (igcm_co2.ne.0) then 1185 1160 detrmod(:,:)=0. 1186 1161 do k=1,zlmax 1187 do ig=1,ngrid mx1162 do ig=1,ngrid 1188 1163 detrmod(ig,k)=fm(ig,k)-fm(ig,k+1) & 1189 1164 & +entr(ig,k) … … 1195 1170 enddo 1196 1171 1197 call thermcell_dqup(ngrid mx,nlayermx,ptimestep &1172 call thermcell_dqup(ngrid,nlayer,ptimestep & 1198 1173 & ,fm,entr,detrmod, & 1199 & masse,pq(:,:,i co2),pdqadj(:,:,ico2),ndt,zlmax)1174 & masse,pq(:,:,igcm_co2),pdqadj(:,:,igcm_co2),ndt,zlmax) 1200 1175 1201 1176 ! Compute the ratio between theta and theta_m 1202 1177 1203 1178 do l=1,zlmax 1204 do ig=1,ngrid mx1205 ratiom(ig,l)=1./(A*(pq(ig,l,i co2)+pdqadj(ig,l,ico2)*ptimestep)+B)1179 do ig=1,ngrid 1180 ratiom(ig,l)=1./(A*(pq(ig,l,igcm_co2)+pdqadj(ig,l,igcm_co2)*ptimestep)+B) 1206 1181 enddo 1207 1182 enddo … … 1215 1190 pdtadj(:,:)=0. 1216 1191 do l=1,zlmax 1217 do ig=1,ngrid mx1192 do ig=1,ngrid 1218 1193 pdtadj(ig,l)=(zdthladj(ig,l)+zdthladj_down(ig,l))*zpopsk(ig,l)*ratiom(ig,l) 1219 1194 enddo … … 1232 1207 1233 1208 1234 do l=1,nlayer mx-11235 do ig=1,ngrid mx1209 do l=1,nlayer-1 1210 do ig=1,ngrid 1236 1211 teta_th_int(ig,l)=0.5*(ztva(ig,l+1)+ztva(ig,l))*ratiom(ig,l) 1237 1212 teta_down_int(ig,l) = 0.5*(ztvd(ig,l+1)+ztvd(ig,l))*ratiom(ig,l) … … 1239 1214 enddo 1240 1215 enddo 1241 do ig=1,ngrid mx1242 teta_th_int(ig,nlayer mx)=teta_th_int(ig,nlayermx-1)1243 teta_env_int(ig,nlayer mx)=teta_env_int(ig,nlayermx-1)1244 teta_down_int(ig,nlayer mx)=teta_down_int(ig,nlayermx-1)1216 do ig=1,ngrid 1217 teta_th_int(ig,nlayer)=teta_th_int(ig,nlayer-1) 1218 teta_env_int(ig,nlayer)=teta_env_int(ig,nlayer-1) 1219 teta_down_int(ig,nlayer)=teta_down_int(ig,nlayer-1) 1245 1220 enddo 1246 1221 heatFlux(:,:)=0. … … 1249 1224 heatFlux_down(:,:)=0. 1250 1225 do l=1,zlmax 1251 do ig=1,ngrid mx1226 do ig=1,ngrid 1252 1227 heatFlux(ig,l)=fm(ig,l)*(teta_th_int(ig,l)-teta_env_int(ig,l))/(rhobarz(ig,l)) 1253 1228 buoyancyOut(ig,l)=g*(ztva(ig,l)-ztv(ig,l))/ztv(ig,l)
Note: See TracChangeset
for help on using the changeset viewer.