phys_convec_tmpp.F90 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485
  1. !
  2. ! Subgrid stuff from TMPP.
  3. !
  4. ! Copied from:
  5. ! TMPP/SOURCE/tmpp_sub_subg.f90
  6. ! TMPP/SOURCE/tmpp_sub_work.f90
  7. ! TMPP/SOURCE/tmpp_geometry.f90
  8. ! TMPP/SOURCE/phys_geopot.f90
  9. !
  10. module phys_convec_tmpp
  11. implicit none
  12. ! --- in/out -------------------------------
  13. private
  14. public :: subscal
  15. public :: subscal_2d
  16. public :: mid2bound_uv
  17. public :: mid2bound_w
  18. public :: mid2bound_t
  19. public :: mid2bound_q
  20. public :: mid2bound_z
  21. public :: mid2bound_p
  22. public :: phlev_ec_rev
  23. public :: geopot
  24. contains
  25. ! ==========================================================
  26. ! ===
  27. ! === TMPP/SOURCE/tmpp_sub_subg.f90
  28. ! ===
  29. ! ==========================================================
  30. !-----------------------------------------------------------------------
  31. ! calculate subscal parameters at a given horizontal location.
  32. ! Three different pressure levels are used in this subroutine:
  33. ! ppress (boundaries ECMWF levels)
  34. ! ppresg (boundaries TM3)
  35. ! zpl (centers ECMWF levels)
  36. ! zplg (centers TM3)
  37. !
  38. !-----------------------------------------------------------------------
  39. !subroutine subscal(pz,ppress,pu,pv,pw,pt,pq,pqac,pqam,pevap, &
  40. ! pentug,pdetug,pentdg,pdetdg,pdkg,pzg)
  41. subroutine subscal_2d( np, lme, at, bt, &
  42. pz,ppress,pw,pt,pq,pqac,pqam,pevap, &
  43. pentug,pdetug,pentdg,pdetdg)
  44. ! --- in/out -----------------------------------
  45. integer, intent(in) :: np
  46. integer, intent(in) :: lme
  47. real, intent(in) :: at(0:lme), bt(0:lme)
  48. real, intent(in) :: pz(np,0:lme)
  49. real, intent(in) :: ppress(np,0:lme)
  50. real, intent(in) :: pw(np,0:lme)
  51. real, intent(in) :: pt(np,0:lme)
  52. real, intent(in) :: pq(np,0:lme)
  53. real, intent(in) :: pqac(np,0:lme)
  54. real, intent(in) :: pqam(np,0:lme)
  55. real, intent(in) :: pevap(np)
  56. real, intent(out) :: pentug(np,lme)
  57. real, intent(out) :: pdetug(np,lme)
  58. real, intent(out) :: pentdg(np,lme)
  59. real, intent(out) :: pdetdg(np,lme)
  60. ! --- local -------------------------------------
  61. integer :: i
  62. ! --- begin ------------------------------------
  63. ! 18 Apr 2012 - P. Le Sager - Commented openMP loop, since it gives
  64. ! wrong results: large differences with serial case results in eu/ed/du
  65. ! /dd fields
  66. !testPLS !$OMP PARALLEL &
  67. !testPLS !$OMP default ( none ) &
  68. !testPLS !$OMP shared ( np, lme, at, bt ) &
  69. !testPLS !$OMP shared ( pz, ppress, pw, pt, pq ) &
  70. !testPLS !$OMP shared ( pqac, pqam, pevap ) &
  71. !testPLS !$OMP shared ( pentug, pdetug, pentdg, pdetdg ) &
  72. !testPLS !$OMP private ( i )
  73. !testPLS !$OMP DO
  74. do i = 1, np
  75. call subscal( lme, at, bt, &
  76. pz(i,:), ppress(i,:), pw(i,:), pt(i,:), pq(i,:), &
  77. pqac(i,:), pqam(i,:), pevap(i), &
  78. pentug(i,:), pdetug(i,:), pentdg(i,:), pdetdg(i,:) )
  79. end do
  80. !testPLS !$OMP END DO
  81. !testPLS !$OMP END PARALLEL
  82. end subroutine subscal_2d
  83. ! *
  84. subroutine subscal( lme, at, bt, &
  85. pz,ppress,pw,pt,pq,pqac,pqam,pevap, &
  86. pentug,pdetug,pentdg,pdetdg) !,pdkg,pzg)
  87. ! >>> adhoc: not from ECMWF to TM levels >>>>>>>>>>>>>>>>>>
  88. ! (set tm stuff to ec stuff)
  89. !use Geometry, only : lm
  90. !use Geometry, only : at => a_tm, bt => b_tm
  91. ! use Geometry, only : lm => lme
  92. ! use Geometry, only : at => a_ec, bt => b_ec
  93. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  94. ! use Geometry, only : lme
  95. use Num, only : IntervalQuad_Lin
  96. use Num, only : interp_muherm
  97. ! --- const ------------------------------------
  98. ! integer, parameter :: jplm = lme
  99. !integer, parameter :: jplmg = lm
  100. !integer, parameter :: jplmgp1 = lm+1
  101. ! integer, parameter :: jplmg = lme
  102. ! integer, parameter :: jplmgp1 = lme+1
  103. real, parameter :: ppg = 9.80665
  104. ! --- in/out ------------------------------------
  105. integer :: status
  106. integer, intent(in) :: lme
  107. real, intent(in) :: at(0:lme), bt(0:lme)
  108. real, intent(in) :: pz(0:lme)
  109. real, intent(in) :: ppress(0:lme)
  110. real, intent(in) :: pw(0:lme)
  111. real, intent(in) :: pt(0:lme)
  112. real, intent(in) :: pq(0:lme)
  113. real, intent(in) :: pqac(0:lme)
  114. real, intent(in) :: pqam(0:lme)
  115. real, intent(in) :: pevap
  116. !real, intent(in) :: pu(0:lme)
  117. !real, intent(in) :: pv(0:lme)
  118. ! entrainment, detrainment rates, diffusion coefficient
  119. real, intent(out) :: pentug(lme)
  120. real, intent(out) :: pdetug(lme)
  121. real, intent(out) :: pentdg(lme)
  122. real, intent(out) :: pdetdg(lme)
  123. ! real, intent(out) :: pdkg(lme)
  124. ! real, intent(out) :: pzg(0:lme)
  125. ! --- local ------------------------------------
  126. integer :: jl,ilast
  127. real :: sumup, sumdown
  128. ! output variables on TM vertical grid
  129. real :: zamu(0:lme),zptc(0:lme),zpqc(0:lme),zplc(0:lme), &
  130. zpqp(0:lme),ppresg(0:lme)
  131. ! real :: zpdk(0:lme)
  132. real :: zpam(lme),zped(lme),zpdd(lme),zpeu(lme),zpdu(lme)
  133. real :: zpl(lme),zplg(lme)
  134. real :: zam
  135. integer :: lct
  136. ! --- begin -------------------------------------------
  137. ! calculate convection by clouds
  138. call cloud( lme, pz,ppress,pt,pq,pw,pqac,pqam,pevap, &
  139. zamu,zptc,zpqc,zplc,zpqp, &
  140. zpam,zpeu,zpdu,zped,zpdd)
  141. ! ! calculate turbulent diffusion coefficient
  142. !
  143. ! call louis(pz,pt,pu,pv,zpdk)
  144. ! generate pressures on TM3 level boundaries and centers respectively
  145. do jl=0,lme
  146. ppresg(jl)=at(jl)+ppress(lme)*bt(jl)
  147. end do
  148. do jl=1,lme
  149. zplg(jl)=0.5*(ppresg(jl)+ppresg(jl-1))
  150. end do
  151. ! --- Vertical averaging of variables defined on level centers
  152. ! * interpolate entrainment/detrainment rates on TM3 vertical coordinate:
  153. ! Dirk Olivie, 12 May 2004
  154. ! No interpolation needed if lme = lme
  155. if ( lme .ne. lme ) then
  156. do jl=1,lme
  157. zpl(jl)=0.5*(ppress(jl)+ppress(jl-1))
  158. zpeu(jl)=zpeu(jl)/(ppress(jl)-ppress(jl-1))
  159. zpdu(jl)=zpdu(jl)/(ppress(jl)-ppress(jl-1))
  160. zped(jl)=zped(jl)/(ppress(jl)-ppress(jl-1))
  161. zpdd(jl)=zpdd(jl)/(ppress(jl)-ppress(jl-1))
  162. end do
  163. ilast=1
  164. do jl=1,lme
  165. call IntervalQuad_Lin(zpl,zpeu,ppresg(jl-1),ppresg(jl),pentug(jl), ilast, status )
  166. if (status/=0) stop 'ERROR in subscal'
  167. call IntervalQuad_Lin(zpl,zpdu,ppresg(jl-1),ppresg(jl),pdetug(jl), ilast, status )
  168. if (status/=0) stop 'ERROR in subscal'
  169. call IntervalQuad_Lin(zpl,zped,ppresg(jl-1),ppresg(jl),pentdg(jl), ilast, status )
  170. if (status/=0) stop 'ERROR in subscal'
  171. call IntervalQuad_Lin(zpl,zpdd,ppresg(jl-1),ppresg(jl),pdetdg(jl), ilast, status )
  172. if (status/=0) stop 'ERROR in subscal'
  173. end do
  174. else
  175. pentug = zpeu
  176. pdetug = zpdu
  177. pentdg = zped
  178. pdetdg = zpdd
  179. endif
  180. ! ! * Interpolate diffusion coefficients from upper boundaries of ECMWF layers to
  181. ! ! upper boundaries of TM3 layers and
  182. ! ! reorganize the vertical index of the diffusion coefficient
  183. ! ! pdkg(1) is diffusion coefficient at the top of layer 1 (TOA)
  184. ! ! pdkg(lme) is diffusion coefficient at the top of layer lme
  185. !
  186. ! call interp_muherm( ppress, zpdk, ppresg, pdkg )
  187. ! pdkg(1)=0.
  188. !
  189. ! ! * Interpolate geopotential height from ECMWF layer boundaries to TM3 layer
  190. ! ! boundaries
  191. !
  192. ! call interp_muherm( ppress, pz, ppresg, pzg )
  193. ! pzg(0)=pz(0)
  194. ! pzg(lme)=pz(lme)
  195. !--------------------------------------------------------------------------
  196. ! correct massfluxes on TM3 grid to conserve mass
  197. !
  198. ! updraft
  199. ! correction level is uppermost level with nonzero detrainment
  200. lct=lme
  201. do jl=1,lme
  202. if ( pdetug(jl) > 0.0 ) then
  203. lct=jl
  204. exit
  205. endif
  206. end do
  207. zam=0.
  208. do jl=lme,1,-1
  209. zam=zam+pentug(jl)-pdetug(jl)
  210. end do
  211. pdetug(lct)=pdetug(lct)+zam
  212. ! downdraft
  213. ! correction level is lowermost level
  214. lct=lme
  215. zam=0.
  216. do jl=lme,1,-1
  217. zam=zam+pentdg(jl)-pdetdg(jl)
  218. end do
  219. pdetdg(lct)=pdetdg(lct)+zam
  220. !
  221. ! check conservation
  222. !
  223. sumup=0.
  224. sumdown=0.
  225. do jl=1,lme
  226. sumup=sumup+pentug(jl)-pdetug(jl)
  227. sumdown=sumdown+pentdg(jl)-pdetdg(jl)
  228. enddo
  229. if ( abs(sumup) > 1.0e-5 ) then
  230. write(*,*)' ERROR no massconserv in updraft'
  231. stop
  232. endif
  233. if ( abs(sumdown) > 1.0e-5 ) then
  234. write(*,*)' ERROR no massconserv in downdraft'
  235. stop
  236. endif
  237. !!pentug = 0.0
  238. !!pdetug = 0.0
  239. !!pentdg = 0.0
  240. !!pdetdg = 0.0
  241. end subroutine subscal
  242. ! =================================================
  243. !***********************************************************************
  244. !**** cloud - routine to calculate cloud properties
  245. !
  246. ! m.heimann mpi HH Nov-12-1990
  247. !
  248. ! Purpose
  249. ! -------
  250. ! cloud calculates all properties associated with subgridscale
  251. ! cloud mixing, i.e. massflux in updraft and downdraft, entrainment
  252. ! and detrainment rates per level, and cloud properties: temperature,
  253. ! moisture and liquid water and precipitation rate on each level
  254. ! boundary.
  255. !
  256. !** interface
  257. ! ---------
  258. !
  259. ! call cloud(pz,ppress,pt,pq,pw,pqac,pqam,
  260. ! . pqtur,pamu,ptc,pqc,plc,pgp,
  261. ! . pam,peu,pdu,ped,pdd,
  262. ! . klc,klt)
  263. !
  264. ! input: (all variables are defined on level boundaries)
  265. ! pz geopotential height (m)
  266. ! ppress pressure (Pa)
  267. ! pt temperature (K)
  268. ! pq moisture (kg water/kg air)
  269. ! pw vertcal velocity (negative upward) (Pa s**-1)
  270. ! pqac div(q v) (kg water/kg air s**-1)
  271. ! pqam div(v) (s**-1)
  272. ! pqtur Fq surf-air (kg water/m**2 s**-1)
  273. !
  274. ! output: variables defined on level boundaries:
  275. ! pamu massflux (kg m**-2 s**-1)
  276. ! ptc updraft temperature (K)
  277. ! pqc updraft moisture (kg water/kg air)
  278. ! plc updraft liquid water (kg water/kg air)
  279. ! pgp updraft precipitation (kg water m**-2 s**-1)
  280. !
  281. ! variables defined on each model level:
  282. ! pam air mass (kg m**-2)
  283. ! peu entrainment in updraft (kg m**-2 s**-1)
  284. ! pdu detrainment in updraft (same)
  285. ! ped entrainment in downdraft (kg m**-2 s**-1)
  286. ! pdd detrainment in downdraft (same)
  287. ! klc lowest level in cloud
  288. ! klt first level above cloud
  289. !
  290. ! method
  291. ! ------
  292. !
  293. ! updraft cloud properties are calculated according to Tiedke scheme
  294. !
  295. ! externals
  296. ! ---------
  297. !
  298. ! needs functions qsat and dqsat_dt
  299. !
  300. ! references
  301. ! ----------
  302. !
  303. ! Tiedke, Mon. Wea. Rev., 117, 1779-1800, 1989.
  304. !
  305. ! revisions
  306. ! ---------
  307. ! 26-jan-1995 , sr
  308. !
  309. ! including now cumulus downdraft and midlevel convection.
  310. ! Calculates corresponding entrainment and detrainment rates
  311. !
  312. !-------------------------------------------------------------------------
  313. subroutine cloud(lme, pz,ppress,pt,pq,pw,pqac,pqam, pqtur,&
  314. pamu,ptc,pqc,plc,pgp, &
  315. pam,peu,pdu,ped,pdd)
  316. use phys_humidity, only : QSat, dQSat_dt
  317. ! --- flags -----------------------------------------
  318. ! parameter llcudo=.true. : cumulus downdraft turned on
  319. ! parameter llcudo=.false. : cumulus downdraft turned off
  320. ! parameter llmilc=.true. : midlevel convection turned on
  321. ! parameter llmilc=.false. : midlevel convection turned off
  322. logical :: llcudo = .true.
  323. logical :: llmilc = .true.
  324. ! --- const (dims) -------------------------------------
  325. !! vertical resolution (no of model layers)
  326. !integer :: jplm = lme
  327. !integer :: jplmm1 = jplm-1
  328. ! --- in/out ----------------------------------------
  329. integer, intent(in) :: lme
  330. real, intent(in) :: pz(0:lme)
  331. real, intent(in) :: pt(0:lme)
  332. real, intent(in) :: pq(0:lme)
  333. real, intent(in) :: pw(0:lme)
  334. real, intent(in) :: ppress(0:lme)
  335. real, intent(in) :: pqac(0:lme),pqam(0:lme)
  336. real, intent(in) :: pqtur
  337. real, intent(out) :: pam(lme),peu(lme),pdu(lme),ped(lme),pdd(lme)
  338. real, intent(out) :: pamu(0:lme),ptc(0:lme),pqc(0:lme),plc(0:lme),pgp(0:lme)
  339. ! --- const (phys) -------------------------------------
  340. ! physical constants
  341. real, parameter :: pprgasd = 287.05
  342. real, parameter :: pprgasv = 461.51
  343. real, parameter :: ppeps = pprgasd/pprgasv
  344. real, parameter :: ppg = 9.80665
  345. real, parameter :: ppcpd = 1005.46
  346. real, parameter :: ppalv = 2.5008e6
  347. real, parameter :: ppzeta = ppalv/ppcpd
  348. real, parameter :: ppvtcf = (1.0-ppeps)/ppeps
  349. ! * constants for turbulent entrainment and detrainment rates
  350. ! penetrative and midlevel convection
  351. real, parameter :: ppepsu = 1.e-4
  352. real, parameter :: ppdeltu = 1.e-4
  353. ! shallow convection
  354. real, parameter :: ppepsus = 3.e-4
  355. real, parameter :: ppdeltus = 3.e-4
  356. ! downdraft
  357. real, parameter :: ppepsd = 2.e-4
  358. real, parameter :: ppdeltd = 2.e-4
  359. ! * constants for precipitation parametrization
  360. real, parameter :: ppkmin = 1500.0
  361. real, parameter :: ppkval = 2.e-3
  362. ! * parameter beta determines the overshoot of the detrainment plumes
  363. ! above level of no buoyancy (beta=0 : no overshoot)
  364. ! penetrative and midlevel convection
  365. real, parameter :: ppbeta = 0.0
  366. ! shallow convection
  367. real, parameter :: ppbetas = 0.15
  368. ! * parameter gamma determines downward massflux at the level of free
  369. ! sinking (LFS)
  370. real, parameter :: ppgamma = 0.3
  371. ! parameter alpha determines specific humidity of air parcel at surface
  372. ! before starting the dry adiabatic ascent
  373. ! (alpha = 0 : air parcel has the specific humidity of the environment,
  374. ! alpha = 1 : air parcel has saturation specific humidity of the
  375. ! environment)
  376. real, parameter :: ppalpha = 0.2
  377. ! no of iterations for saturation calculation
  378. integer, parameter :: jpitermax = 5
  379. ! --- local --------------------------------------
  380. integer :: klc,klt,klfs
  381. real :: zfck,zamub,zamdlfs
  382. real :: zamu,zamd
  383. real :: zlc,zqc,ztc
  384. real :: zlcklc,zqcklc,ztcklc
  385. real :: ztd,zqd
  386. real :: zdq1,zdq2,zsv,zscv,zgp
  387. real :: zpgp(lme)
  388. real :: zepsu,zdeltu
  389. real :: zbeta
  390. integer :: jl,jjl,jiter
  391. integer :: imlc
  392. real :: zdqcmin,zdqdmin
  393. real :: ztenwb,zqenwb
  394. real :: zttest,zqtest,zstv
  395. ! extra
  396. character(len=10) :: convection_type
  397. ! --- begin ----------------------------------------------
  398. convection_type = 'none'
  399. ! default cloud properties on each layer boundary
  400. do jl = 0, lme
  401. pamu(jl) = 0.0
  402. ptc(jl) = pt(jl)
  403. pqc(jl) = pq(jl)
  404. plc(jl) = 0.0
  405. pgp(jl) = 0.0
  406. end do
  407. ! air-masses (kg/m**2) in each layer, default entrainment/detrainment
  408. ! and precipitation rates
  409. do jl = 1, lme
  410. pam(jl)=(ppress(jl)-ppress(jl-1))/ppg
  411. peu(jl)=0.
  412. pdu(jl)=0.
  413. ped(jl)=0.
  414. pdd(jl)=0.
  415. zpgp(jl)=0.
  416. end do
  417. ! find condensation level by lifting an air parcel until supersaturation occurs
  418. ! we start the ascent with moisture and temperature of the upper boundary of
  419. ! the surface layer
  420. ztc = pt(lme-1)
  421. zqc = pq(lme-1) + ppalpha * ( qsat(pt(lme-1),ppress(lme-1)) - pq(lme-1) )
  422. do jl = lme-1-1, 1, -1
  423. ! preliminary value of parcel temperature (dry adiabatic ascent)
  424. ztc = ztc - ppg*(pz(jl)-pz(jl+1))/ppcpd
  425. ! check for supersaturation
  426. if ( zqc > qsat(ztc,ppress(jl)) ) then
  427. ! if supersaturation is detected we adjust moisture and
  428. ! temperature by condensation
  429. ! and set liquid water content equal to the condensate
  430. zdq2 = 0.0
  431. do jiter=1,jpitermax
  432. zdq1=(zqc-QSat(ztc,ppress(jl))) &
  433. /(1.+ppzeta*dQSat_dt(ztc,ppress(jl)))
  434. zqc=zqc-zdq1
  435. ztc=ztc+zdq1*ppzeta
  436. zdq2=zdq2+zdq1
  437. end do
  438. zlc = zdq2
  439. ! check if parcel is buoyant:
  440. ! virtual temperature of parcel
  441. zscv = ztc*( 1.0 + ppvtcf*zqc - zlc )
  442. ! virtual temperature of environment
  443. zsv = pt(jl) * ( 1.0 + ppvtcf*pq(jl) )
  444. if ( zscv > zsv ) then
  445. ! if parcel is still buoyant then we have detected the cloud base
  446. klc=jl
  447. goto 20
  448. else
  449. ! if parcel is not buoyant then there is no penetrative or shallow
  450. ! convection
  451. if (llmilc) then
  452. goto 700
  453. else
  454. goto 3000
  455. endif
  456. endif
  457. endif
  458. end do
  459. ! no condensation level found
  460. goto 3000
  461. 20 continue
  462. ! if we arrive here a cloud base is detected:
  463. ! klc is cloud base level, ztc is cloud temperature, zqc moisture (at
  464. ! saturation)
  465. ! and zlc the liquid water content in the updraft at base level
  466. ztcklc = ztc
  467. zqcklc = zqc
  468. zlcklc = zlc
  469. ! calculate large scale moisture convergence below cloud base
  470. ! (use trapezoidal integration formula)
  471. !zfck=
  472. ! ((pq(klc)*pqam(klc)-pqac(klc))*pam(klc)+
  473. ! Correction Zoe Stockwell - Peter van Velthoven, 5 January 2000 &
  474. zfck = ((pq(klc)*pqam(klc) -pqac(klc) )*pam(klc+1)+ &
  475. (pq(klc)*pqam(lme)-pqac(lme))*pam(lme) )
  476. do jl=klc+1,lme-1
  477. zfck=zfck+(pq(klc)*pqam(jl)-pqac(jl))*(pam(jl)+pam(jl+1))
  478. end do
  479. ! check for shallow or penetrative convection, set proper parameter
  480. ! values
  481. if (zfck.gt.0.) then
  482. ! penetrative and midlevel convection
  483. zepsu=ppepsu
  484. zdeltu=ppdeltu
  485. zbeta=ppbeta
  486. convection_type = 'deep'
  487. else
  488. ! shallow convection
  489. zepsu=ppepsus
  490. zdeltu=ppdeltus
  491. zbeta=ppbetas
  492. convection_type = 'shallow'
  493. endif
  494. zfck=pqtur+0.5*zfck
  495. ! if no moisture convergence then no penetrative or shallow
  496. ! convection is present
  497. if (zfck <= 0.0 ) then
  498. if (llmilc) then
  499. goto 700
  500. else
  501. goto 3000
  502. endif
  503. else
  504. goto 900
  505. endif
  506. 700 continue
  507. ! check possibility for midlevel convection
  508. imlc = 0
  509. ! Check atmosphere from 2 layers above the surface to the middle of
  510. ! the atmosphere to see if midlevel convection might occur
  511. do jl=lme-1-1,lme-int(lme/2.),-1
  512. ! large scale ascent and an environmental relative humidity of more than
  513. ! 90% are needed for midlevel convection to occur
  514. if ( (pq(jl).gt.(0.9*qsat(pt(jl),ppress(jl))) ).and. &
  515. (pw(jl).lt.0.)) then
  516. if (imlc.eq.0) then
  517. ztc = pt(jl+1)
  518. zqc = pq(jl+1)
  519. zlc = 0.
  520. imlc = jl
  521. else if (imlc.gt.0) then
  522. if ((imlc-jl).eq.1) then
  523. imlc = jl
  524. goto 720
  525. else
  526. ztc = pt(jl+1)
  527. zqc = pq(jl+1)
  528. zlc = 0.
  529. imlc = jl
  530. end if
  531. end if
  532. 720 continue
  533. ! do adiabatic ascent
  534. ztc = ztc - ppg*(pz(jl)-pz(jl+1))/ppcpd
  535. ! check for supersaturation
  536. if (zqc.gt.qsat(ztc,ppress(jl))) then
  537. ! if supersaturation is detected we adjust moisture and
  538. ! temperature by condensation
  539. ! and set liquid water content equal to the condensate
  540. zdq2=0.
  541. do jiter=1,jpitermax
  542. zdq1 = (zqc-qsat(ztc,ppress(jl)))/(1.+ppzeta*dqsat_dt(ztc,ppress(jl)))
  543. zqc=zqc-zdq1
  544. ztc=ztc+zdq1*ppzeta
  545. zdq2=zdq2+zdq1
  546. end do
  547. zlc=zdq2
  548. endif
  549. ! check if parcel is buoyant
  550. ! virtual temperature of parcel
  551. zscv = ztc*(1.+ppvtcf*zqc-zlc)
  552. ! virtual temperature of environment
  553. zsv = pt(jl)*(1.+ppvtcf*pq(jl))
  554. if (zscv.gt.zsv) then
  555. ! parcel is buoyant and we have detected the cloud base of midlevel
  556. ! convection
  557. klc = jl
  558. zamub = -pw(klc)/ppg
  559. zepsu = ppepsu
  560. zdeltu = ppdeltu
  561. zbeta = ppbeta
  562. llcudo = .false.
  563. convection_type = 'mid-level'
  564. goto 1000
  565. endif
  566. endif
  567. end do
  568. goto 3000
  569. 900 continue
  570. ! massflux at base of cloud
  571. ! limit specific humidity difference between cloud and environment at
  572. ! cloud base
  573. zdqcmin = max(0.01*pq(klc),1.e-10)
  574. zdqcmin = max(zdqcmin,zqc+zlc-pq(klc))
  575. zamub=zfck/zdqcmin
  576. 1000 continue
  577. ! limit mass flux at cloud base
  578. zamub=min(zamub,1.0)
  579. ! set updraft entrainment rates below cloud base proportional
  580. ! to layer air masses
  581. ! set updraft detrainment rates below cloud base to zero
  582. do jl=lme,klc+1,-1
  583. peu(jl) = zamub*pam(jl)*ppg/(ppress(lme)-ppress(klc))
  584. pdu(jl) = 0.0
  585. end do
  586. ! calculate now parcel ascent within cloud updraft
  587. ! cloud mass flux zamu,
  588. ! cloud moisture zqc,
  589. ! cloud temperature ztc,
  590. ! cloud liquid water zlc
  591. zamu = zamub
  592. do jl = klc,2,-1
  593. ! mass entrainment and detrainment
  594. peu(jl)=zepsu*zamu*(pz(jl-1)-pz(jl))
  595. pdu(jl)=zdeltu*zamu*(pz(jl-1)-pz(jl))
  596. ! preliminary values of cloud temperature, moisture and cloud liquid water
  597. ztc=ztc &
  598. -ppg*(pz(jl-1)-pz(jl))/ppcpd &
  599. +zepsu*(pz(jl-1)-pz(jl))*(pt(jl)-ztc)
  600. zqc=zqc &
  601. +zepsu*(pz(jl-1)-pz(jl))*(pq(jl)-zqc)
  602. zlc=zlc &
  603. +zepsu*(pz(jl-1)-pz(jl))*(-zlc)
  604. ! adjust moisture and temperature by condensation
  605. zdq2=0.
  606. do jiter=1,jpitermax
  607. zdq1=(zqc-qsat(ztc,ppress(jl))) &
  608. /(1.+ppzeta*dqsat_dt(ztc,ppress(jl)))
  609. zqc=zqc-zdq1
  610. ztc=ztc+zdq1*ppzeta
  611. zdq2=zdq2+zdq1
  612. end do
  613. ! precipitation rate out of layer jl
  614. if ((pz(jl)+pz(jl-1))*0.5-pz(klc) .gt. ppkmin) then
  615. zgp=pam(jl)*ppkval/zamu
  616. else
  617. zgp=0.
  618. endif
  619. ! adjust liquid cloud water in updraft (use implicit scheme to prevent
  620. ! instability)
  621. zgp = zgp*zlc/(1+zgp)
  622. zpgp(jl) = zgp*zamu
  623. zlc = zlc-zgp+zdq2
  624. ! check for level of free sinking (LFS) where cumulus downdraft starts
  625. if (.not.llcudo) then
  626. ! downdraft calculation already done or turned off
  627. goto 800
  628. end if
  629. if ( zpgp(jl) == 0.0 ) then
  630. ! no downdraft exists since downdrafts are associated with convective
  631. ! precipitation from the updrafts
  632. goto 800
  633. end if
  634. if (jl.lt.3) then
  635. ! no downdraft since maximum possible cloud height is reached
  636. goto 800
  637. end if
  638. ! The LFS is assumed to be the highest model level where a mixture of equal
  639. ! parts of cloud air and environmental air (at wet bulb temperature) becomes
  640. ! negative buoyant with respect to the environmental air
  641. ! first step :
  642. ! calculate wet bulb temperature and moisture of the environmental air
  643. ztenwb = pt(jl-1)
  644. zqenwb = pq(jl-1)
  645. ! adjust temperature and moisture by evaporation
  646. ! zdq1 must be less equal 0 (zdq1=0 : environmental air is saturated,
  647. ! i.e. zqenwb = pq)
  648. do jiter = 1,jpitermax
  649. zdq1 = (zqenwb-qsat(ztenwb,ppress(jl-1)))/ &
  650. (1.+ppzeta*dqsat_dt(ztenwb,ppress(jl-1)))
  651. zqenwb = zqenwb-zdq1
  652. ztenwb = ztenwb+zdq1*ppzeta
  653. end do
  654. ! second step :
  655. ! do mixing with cloud air
  656. zttest = 0.5*(ztc+ztenwb)
  657. zqtest = 0.5*(zqc+zqenwb)
  658. ! third step :
  659. ! check for negative buoyancy
  660. ! virtual temperature of the air mixture
  661. zstv = zttest*(1.+ppvtcf*zqtest)
  662. ! virtual temperature of the environmental air
  663. zsv = pt(jl-1)*(1.+ppvtcf*pq(jl-1))
  664. if (zstv.lt.zsv) then
  665. ! level of free sinking (LFS) is found, start downdraft calculation
  666. ! massflux at LFS is assumed to be directly proportional to the (preliminary)
  667. ! upward massflux at cloud base
  668. klfs = jl
  669. zamdlfs = -ppgamma*zamub
  670. zamd = zamdlfs
  671. ztd = zttest
  672. zqd = zqtest
  673. ped(klfs) = (-zamd)
  674. pdd(klfs) = 0.
  675. if (klfs.eq.klc) goto 45
  676. do jjl = klfs+1,klc,1
  677. ! mass entrainment and detrainment
  678. ped(jjl) = ppepsd*zamd*(pz(jjl)-pz(jjl-1))
  679. pdd(jjl) = ppdeltd*zamd*(pz(jjl)-pz(jjl-1))
  680. ! preliminary values of cloud temperature and moisture in downdraft
  681. ztd = ztd &
  682. -ppg*(pz(jjl)-pz(jjl-1))/ppcpd &
  683. +ppepsd*(pz(jjl)-pz(jjl-1))*(ztd-pt(jjl-1))
  684. zqd = zqd &
  685. +ppepsd*(pz(jjl)-pz(jjl-1))*(zqd-pq(jjl-1))
  686. ! adjust moisture and temperature by evaporation
  687. do jiter=1,jpitermax
  688. zdq1 = (zqd-qsat(ztd,ppress(jjl-1)))/ &
  689. (1.+ppzeta*dqsat_dt(ztd,ppress(jjl-1)))
  690. zqd = zqd-zdq1
  691. ztd = ztd+zdq1*ppzeta
  692. end do
  693. ! downdraft massflux at lower layer boundary
  694. zamd = zamd - ped(jjl) + pdd(jjl)
  695. end do
  696. 45 continue
  697. zamd = min(0.,zamd)
  698. ! set downdraft detrainment rates below cloud base proportional to layer
  699. ! air masses
  700. ! set downdraft entrainment rates below cloud base to zero
  701. do jjl = lme,klc+1,-1
  702. ped(jjl) = 0.
  703. pdd(jjl) = zamd*pam(jjl)*ppg/(ppress(klc)-ppress(lme))
  704. end do
  705. ! recalculate updraft massflux at cloud base,
  706. ! now allowing for the downdraft massflux
  707. if (zamd.lt.0.) then
  708. zdqdmin = zqd-pq(klc)
  709. zamub = (zfck-zamd*zdqdmin)/zdqcmin
  710. if (zamub.le.0.) then
  711. do jjl=1,lme
  712. peu(jjl)=0.
  713. pdu(jjl)=0.
  714. ped(jjl)=0.
  715. pdd(jjl)=0.
  716. end do
  717. goto 3000
  718. endif
  719. ! go back to cloud base and start updraft calculation again
  720. ztc = ztcklc
  721. zqc = zqcklc
  722. zlc = zlcklc
  723. llcudo = .false.
  724. goto 1000
  725. else
  726. goto 800
  727. endif
  728. else
  729. goto 800
  730. endif
  731. 800 continue
  732. ! check for buoyancy (in updraft)
  733. ! virtual temperature in updraft at upper boundary of layer jl:
  734. zscv=ztc*(1.+ppvtcf*zqc-zlc)
  735. ! virtual temperature outside of cloud
  736. zsv=pt(jl-1)*(1.+ppvtcf*pq(jl-1))
  737. if ( zscv <= zsv ) then
  738. klt=jl
  739. goto 400
  740. endif
  741. ! updraft massflux at upper layer boundary
  742. zamu=zamu+peu(jl)-pdu(jl)
  743. ! store cloud properties on upper layer boundary
  744. ptc(jl-1)=ztc
  745. pqc(jl-1)=zqc
  746. plc(jl-1)=zlc
  747. end do
  748. klt=2
  749. 400 continue
  750. ! set detrainment in two layers above cloud
  751. pdu(klt-1)=zbeta*zamu
  752. peu(klt-1)=0.
  753. pdu(klt)=(1-zbeta)*zamu
  754. peu(klt)=0.
  755. ! add up rainrate on each of the layer boundaries
  756. do jl=klt+1,lme
  757. pgp(jl)=pgp(jl-1)+zpgp(jl)
  758. end do
  759. ! determine net mass flux on each of the layer boundaries
  760. do jl=lme,1,-1
  761. pamu(jl-1)=pamu(jl)+(peu(jl)-pdu(jl))-(ped(jl)-pdd(jl))
  762. end do
  763. llcudo = .true.
  764. llmilc = .true.
  765. return
  766. ! no cloud present, set cloud base and top to 0 and return
  767. 3000 continue
  768. klc=0
  769. klt=0
  770. llcudo = .true.
  771. llmilc = .true.
  772. convection_type = 'none'
  773. end subroutine cloud
  774. ! ==========================================================
  775. ! ===
  776. ! === TMPP/SOURCE/tmpp_sub_work.f90
  777. ! ===
  778. ! ==========================================================
  779. !---------------------------------------------------------------------
  780. ! calculate en/detrainment rates and diffusion coefficient on TM grid
  781. !---------------------------------------------------------------------
  782. ! History:
  783. ! Increased vertical dimension of z,t,q,u,v,w from lme to lme + 1
  784. ! in order to be able to use the same memory location in worksub
  785. ! for u and wu, for t and wt, etc.
  786. ! Added subroutine cen2bound for the same reason
  787. ! Removed dummy fields for geopotential height and zonal means
  788. ! Program just fits into memory of SGI machines (max stacksize = 524288) if
  789. ! TM and ECMWF both have 1x1 degree resolution and 60 levels
  790. ! pvv, 5-2-2000
  791. !---------------------------------------------------------------------
  792. ! =========================================================
  793. ! interpolate variables from the center of parent-model layers to the
  794. ! boundaries of parent-model layers and save result in same memory location
  795. subroutine mid2bound_uv( lme, npe, u, v, ps, mask, a, b )
  796. ! --- in/out ----------------------------------
  797. integer, intent(in) :: lme, npe
  798. real, intent(inout) :: u(npe,0:lme)
  799. real, intent(inout) :: v(npe,0:lme)
  800. real, intent(in) :: ps(npe)
  801. logical, intent(in) :: mask(npe)
  802. real, intent(in) :: a(0:lme)
  803. real, intent(in) :: b(0:lme)
  804. ! --- local ---------------------------------
  805. integer :: i
  806. real :: wcol(0:lme)
  807. ! --- begin -------------------------
  808. do i = 1, npe
  809. if ( mask(i) ) then
  810. call cen2bound_col( lme, u(i,1:lme), ps(i), 1, wcol, a, b )
  811. u(i,:) = wcol
  812. call cen2bound_col( lme, v(i,1:lme), ps(i), 1, wcol, a, b )
  813. v(i,:) = wcol
  814. end if
  815. end do
  816. end subroutine mid2bound_uv
  817. ! ===
  818. subroutine mid2bound_w( lme, npe, w, ps, mask, a, b )
  819. ! --- in/out ----------------------------------
  820. integer, intent(in) :: lme, npe
  821. real, intent(inout) :: w(npe,0:lme)
  822. real, intent(in) :: ps(npe)
  823. logical, intent(in) :: mask(npe)
  824. real, intent(in) :: a(0:lme)
  825. real, intent(in) :: b(0:lme)
  826. ! --- local ---------------------------------
  827. integer :: i
  828. real :: wcol(0:lme)
  829. ! --- begin -------------------------
  830. do i = 1, npe
  831. if ( mask(i) ) then
  832. call cen2bound_col( lme, w(i,1:lme), ps(i), 1, wcol, a, b )
  833. w(i,:) = wcol
  834. ! set to zero at top
  835. w(i,0) = 0.0
  836. end if
  837. end do
  838. end subroutine mid2bound_w
  839. ! ===
  840. subroutine mid2bound_t( lme, npe, t, ps, mask, a, b )
  841. ! --- in/out ----------------------------------
  842. integer, intent(in) :: lme, npe
  843. real, intent(inout) :: t(npe,0:lme)
  844. real, intent(in) :: ps(npe)
  845. logical, intent(in) :: mask(npe)
  846. real, intent(in) :: a(0:lme)
  847. real, intent(in) :: b(0:lme)
  848. ! --- local ---------------------------------
  849. integer :: i
  850. real :: wcol(0:lme)
  851. ! --- begin -------------------------
  852. do i = 1, npe
  853. if ( mask(i) ) then
  854. call cen2bound_col( lme, t(i,1:lme), ps(i), 1, wcol, a, b )
  855. t(i,:) = wcol
  856. end if
  857. end do
  858. end subroutine mid2bound_t
  859. ! ===
  860. subroutine mid2bound_q( lme, npe, q, ps, mask, a, b, t )
  861. use phys_humidity, only : qsat
  862. ! --- in/out ----------------------------------
  863. integer, intent(in) :: lme, npe
  864. real, intent(inout) :: q(npe,0:lme)
  865. real, intent(in) :: ps(npe)
  866. logical, intent(in) :: mask(npe)
  867. real, intent(in) :: a(0:lme)
  868. real, intent(in) :: b(0:lme)
  869. real, intent(in) :: t(npe,0:lme)
  870. ! --- local ---------------------------------
  871. integer :: i, l
  872. real :: wcol(0:lme)
  873. real :: tmpress(0:lme)
  874. ! --- begin -------------------------
  875. do i = 1, npe
  876. if ( mask(i) ) then
  877. call cen2bound_col( lme, q(i,1:lme), ps(i), 1, wcol, a, b )
  878. q(i,:) = wcol
  879. ! limit specific humidity at 0 and qsat(t,p)
  880. ! first establish hybrid vertical coordinate at i,j ;
  881. ! note that ps is expressed in Pa
  882. do l = 0, lme
  883. tmpress(l) = a(l) + ps(i)*b(l)
  884. end do
  885. do l = 0, lme
  886. q(i,l) = min( qsat(t(i,l),tmpress(l)), max(0.0,q(i,l)) )
  887. end do
  888. end if
  889. end do
  890. end subroutine mid2bound_q
  891. ! ===
  892. subroutine mid2bound_z( lme, npe, z, ps, mask, a, b, zsurf )
  893. use Binas, only : g => grav
  894. ! --- in/out ----------------------------------
  895. integer, intent(in) :: lme, npe
  896. real, intent(inout) :: z(npe,0:lme)
  897. real, intent(in) :: ps(npe)
  898. logical, intent(in) :: mask(npe)
  899. real, intent(in) :: a(0:lme)
  900. real, intent(in) :: b(0:lme)
  901. real, intent(in) :: zsurf(npe)
  902. ! --- local ---------------------------------
  903. integer :: i
  904. real :: wcol(0:lme)
  905. ! --- begin -------------------------
  906. do i = 1, npe
  907. if ( mask(i) ) then
  908. call cen2bound_col( lme, z(i,1:lme), ps(i), 1, wcol, a, b )
  909. z(i,:) = wcol
  910. ! set to known value at surface:
  911. z(i,lme) = zsurf(i)/g
  912. end if
  913. end do
  914. end subroutine mid2bound_z
  915. ! ===
  916. subroutine mid2bound_p( lme, npe, p, ps, mask, a, b )
  917. ! --- in/out ----------------------------------
  918. integer, intent(in) :: lme, npe
  919. real, intent(inout) :: p(npe,0:lme)
  920. real, intent(in) :: ps(npe)
  921. logical, intent(in) :: mask(npe)
  922. real, intent(in) :: a(0:lme)
  923. real, intent(in) :: b(0:lme)
  924. ! --- local ---------------------------------
  925. integer :: i, j
  926. real :: wcol(0:lme)
  927. ! --- begin -------------------------
  928. do i = 1, npe
  929. if ( mask(i) ) then
  930. call cen2bound_col( lme, p(i,:), ps(i), 0, wcol, a, b )
  931. p(i,:) = wcol
  932. end if
  933. end do
  934. end subroutine mid2bound_p
  935. ! interpolate from mid-levels of parent model to
  936. ! level boundaries
  937. !
  938. ! Peter van Velthoven - 4 January 2000
  939. ! This subroutine is included to save memory
  940. ! field and field2 use the same space in memory
  941. !
  942. ! iopt = 0 : no field as input : fill wfield with pressure
  943. ! iopt = other: use field as input
  944. !
  945. subroutine cen2bound_col( lme, field, ps, iopt, wfield, a, b )
  946. use Num, only : interp_muherm
  947. ! --- in/out -------------------------------
  948. integer, intent(in) :: lme
  949. real, intent(in) :: field(lme) ! input on (mid-)levels
  950. real, intent(in) :: ps ! surface pressure
  951. integer, intent(in) :: iopt
  952. real, intent(out) :: wfield(0:lme) ! output on vertical level boundaries
  953. real, intent(in) :: a(0:lme)
  954. real, intent(in) :: b(0:lme)
  955. ! --- begin -------------------------------
  956. integer :: status
  957. real :: ztemp(lme)
  958. real :: tmpress(0:lme) ! pressure at ECMWF vertical level boundaries
  959. real :: tcmpress(lme) ! pressure at ECMWF (mid-)levels
  960. integer :: l
  961. ! --- begin --------------------------------
  962. ! establish hybrid vertical coordinate at i,j
  963. ! note that ps is expressed in Pa
  964. tmpress = a + ps * b
  965. ! calculate pressure at model layer center
  966. do l=1,lme
  967. tcmpress(l) = (tmpress(l-1)+tmpress(l))/2.
  968. end do
  969. if ( iopt == 0 ) then
  970. wfield = tmpress
  971. else
  972. call interp_muherm( tcmpress, field, tmpress, wfield, status )
  973. if (status/=0) stop 'ERROR in cen2bound_col'
  974. end if
  975. end subroutine cen2bound_col
  976. ! ==========================================================
  977. ! ===
  978. ! === TMPP/SOURCE/tmpp_geometry.f90
  979. ! ===
  980. ! ==========================================================
  981. ! pressure at half leves from bottom to top
  982. subroutine phlev_ec_rev( lme, a_ec, b_ec, ps, pb )
  983. ! --- in/out --------------------------
  984. integer, intent(in) :: lme
  985. real, intent(in) :: a_ec(0:lme)
  986. real, intent(in) :: b_ec(0:lme)
  987. real, intent(in) :: ps
  988. real, intent(out) :: pb(0:lme)
  989. ! --- local --------------------------
  990. integer :: l
  991. ! --- in/out -------------------------
  992. do l = 0, lme
  993. pb(lme-l) = a_ec(l) + b_ec(l) * ps
  994. end do
  995. end subroutine phlev_ec_rev
  996. ! ==========================================================
  997. ! ===
  998. ! === TMPP/SOURCE/phys_geopot.f90
  999. ! ===
  1000. ! ==========================================================
  1001. !
  1002. ! NAME
  1003. ! GeoPot_col - calculate geopotential height
  1004. !
  1005. ! DESCRIPTION
  1006. ! Calculate geopotential height from halflevel pressures
  1007. ! and full level virtual temperature.
  1008. !
  1009. ! USAGE
  1010. !
  1011. ! call GeoPot( z, zsurf, pt, pq, pb, lm )
  1012. !
  1013. ! integer, intent(in) :: lm ! number of levels
  1014. !
  1015. ! (levels numbered downwards (top -> down) )
  1016. !
  1017. ! real, intent(out) :: z(lm) ! geopotential height (m ?).
  1018. ! real, intent(in) :: zsurf ! orography (m ?)
  1019. ! real, intent(in) :: pt(lm) ! temperature (K ?)
  1020. ! real, intent(in) :: pq(lm) ! specific humidity (??)
  1021. !
  1022. ! (levels numbered upwards (bottom -> up) )
  1023. !
  1024. ! real, intent(in) :: pb(0:lm) ! pressure at half levels
  1025. !
  1026. ! HISTORY
  1027. !
  1028. ! 06-11-2001, Arjo Segers
  1029. ! Extracted from original routines 'geopot' and 'auxhyb'
  1030. ! by Ad Jeuken
  1031. !
  1032. subroutine GeoPot( lm, zsurf, pt, pq, pb, z )
  1033. ! --- in/out -------------------------
  1034. integer, intent(in) :: lm
  1035. real, intent(out) :: z(lm)
  1036. real, intent(in) :: zsurf
  1037. real, intent(in) :: pt(lm)
  1038. real, intent(in) :: pq(lm)
  1039. real, intent(in) :: pb(0:lm)
  1040. ! --- const ------------------------
  1041. real, parameter :: rd = 287.05
  1042. real, parameter :: g0 = 9.801
  1043. ! --- local ------------------------------
  1044. integer :: linv
  1045. real :: pdelp, prdelp
  1046. real :: palfa(lm)
  1047. real :: plnr(lm)
  1048. real :: tv(lm)
  1049. integer :: l, lp1
  1050. ! --- begin ---------------------------------
  1051. ! >>> former routine 'auxhyb' >>>>>>>>>>>>>>>>>>>>>>
  1052. ! loop from top to bottom:
  1053. do l = 1, lm
  1054. linv = lm - l ! lm-1, 0
  1055. pdelp = pb(linv) - pb(linv+1)
  1056. prdelp = 1.0 / pdelp
  1057. if ( l == 1 ) then
  1058. plnr(l) = rd * 1.3862944
  1059. else
  1060. plnr(l) = rd * log( pb(linv)/pb(linv+1) )
  1061. end if
  1062. palfa(l) = rd - pb(linv+1) * plnr(l) * prdelp
  1063. end do
  1064. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1065. ! loop from bottom to top:
  1066. do l = lm, 1, -1
  1067. tv(l) = pt(l) * ( 1.0 + 0.608*pq(l) )
  1068. if ( l == lm ) then
  1069. z(l) = palfa(l)*tv(l)/g0 + zsurf/g0
  1070. else
  1071. lp1=l+1
  1072. z(l) = z(lp1) + ( palfa(l)*tv(l) + (plnr(lp1)-palfa(lp1))*tv(lp1) )/g0
  1073. end if
  1074. end do
  1075. end subroutine GeoPot
  1076. end module phys_convec_tmpp