grid_type_hyb.F90 97 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593
  1. !------------------------
  2. ! MODULE AND DATA TYPES
  3. !------------------------
  4. !
  5. ! USE grid_type_hyb
  6. ! type(TLevelInfo) :: levi
  7. !
  8. !------------------------
  9. ! INITIALIZATION
  10. !------------------------
  11. ! Three possible ways:
  12. !
  13. ! o by half level coeff a (Pa) and b (0-1)
  14. !
  15. ! call Init( levi, 60, (/a0,..,a60/), (/b0,..,b60/), status )
  16. !
  17. ! o by a character key; yet supported:
  18. ! 'ec19' : echam 19 levels
  19. ! 'ec31' : ecmwf 31 levels
  20. ! 'ec4' : ecmwf 4 levels ( 4 levels extracted from 91 levels in IFS : TM5 sees a 4-levels IFS)
  21. ! 'ec10' : ecmwf 10 levels (10 levels extracted from 91 levels in IFS : TM5 sees a 10-levels IFS)
  22. ! 'ec34' : ecmwf 34 levels (34 levels extracted from 91 levels in IFS : TM5 sees a 34-levels IFS)
  23. ! 'ec40' : ecmwf 40 levels
  24. ! 'ec60' : ecmwf 60 levels
  25. ! 'ec62' : ecmwf 62 levels
  26. ! 'ec91' : ecmwf 91 levels
  27. ! 'tm31' : tm 31 levels (reversed ec31)
  28. ! 'tm40' : tm 40 levels (reversed ec40)
  29. ! 'tm60' : tm 60 levels (reversed ec60)
  30. ! 'tm62' : tm 62 levels (reversed ec62)
  31. ! 'tm91' : tm 91 levels (reversed ec91)
  32. !
  33. ! call Init( levi, 'ec60', status )
  34. !
  35. ! o define a selection of half levels:
  36. !
  37. ! call Init( levi_parent, 'ec60', status )
  38. ! call Init( levi, levi_parent, (/0,2,..,58,60/), status )
  39. !
  40. !--------------------------
  41. ! VERTICAL REGRIDDING (I)
  42. !--------------------------
  43. !
  44. ! To regrid an array (InArr) defined on one grid (InGrid) into an array
  45. ! (OutArr) onto another vertical grid (OutGrid), use FillLevels.
  46. !
  47. ! Input array can be 1D (column), 2D (latitudinal or longitudinal slice), or
  48. ! 3D. Data can be on full or half levels, except for 1D (only full levels, no
  49. ! interpolation available: easy to code though. FIXME).
  50. !
  51. ! The regridding is done according to 3 more inputs:
  52. !
  53. ! (1) a combination key, used if 'combination of' or 'interpolation between'
  54. ! input is needed:
  55. !
  56. ! 'bottom' : use closest-to-the-ground neighbor
  57. ! 'top' : use closest-to-the-model-top neighbor
  58. ! 'sum' : sum input values (use for mass [extensive])
  59. ! 'aver' : unweighted average across levels
  60. ! 'mass-aver' : air-mass weighted average (use for mixing ratio [intensive])
  61. !
  62. ! (2) a location key (nw), that determines if the data are pinned to the
  63. ! edge or the center of the boxes:
  64. !
  65. ! 'n' : full levels, a/k/a center of box
  66. ! 'w' : half-levels, a/k/a box edges
  67. !
  68. ! (3) surface pressure (SP), which is one dimension less than InArr
  69. !
  70. !
  71. ! Call is:
  72. !
  73. ! FillLevels( OutGrid, SP, OutArr, InGrid, InArr, combine_key, status ) ! for 1D
  74. ! FillLevels( OutGrid, nw, SP, OutArr, InGrid, InArr, combine_key, status ) ! for 2D and 3D
  75. !
  76. ! Note only two output : OutArr (regridded data) and Status (0/1=success/failure)
  77. !
  78. !--------------------------
  79. ! VERTICAL REGRIDDING (II)
  80. !--------------------------
  81. ! There is a remapping routine specifically for cases when one of the levels set
  82. ! is a subset of the other, be it target or source grid.
  83. !
  84. ! call FillLevelsParents(levi, nw, ArrayIn, combine_key, ArrayOut, status, sp)
  85. !
  86. ! - Works both ways: parent-to-subset and subset-to-parent. Direction is determined by the arrays size.
  87. ! - Surface pressure is optional, since not always needed. If needed and not passed, run stops w/ a message.
  88. ! - 'nw' and 'combine_key' are the same as for FillLevels, but not all cases have been implemented yet.
  89. ! - Arrays follow the order ('u' or 'd') of the levels they are attached to.
  90. !
  91. !------------------------
  92. ! CHECKING
  93. !------------------------
  94. ! You can check that a LevI is initalized:
  95. !
  96. ! call check(levi, status)
  97. !
  98. ! or that a 3D array conforms to the LevI (3rd dim is same as nb of levels):
  99. !
  100. ! call check(levi, Arr, status)
  101. !
  102. ! or just examine the content of a LevI:
  103. !
  104. ! call PrintInfo( LevI )
  105. !
  106. !------------------------
  107. ! PRESSURE
  108. !------------------------
  109. ! You can get the pressure at each half/full level of LevI from surface
  110. ! pressure sp:
  111. !
  112. ! o call H/FPressure( levi, sp, pressure, status)
  113. !
  114. ! Output pressure can be 1-,2- or 3D. Then SP has one dimension less than pressure.
  115. !
  116. !------------------------
  117. ! TODO - ISSUE
  118. !------------------------
  119. ! When remapping:
  120. !
  121. ! It is assumed that 'HEIGHT-AVE' is akin to 'AIR-MASS-AVER'. This is not
  122. ! true, and is a crude approximation at best (going from coarse to fine grid,
  123. ! results should be ok, but not when going from fine-to-coarse grid). Problem
  124. ! is to get grid box height on the non-TM5 levels. See comment in
  125. ! levi_FillParent_3d.
  126. !
  127. ! In TM5, it is used for UDDR and DDDR.
  128. !-
  129. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  130. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  131. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  132. MODULE GRID_TYPE_HYB
  133. use go, only : gol, goPr, goErr
  134. implicit none
  135. private
  136. public :: TLevelInfo
  137. public :: Init, Done ! life cycle of a TLevelInfo instance
  138. public :: Check
  139. public :: Compare
  140. public :: HPressure ! returns pressure [Pa] at each half level of LevI
  141. public :: FPressure ! returns pressure [Pa] at each full level of LevI
  142. public :: FillLevels ! remapping utility b/w two LevelInfo
  143. public :: FillLevelsParents ! remapping utility b/w LevelInfo and its parents
  144. public :: PrintInfo
  145. ! --- const ---------------------------------------
  146. character(len=*), parameter :: mname = 'grid_type_hyb'
  147. ! --- types ---------------------------
  148. type TLevelInfo
  149. character(len=32) :: name ! name used for messages
  150. integer :: nlev ! number of levels
  151. real, pointer :: a(:), b(:) ! hybride half level coeff; indices 0, 1, ..., nlev
  152. real, pointer :: fa(:), fb(:) ! hybride full level coeff; indices 1, ..., nlev
  153. real, pointer :: fa_bounds(:,:), fb_bounds(:,:) ! half level coeff per full level (1:2,1:nlev)
  154. real, pointer :: p0(:), fp0(:), m0(:) ! standard pressures and mass (surface pressure 1e5)
  155. character(len=1) :: updo ! upwards or downwards ?
  156. real, pointer :: da(:), db(:) ! hybride increments; indices 1, ..., nlev
  157. ! -- parent levels if any
  158. logical :: selection ! has parent?
  159. integer, pointer :: hlevs(:) ! indices of parent half levels used in defining child
  160. integer, pointer :: flevs(:,:) ! indice range of parent full levels covered by child level (nlev,2)
  161. integer :: nlev_parent ! number of levels
  162. character(len=1) :: updo_parent ! upwards or downwards?
  163. real, pointer :: a_parent(:), b_parent(:) ! hybride half level coeff
  164. real, pointer :: da_parent(:), db_parent(:) ! hybride increments of parents; indices 1, ..., nlev
  165. end type TLevelInfo
  166. ! --- const ------------------------------------------------------------------
  167. ! *** ec4 **************************************************************
  168. ! Hybrid coordinate coefficients at half level interfaces,
  169. ! specifying 4 vertical ECMWF levels. These are subset of 91 levels, used in EC-Earth.
  170. ! Coefficient a is given in Pa, b in [0,1] .
  171. ! Should match what is in levels/ml4/const_ec_v__ml4.F90
  172. real, parameter :: a_ec4(0:4) = (/ &
  173. 0.000000, &
  174. 15638.053711, &
  175. 8356.252930, &
  176. 6.575628, &
  177. 0.000000 /)
  178. real, parameter :: b_ec4(0:4) = (/ &
  179. 0.000000, &
  180. 0.012508, &
  181. 0.698224, &
  182. 0.994204, &
  183. 1.000000 /)
  184. ! *** ec10 **************************************************************
  185. ! Hybrid coordinate coefficients at half level interfaces,
  186. ! specifying 10 vertical ECMWF levels. These are subset of 91 levels, used in EC-Earth.
  187. ! Coefficient a is given in Pa, b in [0,1] .
  188. ! Should match what is in levels/ml10/const_ec_v__ml10.F90
  189. real, parameter :: a_ec10(0:10) = (/ &
  190. 0.000000, &
  191. 450.685791, &
  192. 3358.425781, &
  193. 7341.469727, &
  194. 15638.053711, &
  195. 20319.011719, &
  196. 14665.645508, &
  197. 3010.146973, &
  198. 336.772369, &
  199. 6.575628, &
  200. 0.000000 /)
  201. real, parameter :: b_ec10(0:10) = (/ &
  202. 0.000000, &
  203. 0.000000, &
  204. 0.000000, &
  205. 0.000000, &
  206. 0.012508, &
  207. 0.176091, &
  208. 0.475016, &
  209. 0.875518, &
  210. 0.973466, &
  211. 0.994204, &
  212. 1.000000 /)
  213. ! *** ec19 **************************************************************
  214. ! Hybrid coordinate coefficients at half level interfaces,
  215. ! specifying 19 vertical ECHAM levels.
  216. ! Coefficient a is given in Pa, b in [0,1] .
  217. real, parameter :: a_ec19(0:19) = (/ &
  218. 0.000 , 2000.000 , 4000.000 , 6046.111 , &
  219. 8267.928 , 10609.510 , 12851.100 , 14698.500 , &
  220. 15861.130 , 16116.240 , 15356.920 , 13621.460 , &
  221. 11101.560 , 8127.144 , 5125.142 , 2549.969 , &
  222. 783.195 , 0.000 , 0.000 , 0.000 /)
  223. real, parameter :: b_ec19(0:19) = (/ &
  224. 0.000000000, 0.00000000, 0.00000000, 0.0003389933, &
  225. 0.003357187, 0.01307004, 0.03407715, 0.0706498300, &
  226. 0.125916700, 0.20119540, 0.29551960, 0.4054092000, &
  227. 0.524932200, 0.64610790, 0.75969840, 0.8564376000, &
  228. 0.928746900, 0.97298520, 0.99228150, 1.0000000000 /)
  229. ! *** ec31 **************************************************************
  230. ! Hybrid coordinate coefficients at half level interfaces,
  231. ! specifying 31 vertical ECMWF levels.
  232. ! Coefficient a is given in Pa, b in [0,1] .
  233. real, parameter :: a_ec31(0:31) = (/ &
  234. 0.0 , 2000.0 , 4000.0 , 6000.0 , &
  235. 8000.0 , 9976.135361 , 11820.539617 , 13431.393926 , &
  236. 14736.356909 , 15689.207458 , 16266.610500 , 16465.005734 , &
  237. 16297.619332 , 15791.598604 , 14985.269630 , 13925.517858 , &
  238. 12665.291662 , 11261.228878 , 9771.406290 , 8253.212096 , &
  239. 6761.341326 , 5345.914240 , 4050.717678 , 2911.569385 , &
  240. 1954.805296 , 1195.889791 , 638.148911 , 271.626545 , &
  241. 72.063577 , 0.0 , 0.0 , 0.0 /)
  242. real, parameter :: b_ec31(0:31) = (/ &
  243. 0.0 , 0.0 , 0.0 , 0.0 , &
  244. 0.0 , 0.0003908582 , 0.0029197006 , 0.0091941320 , &
  245. 0.0203191555, 0.0369748598 , 0.0594876397 , 0.0878949492 , &
  246. 0.1220035886, 0.1614415235 , 0.2057032385 , 0.2541886223 , &
  247. 0.3062353873, 0.3611450218 , 0.4182022749 , 0.4766881754 , &
  248. 0.5358865832, 0.5950842740 , 0.6535645569 , 0.7105944258 , &
  249. 0.7654052430, 0.8171669567 , 0.8649558510 , 0.9077158297 , &
  250. 0.9442132326, 0.9729851852 , 0.9922814815 , 1.0 /)
  251. ! *** ec34 **************************************************************
  252. ! Hybrid coordinate coefficients at half level interfaces,
  253. ! specifying 34 vertical ECMWF levels. These are subset of 91 levels, used in EC-Earth.
  254. ! Coefficient a is given in Pa, b in [0,1] .
  255. real, parameter :: a_ec34(0:34) = (/ &
  256. 0.000000, & ! 0
  257. 21.413612, 76.167656, & ! 5
  258. 204.637451, 450.685791, & ! 10
  259. 857.945801, & ! 15
  260. 1463.163940, 2292.155518, & ! 20
  261. 3358.425781, 4663.776367, & ! 25
  262. 6199.839355, 7341.469727, & ! 30
  263. 8564.624023, 9873.560547, & ! 35
  264. 11262.484375, 12713.897461, 14192.009766, & ! 40
  265. 15638.053711, 16990.623047, & ! 45
  266. 18191.029297, 19184.544922, 19919.796875, & ! 50
  267. 20348.916016, 20319.011719, & ! 55
  268. 19348.775391, & ! 60
  269. 17385.595703, 14665.645508, & ! 65
  270. 11543.166992, 8356.252930, & ! 70
  271. 5422.802734, & ! 75
  272. 3010.146973, 1297.656128, & ! 80
  273. 336.772369, 6.575628, & ! 85
  274. 0.000000 /) ! 90
  275. real, parameter :: b_ec34(0:34) = (/ &
  276. 0.000000, & ! 0
  277. 0.000000, 0.000000, & ! 5
  278. 0.000000, 0.000000, & ! 10
  279. 0.000000, & ! 15
  280. 0.000000, 0.000000, & ! 20
  281. 0.000000, 0.000000, & ! 25
  282. 0.000000, 0.000000, & ! 30
  283. 0.000055, 0.000279, & ! 35
  284. 0.001000, 0.002765, 0.006322, & ! 40
  285. 0.012508, 0.022189, & ! 45
  286. 0.036227, 0.055474, 0.080777, & ! 50
  287. 0.112979, 0.176091, & ! 55
  288. 0.259554, & ! 60
  289. 0.362203, 0.475016, & ! 65
  290. 0.589317, 0.698224, & ! 70
  291. 0.795385, & ! 75
  292. 0.875518, 0.935157, & ! 80
  293. 0.973466, 0.994204, & ! 85
  294. 1.000000 /) ! 90
  295. ! *** ec40 **************************************************************
  296. ! Hybrid coordinate coefficients at half level interfaces,
  297. ! specifying 40 vertical ECMWF levels.
  298. ! Coefficient a is given in [Pa] .
  299. real, parameter :: a_ec40(0:40) = (/ &
  300. 0.000000, 2000.000000, 4000.000000, 6000.000000, &
  301. 8000.000000, 9988.882813, 11914.523438, 13722.941406, &
  302. 15369.730469, 16819.476563, 18045.183594, 19027.695313, &
  303. 19755.109375, 20222.205078, 20429.863281, 20384.480469, &
  304. 20097.402344, 19584.330078, 18864.750000, 17961.357422, &
  305. 16899.468750, 15706.447266, 14411.124023, 13043.218750, &
  306. 11632.758789, 10209.500977, 8802.356445, 7438.803223, &
  307. 6144.314941, 4941.778320, 3850.913330, 2887.696533, &
  308. 2063.779785, 1385.912598, 855.361755, 467.333588, &
  309. 210.393890, 65.889244, 7.367743, 0.000000, &
  310. 0.000000/)
  311. real, parameter :: b_ec40(0:40) = (/ &
  312. 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, &
  313. 0.0000000000, 0.0001971156, 0.0015112918, 0.0048841573, &
  314. 0.0110761747, 0.0206778906, 0.0341211632, 0.0516904071, &
  315. 0.0735338330, 0.0996747017, 0.1300225258, 0.1643843055, &
  316. 0.2024759650, 0.2439331412, 0.2883229256, 0.3351548910, &
  317. 0.3838921785, 0.4339629412, 0.4847716093, 0.5357099175, &
  318. 0.5861684084, 0.6355474591, 0.6832686067, 0.7287858129, &
  319. 0.7715966105, 0.8112534285, 0.8473749161, 0.8796569109, &
  320. 0.9078838825, 0.9319403172, 0.9518215060, 0.9676452279, &
  321. 0.9796627164, 0.9882701039, 0.9940194488, 0.9976301193, &
  322. 1.0000000000 /)
  323. ! *** ec60 **************************************************************
  324. ! Hybrid coordinate coefficients at half level interfaces,
  325. ! specifying 60 vertical ECMWF levels.
  326. ! Coefficient a is given in Pa, b in [0,1] .
  327. real, parameter :: a_ec60(0:60) = (/ &
  328. 0.000000, 20.000000, 38.425343, 63.647804, &
  329. 95.636963, 134.483307, 180.584351, 234.779053, &
  330. 298.495789, 373.971924, 464.618134, 575.651001, &
  331. 713.218079, 883.660522, 1094.834717, 1356.474609, &
  332. 1680.640259, 2082.273926, 2579.888672, 3196.421631, &
  333. 3960.291504, 4906.708496, 6018.019531, 7306.631348, &
  334. 8765.053711, 10376.126953, 12077.446289, 13775.325195, &
  335. 15379.805664, 16819.474609, 18045.183594, 19027.695313, &
  336. 19755.109375, 20222.205078, 20429.863281, 20384.480469, &
  337. 20097.402344, 19584.330078, 18864.750000, 17961.357422, &
  338. 16899.468750, 15706.447266, 14411.124023, 13043.218750, &
  339. 11632.758789, 10209.500977, 8802.356445, 7438.803223, &
  340. 6144.314941, 4941.778320, 3850.913330, 2887.696533, &
  341. 2063.779785, 1385.912598, 855.361755, 467.333588, &
  342. 210.393890, 65.889244, 7.367743, 0.000000, &
  343. 0.000000/)
  344. real, parameter :: b_ec60(0:60) = (/ &
  345. 0.00000000, 0.00000000, 0.00000000, 0.00000000, &
  346. 0.00000000, 0.00000000, 0.00000000, 0.00000000, &
  347. 0.00000000, 0.00000000, 0.00000000, 0.00000000, &
  348. 0.00000000, 0.00000000, 0.00000000, 0.00000000, &
  349. 0.00000000, 0.00000000, 0.00000000, 0.00000000, &
  350. 0.00000000, 0.00000000, 0.00000000, 0.00000000, &
  351. 0.00007582, 0.00046139, 0.00181516, 0.00508112, &
  352. 0.01114291, 0.02067788, 0.03412116, 0.05169041, &
  353. 0.07353383, 0.09967469, 0.13002251, 0.16438432, &
  354. 0.20247590, 0.24393314, 0.28832296, 0.33515489, &
  355. 0.38389215, 0.43396294, 0.48477158, 0.53570992, &
  356. 0.58616841, 0.63554746, 0.68326861, 0.72878581, &
  357. 0.77159661, 0.81125343, 0.84737492, 0.87965691, &
  358. 0.90788388, 0.93194032, 0.95182151, 0.96764523, &
  359. 0.97966272, 0.98827010, 0.99401945, 0.99763012, &
  360. 1.00000000 /)
  361. ! *** ec62 **************************************************************
  362. real, parameter :: a_ec62(0:62) = (/ &
  363. 0.000000, &
  364. 988.835876, 1977.676270, 2966.516602, 3955.356934, 4944.197266, &
  365. 5933.037598, 6921.870117, 7909.441406, 8890.707031, 9860.528320, &
  366. 10807.783203, 11722.749023, 12595.006836, 13419.463867, 14192.009766, &
  367. 14922.685547, 15638.053711, 16329.560547, 16990.623047, 17613.281250, &
  368. 18191.029297, 18716.968750, 19184.544922, 19587.513672, 19919.796875, &
  369. 20175.394531, 20348.916016, 20434.158203, 20426.218750, 20319.011719, &
  370. 20107.031250, 19785.357422, 19348.775391, 18798.822266, 18141.296875, &
  371. 17385.595703, 16544.585938, 15633.566406, 14665.645508, 13653.219727, &
  372. 12608.383789, 11543.166992, 10471.310547, 9405.222656, 8356.252930, &
  373. 7335.164551, 6353.920898, 5422.802734, 4550.215820, 3743.464355, &
  374. 3010.146973, 2356.202637, 1784.854614, 1297.656128, 895.193542, &
  375. 576.314148, 336.772369, 162.043427, 54.208336, 6.575628, &
  376. 0.003160, 0.000000 /)
  377. real, parameter :: b_ec62(0:62) = (/ &
  378. 0.000000, &
  379. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  380. 0.000000, 0.000000, 0.000013, 0.000087, 0.000275, &
  381. 0.000685, 0.001415, 0.002565, 0.004187, 0.006322, &
  382. 0.009035, 0.012508, 0.016860, 0.022189, 0.028610, &
  383. 0.036227, 0.045146, 0.055474, 0.067316, 0.080777, &
  384. 0.095964, 0.112979, 0.131935, 0.152934, 0.176091, &
  385. 0.201520, 0.229315, 0.259554, 0.291993, 0.326329, &
  386. 0.362203, 0.399205, 0.436906, 0.475016, 0.513280, &
  387. 0.551458, 0.589317, 0.626559, 0.662934, 0.698224, &
  388. 0.732224, 0.764679, 0.795385, 0.824185, 0.850950, &
  389. 0.875518, 0.897767, 0.917651, 0.935157, 0.950274, &
  390. 0.963007, 0.973466, 0.982238, 0.989153, 0.994204, &
  391. 0.997630, 1.000000 /)
  392. ! *** ec91 **************************************************************
  393. ! Hybrid coordinate coefficients at half level interfaces,
  394. ! specifying 91 vertical ECMWF levels.
  395. ! Coefficient a is given in Pa, b in [0,1] .
  396. real, parameter :: a_ec91(0:91) = (/ &
  397. 0.000000, 2.000040, 3.980832, 7.387186, 12.908319, &
  398. 21.413612, 33.952858, 51.746601, 76.167656, 108.715561, &
  399. 150.986023, 204.637451, 271.356506, 352.824493, 450.685791, &
  400. 566.519226, 701.813354, 857.945801, 1036.166504, 1237.585449, &
  401. 1463.163940, 1713.709595, 1989.874390, 2292.155518, 2620.898438, &
  402. 2976.302246, 3358.425781, 3767.196045, 4202.416504, 4663.776367, &
  403. 5150.859863, 5663.156250, 6199.839355, 6759.727051, 7341.469727, &
  404. 7942.926270, 8564.624023, 9208.305664, 9873.560547, 10558.881836, &
  405. 11262.484375, 11982.662109, 12713.897461, 13453.225586, 14192.009766, &
  406. 14922.685547, 15638.053711, 16329.560547, 16990.623047, 17613.281250, &
  407. 18191.029297, 18716.968750, 19184.544922, 19587.513672, 19919.796875, &
  408. 20175.394531, 20348.916016, 20434.158203, 20426.218750, 20319.011719, &
  409. 20107.031250, 19785.357422, 19348.775391, 18798.822266, 18141.296875, &
  410. 17385.595703, 16544.585938, 15633.566406, 14665.645508, 13653.219727, &
  411. 12608.383789, 11543.166992, 10471.310547, 9405.222656, 8356.252930, &
  412. 7335.164551, 6353.920898, 5422.802734, 4550.215820, 3743.464355, &
  413. 3010.146973, 2356.202637, 1784.854614, 1297.656128, 895.193542, &
  414. 576.314148, 336.772369, 162.043427, 54.208336, 6.575628, &
  415. 0.003160, 0.000000 /)
  416. real, parameter :: b_ec91(0:91) = (/ &
  417. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  418. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  419. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  420. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  421. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  422. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  423. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  424. 0.000014, 0.000055, 0.000131, 0.000279, 0.000548, &
  425. 0.001000, 0.001701, 0.002765, 0.004267, 0.006322, &
  426. 0.009035, 0.012508, 0.016860, 0.022189, 0.028610, &
  427. 0.036227, 0.045146, 0.055474, 0.067316, 0.080777, &
  428. 0.095964, 0.112979, 0.131935, 0.152934, 0.176091, &
  429. 0.201520, 0.229315, 0.259554, 0.291993, 0.326329, &
  430. 0.362203, 0.399205, 0.436906, 0.475016, 0.513280, &
  431. 0.551458, 0.589317, 0.626559, 0.662934, 0.698224, &
  432. 0.732224, 0.764679, 0.795385, 0.824185, 0.850950, &
  433. 0.875518, 0.897767, 0.917651, 0.935157, 0.950274, &
  434. 0.963007, 0.973466, 0.982238, 0.989153, 0.994204, &
  435. 0.997630, 1.000000 /)
  436. ! *** ec137 **************************************************************
  437. ! Hybrid coordinate coefficients at half level interfaces,
  438. ! specifying 137 vertical ECMWF levels.
  439. ! Coefficient a is given in Pa, b in [0,1] .
  440. real, parameter :: a_ec137(0:137) = (/ &
  441. 0.000000, 2.000365, 3.102241, 4.666084, 6.827977, &
  442. 9.746966, 13.605424, 18.608931, 24.985718, 32.985710, &
  443. 42.879242, 54.955463, 69.520576, 86.895882, 107.415741, &
  444. 131.425507, 159.279404, 191.338562, 227.968948, 269.539581, &
  445. 316.420746, 368.982361, 427.592499, 492.616028, 564.413452, &
  446. 643.339905, 729.744141, 823.967834, 926.344910, 1037.201172, &
  447. 1156.853638, 1285.610352, 1423.770142, 1571.622925, 1729.448975, &
  448. 1897.519287, 2076.095947, 2265.431641, 2465.770508, 2677.348145, &
  449. 2900.391357, 3135.119385, 3381.743652, 3640.468262, 3911.490479, &
  450. 4194.930664, 4490.817383, 4799.149414, 5119.895020, 5452.990723, &
  451. 5798.344727, 6156.074219, 6526.946777, 6911.870605, 7311.869141, &
  452. 7727.412109, 8159.354004, 8608.525391, 9076.400391, 9562.682617, &
  453. 10065.978516, 10584.631836, 11116.662109, 11660.067383, 12211.547852, &
  454. 12766.873047, 13324.668945, 13881.331055, 14432.139648, 14975.615234, &
  455. 15508.256836, 16026.115234, 16527.322266, 17008.789063, 17467.613281, &
  456. 17901.621094, 18308.433594, 18685.718750, 19031.289063, 19343.511719, &
  457. 19620.042969, 19859.390625, 20059.931641, 20219.664063, 20337.863281, &
  458. 20412.308594, 20442.078125, 20425.718750, 20361.816406, 20249.511719, &
  459. 20087.085938, 19874.025391, 19608.572266, 19290.226563, 18917.460938, &
  460. 18489.707031, 18006.925781, 17471.839844, 16888.687500, 16262.046875, &
  461. 15596.695313, 14898.453125, 14173.324219, 13427.769531, 12668.257813, &
  462. 11901.339844, 11133.304688, 10370.175781, 9617.515625, 8880.453125, &
  463. 8163.375000, 7470.343750, 6804.421875, 6168.531250, 5564.382813, &
  464. 4993.796875, 4457.375000, 3955.960938, 3489.234375, 3057.265625, &
  465. 2659.140625, 2294.242188, 1961.500000, 1659.476563, 1387.546875, &
  466. 1143.250000, 926.507813, 734.992188, 568.062500, 424.414063, &
  467. 302.476563, 202.484375, 122.101563, 62.781250, 22.835938, &
  468. 3.757813, 0.000000, 0.000000 /)
  469. real, parameter :: b_ec137(0:137) = (/ &
  470. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  471. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  472. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  473. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  474. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  475. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  476. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  477. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  478. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  479. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  480. 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, &
  481. 0.000007, 0.000024, 0.000059, 0.000112, 0.000199, &
  482. 0.000340, 0.000562, 0.000890, 0.001353, 0.001992, &
  483. 0.002857, 0.003971, 0.005378, 0.007133, 0.009261, &
  484. 0.011806, 0.014816, 0.018318, 0.022355, 0.026964, &
  485. 0.032176, 0.038026, 0.044548, 0.051773, 0.059728, &
  486. 0.068448, 0.077958, 0.088286, 0.099462, 0.111505, &
  487. 0.124448, 0.138313, 0.153125, 0.168910, 0.185689, &
  488. 0.203491, 0.222333, 0.242244, 0.263242, 0.285354, &
  489. 0.308598, 0.332939, 0.358254, 0.384363, 0.411125, &
  490. 0.438391, 0.466003, 0.493800, 0.521619, 0.549301, &
  491. 0.576692, 0.603648, 0.630036, 0.655736, 0.680643, &
  492. 0.704669, 0.727739, 0.749797, 0.770798, 0.790717, &
  493. 0.809536, 0.827256, 0.843881, 0.859432, 0.873929, &
  494. 0.887408, 0.899900, 0.911448, 0.922096, 0.931881, &
  495. 0.940860, 0.949064, 0.956550, 0.963352, 0.969513, &
  496. 0.975078, 0.980072, 0.984542, 0.988500, 0.991984, &
  497. 0.995003, 0.997630, 1.000000 /)
  498. ! *** nc28 **************************************************************
  499. ! Hybrid coordinate coefficients at half level interfaces,
  500. ! specifying the 28 sigma levels of the NCEP reanalysis (surf -> top).
  501. ! Coefficient a is given in Pa, b in [0,1] .
  502. real, parameter :: a_nc28(0:28) = 0.0
  503. real, parameter :: b_nc28(0:28) = (/ &
  504. 1.0000 , 0.9900 , 0.9742 , 0.9546 , &
  505. 0.9304 , 0.9014 , 0.8662 , 0.8254 , &
  506. 0.7774 , 0.7242 , 0.6644 , 0.6014 , &
  507. 0.5348 , 0.4686 , 0.4028 , 0.3412 , &
  508. 0.2838 , 0.2326 , 0.1876 , 0.1488 , &
  509. 0.1164 , 0.0892 , 0.0672 , 0.0488 , &
  510. 0.0348 , 0.0228 , 0.0138 , 0.0064 , &
  511. 0.0000 /)
  512. ! *** cmam **************************************************************
  513. real, parameter :: a_msc71(0:71) = (/ &
  514. 0.0000000E+00, 0.9697381E-01, 0.1359287E+00, 0.1903444E+00, 0.2661948E+00, 0.3729337E+00, &
  515. 0.5219892E+00, 0.7302384E+00, 0.1023965E+01, 0.1429865E+01, 0.1996367E+01, 0.2795496E+01, &
  516. 0.3910756E+01, 0.5469573E+01, 0.7652655E+01, 0.1064398E+02, 0.1476761E+02, 0.2035368E+02, &
  517. 0.2782417E+02, 0.3784165E+02, 0.5115196E+02, 0.6867558E+02, 0.9154660E+02, 0.1215257E+03, &
  518. 0.1601752E+03, 0.2096810E+03, 0.2730070E+03, 0.3534054E+03, 0.4539333E+03, 0.5791536E+03, &
  519. 0.7337209E+03, 0.9020061E+03, 0.1151447E+04, 0.1438797E+04, 0.1756787E+04, 0.2144013E+04, &
  520. 0.2592025E+04, 0.3131841E+04, 0.3718082E+04, 0.4406751E+04, 0.5184419E+04, 0.6002543E+04, &
  521. 0.6901672E+04, 0.7882596E+04, 0.8892869E+04, 0.9923001E+04, 0.1096051E+05, 0.1196177E+05, &
  522. 0.1289793E+05, 0.1371837E+05, 0.1436708E+05, 0.1479985E+05, 0.1496916E+05, 0.1481930E+05, &
  523. 0.1430370E+05, 0.1346313E+05, 0.1242185E+05, 0.1128402E+05, 0.1013239E+05, 0.9018101E+04, &
  524. 0.7976487E+04, 0.7027693E+04, 0.6182180E+04, 0.5440920E+04, 0.4799065E+04, 0.4202355E+04, &
  525. 0.3590442E+04, 0.2963440E+04, 0.2321461E+04, 0.1664614E+04, 0.1115094E+04, 0.0000000E+00 /)
  526. real, parameter :: b_msc71(0:71) = (/ &
  527. 0.0000000E+00, 0.2585571E-09, 0.7040398E-09, 0.1535705E-08, 0.3013138E-08, 0.5588928E-08, &
  528. 0.9977033E-08, 0.1738750E-07, 0.2995330E-07, 0.5067781E-07, 0.8520696E-07, 0.1431463E-06, &
  529. 0.2392853E-06, 0.3989986E-06, 0.6646806E-06, 0.1095722E-05, 0.1800122E-05, 0.2924593E-05, &
  530. 0.4696273E-05, 0.7484670E-05, 0.1182433E-04, 0.1850007E-04, 0.2865571E-04, 0.4416054E-04, &
  531. 0.6735843E-04, 0.1018461E-03, 0.1529120E-03, 0.2279373E-03, 0.3362286E-03, 0.4919699E-03, &
  532. 0.7133741E-03, 0.9869111E-03, 0.1466181E-02, 0.2084517E-02, 0.2893929E-02, 0.4006976E-02, &
  533. 0.5507053E-02, 0.7581515E-02, 0.1018475E-01, 0.1375098E-01, 0.1841276E-01, 0.2415572E-01, &
  534. 0.3156661E-01, 0.4113112E-01, 0.5287339E-01, 0.6738057E-01, 0.8526936E-01, 0.1069703E+00, &
  535. 0.1332617E+00, 0.1646431E+00, 0.2011737E+00, 0.2437835E+00, 0.2934350E+00, 0.3496911E+00, &
  536. 0.4130113E+00, 0.4790453E+00, 0.5416321E+00, 0.5992498E+00, 0.6510819E+00, 0.6971171E+00, &
  537. 0.7375002E+00, 0.7725258E+00, 0.8025842E+00, 0.8281592E+00, 0.8497921E+00, 0.8694991E+00, &
  538. 0.8893561E+00, 0.9093621E+00, 0.9295158E+00, 0.9498163E+00, 0.9665902E+00, 0.1000000E+01 /)
  539. ! --- interface -----------------------
  540. interface Init
  541. module procedure levi_Init
  542. module procedure levi_Init_levi
  543. module procedure levi_Init_key
  544. module procedure levi_Init_select
  545. end interface
  546. interface Done
  547. module procedure levi_Done
  548. end interface
  549. interface Check
  550. module procedure levi_Check
  551. module procedure levi_Check_3d
  552. end interface
  553. interface Compare
  554. module procedure levi_Compare
  555. end interface
  556. interface HPressure
  557. module procedure levi_HPressure_1d
  558. module procedure levi_HPressure_2d
  559. module procedure levi_HPressure_3d
  560. end interface
  561. interface FPressure
  562. module procedure levi_FPressure_1d
  563. module procedure levi_FPressure_2d
  564. module procedure levi_FPressure_3d
  565. end interface
  566. interface FillLevels
  567. module procedure levi_FillLevels_1d
  568. module procedure levi_FillLevels_2d
  569. module procedure levi_FillLevels_3d
  570. end interface
  571. interface FillLevelsParents
  572. !FIXME module procedure levi_FillParent_1d
  573. !FIXME module procedure levi_FillParent_2d
  574. module procedure levi_FillParent_3d
  575. end interface FillLevelsParents
  576. CONTAINS
  577. !--------------------------------------------------------------------------
  578. ! TM5 !
  579. !--------------------------------------------------------------------------
  580. !BOP
  581. !
  582. ! !IROUTINE: PRINTINFO
  583. !
  584. ! !DESCRIPTION: Basic print method for hybrid level objects.
  585. !\\
  586. !\\
  587. ! !INTERFACE:
  588. !
  589. subroutine PrintInfo( LevelInfo )
  590. !
  591. ! !INPUT PARAMETERS:
  592. !
  593. type(TLevelInfo), intent(in) :: LevelInfo
  594. !
  595. ! !REVISION HISTORY:
  596. ! 15 Dec 2010 - P. Le Sager - written
  597. !
  598. !EOP
  599. !------------------------------------------------------------------------
  600. !BOC
  601. write(gol,*)'============Hyb. Lev. Info ==================='; call goPr
  602. write(gol,'("name :", a )') LevelInfo%name; call goPr
  603. write(gol,'("up/down :", a )') LevelInfo%updo; call goPr
  604. write(gol,'("number of levels:", i3 )') LevelInfo%nlev; call goPr
  605. if (associated(LevelInfo%a)) then
  606. write(gol,'("Edge a0..aN:",F12.3,"...",F12.3)') LevelInfo%a(0),LevelInfo%a(LevelInfo%nlev); call goPr
  607. else
  608. write(gol,*)"Edge A coeff not associated yet"; call goPr
  609. endif
  610. if (associated(LevelInfo%b)) then
  611. write(gol,'("Edge b0..bN:",F12.3,"...",F12.3)') LevelInfo%b(0),LevelInfo%b(LevelInfo%nlev); call goPr
  612. else
  613. write(gol,*)"Edge B coeff not associated yet"; call goPr
  614. endif
  615. if (associated(LevelInfo%fa)) then
  616. write(gol,'("Center a1..aN:",F12.3,"...",F12.3)') LevelInfo%fa(1),LevelInfo%fa(LevelInfo%nlev); call goPr
  617. else
  618. write(gol,*)" Center A coeff not associated yet"; call goPr
  619. endif
  620. if (associated(LevelInfo%fb)) then
  621. write(gol,'("Center b1..bN:",F12.3,"...",F12.3)') LevelInfo%fb(1),LevelInfo%fb(LevelInfo%nlev); call goPr
  622. else
  623. write(gol,*)"Center B coeff not associated yet"; call goPr
  624. endif
  625. if (associated(LevelInfo%p0)) then
  626. write(gol,'("Edge p0..pN:",F12.3,"...",F12.3)') LevelInfo%p0(0),LevelInfo%p0(LevelInfo%nlev); call goPr
  627. else
  628. write(gol,*)"Edge Press not associated yet"; call goPr
  629. endif
  630. if (associated(LevelInfo%fp0)) then
  631. write(gol,'("Center p1..pN:",F12.3,"...",F12.3)') LevelInfo%fp0(1),LevelInfo%fp0(LevelInfo%nlev); call goPr
  632. else
  633. write(gol,*)" Center Press coeff not associated yet"; call goPr
  634. endif
  635. if (associated(LevelInfo%m0)) then
  636. write(gol,'("Box mass m1..mN:",F12.3,"...",F12.3)') LevelInfo%m0(1),LevelInfo%m0(LevelInfo%nlev); call goPr
  637. else
  638. write(gol,*)"Mass not associated yet"; call goPr
  639. endif
  640. ! -- parent levels
  641. write(gol,'("has a parent :",L1)') LevelInfo%selection
  642. if (LevelInfo%selection) then
  643. write(gol,'(" with ",i3, " levels")') LevelInfo%nlev_parent; call goPr
  644. endif
  645. write(gol,*)'=============================================='; call goPr
  646. end subroutine PrintInfo
  647. !EOC
  648. ! =========================================================
  649. subroutine levi_Init( levi, nlev, a, b, status, name )
  650. use Binas, only : p0, grav
  651. ! --- in/out ---------------------------------------
  652. type(TLevelInfo), intent(out) :: levi
  653. integer, intent(in) :: nlev
  654. real, intent(in) :: a(:)
  655. real, intent(in) :: b(:)
  656. integer, intent(out) :: status
  657. character(len=*), intent(in), optional :: name
  658. ! --- const --------------------------------------
  659. character(len=*), parameter :: rname = mname//'/levi_Init'
  660. ! --- local --------------------------------------
  661. integer :: l
  662. ! --- begin ---------------------------------------
  663. ! check param
  664. if ( (size(a) /= nlev+1) .or. (size(b) /= nlev+1) ) then
  665. write (*,'("ERROR - invalid length of half level coeff:")')
  666. write (*,'("ERROR - nlev : ",i4)') nlev
  667. write (*,'("ERROR - size(a) : ",i4," (",i4,")")') size(a), nlev+1
  668. write (*,'("ERROR - size(b) : ",i4," (",i4,")")') size(b), nlev+1
  669. TRACEBACK; status=1; return
  670. end if
  671. ! store name ?
  672. if ( present(name) ) then
  673. levi%name = name
  674. else
  675. levi%name = 'levs'
  676. end if
  677. ! number of levels
  678. levi%nlev = nlev
  679. ! store half level hybride coeff
  680. allocate( levi%a(0:nlev) )
  681. allocate( levi%b(0:nlev) )
  682. levi%a = a
  683. levi%b = b
  684. ! hybride coeff increments:
  685. allocate( levi%da(nlev) )
  686. allocate( levi%db(nlev) )
  687. levi%da = levi%a(1:nlev) - levi%a(0:nlev-1)
  688. levi%db = levi%b(1:nlev) - levi%b(0:nlev-1)
  689. ! full level hybride coeff:
  690. allocate( levi%fa(nlev) )
  691. allocate( levi%fb(nlev) )
  692. levi%fa = ( levi%a(0:nlev-1) + levi%a(1:nlev) )/2.0
  693. levi%fb = ( levi%b(0:nlev-1) + levi%b(1:nlev) )/2.0
  694. ! half level coeff per full level:
  695. allocate( levi%fa_bounds(1:2,1:nlev) )
  696. allocate( levi%fb_bounds(1:2,1:nlev) )
  697. levi%fa_bounds(1,:) = levi%a(0:nlev-1)
  698. levi%fa_bounds(2,:) = levi%a(1:nlev )
  699. levi%fb_bounds(1,:) = levi%b(0:nlev-1)
  700. levi%fb_bounds(2,:) = levi%b(1:nlev )
  701. ! fill standard pressures:
  702. allocate( levi%p0(0:nlev) )
  703. levi%p0(0:nlev) = levi%a(0:nlev) + levi%b(0:nlev) * p0 ! Pa
  704. allocate( levi%fp0(1:nlev) )
  705. levi%fp0 = levi%fa + levi%fb * p0 ! Pa
  706. allocate( levi%m0(1:nlev) )
  707. levi%m0 = abs( levi%da + levi%db * p0 )/grav ! kg air / m2
  708. ! upwards (decreasing pressure) or downwards (increasing pressure)
  709. if ( levi%p0(0) > levi%p0(nlev) ) then
  710. levi%updo = 'u'
  711. else
  712. levi%updo = 'd'
  713. end if
  714. ! no selection info
  715. levi%selection = .false.
  716. levi%updo_parent='-'
  717. nullify( levi%hlevs )
  718. nullify( levi%flevs )
  719. nullify( levi%a_parent )
  720. nullify( levi%b_parent )
  721. nullify( levi%da_parent )
  722. nullify( levi%db_parent )
  723. status = 0
  724. end subroutine levi_Init
  725. ! ***
  726. subroutine levi_Init_levi( levi, levi2, status )
  727. ! --- in/out ---------------------------------------
  728. type(TLevelInfo), intent(out) :: levi
  729. type(TLevelInfo), intent(in) :: levi2
  730. integer, intent(out) :: status
  731. ! --- local --------------------------------------
  732. character(len=*), parameter :: rname = mname//'/levi_Init_levi'
  733. ! --- begin ---------------------------------------
  734. ! copy fields:
  735. call Init( levi, levi2%nlev, levi2%a, levi2%b, status, name=trim(levi2%name) )
  736. IF_NOTOK_RETURN(status=1)
  737. status = 0
  738. end subroutine levi_Init_levi
  739. ! ***
  740. subroutine levi_Init_key( levi, key, status )
  741. ! --- in/out ---------------------------------------
  742. type(TLevelInfo), intent(out) :: levi
  743. character(len=*), intent(in) :: key
  744. integer, intent(out) :: status
  745. ! --- const --------------------------------------
  746. character(len=*), parameter :: rname = mname//'/levi_Init_key'
  747. ! --- local ---------------------------------------
  748. real, allocatable :: a(:), b(:)
  749. integer :: l
  750. ! --- begin ---------------------------------------
  751. select case ( key )
  752. case ( 'ec4' )
  753. call Init( levi, 4, a_ec4, b_ec4, status, name=trim(key) )
  754. IF_NOTOK_RETURN(status=1)
  755. case ( 'ec10' )
  756. call Init( levi, 10, a_ec10, b_ec10, status, name=trim(key) )
  757. IF_NOTOK_RETURN(status=1)
  758. case ( 'ec19' )
  759. call Init( levi, 19, a_ec19, b_ec19, status, name=trim(key) )
  760. IF_NOTOK_RETURN(status=1)
  761. case ( 'ec31' )
  762. call Init( levi, 31, a_ec31, b_ec31, status, name=trim(key) )
  763. IF_NOTOK_RETURN(status=1)
  764. case ( 'ec34' )
  765. call Init( levi, 34, a_ec34, b_ec34, status, name=trim(key) )
  766. IF_NOTOK_RETURN(status=1)
  767. case ( 'ec40' )
  768. call Init( levi, 40, a_ec40, b_ec40, status, name=trim(key) )
  769. IF_NOTOK_RETURN(status=1)
  770. case ( 'ec60' )
  771. call Init( levi, 60, a_ec60, b_ec60, status, name=trim(key) )
  772. IF_NOTOK_RETURN(status=1)
  773. case ( 'ec62' )
  774. call Init( levi, 62, a_ec62, b_ec62, status, name=trim(key) )
  775. IF_NOTOK_RETURN(status=1)
  776. case ( 'ec91' )
  777. call Init( levi, 91, a_ec91, b_ec91, status, name=trim(key) )
  778. IF_NOTOK_RETURN(status=1)
  779. case ( 'ec137' )
  780. call Init( levi, 137, a_ec137, b_ec137, status, name=trim(key) )
  781. IF_NOTOK_RETURN(status=1)
  782. case ( 'tm4' )
  783. allocate( a(0:4) )
  784. allocate( b(0:4) )
  785. do l = 0, 4
  786. a(l) = a_ec4(4-l)
  787. b(l) = b_ec4(4-l)
  788. end do
  789. call Init( levi, 4, a, b, status, name=trim(key) )
  790. IF_NOTOK_RETURN(status=1)
  791. deallocate( a )
  792. deallocate( b )
  793. case ( 'tm10' )
  794. allocate( a(0:10) )
  795. allocate( b(0:10) )
  796. do l = 0, 10
  797. a(l) = a_ec10(10-l)
  798. b(l) = b_ec10(10-l)
  799. end do
  800. call Init( levi, 10, a, b, status, name=trim(key) )
  801. IF_NOTOK_RETURN(status=1)
  802. deallocate( a )
  803. deallocate( b )
  804. case ( 'tm31' )
  805. allocate( a(0:31) )
  806. allocate( b(0:31) )
  807. do l = 0, 31
  808. a(l) = a_ec31(31-l)
  809. b(l) = b_ec31(31-l)
  810. end do
  811. call Init( levi, 31, a, b, status, name=trim(key) )
  812. IF_NOTOK_RETURN(status=1)
  813. deallocate( a )
  814. deallocate( b )
  815. case ( 'tm34' )
  816. allocate( a(0:34) )
  817. allocate( b(0:34) )
  818. do l = 0, 34
  819. a(l) = a_ec34(34-l)
  820. b(l) = b_ec34(34-l)
  821. end do
  822. call Init( levi, 34, a, b, status, name=trim(key) )
  823. IF_NOTOK_RETURN(status=1)
  824. deallocate( a )
  825. deallocate( b )
  826. case ( 'tm40' )
  827. allocate( a(0:40) )
  828. allocate( b(0:40) )
  829. do l = 0, 40
  830. a(l) = a_ec40(40-l)
  831. b(l) = b_ec40(40-l)
  832. end do
  833. call Init( levi, 40, a, b, status, name=trim(key) )
  834. IF_NOTOK_RETURN(status=1)
  835. deallocate( a )
  836. deallocate( b )
  837. case ( 'tm60' )
  838. allocate( a(0:60) )
  839. allocate( b(0:60) )
  840. do l = 0, 60
  841. a(l) = a_ec60(60-l)
  842. b(l) = b_ec60(60-l)
  843. end do
  844. call Init( levi, 60, a, b, status, name=trim(key) )
  845. IF_NOTOK_RETURN(status=1)
  846. deallocate( a )
  847. deallocate( b )
  848. case ( 'tm62' )
  849. allocate( a(0:62) )
  850. allocate( b(0:62) )
  851. do l = 0, 62
  852. a(l) = a_ec62(62-l)
  853. b(l) = b_ec62(62-l)
  854. end do
  855. call Init( levi, 62, a, b, status, name=trim(key) )
  856. IF_NOTOK_RETURN(status=1)
  857. deallocate( a )
  858. deallocate( b )
  859. case ( 'tm91' )
  860. allocate( a(0:91) )
  861. allocate( b(0:91) )
  862. do l = 0, 91
  863. a(l) = a_ec91(91-l)
  864. b(l) = b_ec91(91-l)
  865. end do
  866. call Init( levi, 91, a, b, status, name=trim(key) )
  867. IF_NOTOK_RETURN(status=1)
  868. deallocate( a )
  869. deallocate( b )
  870. case ( 'tm137' )
  871. allocate( a(0:137) )
  872. allocate( b(0:137) )
  873. do l = 0, 137
  874. a(l) = a_ec137(137-l)
  875. b(l) = b_ec137(137-l)
  876. end do
  877. call Init( levi, 137, a, b, status, name=trim(key) )
  878. IF_NOTOK_RETURN(status=1)
  879. deallocate( a )
  880. deallocate( b )
  881. case ( 'nc28' )
  882. call Init( levi, 28, a_nc28, b_nc28, status, name=trim(key) )
  883. IF_NOTOK_RETURN(status=1)
  884. case ( 'msc71' )
  885. call Init( levi, 71, a_msc71, b_msc71, status, name=trim(key) )
  886. IF_NOTOK_RETURN(status=1)
  887. case default
  888. write (*,'("ERROR - unknown key `",a,"`")') trim(key)
  889. TRACEBACK; status=1; return
  890. end select
  891. status = 0
  892. end subroutine levi_Init_key
  893. ! ***
  894. subroutine levi_Init_select( levi, levi_parent, hlev_select, status, name )
  895. ! --- in/out ---------------------------------------
  896. type(TLevelInfo), intent(out) :: levi
  897. type(TLevelInfo), intent(in) :: levi_parent
  898. integer, intent(in) :: hlev_select(:)
  899. integer, intent(out) :: status
  900. character(len=*), intent(in), optional :: name
  901. ! --- const --------------------------------------
  902. character(len=*), parameter :: rname = mname//'/levi_Init_select'
  903. ! --- local --------------------------------------
  904. integer :: nlev, l
  905. ! --- begin ---------------------------------------
  906. if ( (size(hlev_select) < 2) .or. (size(hlev_select) > levi_parent%nlev+1) ) then
  907. write(gol,'(" Strange length of array with selected levels:")') ; call goErr
  908. write(gol,'(" expected : ",i4,", ..,",i4)') 2, levi_parent%nlev+1 ; call goErr
  909. write(gol,'(" found : ",i4)') size(hlev_select) ; call goErr
  910. TRACEBACK; status=1; return
  911. end if
  912. ! check range of values:
  913. if ( (minval(hlev_select) /= 0) .or. (maxval(hlev_select) /= levi_parent%nlev) ) then
  914. write(gol,'(" Invalid range of selected levels:")') ; call goErr
  915. write(gol,'(" expected : ",i4,", ..,",i4)') 0, levi_parent%nlev ; call goErr
  916. write(gol,'(" found : ",i4,", ..,",i4)') minval(hlev_select), maxval(hlev_select) ; call goErr
  917. TRACEBACK; status=1; return
  918. end if
  919. ! set number of full levels
  920. nlev = size(hlev_select) - 1
  921. ! copy coeff
  922. call Init( levi, nlev, levi_parent%a(hlev_select), levi_parent%b(hlev_select), status, name=name )
  923. IF_NOTOK_RETURN(status=1)
  924. ! store selection info
  925. levi%selection = .true.
  926. ! o levi_parent half levels indices corresponding to levi half levels
  927. allocate( levi%hlevs(0:nlev) )
  928. levi%hlevs = hlev_select
  929. ! o range of levi_parent full levels covered by a levi level. Note that
  930. ! bounds from hlev_select are (1:nlev+1).
  931. allocate( levi%flevs(nlev,2) )
  932. do l = 1, nlev
  933. levi%flevs(l,1) = hlev_select(l+1) + 1
  934. levi%flevs(l,2) = hlev_select(l)
  935. end do
  936. ! o original hybride coeff:
  937. levi%nlev_parent = levi_parent%nlev
  938. allocate( levi%a_parent(0:levi%nlev_parent) )
  939. allocate( levi%b_parent(0:levi%nlev_parent) )
  940. allocate( levi%da_parent(levi%nlev_parent) )
  941. allocate( levi%db_parent(levi%nlev_parent) )
  942. levi%a_parent = levi_parent%a
  943. levi%b_parent = levi_parent%b
  944. levi%da_parent = levi_parent%da
  945. levi%db_parent = levi_parent%db
  946. ! upwards (decreasing pressure) or downwards (increasing pressure)
  947. levi%updo_parent = levi_parent%updo
  948. status = 0
  949. end subroutine levi_Init_select
  950. ! ***
  951. subroutine levi_Done( levi, status )
  952. ! --- in/out ---------------------------------------
  953. type(TLevelInfo), intent(inout) :: levi
  954. integer, intent(out) :: status
  955. ! --- begin ---------------------------------------
  956. ! deallocate storage for hybride coeff
  957. deallocate( levi%a )
  958. deallocate( levi%b )
  959. ! deallocate storage for full level hybride coeff
  960. deallocate( levi%fa )
  961. deallocate( levi%fb )
  962. ! deallocate storage for half level coeff per full level:
  963. deallocate( levi%fa_bounds )
  964. deallocate( levi%fb_bounds )
  965. ! deallocate storage for standard pressures and mass:
  966. deallocate( levi%p0 )
  967. deallocate( levi%fp0 )
  968. deallocate( levi%m0 )
  969. ! deallocate storage for increment coeff
  970. deallocate( levi%da )
  971. deallocate( levi%db )
  972. ! selection info ?
  973. if ( levi%selection ) then
  974. deallocate( levi%hlevs )
  975. deallocate( levi%flevs )
  976. deallocate( levi%a_parent )
  977. deallocate( levi%b_parent )
  978. deallocate( levi%da_parent )
  979. deallocate( levi%db_parent )
  980. end if
  981. status = 0
  982. end subroutine levi_Done
  983. ! ***
  984. subroutine levi_Check( levi, status )
  985. ! --- in/out ------------------------------
  986. type(TLevelInfo), intent(in) :: levi
  987. integer, intent(out) :: status
  988. ! --- const -------------------------------
  989. character(len=*), parameter :: rname = mname//'/levi_Check'
  990. ! --- begin -------------------------------
  991. if ( levi%nlev < 1 ) then
  992. write (*,'("ERROR - level info contains strange number of levels:")')
  993. write (*,'("ERROR - levi%nlev : ",i4)') levi%nlev
  994. TRACEBACK; status=1; return
  995. end if
  996. if ( (.not. associated(levi%a)) .or. (.not. associated(levi%b)) ) then
  997. write (*,'("ERROR - hybride coeffs in level info not allocated properly.")')
  998. TRACEBACK; status=1; return
  999. end if
  1000. if ( (size(levi%a)/=levi%nlev+1) .or. (size(levi%b)/=levi%nlev+1) ) then
  1001. write (*,'("ERROR - hybride coeffs in level info wrong size:")')
  1002. write (*,'("ERROR - nlev : ",i4)') levi%nlev
  1003. write (*,'("ERROR - size a : ",i4)') size(levi%a)
  1004. write (*,'("ERROR - size b : ",i4)') size(levi%b)
  1005. TRACEBACK; status=1; return
  1006. end if
  1007. if ( (.not. associated(levi%fa)) .or. (.not. associated(levi%fb)) ) then
  1008. write (*,'("ERROR - f hybride coeffs in level info not allocated properly.")')
  1009. TRACEBACK; status=1; return
  1010. end if
  1011. if ( (size(levi%fa)/=levi%nlev) .or. (size(levi%fb)/=levi%nlev) ) then
  1012. write (*,'("ERROR - f hybride coeffs in level info wrong size:")')
  1013. write (*,'("ERROR - nlev : ",i4)') levi%nlev
  1014. write (*,'("ERROR - size fa : ",i4)') size(levi%fa)
  1015. write (*,'("ERROR - size fb : ",i4)') size(levi%fb)
  1016. TRACEBACK; status=1; return
  1017. end if
  1018. status = 0
  1019. end subroutine levi_Check
  1020. ! ***
  1021. subroutine levi_Check_3d( levi, ll, status )
  1022. ! --- in/out ------------------------------
  1023. type(TLevelInfo), intent(in) :: levi
  1024. real, intent(in) :: ll(:,:,:)
  1025. integer, intent(out) :: status
  1026. ! --- const -------------------------------
  1027. character(len=*), parameter :: rname = mname//'/levi_Check_3d'
  1028. ! --- begin -------------------------------
  1029. call Check( levi, status )
  1030. IF_NOTOK_RETURN(status=1)
  1031. if ( size(ll,3) /= levi%nlev ) then
  1032. write(gol,'(" Size of 3D grid does not match with level info")'); call goErr
  1033. write(gol,'(" size(ll,3) : ",i4)') size(ll,3) ; call goErr
  1034. write(gol,'(" levi%nlev : ",i4)') levi%nlev ; call goErr
  1035. TRACEBACK; status=1; return
  1036. end if
  1037. status = 0
  1038. end subroutine levi_Check_3d
  1039. ! ##############################################################
  1040. ! ###
  1041. ! ### combining levels
  1042. ! ###
  1043. ! ##############################################################
  1044. !
  1045. ! How levi and leviX compare?
  1046. ! - exact match : copy
  1047. ! - levi is subset of leviX : combine
  1048. ! - other case : interpol
  1049. !
  1050. ! Also returns if levi and leviX are going in the same direction or not.
  1051. !
  1052. ! Note that case of "source grid is a subset of target grid" is not handled
  1053. ! specifically, and thus is treated as 'interpol'. See FillLevelsParent
  1054. ! routine, which takes care of that case.
  1055. !
  1056. subroutine levi_Compare( levi, leviX, verbose, fillkey, reverse, status )
  1057. ! --- in/out ----------------------------------
  1058. type(TLevelInfo), intent(in) :: levi ! target grid
  1059. type(TLevelInfo), intent(in) :: leviX ! source grid
  1060. integer, intent(in) :: verbose
  1061. character(len=10), intent(out) :: fillkey ! copy, combine, interpol
  1062. logical, intent(out) :: reverse ! same direction
  1063. integer, intent(out) :: status
  1064. ! --- const --------------------------------------
  1065. character(len=*), parameter :: rname = mname//'/levi_Compare'
  1066. ! --- local -----------------------------------
  1067. integer :: l
  1068. real, allocatable :: Xa_rev(:), Xb_rev(:)
  1069. ! --- begin ------------------------------------
  1070. ! reverse hybride coeff of source grid
  1071. allocate( Xa_rev(0:leviX%nlev), Xb_rev(0:leviX%nlev) )
  1072. do l = 0, leviX%nlev
  1073. Xa_rev(l) = leviX%a(leviX%nlev-l)
  1074. Xb_rev(l) = leviX%b(leviX%nlev-l)
  1075. end do
  1076. ! default
  1077. fillkey = 'interpol'
  1078. reverse = levi%updo /= leviX%updo
  1079. ! same number of levels ?
  1080. if ( leviX%nlev == levi%nlev ) then
  1081. ! exact match or reverse ...
  1082. if ( all(abs(leviX%a-levi%a)<0.1) .and. all(abs(leviX%b-levi%b)<0.1) ) then
  1083. fillkey = 'copy'
  1084. reverse = .false.
  1085. else if ( all(abs(Xa_rev -levi%a)<0.1) .and. all(abs(Xb_rev -levi%b)<0.1) ) then
  1086. fillkey = 'copy'
  1087. reverse = .true.
  1088. end if
  1089. ! is target grid a subset of source grid?
  1090. else if ( levi%selection .and. (leviX%nlev == levi%nlev_parent) ) then
  1091. ! exact match or reverse ...
  1092. if ( all(abs(leviX%a-levi%a_parent)<0.1) .and. all(abs(leviX%b-levi%b_parent)<0.1) ) then
  1093. fillkey = 'combine'
  1094. reverse = .false.
  1095. else if ( all(abs( Xa_rev-levi%a_parent)<0.1) .and. all(abs( Xb_rev-levi%b_parent)<0.1) ) then
  1096. fillkey = 'combine'
  1097. reverse = .true.
  1098. end if
  1099. !PLS The case of "source grid a subset of target grid" is not specifically
  1100. ! covered (ie it uses 'interpol'). Could be added here, but decided
  1101. ! for the alternate FillLevelsParents routine, which should be a bit faster.
  1102. end if
  1103. deallocate( Xa_rev, Xb_rev )
  1104. status = 0
  1105. end subroutine levi_Compare
  1106. ! =====================================================================
  1107. ! ===
  1108. ! === pressure levels - returns pressure [Pa] at each half level of LevI
  1109. ! ===
  1110. ! =====================================================================
  1111. subroutine levi_HPressure_1d( levi, sp, ph, status )
  1112. ! --- in/out -------------------------------
  1113. type(TLevelInfo), intent(in) :: levi
  1114. real, intent(in) :: sp ! Pa
  1115. real, intent(out) :: ph(:) ! Pa
  1116. integer, intent(out) :: status
  1117. ! --- const --------------------------------------
  1118. character(len=*), parameter :: rname = mname//'/levi_HPressure_1d'
  1119. ! --- begin ---------------------------------
  1120. ! check ...
  1121. if ( size(ph) /= levi%nlev+1 ) then
  1122. write (*,'("ERROR - shape of output grid does not match definition:")')
  1123. write (*,'("ERROR - half levels : ",i4)') levi%nlev+1
  1124. write (*,'("ERROR - ph shape : ",i4)') shape(ph)
  1125. TRACEBACK; status=1; return
  1126. end if
  1127. ! half level pressure
  1128. ph = levi%a + levi%b * sp
  1129. status = 0
  1130. end subroutine levi_HPressure_1d
  1131. ! *
  1132. subroutine levi_HPressure_2d( levi, sp, ph, status )
  1133. ! --- in/out -------------------------------
  1134. type(TLevelInfo), intent(in) :: levi
  1135. real, intent(in) :: sp(:) ! Pa
  1136. real, intent(out) :: ph(:,:) ! Pa
  1137. integer, intent(out) :: status
  1138. ! --- const --------------------------------------
  1139. character(len=*), parameter :: rname = mname//'/levi_HPressure_2d'
  1140. ! --- local ---------------------------------
  1141. integer :: i
  1142. ! --- begin ---------------------------------
  1143. if ( any( shape(ph) /= (/shape(sp),levi%nlev+1/) ) ) then
  1144. write (*,'("ERROR - shape of output grid does not match definition:")')
  1145. write (*,'("ERROR - sp shape : ",i6)') shape(sp)
  1146. write (*,'("ERROR - half levels : ",i4)') levi%nlev+1
  1147. write (*,'("ERROR - ph shape : ",i6,i4)') shape(ph)
  1148. TRACEBACK; status=1; return
  1149. end if
  1150. ! half level pressure
  1151. do i = 1, size(sp)
  1152. ph(i,:) = levi%a + levi%b * sp(i)
  1153. end do
  1154. status = 0
  1155. end subroutine levi_HPressure_2d
  1156. ! *
  1157. subroutine levi_HPressure_3d( levi, sp, ph, status )
  1158. ! --- in/out -------------------------------
  1159. type(TLevelInfo), intent(in) :: levi
  1160. real, intent(in) :: sp(:,:) ! Pa
  1161. real, intent(out) :: ph(:,:,:) ! Pa
  1162. integer, intent(out) :: status
  1163. ! --- const --------------------------------------
  1164. character(len=*), parameter :: rname = mname//'/levi_HPressure_3d'
  1165. ! --- local ---------------------------------
  1166. integer :: i, j
  1167. ! --- begin ---------------------------------
  1168. if ( any( shape(ph) /= (/shape(sp),levi%nlev+1/) ) ) then
  1169. write (*,'("ERROR - shape of output grid does not match definition:")')
  1170. write (*,'("ERROR - sp shape : ",2i6)') shape(sp)
  1171. write (*,'("ERROR - half levels : ",i4)') levi%nlev+1
  1172. write (*,'("ERROR - ph shape : ",2i6,i4)') shape(ph)
  1173. TRACEBACK; status=1; return
  1174. end if
  1175. ! half level pressure
  1176. do i = 1, size(sp,1)
  1177. do j = 1, size(sp,2)
  1178. ph(i,j,:) = levi%a + levi%b * sp(i,j)
  1179. end do
  1180. end do
  1181. status = 0
  1182. end subroutine levi_HPressure_3d
  1183. ! ***
  1184. subroutine levi_FPressure_1d( levi, sp, pf, status )
  1185. ! --- in/out -------------------------------
  1186. type(TLevelInfo), intent(in) :: levi
  1187. real, intent(in) :: sp ! Pa
  1188. real, intent(out) :: pf(:) ! Pa
  1189. integer, intent(out) :: status
  1190. ! --- const --------------------------------------
  1191. character(len=*), parameter :: rname = mname//'/levi_FPressure_1d'
  1192. ! --- begin ---------------------------------
  1193. if ( size(pf) /= levi%nlev ) then
  1194. write(gol,'("ERROR - shape of output grid does not match definition:")'); call goErr
  1195. write(gol,'("ERROR - full levels : ",i4)') levi%nlev ; call goErr
  1196. write(gol,'("ERROR - pf shape : ",i4)') shape(pf) ; call goErr
  1197. TRACEBACK; status=1; return
  1198. end if
  1199. ! full level pressure
  1200. pf = levi%fa + levi%fb * sp
  1201. status = 0
  1202. end subroutine levi_FPressure_1d
  1203. ! *
  1204. subroutine levi_FPressure_2d( levi, sp, pf, status )
  1205. ! --- in/out -------------------------------
  1206. type(TLevelInfo), intent(in) :: levi
  1207. real, intent(in) :: sp(:) ! Pa
  1208. real, intent(out) :: pf(:,:) ! Pa
  1209. integer, intent(out) :: status
  1210. ! --- const --------------------------------------
  1211. character(len=*), parameter :: rname = mname//'/levi_FPressure_2d'
  1212. ! --- local ---------------------------------
  1213. integer :: i
  1214. ! --- begin ---------------------------------
  1215. if ( any( shape(pf) /= (/shape(sp),levi%nlev/) ) ) then
  1216. write(gol,'("ERROR - shape of output grid does not match definition:")'); call goErr
  1217. write(gol,'("ERROR - sp shape : ",i6)') shape(sp) ; call goErr
  1218. write(gol,'("ERROR - full levels : ",i4)') levi%nlev ; call goErr
  1219. write(gol,'("ERROR - pf shape : ",i6,i4)') shape(pf) ; call goErr
  1220. TRACEBACK; status=1; return
  1221. end if
  1222. ! full level pressure
  1223. do i = 1, size(sp)
  1224. pf(i,:) = levi%fa + levi%fb * sp(i)
  1225. end do
  1226. status = 0
  1227. end subroutine levi_FPressure_2d
  1228. ! *
  1229. subroutine levi_FPressure_3d( levi, sp, pf, status )
  1230. ! --- in/out -------------------------------
  1231. type(TLevelInfo), intent(in) :: levi
  1232. real, intent(in) :: sp(:,:) ! Pa
  1233. real, intent(out) :: pf(:,:,:) ! Pa
  1234. integer, intent(out) :: status
  1235. ! --- const --------------------------------------
  1236. character(len=*), parameter :: rname = mname//'/levi_FPressure_3d'
  1237. ! --- local ---------------------------------
  1238. integer :: i, j
  1239. ! --- begin ---------------------------------
  1240. if ( any( shape(pf) /= (/shape(sp),levi%nlev/) ) ) then
  1241. write(gol,'(" Shape of output grid does not match definition:")'); call goErr
  1242. write(gol,'(" sp shape : ",2i6)') shape(sp) ; call goErr
  1243. write(gol,'(" full levels : ",i4)') levi%nlev ; call goErr
  1244. write(gol,'(" pf shape : ",2i6,i4)') shape(pf) ; call goErr
  1245. TRACEBACK; status=1; return
  1246. end if
  1247. ! full level pressure
  1248. do i = 1, size(sp,1)
  1249. do j = 1, size(sp,2)
  1250. pf(i,j,:) = levi%fa + levi%fb * sp(i,j)
  1251. end do
  1252. end do
  1253. status = 0
  1254. end subroutine levi_FPressure_3d
  1255. ! =====================================================================
  1256. ! ===
  1257. ! === REMAPPING
  1258. ! ===
  1259. ! =====================================================================
  1260. !
  1261. ! Interpolate llX (defined on leviX) to ll (defined on levi).
  1262. !
  1263. ! How levels are combined/interpolated is specified by a key:
  1264. !
  1265. ! 'bottom' : use closest-to-the-ground neighbor
  1266. ! 'top' : use closest-to-the-model-top neighbor
  1267. ! 'sum' : sum input values (use for mass [extensive])
  1268. ! 'aver' : unweighted average across levels
  1269. ! 'mass-aver' : air-mass weighted average (use for mixing ratio [intensive])
  1270. !
  1271. ! Surface pressure field is used to compute mass in case of 'mass-aver' combination.
  1272. !
  1273. subroutine FillLevels_errmess(fillkey,nw,combine_key)
  1274. character(len=*), intent(in) :: fillkey
  1275. character(len=*), intent(in) :: nw
  1276. character(len=*), intent(in), optional :: combine_key
  1277. if (present(combine_key)) then
  1278. write (gol,'(" Combine key not supported:")') ; call goErr
  1279. write (gol,'(" combine key : ",a)') trim(combine_key) ; call goErr
  1280. write (gol,'(" fill key : ",a)') trim(fillkey) ; call goErr
  1281. write (gol,'(" nw key : ",a)') trim(nw) ; call goErr
  1282. end if
  1283. write (gol,'(" Fill key not supported:")') ; call goErr
  1284. write (gol,'(" fill key : ",a)') trim(fillkey) ; call goErr
  1285. write (gol,'(" nw key : ",a)') trim(nw) ; call goErr
  1286. end subroutine FillLevels_errmess
  1287. ! ***
  1288. subroutine levi_FillLevels_1d( levi, ps, ll, leviX, llX, combine_key, status )
  1289. ! --- in/out ----------------------------------
  1290. type(TLevelInfo), intent(in) :: levi
  1291. real, intent(in) :: ps ! Pa
  1292. real, intent(out) :: ll(:)
  1293. type(TLevelInfo), intent(in) :: leviX
  1294. real, intent(in) :: llX(:)
  1295. character(len=*), intent(in) :: combine_key
  1296. integer, intent(out) :: status
  1297. ! --- const --------------------------------------
  1298. character(len=*), parameter :: rname = mname//'/levi_FillLevels_1d'
  1299. ! --- local ------------------------------
  1300. integer :: verbose
  1301. character(len=10) :: fillkey
  1302. logical :: reverse
  1303. integer :: k, l
  1304. integer :: le, nle, le1, le2
  1305. real :: Xfp0, Xfp0_save
  1306. ! --- begin -------------------------------
  1307. ! correct number of levels ?
  1308. if ( size(ll) /= levi%nlev ) then
  1309. write(gol,'(" number of levels in output grid does not match definition:")') ; call goErr
  1310. write(gol,'(" ll levels : ",i3)') size(ll) ; call goErr
  1311. write(gol,'(" levi nlev : ",i3)') levi%nlev ; call goErr
  1312. write(gol,'(" **NOTE** NO HALF-LEVELS case in 1D vertical remap!")') ; call goErr
  1313. TRACEBACK; status=1; return
  1314. end if
  1315. ! necessary to combine or reverse ?
  1316. verbose = 1
  1317. call Compare( levi, leviX, verbose, fillkey, reverse, status )
  1318. IF_NOTOK_RETURN(status=1)
  1319. status = 1
  1320. select case ( fillkey )
  1321. case ( 'copy' )
  1322. do l = 1, levi%nlev
  1323. ! index of corresponding level in field 'llX' read from file:
  1324. k = l
  1325. if ( reverse ) k = levi%nlev + 1 - l
  1326. ! copy level:
  1327. ll(l) = llX(k)
  1328. end do
  1329. case ( 'combine' )
  1330. ll = 0.0
  1331. do l = 1, levi%nlev
  1332. ! loop over range of parent levels:
  1333. le1 = levi%flevs(l,1)
  1334. le2 = levi%flevs(l,2)
  1335. nle = le2 - le1 + 1
  1336. Xfp0_save = -1.0
  1337. do le = le1, le2
  1338. ! index of corresponding level in field 'llX' read from file:
  1339. k = le
  1340. if ( reverse ) k = levi%nlev_parent + 1 - le
  1341. ! standard pressure for level in llX :
  1342. Xfp0 = leviX%fp0(k)
  1343. ! based on combine key, add contribution of this level:
  1344. select case ( combine_key )
  1345. case ( 'sum' )
  1346. ll(l) = ll(l) + llX(k)
  1347. case ( 'aver' )
  1348. ll(l) = ll(l) + llX(k)/(nle*1.0)
  1349. case ( 'mass-aver' )
  1350. !
  1351. ! m = dp * A / g = |da+db*ps| * A/g
  1352. ! ( X1*mX1 + X2*mX2 + .. ) / m
  1353. ! ~ ( X1*|daX1+dbX1*ps| + X2*|daX2+dbX2*ps| + .. ) / |da+db*ps|
  1354. !
  1355. ll(l) = ll(l) + llX(k)*abs(leviX%da(k)+leviX%db(k)*ps) / &
  1356. abs( levi%da(l)+ levi%db(l)*ps)
  1357. case ( 'bottom' )
  1358. if ( (Xfp0_save < 0.0) .or. (Xfp0 >= Xfp0_save) ) then
  1359. ll(l) = llX(k)
  1360. Xfp0_save = Xfp0
  1361. end if
  1362. case ( 'top' )
  1363. if ( (Xfp0_save < 0.0) .or. (Xfp0 <= Xfp0_save) ) then
  1364. ll(l) = llX(k)
  1365. Xfp0_save = Xfp0
  1366. end if
  1367. case default
  1368. call FillLevels_errmess(fillkey,'n',combine_key)
  1369. IF_NOTOK_RETURN(status=1)
  1370. end select
  1371. end do
  1372. end do
  1373. case default
  1374. call FillLevels_errmess(fillkey,'n')
  1375. IF_NOTOK_RETURN(status=1)
  1376. end select
  1377. status = 0
  1378. end subroutine levi_FillLevels_1d
  1379. ! ***
  1380. subroutine levi_FillLevels_2d( levi, nw, ps, ll, &
  1381. leviX, llX, combine_key, status )
  1382. use Num, only : IntervalSum, Interp_Lin
  1383. ! --- in/out ----------------------------------
  1384. type(TLevelInfo), intent(in) :: levi
  1385. character(len=*), intent(in) :: nw
  1386. real, intent(in) :: ps(:) ! Pa
  1387. real, intent(out) :: ll(:,:)
  1388. type(TLevelInfo), intent(in) :: leviX
  1389. real, intent(in) :: llX(:,:)
  1390. character(len=*), intent(in) :: combine_key
  1391. integer, intent(out) :: status
  1392. ! --- const --------------------------------------
  1393. character(len=*), parameter :: rname = mname//'/levi_FillLevels_2d'
  1394. ! --- local ------------------------------
  1395. integer :: verbose
  1396. character(len=10) :: fillkey
  1397. logical :: reverse
  1398. integer :: j, k, l
  1399. integer :: le, nle, le1, le2
  1400. real :: Xfp0, Xfp0_save
  1401. real, allocatable :: phalf(:)
  1402. real, allocatable :: phalfX(:)
  1403. real, allocatable :: dpX(:)
  1404. real :: pfac
  1405. integer :: ilast
  1406. ! --- begin -------------------------------
  1407. ! correct number of levels ?
  1408. if ( ((nw == 'n') .and. (size(ll,2) /= levi%nlev )) .or. &
  1409. ((nw == 'w') .and. (size(ll,2) /= levi%nlev+1)) ) then
  1410. write (*,'("ERROR - number of levels in output grid does not match definition:")')
  1411. write (*,'("ERROR - levi nlev : ",i3)') levi%nlev
  1412. write (*,'("ERROR - nw : ",a )') nw
  1413. write (*,'("ERROR - ll levels : ",i3)') size(ll,2)
  1414. TRACEBACK; status=1; return
  1415. end if
  1416. ! correct number of levels ?
  1417. if ( ((nw == 'n') .and. (size(llX,2) /= leviX%nlev )) .or. &
  1418. ((nw == 'w') .and. (size(llX,2) /= leviX%nlev+1)) ) then
  1419. write (*,'("ERROR - number of levels in input grid does not match definition:")')
  1420. write (*,'("ERROR - leviX nlev : ",i3)') leviX%nlev
  1421. write (*,'("ERROR - nw : ",a )') nw
  1422. write (*,'("ERROR - llX levels : ",i3)') size(llX,2)
  1423. TRACEBACK; status=1; return
  1424. end if
  1425. ! same horizontal grid sizes of ll and llX ?
  1426. if ( (size(ll,1) /= size(llX,1)) ) then
  1427. write (*,'("ERROR - horizontal size does not match:")')
  1428. write (*,'("ERROR - ll : ",i3)') size(ll,1)
  1429. write (*,'("ERROR - llX : ",i3)') size(llX,1)
  1430. TRACEBACK; status=1; return
  1431. end if
  1432. ! necessary to combine or reverse ?
  1433. verbose = 0
  1434. call Compare( levi, leviX, verbose, fillkey, reverse, status )
  1435. IF_NOTOK_RETURN(status=1)
  1436. ! correct size of surface pressure field ?
  1437. if ( (combine_key == 'mass-aver') .or. (fillkey == 'interpol') ) then
  1438. if ( (size(ps) /= size(ll,1)) ) then
  1439. write (*,'("ERROR - horizontal sizes do not match:")')
  1440. write (*,'("ERROR - ps : ",i3)') size(ps)
  1441. write (*,'("ERROR - ll : ",i3)') size(ll,1)
  1442. write (*,'("ERROR - combine_key : ",a)') combine_key
  1443. write (*,'("ERROR - fillkey : ",a)') fillkey
  1444. write (*,'("ERROR - reverse : ",l1)') reverse
  1445. TRACEBACK; status=1; return
  1446. end if
  1447. end if
  1448. ! levels or half-levels ?
  1449. select case ( nw )
  1450. case ( 'n' )
  1451. !
  1452. ! === levels ===================================
  1453. !
  1454. select case ( fillkey )
  1455. case ( 'copy' )
  1456. if ( reverse ) then
  1457. do l = 1, levi%nlev
  1458. ! copy corresponding level in field 'llX' read from file:
  1459. ll(:,l) = llX(:,levi%nlev+1-l)
  1460. end do
  1461. else
  1462. ll = llX
  1463. end if
  1464. case ( 'combine' )
  1465. ll = 0.0
  1466. do l = 1, levi%nlev
  1467. ! loop over range of parent levels:
  1468. le1 = levi%flevs(l,1)
  1469. le2 = levi%flevs(l,2)
  1470. nle = le2 - le1 + 1
  1471. Xfp0_save = -1.0
  1472. do le = le1, le2
  1473. ! index of corresponding level in field 'llX' read from file:
  1474. k = le
  1475. if ( reverse ) k = levi%nlev_parent + 1 - le
  1476. ! standard pressure for level in llX :
  1477. Xfp0 = leviX%fp0(k)
  1478. ! based on combine key, add contribution of this level:
  1479. select case ( combine_key )
  1480. case ( 'sum' )
  1481. ll(:,l) = ll(:,l) + llX(:,k)
  1482. case ( 'aver' )
  1483. ll(:,l) = ll(:,l) + llX(:,k)/(nle*1.0)
  1484. case ( 'mass-aver' )
  1485. !
  1486. ! m = dp * A / g = |da+db*ps| * A/g
  1487. ! ( X1*mX1 + X2*mX2 + .. ) / m
  1488. ! ~ ( X1*|daX1+dbX1*ps| + X2*|daX2+dbX2*ps| + .. ) / |da+db*ps|
  1489. !
  1490. ll(:,l) = ll(:,l) + llX(:,k)*abs(leviX%da(k)+leviX%db(k)*ps) / &
  1491. abs( levi%da(l)+ levi%db(l)*ps)
  1492. case ( 'bottom' )
  1493. if ( (Xfp0_save < 0.0) .or. (Xfp0 >= Xfp0_save) ) then
  1494. ll(:,l) = llX(:,k)
  1495. Xfp0_save = Xfp0
  1496. end if
  1497. case ( 'top' )
  1498. if ( (Xfp0_save < 0.0) .or. (Xfp0 <= Xfp0_save) ) then
  1499. ll(:,l) = llX(:,k)
  1500. Xfp0_save = Xfp0
  1501. end if
  1502. case default
  1503. call FillLevels_errmess(fillkey,nw,combine_key)
  1504. TRACEBACK; status=1; return
  1505. end select
  1506. end do
  1507. end do
  1508. case ( 'interpol' )
  1509. allocate( phalf (0: levi%nlev) )
  1510. allocate( phalfX(0:leviX%nlev) )
  1511. allocate( dpX( leviX%nlev) )
  1512. ! phalfX should be increasing
  1513. pfac = 1.0
  1514. if ( leviX%updo == 'u' ) pfac = -1.0
  1515. select case ( combine_key )
  1516. case ( 'sum' )
  1517. do j = 1, size(ll,1)
  1518. phalf = levi%a + levi%b * ps(j) ! Pa
  1519. phalfX = leviX%a + leviX%b * ps(j) ! Pa
  1520. ilast = 1
  1521. do l = 1, levi%nlev
  1522. ! take partly sums of f(i)*m(i) within [phalf(l-1),phalf(l)]
  1523. ! NOTE: if phalf(l) < phalf(l-1), the result of IntervalSum is negative
  1524. call IntervalSum( phalfX*pfac, llX(j,:), &
  1525. phalf(l-1)*pfac, phalf(l)*pfac, &
  1526. ll(j,l), ilast, status )
  1527. if (status/=0) then;
  1528. write (*,'("ERROR - from IntervalSum (combine key `sum`)")')
  1529. write (*,'("ERROR - j : ",2i4 )') j
  1530. write (*,'("ERROR - ps : ", f16.4)') ps(j)
  1531. write (*,'("ERROR - leviX%a : ",es11.4)') leviX%a
  1532. write (*,'("ERROR - leviX%b : ",es11.4)') leviX%b
  1533. TRACEBACK; status=1; return
  1534. end if
  1535. ll(j,l) = ll(j,l) * sign(1.0,(phalf(l)-phalf(l-1))*pfac)
  1536. end do
  1537. end do
  1538. case ( 'mass-aver' )
  1539. do j = 1, size(ll,1)
  1540. phalf = levi%a + levi%b * ps(j) ! Pa
  1541. phalfX = leviX%a + leviX%b * ps(j) ! Pa
  1542. dpX = abs(leviX%da + leviX%db * ps(j)) ! Pa
  1543. ilast = 1
  1544. do l = 1, levi%nlev
  1545. ! take partly sums of f(i)*m(i) within [phalf(l-1),phalf(l)]
  1546. ! NOTE: if phalf(l) < phalf(l-1), the result of IntervalSum is negative
  1547. call IntervalSum( phalfX*pfac, llX(j,:)*dpX, &
  1548. phalf(l-1)*pfac, phalf(l)*pfac, &
  1549. ll(j,l), ilast, status )
  1550. IF_NOTOK_RETURN(status=1)
  1551. ll(j,l) = ll(j,l) / (phalf(l)-phalf(l-1))*pfac
  1552. end do
  1553. end do
  1554. case ( 'top' )
  1555. do j = 1, size(ll,1)
  1556. phalf = levi%a + levi%b * ps(j) ! Pa, 0..
  1557. phalfX = leviX%a + leviX%b * ps(j) ! Pa, 0..
  1558. do l = 1, levi%nlev
  1559. ! interpolate to top half level pressure:
  1560. call Interp_Lin( phalfX(1:leviX%nlev)*pfac, llX(j,:), &
  1561. phalf (l) *pfac, ll(j,l), ilast, status )
  1562. IF_NOTOK_RETURN(status=1)
  1563. end do
  1564. end do
  1565. case ( 'bottom' )
  1566. do j = 1, size(ll,1)
  1567. phalf = levi%a + levi%b * ps(j) ! Pa, 0..
  1568. phalfX = leviX%a + leviX%b * ps(j) ! Pa, 0..
  1569. do l = 1, levi%nlev
  1570. ! interpolate to bottom half level pressure:
  1571. call Interp_Lin( phalfX(0:leviX%nlev-1)*pfac, llX(j,:), &
  1572. phalf (l-1) *pfac, ll(j,l), ilast, status )
  1573. IF_NOTOK_RETURN(status=1)
  1574. end do
  1575. end do
  1576. case default
  1577. call FillLevels_errmess(fillkey,nw,combine_key)
  1578. TRACEBACK; status=1; return
  1579. end select
  1580. deallocate( phalf )
  1581. deallocate( phalfX )
  1582. deallocate( dpX )
  1583. case default
  1584. call FillLevels_errmess(fillkey,nw)
  1585. TRACEBACK; status=1; return
  1586. end select
  1587. case ( 'w' )
  1588. !
  1589. ! === half levels ========================================
  1590. !
  1591. select case ( fillkey )
  1592. case ( 'copy' )
  1593. if ( reverse ) then
  1594. do l = 1, levi%nlev+1
  1595. ll(:,l) = llX(:,levi%nlev+2-l)
  1596. end do
  1597. else
  1598. ll = llX
  1599. end if
  1600. case ( 'combine' )
  1601. ll = 0.0
  1602. do l = 0, levi%nlev
  1603. ! note: k=0,..,nlev
  1604. k = levi%hlevs(l)
  1605. if ( reverse ) k = levi%nlev_parent - k
  1606. ! copy:
  1607. ll(:,l+1) = llX(:,k+1)
  1608. end do
  1609. case ( 'interpol' )
  1610. allocate( phalf (0: levi%nlev) )
  1611. allocate( phalfX(0:leviX%nlev) )
  1612. allocate( dpX( leviX%nlev) )
  1613. ! phalfX should be increasing
  1614. pfac = 1.0
  1615. if ( leviX%updo == 'u' ) pfac = -1.0
  1616. select case ( combine_key )
  1617. case ( 'top', 'bottom' )
  1618. do j = 1, size(ll,1)
  1619. phalf = levi%a + levi%b * ps(j) ! Pa
  1620. phalfX = leviX%a + leviX%b * ps(j) ! Pa
  1621. do l = 0, levi%nlev
  1622. ! interpolate to half level pressure:
  1623. call Interp_Lin( phalfX *pfac, llX(j,: ), &
  1624. phalf (l)*pfac, ll(j,l+1), ilast, status )
  1625. IF_NOTOK_RETURN(status=1)
  1626. end do
  1627. end do
  1628. case default
  1629. call FillLevels_errmess(fillkey,nw,combine_key)
  1630. TRACEBACK; status=1; return
  1631. end select
  1632. deallocate( phalf )
  1633. deallocate( phalfX )
  1634. deallocate( dpX )
  1635. case default
  1636. call FillLevels_errmess(fillkey,nw)
  1637. TRACEBACK; status=1; return
  1638. end select
  1639. case default
  1640. write (*,'("ERROR - nw key `",a,"` not supported.")') trim(nw)
  1641. TRACEBACK; status=1; return
  1642. end select
  1643. status = 0
  1644. end subroutine levi_FillLevels_2d
  1645. ! ***
  1646. subroutine levi_FillLevels_3d( levi, nw, ps, ll, &
  1647. leviX, llX, combine_key, status )
  1648. use Num, only : IntervalSum, Interp_Lin
  1649. ! --- in/out ----------------------------------
  1650. type(TLevelInfo), intent(in) :: levi
  1651. character(len=*), intent(in) :: nw
  1652. real, intent(in) :: ps(:,:) ! Pa
  1653. real, intent(out) :: ll(:,:,:)
  1654. type(TLevelInfo), intent(in) :: leviX
  1655. real, intent(in) :: llX(:,:,:)
  1656. character(len=*), intent(in) :: combine_key
  1657. integer, intent(out) :: status
  1658. ! --- const --------------------------------------
  1659. character(len=*), parameter :: rname = mname//'/levi_FillLevels_3d'
  1660. ! --- local ------------------------------
  1661. integer :: verbose
  1662. character(len=10) :: fillkey
  1663. logical :: reverse
  1664. integer :: i, j, k, l
  1665. integer :: le, nle, le1, le2
  1666. real :: Xfp0, Xfp0_save
  1667. real, allocatable :: phalf(:)
  1668. real, allocatable :: phalfX(:)
  1669. real, allocatable :: dpX(:)
  1670. real :: pfac
  1671. integer :: ilast
  1672. ! --- begin -------------------------------
  1673. ! correct number of levels OUT?
  1674. if ( ((nw == 'n') .and. (size(ll,3) /= levi%nlev )) .or. &
  1675. ((nw == 'w') .and. (size(ll,3) /= levi%nlev+1)) ) then
  1676. write(gol,'(" number of levels in output grid does not match definition:")') ; call goErr
  1677. write(gol,'(" levi nlev : ",i3)') levi%nlev ; call goErr
  1678. write(gol,'(" nw : ",a )') nw ; call goErr
  1679. write(gol,'(" ll levels : ",i3)') size(ll,3) ; call goErr
  1680. TRACEBACK; status=1; return
  1681. end if
  1682. ! correct number of levels IN?
  1683. if ( ((nw == 'n') .and. (size(llX,3) /= leviX%nlev )) .or. &
  1684. ((nw == 'w') .and. (size(llX,3) /= leviX%nlev+1)) ) then
  1685. write(gol,'(" number of levels in input grid does not match definition:")') ; call goErr
  1686. write(gol,'(" leviX nlev : ",i3)') leviX%nlev ; call goErr
  1687. write(gol,'(" nw : ",a )') nw ; call goErr
  1688. write(gol,'(" llX levels : ",i3)') size(llX,3) ; call goErr
  1689. TRACEBACK; status=1; return
  1690. end if
  1691. ! same horizontal grid sizes of ll and llX ?
  1692. if ( (size(ll,1) /= size(llX,1)) .or. (size(ll,2) /= size(llX,2)) ) then
  1693. write(gol,'(" horizontal sizes do not match:")') ; call goErr
  1694. write(gol,'(" ll : ",i3," x ",i3)') size(ll,1), size(ll,2) ; call goErr
  1695. write(gol,'(" llX : ",i3," x ",i3)') size(llX,1), size(llX,2); call goErr
  1696. TRACEBACK; status=1; return
  1697. end if
  1698. ! necessary to combine or reverse ?
  1699. verbose = 0
  1700. call Compare( levi, leviX, verbose, fillkey, reverse, status )
  1701. IF_NOTOK_RETURN(status=1)
  1702. ! correct size of surface pressure field ?
  1703. if ( (combine_key == 'mass-aver') .or. (fillkey == 'interpol') ) then
  1704. if ( (size(ps,1) /= size(ll,1)) .or. (size(ps,2) /= size(ll,2)) ) then
  1705. write(gol,'(" horizontal sizes do not match:")') ; call goErr
  1706. write(gol,'(" ps : ",i3," x ",i3)') size(ps ,1), size(ps ,2) ; call goErr
  1707. write(gol,'(" ll : ",i3," x ",i3)') size(ll ,1), size(ll ,2) ; call goErr
  1708. write(gol,'(" combine_key : ",a)') combine_key ; call goErr
  1709. write(gol,'(" fillkey : ",a)') fillkey ; call goErr
  1710. write(gol,'(" reverse : ",l1)') reverse ; call goErr
  1711. TRACEBACK; status=1; return
  1712. end if
  1713. end if
  1714. select case ( nw )
  1715. case ( 'n' )
  1716. !
  1717. ! === full levels ===================================
  1718. !
  1719. select case ( fillkey )
  1720. case ( 'copy' )
  1721. if ( reverse ) then
  1722. do l = 1, levi%nlev
  1723. ll(:,:,l) = llX(:,:,levi%nlev+1-l)
  1724. end do
  1725. else
  1726. ll = llX
  1727. end if
  1728. case ( 'combine' )
  1729. ll = 0.0
  1730. do l = 1, levi%nlev
  1731. ! loop over range of parent levels:
  1732. le1 = levi%flevs(l,1)
  1733. le2 = levi%flevs(l,2)
  1734. nle = le2 - le1 + 1
  1735. Xfp0_save = -1.0
  1736. do le = le1, le2
  1737. ! index of corresponding level in field 'llX' read from file:
  1738. k = le
  1739. if ( reverse ) k = levi%nlev_parent + 1 - le
  1740. ! standard pressure for level in llX :
  1741. Xfp0 = leviX%fp0(k)
  1742. ! based on combine key, add contribution of this level:
  1743. select case ( combine_key )
  1744. case ( 'sum' )
  1745. ll(:,:,l) = ll(:,:,l) + llX(:,:,k)
  1746. case ( 'aver' )
  1747. ll(:,:,l) = ll(:,:,l) + llX(:,:,k)/(nle*1.0)
  1748. case ( 'mass-aver', 'height-ave')
  1749. !
  1750. ! m = dp * A / g = |da+db*ps| * A/g
  1751. ! ( X1*mX1 + X2*mX2 + .. ) / m
  1752. ! ~ ( X1*|daX1+dbX1*ps| + X2*|daX2+dbX2*ps| + .. ) / |da+db*ps|
  1753. !
  1754. ll(:,:,l) = ll(:,:,l) + llX(:,:,k)*abs(leviX%da(k)+leviX%db(k)*ps) / &
  1755. abs( levi%da(l)+ levi%db(l)*ps)
  1756. case ( 'bottom' )
  1757. if ( (Xfp0_save < 0.0) .or. (Xfp0 >= Xfp0_save) ) then
  1758. ll(:,:,l) = llX(:,:,k)
  1759. Xfp0_save = Xfp0
  1760. end if
  1761. case ( 'top' )
  1762. if ( (Xfp0_save < 0.0) .or. (Xfp0 <= Xfp0_save) ) then
  1763. ll(:,:,l) = llX(:,:,k)
  1764. Xfp0_save = Xfp0
  1765. end if
  1766. case default
  1767. call FillLevels_errmess(fillkey,nw,combine_key)
  1768. TRACEBACK; status=1; return
  1769. end select
  1770. end do
  1771. end do
  1772. case ( 'interpol' )
  1773. allocate( phalf (0: levi%nlev) )
  1774. allocate( phalfX(0:leviX%nlev) )
  1775. allocate( dpX( leviX%nlev) )
  1776. ! phalfX should be increasing
  1777. pfac = 1.0
  1778. if ( leviX%updo == 'u' ) pfac = -1.0
  1779. select case ( combine_key )
  1780. case ( 'sum' )
  1781. do j = 1, size(ll,2)
  1782. do i = 1, size(ll,1)
  1783. phalf = levi%a + levi%b * ps(i,j) ! Pa
  1784. phalfX = leviX%a + leviX%b * ps(i,j) ! Pa
  1785. ilast = 1
  1786. do l = 1, levi%nlev
  1787. ! take partly sums of f(i)*m(i) within [phalf(l-1),phalf(l)]
  1788. ! NOTE: if phalf(l) < phalf(l-1), the result of IntervalSum is negative
  1789. call IntervalSum( phalfX*pfac, llX(i,j,:), &
  1790. phalf(l-1)*pfac, phalf(l)*pfac, &
  1791. ll(i,j,l), ilast, status )
  1792. if (status/=0) then;
  1793. write(gol,'(" from IntervalSum (combine key `sum`)")') ; call goErr
  1794. write(gol,'(" i, j : ",2i4 )') i, j ; call goErr
  1795. write(gol,'(" ps : ", f16.4)') ps(i,j) ; call goErr
  1796. write(gol,'(" leviX%a : ",es11.4)') leviX%a ; call goErr
  1797. write(gol,'(" leviX%b : ",es11.4)') leviX%b ; call goErr
  1798. TRACEBACK; status=1; return
  1799. end if
  1800. ll(i,j,l) = ll(i,j,l) * sign(1.0,(phalf(l)-phalf(l-1))*pfac)
  1801. end do
  1802. end do
  1803. end do
  1804. case ( 'mass-aver', 'height-ave' )
  1805. do j = 1, size(ll,2)
  1806. do i = 1, size(ll,1)
  1807. phalf = levi%a + levi%b * ps(i,j) ! Pa
  1808. phalfX = leviX%a + leviX%b * ps(i,j) ! Pa
  1809. dpX = abs(leviX%da + leviX%db * ps(i,j)) ! Pa
  1810. ilast = 1
  1811. do l = 1, levi%nlev
  1812. ! take partly sums of f(i)*m(i) within [phalf(l-1),phalf(l)]
  1813. ! NOTE: if phalf(l) < phalf(l-1), the result of IntervalSum is negative
  1814. call IntervalSum( phalfX*pfac, llX(i,j,:)*dpX, &
  1815. phalf(l-1)*pfac, phalf(l)*pfac, &
  1816. ll(i,j,l), ilast, status )
  1817. IF_NOTOK_RETURN(status=1)
  1818. ll(i,j,l) = ll(i,j,l) / (phalf(l)-phalf(l-1))*pfac
  1819. end do
  1820. end do
  1821. end do
  1822. case ( 'top' )
  1823. do j = 1, size(ll,2)
  1824. do i = 1, size(ll,1)
  1825. phalf = levi%a + levi%b * ps(i,j) ! Pa, 0..
  1826. phalfX = leviX%a + leviX%b * ps(i,j) ! Pa, 0..
  1827. do l = 1, levi%nlev
  1828. ! interpolate to top half level pressure:
  1829. call Interp_Lin( phalfX(1:leviX%nlev)*pfac, llX(i,j,:), &
  1830. phalf (l) *pfac, ll(i,j,l), ilast, status )
  1831. IF_NOTOK_RETURN(status=1)
  1832. end do
  1833. end do
  1834. end do
  1835. case ( 'bottom' )
  1836. do j = 1, size(ll,2)
  1837. do i = 1, size(ll,1)
  1838. phalf = levi%a + levi%b * ps(i,j) ! Pa, 0..
  1839. phalfX = leviX%a + leviX%b * ps(i,j) ! Pa, 0..
  1840. do l = 1, levi%nlev
  1841. ! interpolate to bottom half level pressure:
  1842. call Interp_Lin( phalfX(0:leviX%nlev-1)*pfac, llX(i,j,:), &
  1843. phalf (l-1) *pfac, ll(i,j,l), ilast, status )
  1844. IF_NOTOK_RETURN(status=1)
  1845. end do
  1846. end do
  1847. end do
  1848. case default
  1849. call FillLevels_errmess(fillkey,nw,combine_key)
  1850. TRACEBACK; status=1; return
  1851. end select
  1852. deallocate( phalf )
  1853. deallocate( phalfX )
  1854. deallocate( dpX )
  1855. case default
  1856. call FillLevels_errmess(fillkey,nw)
  1857. TRACEBACK; status=1; return
  1858. end select
  1859. case ( 'w' )
  1860. !
  1861. ! === half levels ========================================
  1862. !
  1863. select case ( fillkey )
  1864. case ( 'copy' )
  1865. if ( reverse ) then
  1866. do l = 1, levi%nlev+1
  1867. ! copy corresponding level in field 'llX' read from file:
  1868. ll(:,:,l) = llX(:,:,levi%nlev+2-l)
  1869. end do
  1870. else
  1871. ll = llX
  1872. end if
  1873. case ( 'combine' )
  1874. ll = 0.0
  1875. do l = 0, levi%nlev
  1876. ! index of corresponding level in field 'llX' read from file:
  1877. ! note: k=0,..,nlev
  1878. k = levi%hlevs(l)
  1879. if ( reverse ) k = levi%nlev_parent - k
  1880. ! copy:
  1881. ll(:,:,l+1) = llX(:,:,k+1)
  1882. end do
  1883. case ( 'interpol' )
  1884. allocate( phalf (0: levi%nlev) )
  1885. allocate( phalfX(0:leviX%nlev) )
  1886. allocate( dpX( leviX%nlev) )
  1887. ! phalfX should be increasing
  1888. pfac = 1.0
  1889. if ( leviX%updo == 'u' ) pfac = -1.0
  1890. select case ( combine_key )
  1891. case ( 'top', 'bottom' )
  1892. do j = 1, size(ll,2)
  1893. do i = 1, size(ll,1)
  1894. phalf = levi%a + levi%b * ps(i,j) ! Pa
  1895. phalfX = leviX%a + leviX%b * ps(i,j) ! Pa
  1896. do l = 0, levi%nlev
  1897. ! interpolate to half level pressure:
  1898. call Interp_Lin( phalfX *pfac, llX(i,j,: ), &
  1899. phalf (l)*pfac, ll(i,j,l+1), ilast, status )
  1900. IF_NOTOK_RETURN(status=1)
  1901. end do
  1902. end do
  1903. end do
  1904. case default
  1905. call FillLevels_errmess(fillkey,nw,combine_key)
  1906. TRACEBACK; status=1; return
  1907. end select
  1908. deallocate( phalf )
  1909. deallocate( phalfX )
  1910. deallocate( dpX )
  1911. case default
  1912. call FillLevels_errmess(fillkey,nw)
  1913. TRACEBACK; status=1; return
  1914. end select
  1915. case default
  1916. write (*,'("ERROR - nw key `",a,"` not supported.")') trim(nw)
  1917. TRACEBACK; status=1; return
  1918. end select
  1919. status = 0
  1920. end subroutine levi_FillLevels_3d
  1921. !--------------------------------------------------------------------------
  1922. ! TM5 !
  1923. !--------------------------------------------------------------------------
  1924. !BOP
  1925. !
  1926. ! !IROUTINE: LEVI_FILLPARENT_3D
  1927. !
  1928. ! !DESCRIPTION: remap one array into another one, their 3rd dimension being
  1929. ! along either LevInfo levels or its parent levels.
  1930. !\\
  1931. !\\
  1932. ! !INTERFACE:
  1933. !
  1934. subroutine levi_FillParent_3d( levi, nw, ArrIn, combine_key, ArrOut, status, ps)
  1935. !
  1936. ! !INPUT PARAMETERS:
  1937. !
  1938. type(TLevelInfo), intent(in) :: levi
  1939. character(len=*), intent(in) :: nw
  1940. real, intent(in) :: ArrIn(:,:,:)
  1941. character(len=*), intent(in) :: combine_key
  1942. !
  1943. real, optional, intent(in) :: ps(:,:) ! Pa
  1944. !
  1945. ! !OUTPUT PARAMETERS:
  1946. !
  1947. real, intent(out) :: ArrOut(:,:,:)
  1948. integer, intent(out) :: status
  1949. !
  1950. ! !REMARKS:
  1951. ! (1) developed to account for child-to-parent cases, which were handled always as 'interpol' in FillLevels.
  1952. ! (2) by design, we are always in 'combine' filling mode. No 'interpolation' or 'copy'. No need to call levi_compare.
  1953. ! (3) Arrays follow the order ('u' or 'd') of the levels they are attached to.
  1954. !
  1955. !EOP
  1956. !------------------------------------------------------------------------
  1957. !BOC
  1958. character(len=*), parameter :: rname = mname//'/levi_FillParent_3d'
  1959. logical :: reverse, to_parent, to_child
  1960. integer :: i, j, k, l
  1961. integer :: le, nle, le1, le2
  1962. real :: Xfp0, Xfp0_save
  1963. real, allocatable :: phalf(:)
  1964. real, allocatable :: phalfX(:)
  1965. real, allocatable :: dpX(:)
  1966. real :: pfac
  1967. integer :: ilast
  1968. ! --- begin -------------------------------
  1969. if (.not.levi%selection) then
  1970. write(gol,*) "Cannot use FillLevelsParents: no parent available in levI"; call goErr
  1971. TRACEBACK; status=1; return
  1972. endif
  1973. select case ( nw )
  1974. case ('n')
  1975. to_parent = (size(ArrOut,3) == levi%nlev_parent).and.(size(ArrIn,3) == levi%nlev )
  1976. to_child = (size(ArrOut,3) == levi%nlev) .and.(size(ArrIn,3) == levi%nlev_parent)
  1977. case ('w')
  1978. write(gol,*) "FillLevelsParents: not implemented yet for half-levels"; call goErr
  1979. TRACEBACK; status=1; return
  1980. case default
  1981. write(gol,*) "FillLevelsParents: input nw must be 'n' and not "//trim(nw); call goErr
  1982. TRACEBACK; status=1; return
  1983. end select
  1984. if (.not.(to_parent.or.to_child)) then
  1985. write(gol,*) "Cannot use FillLevelsParents: array sizes do not match number of levels"; call goErr
  1986. write(gol,'(" ArrOut nlevels: ",i3)') size(ArrOut,3) ; call goErr
  1987. write(gol,'(" ArrIn nlevels: ",i3)') size(ArrIn,3) ; call goErr
  1988. write(gol,'(" child nlevels: ",i3)') levi%nlev ; call goErr
  1989. write(gol,'(" parent nlevels: ",i3)') levi%nlev_parent ; call goErr
  1990. TRACEBACK; status=1; return
  1991. endif
  1992. ! same horizontal grid sizes of ArrOut and ArrIn ?
  1993. if ( (size(ArrOut,1) /= size(ArrIn,1)) .or. (size(ArrOut,2) /= size(ArrIn,2)) ) then
  1994. write(gol,'(" Horizontal sizes do not match:")') ; call goErr
  1995. write(gol,'(" ArrOut : ",i3," x ",i3)') size(ArrOut,1), size(ArrOut,2) ; call goErr
  1996. write(gol,'(" ArrIn : ",i3," x ",i3)') size(ArrIn,1), size(ArrIn,2) ; call goErr
  1997. TRACEBACK; status=1; return
  1998. end if
  1999. ! check cases when surface pressure needed
  2000. if ( ((combine_key == 'mass-aver') .and. to_child ) .or. &
  2001. ((combine_key == 'sum') .and. to_parent ) ) then
  2002. if (.not. present(ps)) then
  2003. write(gol,*)" surface pressure required"; call goErr
  2004. TRACEBACK; status=1; return
  2005. endif
  2006. if ( (size(ps,1) /= size(ArrOut,1)) .or. (size(ps,2) /= size(ArrOut,2)) ) then
  2007. write(gol,'(" Horizontal sizes do not match:")') ; call goErr
  2008. write(gol,'(" ps : ",i3," x ",i3)') size(ps ,1), size(ps ,2) ; call goErr
  2009. write(gol,'(" ArrOut : ",i3," x ",i3)') size(ArrOut ,1), size(ArrOut ,2) ; call goErr
  2010. TRACEBACK; status=1; return
  2011. end if
  2012. end if
  2013. ! reverse = levi%updo /= levi%updo_parent ! NOT USED YET
  2014. ArrOut = 0.
  2015. select case ( nw )
  2016. case ( 'n' )
  2017. !
  2018. ! === full levels ===================================
  2019. !
  2020. select case ( combine_key )
  2021. case ( 'mass-aver' ) ! Intensive w/r/t pressure/air_mass (eg, mass-mixing-ratio)
  2022. if(to_parent) then
  2023. do l = 1, levi%nlev
  2024. le1 = levi%flevs(l,1)
  2025. le2 = levi%flevs(l,2)
  2026. do le = le1, le2
  2027. ArrOut(:,:,le)=ArrIn(:,:,l)
  2028. enddo
  2029. enddo
  2030. else if(to_child) then ! same as combine/mass-aver from FillLevels
  2031. do l = 1, levi%nlev
  2032. le1 = levi%flevs(l,1)
  2033. le2 = levi%flevs(l,2)
  2034. do le = le1, le2
  2035. ArrOut(:,:,l) = ArrOut(:,:,l) + ArrIn(:,:,le)*abs(levi%da_parent(le)+levi%db_parent(le)*ps)
  2036. enddo
  2037. ArrOut(:,:,l) = ArrOut(:,:,l) / abs( levi%da(l)+ levi%db(l)*ps )
  2038. enddo
  2039. endif
  2040. case ( 'sum' ) ! Extensive (eg, mass)
  2041. if(to_parent) then
  2042. do l = 1, levi%nlev
  2043. le1 = levi%flevs(l,1)
  2044. le2 = levi%flevs(l,2)
  2045. do le = le1, le2
  2046. ArrOut(:,:,le) = ArrIn(:,:,l)*abs(levi%da_parent(le)+levi%db_parent(le)*ps) / &
  2047. abs( levi%da(l)+ levi%db(l)*ps )
  2048. enddo
  2049. enddo
  2050. else if(to_child) then ! same as combine/sum from FillLevels
  2051. do l = 1, levi%nlev
  2052. le1 = levi%flevs(l,1)
  2053. le2 = levi%flevs(l,2)
  2054. ArrOut(:,:,l) = sum(ArrIn(:,:,le1:le2),dim=3)
  2055. enddo
  2056. endif
  2057. case ( 'aver' ) ! Nominal (dimensionless, eg, level number)
  2058. if(to_parent) then
  2059. do l = 1, levi%nlev
  2060. le1 = levi%flevs(l,1)
  2061. le2 = levi%flevs(l,2)
  2062. do le = le1, le2
  2063. ArrOut(:,:,le)=ArrIn(:,:,l)
  2064. enddo
  2065. enddo
  2066. else if(to_child) then ! same as combine/aver from FillLevels
  2067. do l = 1, levi%nlev
  2068. le1 = levi%flevs(l,1)
  2069. le2 = levi%flevs(l,2)
  2070. ArrOut(:,:,l) = sum(ArrIn(:,:,le1:le2),dim=3)/((le2 - le1 + 1)*1.0)
  2071. enddo
  2072. endif
  2073. case ( 'height-ave') ! Intensive w/r/t height
  2074. if(to_parent) then
  2075. do l = 1, levi%nlev
  2076. le1 = levi%flevs(l,1)
  2077. le2 = levi%flevs(l,2)
  2078. do le = le1, le2
  2079. ArrOut(:,:,le)=ArrIn(:,:,l)
  2080. enddo
  2081. enddo
  2082. else if(to_child) then
  2083. ! Layer Height is available from gph for child levels only. See compute_gph and phys_gph.F90.
  2084. ! FIXME - dH (delta Height on the parent grid is not known. Requires temperature and humidity.
  2085. ! do l = 1, levi%nlev
  2086. ! le1 = levi%flevs(l,1)
  2087. ! le2 = levi%flevs(l,2)
  2088. ! do le = le1, le2
  2089. ! ArrOut(:,:,l)=ArrOut(:,:,l)+ArrIn(:,:,le)*dH(le)
  2090. ! enddo
  2091. ! ArrOut(:,:,l) = ArrOut(:,:,l) / ( gph(:,:,l+1)-gph(:,:,l) )
  2092. ! enddo
  2093. call FillLevels_errmess('combine',nw,combine_key)
  2094. TRACEBACK; status=1; return
  2095. end if
  2096. case default
  2097. call FillLevels_errmess('combine',nw,combine_key)
  2098. TRACEBACK; status=1; return
  2099. end select
  2100. ! case ( 'w' )
  2101. ! !
  2102. ! ! === half levels ========================================
  2103. ! !
  2104. case default
  2105. write(gol,'(" nw key `",a,"` not supported.")') trim(nw) ; call goErr
  2106. TRACEBACK; status=1; return
  2107. end select
  2108. status = 0
  2109. END SUBROUTINE LEVI_FILLPARENT_3D
  2110. !EOC
  2111. END MODULE GRID_TYPE_HYB