tmm.F90 167 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163
  1. !###############################################################################
  2. !
  3. !ProTeX: 1.14-AJS
  4. !
  5. !BOI
  6. !
  7. ! !TITLE: TMM - TM Meteo
  8. ! !AUTHORS: Arjo Segers
  9. ! !AFFILIATION: KNMI
  10. ! !DATE: 21/04/2004
  11. !
  12. ! !INTRODUCTION: Introduction
  13. !
  14. ! Module to access TM meteo.
  15. !
  16. ! The main structure provides access to a list of opened meteo files.
  17. ! If a new meteo field is required, the subroutines search in the
  18. ! list wether the field is available.
  19. ! If not, a new file is opened and added to the list.
  20. ! Optionally, a shell script is invoked to search for a file
  21. ! and to store it locally if necessary.
  22. !
  23. !
  24. ! !INTRODUCTION: Usage
  25. !
  26. ! \bv
  27. !
  28. ! ! --- modules -----------------------------------------
  29. !
  30. ! use GO, only : TDate, NewDate
  31. !
  32. ! use grid, only : TllGridInfo, Init, Done
  33. ! use grid, only : TLevelInfo, Init, Done
  34. !
  35. ! use TMM, only : TTmMeteo
  36. ! use TMM, only : Init, Done
  37. ! use TMM, only : ReadField, ReadUVSP
  38. !
  39. ! ! --- local -----------------------------------------
  40. !
  41. ! type(TllGridInfo) :: lli
  42. ! type(TLevelInfo) :: levi_ec, levi
  43. !
  44. ! type(TTmMeteo) :: tmmd
  45. !
  46. ! type(TDate) :: tday, t1, t2
  47. !
  48. ! real :: psurf(120,90)
  49. ! real :: temper(120,90,25)
  50. ! real :: pu(0:120,90,25)
  51. !
  52. ! ! --- begin -----------------------------------------
  53. !
  54. ! ! define horizontal grid
  55. ! call Init( lli, -178.5, 3.0, 120, -89.0, 2.0, 90, status )
  56. !
  57. ! ! define vertical hybride levels
  58. ! call Init( levi_ec, 'ec60', status ) ! ecmwf levels
  59. ! call Init( levi, levi_ec, (/60,..,0/), status ) ! tm half level selection
  60. !
  61. ! ! setup TM meteo access:
  62. ! call Init( tmmd, 'tm5.rc', status )
  63. !
  64. ! ! define time range for field:
  65. ! tday = NewDate( year=2003, month=01, day=01 )
  66. ! t1 = NewDate( year=2002, month=12, day=31, hour=21 )
  67. ! t2 = NewDate( year=2003, month=01, day=01, hour=03 )
  68. !
  69. ! ! Read meteo arrays; specify grid, parameter, time, etc.
  70. ! !
  71. ! ! Type of grid is defined by nuv key:
  72. ! ! 'n' = normal grid (cell centers)
  73. ! ! 'u' = u-grid (east/west boundaries)
  74. ! ! 'v' = v-grid (north/south boundaries)
  75. ! !
  76. ! ! Requested grid (lli/levi) might be different from the grid in the file.
  77. ! ! Horizontal:
  78. ! ! o if file contains same resolutions as defined by lli,
  79. ! ! a part of the data in the file is selected;
  80. ! ! o if file contains higher resolution fields,
  81. ! ! the ll array is filled with combined values from the file;
  82. ! ! depending on the parameter, the result is summed/avaraged/etc.
  83. ! ! Vertical:
  84. ! ! o if a file contains a supperset of the levels in levi,
  85. ! ! some levels are combined;
  86. ! ! depending on the parameter, the result is summed/avaraged/etc;
  87. ! ! o the file might contain fields with reversed level order.
  88. ! !
  89. ! ! 3D fields require surface pressure for the level definition.
  90. ! ! It should be valid for [t1,t2] !
  91. ! ! Best is to use the spm from ReadUVSP.
  92. !
  93. ! call ReadUVSP ( tmmd, 'tmpp:od-fc-ml60-glb3x2', tday, t1, t2, lli, levi, sp1, spm, sp2, pu, pv, status )
  94. !
  95. ! call ReadField( tmmd, 'tmpp:od-fc-ml60-glb3x2', 'T' , tday, t1, t2, lli, 'n', levi, spm, temper, status )
  96. ! call ReadField( tmmd, 'tmpp:od-fc-ml60-glb3x2', 'pu', tday, t1, t2, lli, 'u', levi, spm, pu , status )
  97. !
  98. ! !
  99. ! ! TMPP surface fields can be called using the 1x1 as well as the 3x2 key.
  100. ! !
  101. ! call ReadField( tmmd, 'tmpp:od-fc-sfc-glb1x1' , 'ci', tday, t1, t2, lli, 'n', ci, status )
  102. ! call ReadField( tmmd, 'tmpp:od-fc-ml60-glb3x2', 'ci', tday, t1, t2, lli, 'n', ci, status )
  103. ! !
  104. ! ! Similar for spm surface pressures:
  105. ! !
  106. ! call ReadField( tmmd, 'tmpp:od-fc-ml1-glb3x2' , 'spm', tday, t1, t1, lli, 'n', spm, status )
  107. ! call ReadField( tmmd, 'tmpp:od-fc-ml60-glb3x2', 'spm', tday, t1, t1, lli, 'n', spm, status )
  108. !
  109. !
  110. ! ! *** output
  111. !
  112. ! call WriteField( tmmd, 'tmpp:od-fc-ml60-glb3x2', 'T', 'K', t1, t2, &
  113. ! lli, 'n', levi, spm, temper, status )
  114. !
  115. ! ! *** finish
  116. !
  117. ! call Done( tmmd, status )
  118. ! call Done( levi, status )
  119. ! call Done( levi_ec, status )
  120. ! call Done( lli )
  121. !
  122. ! ! -- end
  123. !
  124. ! \ev
  125. !
  126. !
  127. ! !INTRODUCTION: Rcfile
  128. !
  129. ! \bv
  130. !
  131. ! !
  132. ! ! Meteo files are linked to or unpacked in a buffer directory.
  133. ! ! o Set the clean flag (T|F) such that files that have not been accessed
  134. ! ! for a long time are removed if a maximum buffer usage is exceeded.
  135. ! ! o specify a maximum size in Mb
  136. ! !
  137. ! tmm.dir : ${RUNDIR}/tmm-buf
  138. ! tmm.dir.clean : T
  139. ! tmm.dir.size : 500
  140. !
  141. ! !
  142. ! ! TMM requires keys on how to form meteo for a certain region.
  143. ! ! A key should be defined for each region, names are in 'dims_grid.F90'
  144. ! ! For example:
  145. ! !
  146. ! ! tmpp:od-fc-ml60-glb3x2
  147. ! ! Read global 3x2, 60 level files produced by TMPP.
  148. ! ! Optionally, the meteo is combined over levels or grid cells.
  149. ! ! The files are expected to be present in the buffer directory
  150. ! ! specified below after 'tmm.buf.dir' .
  151. ! ! To have the appropriate files installed at the begin of a run,
  152. ! ! use the 'tmm.setup.*' stuff below.
  153. ! !
  154. ! ! tmppS:od-fc-ml60-glb3x2
  155. ! ! Idem, but also calls a script to search for an appropriate file
  156. ! ! from within the fortran program.
  157. ! ! The system call to this script turned out to be rather slow.
  158. ! ! This source type should be avoided therefore, but might be
  159. ! ! very usefull in case of limitted disk space.
  160. ! !
  161. ! ! prism:
  162. ! ! Receive meteo from the prism coupler.
  163. ! !
  164. ! tmm.sourcekey.glb6x4 : tmpp:od-fc-ml60-glb3x2
  165. ! tmm.sourcekey.eur3x2 : tmpp:od-fc-ml60-glb3x2
  166. ! tmm.sourcekey.eur1x1 : tmpp:od-fc-tropo25-eur1x1
  167. !
  168. ! !
  169. ! ! Meteo files could be setup before the actual program is started.
  170. ! ! Fill the following settings:
  171. ! ! o set the apply flag apply this feature or not (T|F)
  172. ! ! o specify a list of meteo files to be installed (spm,uvsp, etc)
  173. ! ! o specify a list of meteo sources (od-fc-ml60-glb3x2 etc)
  174. ! ! o specify wether message are printend or not (T|F)
  175. ! !
  176. ! tmm.setup.apply : T
  177. ! tmm.setup.files : spm uvsp t q cld sub surf
  178. ! tmm.setup.sources : od-fc-ml60-glb3x2
  179. ! tmm.setup.verbose : T
  180. !
  181. ! !
  182. ! ! Archive(s) to be searched for monthly tar files.
  183. ! ! If more than one is specified (space seperated list),
  184. ! ! multiple directories are examined.
  185. ! ! o disk archives
  186. ! ! o tape archives ecfs/mos ('massive-storage-system')
  187. ! !
  188. ! tmm.search.disk : ${DATADIR}/meteo
  189. ! tmm.search.mss : /nlh/TM/meteo
  190. !
  191. ! \ev
  192. !
  193. !
  194. ! !INTRODUCTION: Source and scripts
  195. !
  196. ! \bv
  197. !
  198. ! tmm.f90 : Main routines and collecting data structure.
  199. ! Provides access to a list of open meteo files.
  200. !
  201. ! tmm_mf.f90 : Search, open, close a meteo file.
  202. ! Calls shell script 'bin/tmm_getmeteo'.
  203. ! Calls specific routines for hdf/etc files.
  204. !
  205. ! tmm_mf_hdf.f90 : Read fields from hdf files.
  206. !
  207. ! tmm_param.f90 : Parameter specific stuff:
  208. ! what to do with temperature fields,
  209. ! what to do with mass fluxes etc.
  210. !
  211. ! \ev
  212. !
  213. !EOI
  214. !
  215. !
  216. ! The spm/spmid problem ...
  217. !
  218. ! Glossary:
  219. ! spm : surface pressures for 00, 06, ...;
  220. ! read from 'spm_' files, computed from ecmwf lnsp
  221. ! spmid : average of surface pressures at begin/end interval
  222. !
  223. ! To have the same algorithm as in TMPP,
  224. ! the following procedure should be used:
  225. !
  226. ! 1) use ReadUVSP to get sp1, spm, sp2
  227. ! spm is now in fact a spmid field (average of sp1 and sp2);
  228. ! in future it should be the real spm:
  229. !
  230. ! call ReadUVSP( tmm, archivekey, tday, t1, t2, &
  231. ! lli, levi, sp1, spm, sp2, pu, pv, status )
  232. !
  233. ! 2) use this spm in calls to ReadField:
  234. !
  235. ! call ReadField( tmm, archivekey, paramkey, tday, t1, t2, &
  236. ! lli, nuv, levi, spm, ll, status )
  237. !
  238. ! Examples of current implementation:
  239. !
  240. ! 1) Temperature 6x4x25 from 3x2x60
  241. ! read spm 3x2 from file
  242. ! horizontal mass average to 6x4x60 using spm 3x2 from
  243. ! vertical combination to 6x4x25 using provided sp 3x2
  244. !
  245. ! 2) Temperature 6x4x25 from N80x60
  246. ! read spm N80
  247. ! horizontal mass average to 6x4x60 using spm N80 and provided sp 3x2
  248. ! --> should be spm 3x2 from spm N80
  249. !
  250. !###############################################################################
  251. !
  252. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  253. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  254. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  255. !
  256. #include "tmm.inc"
  257. !
  258. !###############################################################################
  259. module TMM
  260. use GO , only : gol, goPr, goErr, goBug, goLabel
  261. use GO , only : TDate, wrtgol
  262. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo, TLevelInfo
  263. use tmm_mf , only : TMeteoFile
  264. use tmm_info, only : TMeteoInfo, SetHistory, AddHistory
  265. implicit none
  266. ! --- in/out -------------------------------------
  267. private
  268. public :: TTmMeteo
  269. public :: Init, Done
  270. public :: ReadField
  271. public :: Read_SP, Read_TQ
  272. public :: Read_Convec, Read_CloudCovers
  273. public :: Read_Diffus
  274. public :: Read_SR_OLS
  275. ! public :: ReadEqvLat
  276. #ifdef with_prism
  277. public :: TMM_READ_UVW
  278. #endif
  279. public :: WriteField
  280. public :: TMeteoInfo, SetHistory, AddHistory
  281. ! --- const ---------------------------------------
  282. character(len=*), parameter :: mname = 'tmm'
  283. ! maximum number of opened meteo files
  284. integer, parameter :: maxmf = 200
  285. ! --- types ---------------------------------------
  286. type TTmMeteo
  287. ! rc file with paths etc
  288. character(len=256) :: rcfilename
  289. ! paths
  290. character(len=256) :: input_dir, output_dir
  291. ! list of meteo files
  292. integer :: nmf
  293. type(TMeteoFile) :: mf(maxmf)
  294. !
  295. ! buffers for latest read raw field
  296. !
  297. logical :: buf_filled
  298. !
  299. character(len=10) :: buf_archivekey
  300. character(len=10) :: buf_paramkey
  301. type(TDate) :: buf_tday, buf_t1, buf_t2
  302. character(len=1) :: buf_nuv
  303. character(len=1) :: buf_nw
  304. type(TMeteoInfo) :: buf_tmi
  305. !
  306. character(len=2) :: buf_gridtype
  307. !
  308. type(TllGridInfo) :: buf_lli
  309. real, pointer :: buf_ll(:,:,:)
  310. real, pointer :: buf_sp_ll(:,:)
  311. !
  312. type(TggGridInfo) :: buf_ggi
  313. real, pointer :: buf_gg(:,:)
  314. real, pointer :: buf_sp_gg(:)
  315. !
  316. type(TshGridInfo) :: buf_shi
  317. complex, pointer :: buf_sh(:,:)
  318. complex, pointer :: buf_lnsp_sh(:)
  319. !
  320. type(TLevelInfo) :: buf_levi
  321. !
  322. ! storage for horizontal interpol
  323. real, pointer :: llX(:,:,:)
  324. end type TTmMeteo
  325. ! --- interfaces -------------------------------------
  326. interface Init
  327. module procedure tmm_Init
  328. end interface
  329. interface Done
  330. module procedure tmm_Done
  331. end interface
  332. interface SelectMF
  333. module procedure tmm_SelectMF
  334. end interface
  335. interface ReadField
  336. module procedure tmm_ReadField_2d
  337. module procedure tmm_ReadField_3d
  338. end interface
  339. ! interface ReadUVSP
  340. ! module procedure tmm_ReadUVSP
  341. ! end interface
  342. interface Read_SP
  343. module procedure tmm_Read_SP
  344. end interface
  345. interface Read_TQ
  346. module procedure tmm_Read_TQ
  347. end interface
  348. interface Read_Convec
  349. module procedure tmm_Read_Convec
  350. end interface
  351. interface Read_Diffus
  352. module procedure tmm_Read_Diffus
  353. end interface
  354. interface Read_CloudCovers
  355. module procedure tmm_Read_CloudCovers
  356. end interface
  357. interface Read_SR_OLS
  358. module procedure tmm_Read_SR_OLS
  359. end interface
  360. ! interface ReadEqvLat
  361. ! module procedure tmm_ReadEqvLat
  362. ! end interface
  363. interface WriteField
  364. module procedure tmm_WriteField_2d
  365. module procedure tmm_WriteField_3d
  366. end interface
  367. ! --- var --------------------------------------
  368. ! timer id's:
  369. integer :: itim_fillbuffer
  370. integer :: itim_readfield_2d
  371. integer :: itim_readfield_3d
  372. integer :: itim_transform_2d
  373. integer :: itim_transform_3dh
  374. integer :: itim_transform_3dv
  375. contains
  376. ! ===================================================================
  377. subroutine tmm_Init( tmm, rcF, status )
  378. use PArray , only : pa_Init
  379. use GO , only : NewDate
  380. use GO , only : TrcFile, ReadRc
  381. use GO , only : GO_Timer_Def
  382. #ifdef with_tmm_tm5
  383. use tmm_mf_tm5_nc , only : TMM_MF_TM5_NC_Init
  384. #endif
  385. #ifdef with_prism
  386. use tmm_mf_prism, only : mfPrism_Init
  387. #endif
  388. ! --- in/out ----------------------------------
  389. type(TTmMeteo), intent(inout) :: tmm
  390. type(TrcFile), intent(in) :: rcF
  391. integer, intent(out) :: status
  392. ! --- const ------------------------------------
  393. character(len=*), parameter :: rname = mname//'/tmm_Init'
  394. ! --- local -----------------------------------
  395. ! --- begin -----------------------------------
  396. ! store rc file name
  397. tmm%rcfilename = trim(rcf%fname)
  398. ! read paths
  399. call ReadRc( rcF, 'tmm.dir', tmm%input_dir, status )
  400. IF_NOTOK_RETURN(status=1)
  401. ! read output path: set to a dummy value if key not found in rcfiles,
  402. ! since probably no meteo output requested anyway in this case ...
  403. call ReadRc( rcF, 'tmm.output.dir', tmm%output_dir, status, &
  404. default='/no/tmm/output/dir/specified/' )
  405. ! no files open yet
  406. tmm%nmf = 0
  407. ! buffer empty
  408. tmm%buf_filled = .false.
  409. tmm%buf_archivekey = 'none'
  410. tmm%buf_paramkey = 'none'
  411. tmm%buf_tday = NewDate(time5=(/0001,01,01,00,00/))
  412. tmm%buf_t1 = NewDate(time5=(/0001,01,01,00,00/))
  413. tmm%buf_t2 = NewDate(time5=(/9999,12,31,00,00/))
  414. tmm%buf_nuv = 'n'
  415. tmm%buf_nw = 'n'
  416. tmm%buf_gridtype = 'xx'
  417. call pa_Init( tmm%buf_ll )
  418. call pa_Init( tmm%buf_sp_ll )
  419. call pa_Init( tmm%buf_gg )
  420. call pa_Init( tmm%buf_sp_gg )
  421. call pa_Init( tmm%buf_sh )
  422. call pa_Init( tmm%buf_lnsp_sh )
  423. ! init temp grid on destination grid but raw levels
  424. call pa_Init( tmm%llX )
  425. #ifdef with_prism
  426. ! init prism stuff:
  427. call mfPrism_Init( status )
  428. IF_NOTOK_RETURN(status=1)
  429. #endif
  430. #ifdef with_tmm_tm5
  431. ! init input of TM5/NetCDF files:
  432. call TMM_MF_TM5_NC_Init( rcf, status )
  433. IF_NOTOK_RETURN(status=1)
  434. #endif
  435. ! init timers:
  436. call GO_Timer_Def( itim_fillbuffer , 'tmm fill buffer', status )
  437. IF_NOTOK_RETURN(status=1)
  438. call GO_Timer_Def( itim_readfield_2d , 'tmm readfield 2D', status )
  439. IF_NOTOK_RETURN(status=1)
  440. call GO_Timer_Def( itim_readfield_3d , 'tmm readfield 3D', status )
  441. IF_NOTOK_RETURN(status=1)
  442. call GO_Timer_Def( itim_transform_2d , 'tmm transform 2D', status )
  443. IF_NOTOK_RETURN(status=1)
  444. call GO_Timer_Def( itim_transform_3dh, 'tmm transform 3D hor' , status )
  445. IF_NOTOK_RETURN(status=1)
  446. call GO_Timer_Def( itim_transform_3dv, 'tmm transform 3D vert', status )
  447. IF_NOTOK_RETURN(status=1)
  448. ! ok
  449. status = 0
  450. end subroutine tmm_Init
  451. ! ***
  452. subroutine tmm_Done( tmm, status )
  453. use PArray , only : pa_Done
  454. use tmm_mf , only : Opened, Done
  455. #ifdef with_tmm_tm5
  456. use tmm_mf_tm5_nc , only : TMM_MF_TM5_NC_Done
  457. #endif
  458. #ifdef with_prism
  459. use tmm_mf_prism, only : mfPrism_Done
  460. #endif
  461. ! --- in/out ----------------------------------
  462. type(TTmMeteo), intent(inout) :: tmm
  463. integer, intent(out) :: status
  464. ! --- const ------------------------------------
  465. character(len=*), parameter :: rname = mname//'/tmm_Done'
  466. ! --- local ----------------------------------------
  467. integer :: imf
  468. ! --- begin -------------------------------------------
  469. #ifdef with_tmm_tm5
  470. ! init input of TM5/NetCDF files:
  471. call TMM_MF_TM5_NC_Done( status )
  472. IF_NOTOK_RETURN(status=1)
  473. #endif
  474. #ifdef with_prism
  475. ! done with prism stuff:
  476. call mfPrism_Done( status )
  477. IF_NOTOK_RETURN(status=1)
  478. #endif
  479. ! loop over all available meteo files
  480. do imf = 1, tmm%nmf
  481. ! in use ?
  482. if ( .not. Opened( tmm%mf(imf) ) ) cycle
  483. ! close ...
  484. call Done( tmm%mf(imf), status )
  485. IF_NOTOK_RETURN(status=1)
  486. end do
  487. ! clear buffer
  488. call ClearBuffer( tmm, status )
  489. IF_NOTOK_RETURN(status=1)
  490. call pa_Done( tmm%buf_ll )
  491. call pa_Done( tmm%buf_sp_ll )
  492. call pa_Done( tmm%buf_gg )
  493. call pa_Done( tmm%buf_sp_gg )
  494. call pa_Done( tmm%buf_sh )
  495. call pa_Done( tmm%buf_lnsp_sh )
  496. ! clear temp grid
  497. call pa_Done( tmm%llX )
  498. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  499. ! ok
  500. status = 0
  501. end subroutine tmm_Done
  502. ! ***
  503. ! Select meteo file for this param and time,
  504. ! search for a new file if necessary
  505. subroutine tmm_SelectMF( tmm, io, archivekey, paramkey, tday, t1, t2, imf, status )
  506. use tmm_mf, only : Init, Done, Opened, CheckTime, CheckParam, SetupInput
  507. use tmm_mf, only : SetupInput, SetupOutput
  508. ! --- in/out ----------------------------------------
  509. type(TTmMeteo), intent(inout) :: tmm
  510. character(len=1), intent(in) :: io
  511. character(len=*), intent(in) :: archivekey
  512. character(len=*), intent(in) :: paramkey
  513. type(TDate), intent(in) :: tday, t1, t2
  514. integer, intent(out) :: imf
  515. integer, intent(out) :: status
  516. ! --- const ------------------------------------
  517. character(len=*), parameter :: rname = mname//'/tmm_SelectMF'
  518. ! --- local ----------------------------------------
  519. integer :: i
  520. ! --- begin ----------------------------------------
  521. !write (gol,'(" DDD selectmf paramkey : ==",a,"==")')paramkey; call goBug
  522. !write (gol,*) 'DDD selectmf archivekey : ', trim(archivekey); call gobug
  523. !call wrtgol( ' DDD selectmf tday : ', tday ); call gobug
  524. !call wrtgol( ' DDD selectmf t1 - t2 : ', t1, ' - ', t2 ); call gobug
  525. ! not found yet ...
  526. imf = -1
  527. ! loop over currently used meteo files
  528. do i = 1, tmm%nmf
  529. ! in use ?
  530. if ( .not. Opened( tmm%mf(i) ) ) cycle
  531. ! test on requested grid and param:
  532. call CheckParam( tmm%mf(i), io, archivekey, paramkey, status )
  533. !write (gol,*) 'DDD selectmf chk param : ', i, trim(tmm%mf(i)%filename), status; call gobug
  534. if ( status == 0 ) then
  535. ! param included: leave
  536. imf = i
  537. exit
  538. else if ( status < 0 ) then
  539. ! param not included, try next
  540. cycle
  541. else
  542. ! error ...
  543. TRACEBACK; status=1; return
  544. end if
  545. end do
  546. ! time ok ? close if data in file is too old:
  547. if ( imf > 0 ) then
  548. ! time ok ?
  549. call CheckTime( tmm%mf(imf), t1, t2, status )
  550. !write (gol,*) 'DDD selectmf chk time : ', status; call gobug
  551. if ( status == 0 ) then
  552. ! mf includes [t1,t2]; return with this imf
  553. status = 0; return
  554. else if ( status < 0 ) then
  555. ! mf does not include [t1,t2]; close file
  556. !write (gol,*) 'DDD selectmf close : ', imf, trim(tmm%mf(imf)%filename); call gobug
  557. call Done( tmm%mf(imf), status )
  558. IF_NOTOK_RETURN(status=1)
  559. ! not in use anymore ...
  560. imf = -1
  561. else
  562. TRACEBACK; status=1; return
  563. end if
  564. end if
  565. !write (gol,*) 'DDD selectmf imf : ', imf; call gobug
  566. ! open new meteo file ?
  567. if ( imf < 0 ) then
  568. ! search first available empty mf
  569. do i = 1, tmm%nmf
  570. if ( .not. Opened(tmm%mf(i)) ) then
  571. imf = i
  572. exit
  573. end if
  574. end do
  575. ! next number ?
  576. if ( imf < 0 ) then
  577. tmm%nmf = tmm%nmf + 1
  578. if ( tmm%nmf > maxmf ) then
  579. write (gol,'("Tried to init meteo file beyond maximum number: ",i6)') maxmf; call goErr
  580. write (gol,'("Initialized files:")'); call goErr
  581. do i = 1, maxmf
  582. write (gol,'(" ",a)') trim(tmm%mf(i)%filename); call goErr
  583. end do
  584. write (gol,'("Please increase parameter `maxmf` in ",a)') mname; call goErr
  585. TRACEBACK; status=1; return
  586. end if
  587. imf = tmm%nmf
  588. end if
  589. ! start new mf ...
  590. call Init( tmm%mf(imf), io, status )
  591. IF_NOTOK_RETURN(status=1)
  592. end if
  593. ! input or output ?
  594. select case ( io )
  595. case ( 'i' ) ! input
  596. ! open file, store description, etc
  597. call SetupInput( tmm%mf(imf), archivekey, paramkey, tday, t1, t2, &
  598. tmm%rcfilename, tmm%input_dir, status )
  599. IF_NOTOK_RETURN(status=1)
  600. case ( 'o' ) ! output
  601. ! open file, store description, etc
  602. call SetupOutput( tmm%mf(imf), archivekey, paramkey, tday, t1, t2, &
  603. tmm%rcfilename, tmm%output_dir, status )
  604. IF_NOTOK_RETURN(status=1)
  605. case default
  606. write (gol,'("unsupported io `",a,"`")') io; call goErr
  607. TRACEBACK; status=1; return
  608. end select
  609. ! ok
  610. status = 0
  611. end subroutine tmm_SelectMF
  612. ! ==================================================================
  613. ! ===
  614. ! === buffer
  615. ! ===
  616. ! ==================================================================
  617. subroutine FillBuffer( tmm, archivekey, paramkey, unit, tday, t1, t2, nuv, nw, status )
  618. use GO , only : TDate, operator(==)
  619. use GO , only : GO_Timer_Start, GO_Timer_End
  620. use tmm_mf, only : ReadRecord
  621. ! --- in/out --------------------------------
  622. type(TTmMeteo), intent(inout) :: tmm
  623. character(len=*), intent(in) :: archivekey
  624. character(len=*), intent(in) :: paramkey
  625. character(len=*), intent(in) :: unit
  626. type(TDate), intent(in) :: tday, t1, t2
  627. character(len=1), intent(in) :: nuv
  628. character(len=1), intent(in) :: nw
  629. integer, intent(out) :: status
  630. ! --- const ------------------------------------
  631. character(len=*), parameter :: rname = mname//'/FillBuffer'
  632. ! --- local -------------------------------
  633. integer :: imf
  634. ! --- begin -------------------------------
  635. ! start timing
  636. call GO_Timer_Start( itim_fillbuffer, status )
  637. IF_NOTOK_RETURN(status=1)
  638. ! is requested field already in buffer?
  639. if ( (archivekey == tmm%buf_archivekey) .and. (paramkey == tmm%buf_paramkey) .and. &
  640. (nuv == tmm%buf_nuv) .and. (nw == tmm%buf_nw) .and. &
  641. (tday == tmm%buf_tday) .and. (t1 == tmm%buf_t1) .and. (t2 == tmm%buf_t2) ) then
  642. call GO_Timer_End( itim_fillbuffer, status )
  643. IF_NOTOK_RETURN(status=1)
  644. return
  645. end if
  646. ! select (eventually retrieve first) the meteo file with this param:
  647. call SelectMF( tmm, 'i', archivekey, paramkey, tday, t1, t2, imf, status )
  648. IF_NOTOK_RETURN(status=1)
  649. ! clear buffer
  650. call ClearBuffer( tmm, status )
  651. IF_NOTOK_RETURN(status=1)
  652. ! fill keys:
  653. tmm%buf_archivekey = archivekey
  654. tmm%buf_paramkey = paramkey
  655. tmm%buf_t1 = t1
  656. tmm%buf_t2 = t2
  657. tmm%buf_tday = tday
  658. tmm%buf_nuv = nuv
  659. tmm%buf_nw = nw
  660. ! read field:
  661. call ReadRecord( tmm%mf(imf), paramkey, unit, tday, t1, t2, nuv, nw, &
  662. tmm%buf_gridtype, tmm%buf_levi, &
  663. tmm%buf_lli, tmm%buf_ll, tmm%buf_sp_ll, &
  664. tmm%buf_ggi, tmm%buf_gg, tmm%buf_sp_gg, &
  665. tmm%buf_shi, tmm%buf_sh, tmm%buf_lnsp_sh, &
  666. tmm%buf_tmi, status )
  667. IF_NOTOK_RETURN(status=1)
  668. ! some data present ..
  669. tmm%buf_filled = .true.
  670. ! end timing:
  671. call GO_Timer_End( itim_fillbuffer, status )
  672. IF_NOTOK_RETURN(status=1)
  673. ! ok
  674. status = 0
  675. end subroutine FillBuffer
  676. ! ***
  677. subroutine ClearBuffer( tmm, status )
  678. use PArray , only : pa_Done
  679. use GO , only : goErr
  680. use Grid , only : Done
  681. use tmm_info, only : Done
  682. ! --- in/out --------------------------------
  683. type(TTmMeteo), intent(inout) :: tmm
  684. integer, intent(out) :: status
  685. ! --- const ------------------------------------
  686. character(len=*), parameter :: rname = mname//'/ClearBuffer'
  687. ! --- begin -------------------------------
  688. if ( tmm%buf_filled ) then
  689. call Done( tmm%buf_tmi, status )
  690. IF_NOTOK_RETURN(status=1)
  691. if ( tmm%buf_gridtype == 'll' ) then
  692. call Done( tmm%buf_lli, status )
  693. IF_NOTOK_RETURN(status=1)
  694. call pa_Done( tmm%buf_ll )
  695. call pa_Done( tmm%buf_sp_ll )
  696. end if
  697. if ( tmm%buf_gridtype == 'gg' ) then
  698. call Done( tmm%buf_ggi, status )
  699. IF_NOTOK_RETURN(status=1)
  700. call pa_Done( tmm%buf_gg )
  701. call pa_Done( tmm%buf_sp_gg )
  702. end if
  703. if ( tmm%buf_gridtype == 'sh' ) then
  704. call Done( tmm%buf_shi )
  705. call pa_Done( tmm%buf_sh )
  706. call pa_Done( tmm%buf_lnsp_sh )
  707. end if
  708. call Done( tmm%buf_levi, status )
  709. IF_NOTOK_RETURN(status=1)
  710. end if
  711. ! ok
  712. status = 0
  713. end subroutine ClearBuffer
  714. ! ***
  715. subroutine CheckBuffer( tmm, status, gridtype, np, shT, nlev )
  716. ! --- in/out --------------------------------
  717. type(TTmMeteo), intent(inout) :: tmm
  718. integer, intent(out) :: status
  719. character(len=*), intent(in), optional :: gridtype
  720. integer, intent(in), optional :: np
  721. integer, intent(in), optional :: shT
  722. integer, intent(in), optional :: nlev
  723. ! --- const ------------------------------------
  724. character(len=*), parameter :: rname = mname//'/CheckBuffer'
  725. ! --- begin -------------------------------
  726. if ( .not. tmm%buf_filled ) then
  727. write (gol,'("buffer not filled ...")'); call goErr
  728. TRACEBACK; status=1; return
  729. end if
  730. if ( present(gridtype) ) then
  731. if ( tmm%buf_gridtype /= gridtype ) then
  732. write (gol,'("unexpected gridtype in buffer:")'); call goErr
  733. write (gol,'(" buffer : ",a)') tmm%buf_gridtype; call goErr
  734. write (gol,'(" expected : ",a)') gridtype; call goErr
  735. TRACEBACK; status=1; return
  736. end if
  737. end if
  738. if ( present(nlev) ) then
  739. if ( tmm%buf_levi%nlev /= nlev ) then
  740. write (gol,'("unexpected number of levels in buffer:")'); call goErr
  741. write (gol,'(" buffer : ",i4)') tmm%buf_levi%nlev ; call goErr
  742. write (gol,'(" expected : ",i4)') nlev ; call goErr
  743. TRACEBACK; status=1; return
  744. end if
  745. end if
  746. if ( present(np) ) then
  747. if ( tmm%buf_ggi%np /= np ) then
  748. write (gol,'("unexpected grid size in buffer:")'); call goErr
  749. write (gol,'(" buffer ggi%np : ",i6)') tmm%buf_ggi%np; call goErr
  750. write (gol,'(" expected : ",i6)') np; call goErr
  751. TRACEBACK; status=1; return
  752. end if
  753. end if
  754. if ( present(shT) ) then
  755. if ( tmm%buf_shi%T /= shT ) then
  756. write (gol,'("unexpected grid size in buffer:")'); call goErr
  757. write (gol,'(" buffer shi%shT : ",i6)') tmm%buf_shi%T; call goErr
  758. write (gol,'(" expected : ",i6)') shT; call goErr
  759. TRACEBACK; status=1; return
  760. end if
  761. end if
  762. ! ok
  763. status = 0
  764. end subroutine CheckBuffer
  765. ! ***
  766. subroutine Transform2D( tmm, lli, nuv, tmi, status )
  767. ! use PArray , only : pa_SetShape
  768. use GO , only : GO_Timer_Start, GO_Timer_End
  769. use Grid , only : Tgg2llFracs, Init, Done
  770. use Grid , only : Interpol, FillGrid
  771. use Grid , only : FracSum
  772. use tmm_param , only : GetCombineKeys
  773. use tmm_info , only : TMeteoInfo, Init, AddHistory
  774. ! --- in/out --------------------------------
  775. type(TTmMeteo), intent(inout) :: tmm ! meteo buffer (incl. source data[in], target data[out], source grid)
  776. type(TllGridInfo), intent(in) :: lli ! grid of target data
  777. character(len=1), intent(in) :: nuv ! horizontal staggering of target data
  778. type(TMeteoInfo), intent(out) :: tmi !
  779. integer, intent(out) :: status !
  780. ! --- const ------------------------------------
  781. character(len=*), parameter :: rname = mname//'/Transform2D'
  782. ! --- local -------------------------------
  783. character(len=10) :: hcomb, vcomb
  784. type(Tgg2llFracs) :: gg2ll
  785. ! --- begin ----------------------------------
  786. ! start timing:
  787. call GO_Timer_Start( itim_transform_2d, status )
  788. IF_NOTOK_RETURN(status=1)
  789. ! copy info:
  790. tmi = tmm%buf_tmi
  791. ! set shape of target grid:
  792. ! Note: switched from pa_SetShape to allocate when developping the parallel IO reading of nc met fields.
  793. if (associated (tmm%llX)) deallocate(tmm%llX)
  794. select case ( nuv )
  795. case ( 'n' )
  796. allocate( tmm%llX( lli%nlon , lli%nlat , 1 ) )
  797. case ( 'u' )
  798. allocate( tmm%llX( lli%nlon+1, lli%nlat , 1 ) )
  799. case ( 'v' )
  800. allocate( tmm%llX( lli%nlon , lli%nlat+1, 1 ) )
  801. case default
  802. write (gol,'("unsupported nuv `",a,"`")') nuv
  803. TRACEBACK; status=1; return
  804. end select
  805. ! fill with zero's for safety:
  806. tmm%llX = 0.0
  807. ! define how to combine horizontal cells and vertical levels:
  808. call GetCombineKeys( hcomb, vcomb, tmm%buf_paramkey, status )
  809. IF_NOTOK_RETURN(status=1)
  810. ! transform raw field to ll :
  811. select case ( tmm%buf_gridtype )
  812. ! ~~~ lat/lon ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  813. case ( 'll' )
  814. ! copy or combine horizontal cells from buffer into lli/llX :
  815. call FillGrid( lli, nuv, tmm%llX(:,:,1), &
  816. tmm%buf_lli, tmm%buf_nuv, tmm%buf_ll(:,:,1), &
  817. hcomb, status )
  818. IF_ERROR_RETURN(status=1)
  819. ! Catch cases of incomplete mapping
  820. if (status==-1)then
  821. write(gol,*) " "; call goErr
  822. write(gol,*) "Only part of target array was filled!"; call goErr
  823. write(gol,*) "Make sure that the number of processors divides the number of grid boxes."; call goErr
  824. write(gol,*) " "; call goErr
  825. TRACEBACK; status=1; return
  826. endif
  827. ! ~~~ gg ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  828. case ( 'gg' )
  829. ! determine fraction
  830. call Init( gg2ll, tmm%buf_ggi, lli, status )
  831. IF_NOTOK_RETURN(status=1)
  832. ! deceide how to interpolate given hcomb key:
  833. select case ( hcomb )
  834. case ( 'area-aver' )
  835. ! take fractions of overlapping cells
  836. call FracSum( gg2ll, tmm%buf_gg(:,1), tmm%llX(:,:,1), status, 'area-aver' )
  837. IF_NOTOK_RETURN(status=1)
  838. case default
  839. write (gol,'("unsupported horizonal combination key for gg :",a)') hcomb; call goErr
  840. write (gol,'("TIP: hcomb not set for this variable in module tmm_param ?")'); call goErr
  841. TRACEBACK; status=1; return
  842. end select
  843. ! done
  844. call Done( gg2ll )
  845. ! ~~~ sh ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  846. case ( 'sh' )
  847. ! interpolate field in shi/sh into lli/ll :
  848. call Interpol( tmm%buf_shi, tmm%buf_sh(:,1), lli, tmm%llX(:,:,1), status )
  849. IF_NOTOK_RETURN(status=1)
  850. case default
  851. write (gol,'("unsupported input grid type `",a,"`")') tmm%buf_gridtype; call goErr
  852. TRACEBACK; status=1; return
  853. end select
  854. ! fill history:
  855. call Init( tmi, tmm%buf_tmi, status )
  856. call AddHistory( tmi, 'oper==hcomb,'//trim(hcomb), status )
  857. ! end timing:
  858. call GO_Timer_End( itim_transform_2d, status )
  859. IF_NOTOK_RETURN(status=1)
  860. ! ok
  861. status = 0
  862. end subroutine Transform2D
  863. ! ***
  864. subroutine Transform3Dh( tmm, lli, nuv, levi, nw, sp, tmi, status )
  865. use PArray , only : pa_SetShape
  866. use GO , only : GO_Timer_Start, GO_Timer_End
  867. use Grid , only : FillLevels, FillGrid, AreaOper
  868. use Grid , only : Tgg2llFracs, Init, Done
  869. use Grid , only : IntArea
  870. use Grid , only : FracSum
  871. use tmm_param , only : GetCombineKeys
  872. use tmm_info , only : TMeteoInfo, Init, AddHistory
  873. ! --- in/out --------------------------------
  874. type(TTmMeteo), intent(inout) :: tmm
  875. type(TllGridInfo), intent(in) :: lli
  876. character(len=1), intent(in) :: nuv
  877. type(TLevelInfo), intent(in) :: levi
  878. character(len=1), intent(in) :: nw
  879. real, intent(out) :: sp(:,:)
  880. type(TMeteoInfo), intent(out) :: tmi
  881. integer, intent(out) :: status
  882. ! --- const ------------------------------------
  883. character(len=*), parameter :: rname = mname//'/Transform3Dh'
  884. ! --- local -------------------------------
  885. integer :: nlon, nlat, nlev
  886. character(len=10) :: hcomb, vcomb
  887. integer :: l
  888. type(Tgg2llFracs) :: gg2ll
  889. real, allocatable :: dp_ll(:,:)
  890. real, allocatable :: dp_llX(:,:)
  891. real, allocatable :: dp_gg(:)
  892. ! --- begin ----------------------------------
  893. ! start timing:
  894. call GO_Timer_Start( itim_transform_3dh, status )
  895. IF_NOTOK_RETURN(status=1)
  896. ! set shape of target grid:
  897. select case ( nuv )
  898. case ( 'n' )
  899. nlon = lli%nlon
  900. nlat = lli%nlat
  901. case ( 'u' )
  902. nlon = lli%nlon+1
  903. nlat = lli%nlat
  904. case ( 'v' )
  905. nlon = lli%nlon
  906. nlat = lli%nlat+1
  907. case default
  908. write (gol,'("unsupported nuv `",a,"`")') nuv; call goErr
  909. TRACEBACK; status=1; return
  910. end select
  911. select case ( nw )
  912. case ( 'n' )
  913. nlev = tmm%buf_levi%nlev
  914. case ( 'w' )
  915. nlev = tmm%buf_levi%nlev+1
  916. case default
  917. write (gol,'("unsupported nw `",a,"`")') nw; call goErr
  918. TRACEBACK; status=1; return
  919. end select
  920. call pa_SetShape( tmm%llX, nlon, nlat, nlev )
  921. tmm%llX = 0.0
  922. ! define how to combine horizontal cells and vertical levels:
  923. call GetCombineKeys( hcomb, vcomb, tmm%buf_paramkey, status )
  924. IF_NOTOK_RETURN(status=1)
  925. ! transform raw field to ll :
  926. select case ( tmm%buf_gridtype )
  927. ! ~~~ lat/lon ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  928. case ( 'll' )
  929. !! check size of buffer array
  930. !if ( size(tmm%buf_ll,3) /= nlev ) then
  931. ! write (gol,'("buffer array does not match with level definition:")')
  932. ! write (gol,'(" nw : ",a )') nw
  933. ! write (gol,'(" buf_levi nlev : ",i3)') tmm%buf_levi%nlev
  934. ! write (gol,'(" buf_ll levels : ",i3)') size(tmm%buf_ll,3)
  935. ! TRACEBACK; status=1; return
  936. !end if
  937. ! convective fluxes have only lowest layers ...
  938. if ( size(tmm%buf_ll,3) > nlev ) then
  939. write (gol,'("buffer array has more layers than implied by nw and level definition:")'); call goErr
  940. write (gol,'(" nw : ",a )') nw; call goErr
  941. write (gol,'(" buf_levi nlev : ",i3)') tmm%buf_levi%nlev; call goErr
  942. write (gol,'(" buf_ll levels : ",i3)') size(tmm%buf_ll,3); call goErr
  943. TRACEBACK; status=1; return
  944. end if
  945. ! surface pressure: aver horizontal cells from buffer into lli/llX :
  946. call FillGrid( lli, nuv, sp, &
  947. tmm%buf_lli, tmm%buf_nuv, tmm%buf_sp_ll, &
  948. 'area-aver', status )
  949. IF_ERROR_RETURN(status=1)
  950. ! Catch cases of incomplete mapping
  951. if (status==-1)then
  952. write(gol,*) " "; call goErr
  953. write(gol,*) "Only part of target array was filled!"; call goErr
  954. write(gol,*) "Make sure that the number of processors divides the number of grid boxes."; call goErr
  955. write(gol,*) " "; call goErr
  956. TRACEBACK; status=1; return
  957. endif
  958. ! deceide how to interpolate given hcomb key;
  959. ! for most keys, let 'FillGrid' determine what to do ...
  960. select case ( hcomb )
  961. case ( 'mass-aver' )
  962. ! check ...
  963. if ( nw /= 'n' ) then
  964. write (gol,'("nw should be `n` for mass aver ...")'); call goErr
  965. TRACEBACK; status=1; return
  966. end if
  967. !
  968. ! mass weighted fractions:
  969. !
  970. ! sum_i f_i dp_i/g dA_i
  971. ! ----------------------
  972. ! sum_i dp_i/g dA_i
  973. !
  974. ! temporary pressure field:
  975. allocate( dp_ll(tmm%buf_lli%nlon,tmm%buf_lli%nlat) )
  976. ! loop over layers
  977. !do l = 1, nlev
  978. do l = 1, size(tmm%buf_ll,3)
  979. ! pressure gradients in this layer:
  980. dp_ll = tmm%buf_levi%da(l) + tmm%buf_levi%db(l) * tmm%buf_sp_ll
  981. call AreaOper( tmm%buf_lli, dp_ll, '*', 'm2', status )
  982. IF_NOTOK_RETURN(status=1)
  983. ! copy or combine horizontal cells from buffer into lli/llX;
  984. ! combining cells is weighted by 'mass' dp_ll :
  985. call FillGrid( lli, nuv, tmm%llX(:,:,l), &
  986. tmm%buf_lli, tmm%buf_nuv, tmm%buf_ll(:,:,l), &
  987. 'weight', status, dp_ll )
  988. IF_ERROR_RETURN(status=1)
  989. ! Catch cases of incomplete mapping
  990. if (status==-1)then
  991. write(gol,*) " "; call goErr
  992. write(gol,*) "Only part of target array was filled!"; call goErr
  993. write(gol,*) "Make sure that the number of processors divides the number of grid boxes."; call goErr
  994. write(gol,*) " "; call goErr
  995. TRACEBACK; status=1; return
  996. endif
  997. end do
  998. ! clear:
  999. deallocate( dp_ll )
  1000. case default
  1001. ! loop over layers in ll array:
  1002. !do l = 1, nlev
  1003. do l = 1, size(tmm%buf_ll,3)
  1004. ! copy or combine horizontal cells from buffer into lli/llX;
  1005. ! pass hcomb to FillGrid to define how cells are combined:
  1006. call FillGrid( lli, nuv, tmm%llX(:,:,l), &
  1007. tmm%buf_lli, tmm%buf_nuv, tmm%buf_ll(:,:,l), &
  1008. hcomb, status )
  1009. IF_ERROR_RETURN(status=1)
  1010. ! Catch cases of incomplete mapping
  1011. if (status==-1)then
  1012. write(gol,*) " "; call goErr
  1013. write(gol,*) "Only part of target array was filled!"; call goErr
  1014. write(gol,*) "Make sure that the number of processors divides the number of grid boxes."; call goErr
  1015. write(gol,*) " "; call goErr
  1016. TRACEBACK; status=1; return
  1017. endif
  1018. end do
  1019. end select
  1020. ! ~~~ gg ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1021. case ( 'gg' )
  1022. ! check size of buffer array
  1023. if ( size(tmm%buf_gg,2) /= nlev ) then
  1024. write (gol,'("buffer array does not match with level definition:")'); call goErr
  1025. write (gol,'(" nw : ",a )') nw; call goErr
  1026. write (gol,'(" buf_levi nlev : ",i3)') tmm%buf_levi%nlev; call goErr
  1027. write (gol,'(" buf_gg levels : ",i3)') size(tmm%buf_gg,2); call goErr
  1028. TRACEBACK; status=1; return
  1029. end if
  1030. ! determine fraction
  1031. call Init( gg2ll, tmm%buf_ggi, lli, status )
  1032. IF_NOTOK_RETURN(status=1)
  1033. ! surface pressure: take fractions of overlapping cells
  1034. call FracSum( gg2ll, tmm%buf_sp_gg, sp, status, 'area-aver' )
  1035. IF_NOTOK_RETURN(status=1)
  1036. ! deceide how to interpolate given hcomb key:
  1037. select case ( hcomb )
  1038. case ( 'area-aver' )
  1039. !
  1040. ! area weighted fractions:
  1041. !
  1042. ! sum_i f_i dA_i
  1043. ! ---------------
  1044. ! sum_i dA_i
  1045. !
  1046. ! loop over layers
  1047. do l = 1, nlev
  1048. ! take fractions of overlapping cells
  1049. call FracSum( gg2ll, tmm%buf_gg(:,l), tmm%llX(:,:,l), status, 'area-aver' )
  1050. IF_NOTOK_RETURN(status=1)
  1051. end do
  1052. case ( 'mass-aver' )
  1053. ! check ...
  1054. if ( nw /= 'n' ) then
  1055. write (gol,'("nw should be `n` for mass aver ...")'); call goErr
  1056. TRACEBACK; status=1; return
  1057. end if
  1058. !
  1059. ! mass weighted fractions:
  1060. !
  1061. ! sum_i f_i dp_i/g dA_i
  1062. ! ----------------------
  1063. ! sum_i dp_i/g dA_i
  1064. !
  1065. ! temporary pressure field:
  1066. allocate( dp_gg(size(tmm%buf_sp_gg)) )
  1067. allocate( dp_llX(size(sp,1),size(sp,2)) )
  1068. ! loop over layers
  1069. do l = 1, nlev
  1070. ! pressure gradients in this layer:
  1071. dp_gg = tmm%buf_levi%da(l) + tmm%buf_levi%db(l) * tmm%buf_sp_gg
  1072. dp_llX = tmm%buf_levi%da(l) + tmm%buf_levi%db(l) * sp
  1073. ! take fractions of overlapping cells:
  1074. ! sum_i f_i dp_i dA_i
  1075. call FracSum( gg2ll, tmm%buf_gg(:,l)*dp_gg, tmm%llX(:,:,l), status, 'area-sum' )
  1076. IF_NOTOK_RETURN(status=1)
  1077. ! weight by total dp dA
  1078. tmm%llX(:,:,l) = tmm%llX(:,:,l) / dp_llX
  1079. call AreaOper( lli, tmm%llX(:,:,l), '/', 'm2', status )
  1080. IF_NOTOK_RETURN(status=1)
  1081. end do
  1082. ! clear:
  1083. deallocate( dp_gg )
  1084. deallocate( dp_llX )
  1085. case default
  1086. write (gol,'("unsupported horizonal combination key for gg :",a)') hcomb; call goErr
  1087. TRACEBACK; status=1; return
  1088. end select
  1089. ! done
  1090. call Done( gg2ll )
  1091. ! ~~~ sh ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1092. case ( 'sh' )
  1093. ! check size of buffer array
  1094. if ( size(tmm%buf_sh,2) /= nlev ) then
  1095. write (gol,'("buffer array does not match with level definition:")'); call goErr
  1096. write (gol,'(" nw : ",a )') nw; call goErr
  1097. write (gol,'(" buf_levi nlev : ",i3)') tmm%buf_levi%nlev; call goErr
  1098. write (gol,'(" buf_sh levels : ",i3)') size(tmm%buf_sh,2); call goErr
  1099. TRACEBACK; status=1; return
  1100. end if
  1101. ! surface pressure: interpolate lnsp to target horizontal resolution:
  1102. call IntArea( 'exp,aver', tmm%buf_shi, tmm%buf_lnsp_sh, lli, sp, status )
  1103. IF_NOTOK_RETURN(status=1)
  1104. ! deceide how to interpolate given hcomb key:
  1105. select case ( hcomb )
  1106. !case ( 'area-aver' )
  1107. !
  1108. ! ! area average over sepectral fields:
  1109. ! call IntArea( 'aver', tmm%buf_shi, tmm%buf_sh, lli, tmm%llX, status )
  1110. ! IF_NOTOK_RETURN(status=1)
  1111. case ( 'mass-aver' )
  1112. ! check ...
  1113. if ( nw /= 'n' ) then
  1114. write (gol,'("nw should be `n` for mass aver ...")'); call goErr
  1115. TRACEBACK; status=1; return
  1116. end if
  1117. ! mass average over sepectral fields:
  1118. call IntArea( '[F*(da+db*exp(H))*cos]/[()*cos]', &
  1119. tmm%buf_shi, nlev, tmm%buf_sh, &
  1120. tmm%buf_lnsp_sh, tmm%buf_levi%da, tmm%buf_levi%db, &
  1121. lli, tmm%llX, status )
  1122. IF_NOTOK_RETURN(status=1)
  1123. case default
  1124. write (gol,'("unsupported horizonal combination key for sh :",a)') hcomb; call goErr
  1125. TRACEBACK; status=1; return
  1126. end select
  1127. ! ~~~ ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1128. case default
  1129. write (gol,'("unsupported input grid type `",a,"`")') tmm%buf_gridtype; call goErr
  1130. TRACEBACK; status=1; return
  1131. end select
  1132. ! fill history:
  1133. call Init( tmi, tmm%buf_tmi, status )
  1134. call AddHistory( tmi, 'oper==hcomb,'//trim(hcomb), status )
  1135. ! end timing:
  1136. call GO_Timer_End( itim_transform_3dh, status )
  1137. IF_NOTOK_RETURN(status=1)
  1138. ! ok
  1139. status = 0
  1140. end subroutine Transform3Dh
  1141. ! ***
  1142. subroutine Transform3Dv( tmm, levi, nw, sp, ll, tmi, status )
  1143. use PArray , only : pa_SetShape
  1144. use GO , only : GO_Timer_Start, GO_Timer_End
  1145. use Grid , only : FillLevels, FillGrid, AreaOper
  1146. use Grid , only : Tgg2llFracs, Init, Done
  1147. use Grid , only : IntArea
  1148. use Grid , only : FracSum
  1149. use tmm_param , only : GetCombineKeys
  1150. use tmm_info , only : TMeteoInfo, AddHistory
  1151. ! --- in/out --------------------------------
  1152. type(TTmMeteo), intent(inout) :: tmm
  1153. type(TLevelInfo), intent(in) :: levi
  1154. character(len=1), intent(in) :: nw
  1155. real, intent(in) :: sp(:,:)
  1156. real, intent(out) :: ll(:,:,:)
  1157. type(TMeteoInfo), intent(inout) :: tmi
  1158. integer, intent(out) :: status
  1159. ! --- const ------------------------------------
  1160. character(len=*), parameter :: rname = mname//'/Transform3Dv'
  1161. ! --- local -------------------------------
  1162. character(len=10) :: hcomb, vcomb
  1163. ! --- begin ----------------------------------
  1164. ! start timing:
  1165. call GO_Timer_Start( itim_transform_3dv, status )
  1166. IF_NOTOK_RETURN(status=1)
  1167. ! define how to combine horizontal cells and vertical levels:
  1168. call GetCombineKeys( hcomb, vcomb, tmm%buf_paramkey, status )
  1169. IF_NOTOK_RETURN(status=1)
  1170. ! collect or copy levels, eventually reversed, from leviX/llX into levi/ll :
  1171. !write (gol,'(a,": vertical ...")') rname
  1172. call FillLevels( levi, nw, sp, ll, tmm%buf_levi, tmm%llX, vcomb, status )
  1173. IF_NOTOK_RETURN(status=1)
  1174. ! add history:
  1175. call AddHistory( tmi, 'oper==vcomb,'//trim(vcomb), status )
  1176. ! end timing:
  1177. call GO_Timer_End( itim_transform_3dv, status )
  1178. IF_NOTOK_RETURN(status=1)
  1179. ! ok
  1180. status = 0
  1181. end subroutine Transform3Dv
  1182. ! ==================================================================
  1183. ! ===
  1184. ! === read ll field
  1185. ! ===
  1186. ! ==================================================================
  1187. subroutine tmm_ReadField_2d( tmm, archivekey, paramkey, unit, tday, t1, t2, &
  1188. lli, nuv, ll, tmi, status )
  1189. use PArray , only : pa_Init, pa_Done
  1190. use GO , only : GO_Timer_Start, GO_Timer_End
  1191. use tmm_info, only : TMeteoInfo
  1192. ! --- in/out --------------------------------
  1193. type(TTmMeteo), intent(inout) :: tmm ! meteo buffer (all about the SRC, TGT data)
  1194. character(len=*), intent(in) :: archivekey
  1195. character(len=*), intent(in) :: paramkey
  1196. character(len=*), intent(in) :: unit
  1197. type(TDate), intent(in) :: tday, t1, t2 ! date, time interval of request
  1198. type(TllGridInfo), intent(in) :: lli ! grid info of requested data. Tile only if //-IO.
  1199. character(len=1), intent(in) :: nuv ! horizontal staggering of requested data
  1200. real, intent(out) :: ll(:,:) ! read (and regridded) data. Bounds are lost.
  1201. type(TMeteoInfo), intent(out) :: tmi ! info
  1202. integer, intent(out) :: status ! return code
  1203. ! --- const ------------------------------------
  1204. character(len=*), parameter :: rname = mname//'/tmm_ReadField_2d'
  1205. ! --- local -------------------------------
  1206. character(len=10) :: hcomb, vcomb
  1207. character(len=32) :: paramkey_in
  1208. ! --- begin ----------------------------------
  1209. call goLabel(rname)
  1210. ! start timing:
  1211. call GO_Timer_Start( itim_readfield_2d, status )
  1212. IF_NOTOK_RETURN(status=1)
  1213. !DBG call wrtgol( ' tmm read 2D : '//trim(paramkey)//' (', tday, ') ', t1, ' - ', t2 ); call goPr
  1214. ! check shape of target grid:
  1215. if ( ((nuv == 'n') .and. ((size(ll,1) /= lli%nlon ) .or. (size(ll,2) /= lli%nlat ))) .or. &
  1216. ((nuv == 'u') .and. ((size(ll,1) /= lli%nlon+1) .or. (size(ll,2) /= lli%nlat ))) .or. &
  1217. ((nuv == 'v') .and. ((size(ll,1) /= lli%nlon ) .or. (size(ll,2) /= lli%nlat+1))) ) then
  1218. write (gol,'("target array does not match with grid definition:")'); call goErr
  1219. write (gol,'(" param : ",a )') paramkey; call goErr
  1220. write (gol,'(" lli : ",i3," x ",i3)') lli%nlon, lli%nlat; call goErr
  1221. write (gol,'(" nuv : ",a )') nuv; call goErr
  1222. write (gol,'(" ll : ",i3," x ",i3)') shape(ll); call goErr
  1223. TRACEBACK; status=1; return
  1224. end if
  1225. !
  1226. ! convert grid
  1227. !
  1228. ! standard values?
  1229. if ( trim(archivekey) == 'standard' ) then
  1230. ! dummy value
  1231. ll = 0.0
  1232. else
  1233. ! translate?
  1234. #ifdef with_ec_aver
  1235. select case ( trim(paramkey) )
  1236. case ( 'lsp' ) ; paramkey_in = 'mlspr'
  1237. case ( 'cp' ) ; paramkey_in = 'mcpr'
  1238. case ( 'sf' ) ; paramkey_in = 'msr'
  1239. case ( 'sshf' ) ; paramkey_in = 'msshf'
  1240. case ( 'slhf' ) ; paramkey_in = 'mslhf'
  1241. case ( 'ssrd' ) ; paramkey_in = 'msdwswrf'
  1242. case ( 'strd' ) ; paramkey_in = 'msdwlwrf'
  1243. case ( 'ssr' ) ; paramkey_in = 'msnswrf'
  1244. case ( 'str' ) ; paramkey_in = 'msnlwrf'
  1245. case ( 'ewss' ) ; paramkey_in = 'metss'
  1246. case ( 'nsss' ) ; paramkey_in = 'mntss'
  1247. case default
  1248. paramkey_in = trim(paramkey)
  1249. end select
  1250. #else
  1251. paramkey_in = trim(paramkey)
  1252. #endif
  1253. ! read raw field in buffer
  1254. call FillBuffer( tmm, archivekey, paramkey_in, unit, tday, t1, t2, nuv, 'n', status )
  1255. IF_NOTOK_RETURN(status=1)
  1256. ! horizontal interpolation:
  1257. call Transform2D( tmm, lli, nuv, tmi, status )
  1258. IF_NOTOK_RETURN(status=1)
  1259. ! expecting single level ...
  1260. if ( size(tmm%llX,3) /= 1 ) then
  1261. write (gol,'("expecting single level:")'); call goErr
  1262. if ( trim(paramkey_in) /= trim(paramkey) ) then
  1263. write (gol,'(" paramkey : ",a," (",a,")")') trim(paramkey_in), trim(paramkey); call goErr
  1264. else
  1265. write (gol,'(" paramkey : ",a)') trim(paramkey_in); call goErr
  1266. end if
  1267. write (gol,'(" levels : ",a)') size(tmm%llX,3); call goErr
  1268. TRACEBACK; status=1; return
  1269. end if
  1270. ! extract first level
  1271. ll = tmm%llX(:,:,1)
  1272. end if
  1273. !
  1274. ! unit conversions, truncations, etc
  1275. !
  1276. select case ( paramkey )
  1277. case ( 'oro', 'cp', 'lsp' )
  1278. ! set minium; some negative values if made from spectral field:
  1279. ll = max( 0.0, ll )
  1280. end select
  1281. !
  1282. ! done
  1283. !
  1284. ! end timing:
  1285. call GO_Timer_End( itim_readfield_2d, status )
  1286. IF_NOTOK_RETURN(status=1)
  1287. ! ok
  1288. call goLabel()
  1289. status = 0
  1290. end subroutine tmm_ReadField_2d
  1291. ! ***
  1292. subroutine tmm_ReadField_3d( tmm, archivekey, paramkey, unit, tday, t1, t2, &
  1293. lli, nuv, levi, nw, sp, ll, tmi, status )
  1294. use GO , only : GO_Timer_Start, GO_Timer_End
  1295. use Binas , only : p_global
  1296. use tmm_info, only : TMeteoInfo
  1297. ! --- in/out --------------------------------
  1298. type(TTmMeteo), intent(inout) :: tmm
  1299. character(len=*), intent(in) :: archivekey
  1300. character(len=*), intent(in) :: paramkey, unit
  1301. type(TDate), intent(in) :: tday, t1, t2
  1302. type(TllGridInfo), intent(in) :: lli
  1303. character(len=1), intent(in) :: nuv
  1304. type(TLevelInfo), intent(in) :: levi
  1305. character(len=1), intent(in) :: nw
  1306. real, intent(out) :: sp(:,:)
  1307. real, intent(out) :: ll(:,:,:)
  1308. type(TMeteoInfo), intent(out) :: tmi
  1309. integer, intent(out) :: status
  1310. ! --- const ------------------------------------
  1311. character(len=*), parameter :: rname = mname//'/tmm_ReadField_3d'
  1312. ! --- begin ----------------------------------
  1313. call goLabel(rname)
  1314. ! start timing:
  1315. call GO_Timer_Start( itim_readfield_3d, status )
  1316. IF_NOTOK_RETURN(status=1)
  1317. !DBG call wrtgol( ' tmm read3D : '//trim(paramkey)//' ', t1, ' - ', t2 ); call goPr
  1318. ! check shape of target grid:
  1319. if ( ((nuv == 'n') .and. ((size(ll,1) /= lli%nlon ) .or. (size(ll,2) /= lli%nlat ))) .or. &
  1320. ((nuv == 'u') .and. ((size(ll,1) /= lli%nlon+1) .or. (size(ll,2) /= lli%nlat ))) .or. &
  1321. ((nuv == 'v') .and. ((size(ll,1) /= lli%nlon ) .or. (size(ll,2) /= lli%nlat+1))) .or. &
  1322. ((nuv == 'n') .and. ((size(sp,1) /= lli%nlon ) .or. (size(sp,2) /= lli%nlat ))) .or. &
  1323. ((nuv == 'u') .and. ((size(sp,1) /= lli%nlon+1) .or. (size(sp,2) /= lli%nlat ))) .or. &
  1324. ((nuv == 'v') .and. ((size(sp,1) /= lli%nlon ) .or. (size(sp,2) /= lli%nlat+1))) .or. &
  1325. ((nw == 'n') .and. (size(ll,3) /= levi%nlev )) .or. &
  1326. ((nw == 'w') .and. (size(ll,3) /= levi%nlev+1)) ) then
  1327. write (gol,'("target arrays do not match with grid definition:")'); call goErr
  1328. write (gol,'(" param : ",a )') paramkey ; call goErr
  1329. write (gol,'(" lli : ",i3," x ",i3 )') lli%nlon, lli%nlat; call goErr
  1330. write (gol,'(" nuv : ",a )') nuv; call goErr
  1331. write (gol,'(" levi : ",i3 )') levi%nlev; call goErr
  1332. write (gol,'(" nw : ",a )') nw; call goErr
  1333. write (gol,'(" sp : ",i3," x ",i3 )') shape(sp); call goErr
  1334. write (gol,'(" ll : ",i3," x ",i3," x ",i3)') shape(ll); call goErr
  1335. TRACEBACK; status=1; return
  1336. end if
  1337. !
  1338. ! read, convert
  1339. !
  1340. ! standard values?
  1341. if ( trim(archivekey) == 'standard' ) then
  1342. ! dummy values
  1343. sp = p_global
  1344. ll = 0.0
  1345. else
  1346. ! read raw field in buffer
  1347. call FillBuffer( tmm, archivekey, paramkey, unit, tday, t1, t2, nuv, nw, status )
  1348. IF_NOTOK_RETURN(status=1)
  1349. ! 3d horizontal conversion:
  1350. call Transform3Dh( tmm, lli, nuv, levi, nw, sp, tmi, status )
  1351. IF_NOTOK_RETURN(status=1)
  1352. ! 3d vertical conversion:
  1353. call Transform3Dv( tmm, levi, nw, sp, ll, tmi, status )
  1354. IF_NOTOK_RETURN(status=1)
  1355. end if
  1356. !
  1357. ! unit conversion, extreme values
  1358. !
  1359. select case ( paramkey )
  1360. case ( 'Q', 'CLWC', 'CIWC' )
  1361. ! set minimum, stored values could be slightly negative
  1362. ll = max( 0.0, ll )
  1363. ll = max( 0.0, ll )
  1364. end select
  1365. !
  1366. ! done
  1367. !
  1368. ! start timing:
  1369. call GO_Timer_End( itim_readfield_3d, status )
  1370. IF_NOTOK_RETURN(status=1)
  1371. ! ok
  1372. call goLabel()
  1373. status = 0
  1374. end subroutine tmm_ReadField_3d
  1375. ! ==================================================================
  1376. ! ===
  1377. ! === VO/D/LNSP -> pu/pv/sp
  1378. ! ===
  1379. ! ==================================================================
  1380. subroutine tmm_Read_SP( tmm, archivekey, paramname, paramunit, tday, t1, t2, &
  1381. lli, sp, tmi, status )
  1382. use binas , only : p_global
  1383. use GO , only : goSplitLine, Get
  1384. use Grid , only : TshGrid, Init, Done, Set
  1385. use Grid , only : IntArea
  1386. use Grid , only : Tgg2llFracs, FracSum
  1387. use tmm_info, only : TMeteoInfo, Init, AddHistory
  1388. ! --- in/out --------------------------------
  1389. type(TTmMeteo), intent(inout) :: tmm
  1390. character(len=*), intent(in) :: archivekey, paramname, paramunit
  1391. type(TDate), intent(in) :: tday, t1, t2
  1392. type(TllGridInfo), intent(in) :: lli
  1393. real, intent(out) :: sp(:,:) ! Pa
  1394. type(TMeteoInfo), intent(out) :: tmi
  1395. integer, intent(out) :: status
  1396. ! --- const ------------------------------------
  1397. character(len=*), parameter :: rname = mname//'/tmm_Read_SP'
  1398. ! --- local -------------------------------
  1399. character(len=10) :: sourcetype
  1400. character(len=256) :: sourcename
  1401. integer :: hour
  1402. type(Tgg2llFracs) :: gg2ll
  1403. ! --- begin -------------------------------
  1404. call goLabel(rname)
  1405. ! split source key in type and name:
  1406. call goSplitLine( archivekey, sourcetype, ':', sourcename, status )
  1407. IF_NOTOK_RETURN(status=1)
  1408. ! input TMPP fields or raw prism fields ?
  1409. select case ( sourcetype )
  1410. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1411. ! standard
  1412. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1413. case ( 'standard' )
  1414. !write (gol,'(" tmm read : sp standard global mean pressure")'); call goPr
  1415. ! fill field with global mean pressure:
  1416. sp = p_global
  1417. ! set history info
  1418. call Init( tmi, 'sp', 'Pa', status )
  1419. call AddHistory( tmi, 'standard', status )
  1420. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1421. ! read directly from tmpp hdf file
  1422. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1423. case ( 'tmpp' )
  1424. ! select parameter given hour:
  1425. call Get( t1, hour=hour )
  1426. if ( modulo(hour,6) == 3 ) then
  1427. ! hour = 21/03/.. : uvsp files
  1428. call ReadField( tmm, archivekey, 'sp', 'Pa', tday, t1, t1, &
  1429. lli, 'n', sp, tmi, status )
  1430. IF_NOTOK_RETURN(status=1)
  1431. else
  1432. ! hour = 00/06/.. : spm files
  1433. call ReadField( tmm, archivekey, 'spm', 'Pa', tday, t1, t1, &
  1434. lli, 'n', sp, tmi, status )
  1435. IF_NOTOK_RETURN(status=1)
  1436. end if
  1437. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1438. ! read directly from tm5 hdf file
  1439. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1440. case ( 'tm5-hdf', 'tm5-nc' )
  1441. ! sp always storred in 'sp' files ...
  1442. call ReadField( tmm, archivekey, paramname, paramunit, tday, t1, t1, &
  1443. lli, 'n', sp, tmi, status )
  1444. IF_NOTOK_RETURN(status=1)
  1445. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1446. ! convert spectral lnsp
  1447. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1448. case ( 'ecmwf-tmpp', 'ncep-cdc', 'ncep-gfs', 'msc-data', 'prism' )
  1449. !DBG call wrtgol( ' tmm read : sp ', t1, ' - ', t2 ); call goPr
  1450. ! read LNSP
  1451. call FillBuffer( tmm, archivekey, 'LNSP', '1', tday, t1, t1, 'n', 'n', status )
  1452. IF_NOTOK_RETURN(status=1)
  1453. !write (gol,*) " read LNSP and convert to SP!"; call goPr
  1454. ! should be spectral ...
  1455. if ( tmm%buf_gridtype /= 'sh' ) then
  1456. write (gol,'("expecting sh field, not ",a)') tmm%buf_gridtype
  1457. TRACEBACK; status=1; return
  1458. end if
  1459. ! aera average exp(lnsp)
  1460. call IntArea( 'exp,aver', tmm%buf_shi, tmm%buf_sh(:,1), lli, sp, status )
  1461. IF_NOTOK_RETURN(status=1)
  1462. ! set history info
  1463. call Init( tmi, 'sp', 'Pa', status, (/tmm%buf_tmi/) )
  1464. call AddHistory( tmi, 'oper==exp,aver', status )
  1465. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1466. ! convert gaussian sp or spectral lnsp
  1467. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1468. case ( 'ecmwf-tm5' )
  1469. select case ( paramname )
  1470. case ( 'sp', 'SP' )
  1471. !DBG call wrtgol( ' tmm read : sp ', t1, ' - ', t2 ); call goPr
  1472. ! read LNSP
  1473. call FillBuffer( tmm, archivekey, 'LNSP', '1', tday, t1, t1, 'n', 'n', status )
  1474. IF_NOTOK_RETURN(status=1)
  1475. ! should be spectral ...
  1476. if ( tmm%buf_gridtype /= 'sh' ) then
  1477. write (gol,'("expecting sh field, not ",a)') tmm%buf_gridtype
  1478. TRACEBACK; status=1; return
  1479. end if
  1480. ! aera average exp(lnsp)
  1481. call IntArea( 'exp,aver', tmm%buf_shi, tmm%buf_sh(:,1), lli, sp, status )
  1482. IF_NOTOK_RETURN(status=1)
  1483. ! set history info
  1484. call Init( tmi, 'sp', 'Pa', status, (/tmm%buf_tmi/) )
  1485. call AddHistory( tmi, 'oper==exp,aver', status )
  1486. case ( 'sps', 'SPS' )
  1487. !DBG call wrtgol( ' tmm read : sps ', t1, ' - ', t2 ); call goPr
  1488. ! read gg field
  1489. call FillBuffer( tmm, archivekey, 'sp', 'Pa', tday, t1, t1, 'n', 'n', status )
  1490. IF_NOTOK_RETURN(status=1)
  1491. ! should be gg ...
  1492. if ( tmm%buf_gridtype /= 'gg' ) then
  1493. write (gol,'("expecting gg field, not ",a)') tmm%buf_gridtype
  1494. TRACEBACK; status=1; return
  1495. end if
  1496. ! determine fraction
  1497. call Init( gg2ll, tmm%buf_ggi, lli, status )
  1498. IF_NOTOK_RETURN(status=1)
  1499. ! take fractions of overlapping cells
  1500. call FracSum( gg2ll, tmm%buf_gg(:,1), sp, status, 'area-aver' )
  1501. IF_NOTOK_RETURN(status=1)
  1502. ! done
  1503. call Done( gg2ll )
  1504. ! set history info
  1505. call Init( tmi, 'sp', 'Pa', status, (/tmm%buf_tmi/) )
  1506. call AddHistory( tmi, 'oper==area-aver', status )
  1507. case default
  1508. write (gol,'("unsupported param `",a,"` for source type `",a,"`")') &
  1509. trim(paramname), trim(sourcetype); call goErr
  1510. TRACEBACK; status=1; return
  1511. end select
  1512. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1513. ! error ...
  1514. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1515. case default
  1516. write (gol,'("unsupported source type `",a,"`")') trim(sourcetype); call goErr
  1517. TRACEBACK; status=1; return
  1518. end select
  1519. ! ok
  1520. call goLabel()
  1521. status = 0
  1522. end subroutine tmm_Read_SP
  1523. ! *****************************************************************
  1524. #ifdef with_prism
  1525. SUBROUTINE TMM_READ_UVW( tmm, archivekey, tday, t1, t2, &
  1526. lli, levi, &
  1527. spu, mfu, mfu_tmi, &
  1528. spv, mfv, mfv_tmi, &
  1529. sp, mfw, tsp, tmi, &
  1530. status )
  1531. use Binas , only : R => ae
  1532. use Binas , only : g => grav
  1533. use Binas , only : p_global
  1534. use GO , only : goSplitLine
  1535. use Grid , only : TshGrid, Init, Done, Set
  1536. use Grid , only : IntLat, IntLon, vod2uv
  1537. use Grid , only : FillLevels, Nabla, IntArea, AreaOper
  1538. use tmm_info, only : TMeteoInfo, Init, Done, AddHistory
  1539. ! --- in/out --------------------------------
  1540. type(TTmMeteo), intent(inout) :: tmm
  1541. character(len=*), intent(in) :: archivekey
  1542. type(TDate), intent(in) :: tday, t1, t2
  1543. type(TllGridInfo), intent(in) :: lli
  1544. type(TLevelInfo), intent(in) :: levi
  1545. real, intent(out) :: spu(:,:) , spv(:,:) ! Pa
  1546. real, intent(out) :: mfu(:,:,:), mfv(:,:,:) ! kg/s ==> lower bounds become 1 !!!!
  1547. type(TMeteoInfo), intent(out) :: mfu_tmi, mfv_tmi
  1548. real, intent(out) :: sp(:,:) ! Pa
  1549. real, intent(out) :: mfw(:,:,:) ! kg/s
  1550. real, intent(out) :: tsp(:,:) ! tendency of surface pressure Pa/s
  1551. type(TMeteoInfo), intent(out) :: tmi
  1552. integer, intent(out) :: status
  1553. ! --- const ------------------------------------
  1554. character(len=*), parameter :: rname = mname//'/tmm_Read_UVW'
  1555. ! --- local -------------------------------
  1556. character(len=10) :: sourcetype
  1557. character(len=256) :: sourcename
  1558. type(TshGridInfo) :: shi
  1559. integer :: shT
  1560. integer :: nlev
  1561. ! spectral fields
  1562. type(TshGrid) :: LNSP_sh
  1563. complex , pointer :: D_sh(:,:), VO_sh(:,:)
  1564. complex , pointer :: U_sh(:,:), V_sh(:,:)
  1565. complex , pointer :: Help_LNSP_sh(:,:)
  1566. ! nabla.lnps
  1567. type(TshGrid) :: NabLNSP_sh(2)
  1568. ! integrated Omega arrays:
  1569. real, pointer :: IIOmega (:,:,:)
  1570. real, pointer :: IIOmega2(:,:,:)
  1571. ! mfu/mfv/mfw on source levels
  1572. real, allocatable :: mfuX(:,:,:)
  1573. real, allocatable :: mfvX(:,:,:)
  1574. real, pointer :: mfwX(:,:,:)
  1575. ! loops etc
  1576. integer :: l
  1577. ! extra info
  1578. type(TMeteoInfo) :: LNSP_tmi
  1579. type(TMeteoInfo) :: vo_tmi, div_tmi, u_tmi, v_tmi
  1580. ! temporary arrays
  1581. real, allocatable :: tmp_sp(:,:,:)
  1582. ! --- begin -------------------------------
  1583. call goLabel(rname)
  1584. ! split source key in type and name:
  1585. call goSplitLine( archivekey, sourcetype, ':', sourcename, status )
  1586. IF_NOTOK_RETURN(status=1)
  1587. ! input TMPP fields or raw prism fields ?
  1588. select case ( sourcetype )
  1589. case ( 'prism' )
  1590. !DBG call wrtgol( ' tmm read : mfuvw ', t1, ' - ', t2 ); call goPr
  1591. ! read LNSP
  1592. call FillBuffer( tmm, archivekey, 'LNSP', 'Pa', tday, t1, t1, 'n', 'n', status )
  1593. IF_NOTOK_RETURN(status=1)
  1594. ! check ...
  1595. call CheckBuffer( tmm, status, gridtype='sh' )
  1596. IF_NOTOK_RETURN(status=1)
  1597. ! extract grid size
  1598. call Init( shi, tmm%buf_shi, status )
  1599. IF_NOTOK_RETURN(status=1)
  1600. shT = tmm%buf_shi%T
  1601. ! copy 1d spectral lnsp from buffer:
  1602. call Init( LNSP_sh )
  1603. call Set( LNSP_sh, tmm%buf_shi%T, tmm%buf_sh(:,1) )
  1604. LNSP_tmi = tmm%buf_tmi
  1605. ! read VO
  1606. call FillBuffer( tmm, archivekey, 'VO', '1/s', tday, t1, t2, 'n', 'n', status )
  1607. IF_NOTOK_RETURN(status=1)
  1608. ! check ...
  1609. call CheckBuffer( tmm, status, gridtype='sh', shT=shi%T )
  1610. IF_NOTOK_RETURN(status=1)
  1611. ! extract grid size
  1612. nlev = tmm%buf_levi%nlev
  1613. ! copy 3d spectral field from buffer:
  1614. allocate( VO_sh(shi%np,nlev) )
  1615. VO_sh = tmm%buf_sh
  1616. vo_tmi = tmm%buf_tmi
  1617. ! read D
  1618. call FillBuffer( tmm, archivekey, 'D', '1/s', tday, t1, t2, 'n', 'n', status )
  1619. IF_NOTOK_RETURN(status=1)
  1620. ! check ...
  1621. call CheckBuffer( tmm, status, gridtype='sh', shT=shi%T, nlev=nlev )
  1622. IF_NOTOK_RETURN(status=1)
  1623. ! copy 3d spectral field from buffer:
  1624. allocate( D_sh(shi%np,nlev) )
  1625. D_sh = tmm%buf_sh
  1626. div_tmi = tmm%buf_tmi
  1627. !
  1628. ! compute U/V from VO/D
  1629. !
  1630. allocate( U_sh(shi%np,nlev) )
  1631. allocate( V_sh(shi%np,nlev) )
  1632. allocate( Help_LNSP_sh(shi%np,1) )
  1633. !$OMP PARALLEL &
  1634. !$OMP default ( none ) &
  1635. !$OMP shared ( nlev, shi, VO_sh, D_sh, U_sh, V_sh ) &
  1636. !$OMP private ( l )
  1637. do l = 1, nlev
  1638. call vod2uv( shi, VO_sh(:,l), D_sh(:,l), shi, U_sh(:,l), V_sh(:,l) )
  1639. enddo
  1640. !$OMP END PARALLEL
  1641. ! history ...
  1642. call Init( u_tmi, 'U', 'm/s', status, (/vo_tmi,div_tmi/) )
  1643. call Init( v_tmi, 'V', 'm/s', status, (/vo_tmi,div_tmi/) )
  1644. !
  1645. ! MFU = R/g int U (da+db*exp(LNSP)) / cos(lat) dlat
  1646. !
  1647. allocate( mfuX(0:lli%nlon,lli%nlat,nlev) )
  1648. allocate( tmp_sp(0:lli%nlon,lli%nlat,1) )
  1649. ! integral over boundary:
  1650. call IntLat( '(da+exp*db)/cos', shi, nlev, U_sh, LNSP_sh%c, &
  1651. tmm%buf_levi%da, tmm%buf_levi%db, lli, mfuX, status )
  1652. IF_NOTOK_RETURN(status=1)
  1653. mfuX = mfuX * R/g
  1654. ! average surface pressure on boundary:
  1655. Help_LNSP_sh(:,1)=LNSP_sh%c(:)
  1656. call IntLat( 'exp(H),aver',shi,1, Help_LNSP_sh, LNSP_sh%c, (/0.0/), (/0.0/), lli, tmp_sp, status )
  1657. IF_NOTOK_RETURN(status=1)
  1658. spu = tmp_sp(:,:,1)
  1659. ! collect levels:
  1660. call FillLevels( levi, 'n', spu, mfu, tmm%buf_levi, mfuX, 'sum', status )
  1661. IF_NOTOK_RETURN(status=1)
  1662. ! clear:
  1663. deallocate( mfuX )
  1664. deallocate( tmp_sp )
  1665. ! info ...
  1666. call Init( mfu_tmi, 'mfu', 'kg/s', status, (/u_tmi,LNSP_tmi/) )
  1667. call AddHistory( mfu_tmi, 'oper==intlat', status )
  1668. call AddHistory( mfu_tmi, 'oper==collectlevels', status )
  1669. !
  1670. ! MFV = R/g int V (da+db*exp(LNSP)) dlon
  1671. !
  1672. allocate( mfvX(lli%nlon,0:lli%nlat,nlev) )
  1673. allocate( tmp_sp(lli%nlon,0:lli%nlat,1) )
  1674. ! integral over boundary:
  1675. call IntLon( '(da+exp*db)',shi,nlev, V_sh, LNSP_sh%c, &
  1676. tmm%buf_levi%da, tmm%buf_levi%db, lli, mfvX, status )
  1677. IF_NOTOK_RETURN(status=1)
  1678. mfvX = mfvX * R/g
  1679. ! average surface pressure on boundary:
  1680. Help_LNSP_sh(:,1)=LNSP_sh%c(:)
  1681. call IntLon( 'exp(H),aver', shi,1,Help_LNSP_sh, LNSP_sh%c, (/0.0/), (/0.0/), lli, tmp_sp, status )
  1682. IF_NOTOK_RETURN(status=1)
  1683. spv = tmp_sp(:,:,1)
  1684. ! collect levels:
  1685. call FillLevels( levi, 'n', spv, mfv, tmm%buf_levi, mfvX, 'sum', status )
  1686. IF_NOTOK_RETURN(status=1)
  1687. ! clear:
  1688. deallocate( Help_LNSP_sh)
  1689. deallocate( mfvX )
  1690. deallocate( tmp_sp )
  1691. ! info ...
  1692. call Init( mfv_tmi, 'mfv', 'kg/s', status, (/v_tmi,LNSP_tmi/) )
  1693. call AddHistory( mfv_tmi, 'oper==intlon', status )
  1694. call AddHistory( mfv_tmi, 'oper==collectlevels', status )
  1695. !
  1696. ! MFW
  1697. !
  1698. allocate( IIOmega (lli%nlon,lli%nlat,nlev) )
  1699. allocate( IIOmega2(lli%nlon,lli%nlat,nlev) )
  1700. allocate( mfwX(lli%nlon,lli%nlat,nlev+1) )
  1701. !
  1702. ! int int D (da+db*exp(LNSP)) cos(lat) dA
  1703. !
  1704. IIOmega = 0.0
  1705. call IntArea( 'F*(da+db*exp(H))*cos', shi, nlev, D_sh, LNSP_sh%c, LNSP_sh%c, &
  1706. tmm%buf_levi%da, tmm%buf_levi%db, lli, IIOmega, status )
  1707. IF_NOTOK_RETURN(status=1)
  1708. ! int int U dLNSP1 exp(LNSP) db / cos(lat) dA
  1709. ! int int V dLNSP2 exp(LNSP) db / cos(lat) dA
  1710. !
  1711. call Init( NabLNSP_sh(1) )
  1712. call Init( NabLNSP_sh(2) )
  1713. call Nabla( LNSP_sh, NabLNSP_sh ) ! compute nabla.lnsp
  1714. ! integral over cell area; add contributions
  1715. IIOmega2 = 0.0
  1716. call IntArea( 'F*G*(db*exp(H))/cos', shi, nlev, U_sh, NabLNSP_sh(1)%c, LNSP_sh%c, &
  1717. tmm%buf_levi%da, tmm%buf_levi%db, lli, IIOmega2, status )
  1718. IF_NOTOK_RETURN(status=1)
  1719. call IntArea( 'F*G*(db*exp(H))/cos', shi, nlev, V_sh, NabLNSP_sh(2)%c, LNSP_sh%c, &
  1720. tmm%buf_levi%da, tmm%buf_levi%db, lli, IIOmega2, status )
  1721. IF_NOTOK_RETURN(status=1)
  1722. ! deallocate
  1723. call Done( NabLNSP_sh(1) )
  1724. call Done( NabLNSP_sh(2) )
  1725. !
  1726. ! column integrated Omega
  1727. !
  1728. ! parent levels downwards or upwards ?
  1729. if ( tmm%buf_levi%updo == 'd' ) then
  1730. ! loop from top to bottom:
  1731. do l = 1, nlev
  1732. ! replace with contribution of current level:
  1733. IIOmega(:,:,l) = (R**2)*IIOmega(:,:,l)/g + R*IIOmega2(:,:,l)/g
  1734. ! add contribution of previous levels:
  1735. if ( l > 1 ) then
  1736. IIOmega(:,:,l) = IIOmega(:,:,l) + IIOmega(:,:,l-1)
  1737. end if
  1738. end do
  1739. else
  1740. ! loop from top to bottom:
  1741. do l = nlev, 1, -1
  1742. ! replace with contribution of current level:
  1743. IIOmega(:,:,l) = (R**2)*IIOmega(:,:,l)/g + R*IIOmega2(:,:,l)/g
  1744. ! add contribution of levels above:
  1745. if ( l < nlev ) then
  1746. IIOmega(:,:,l) = IIOmega(:,:,l) + IIOmega(:,:,l+1)
  1747. end if
  1748. end do
  1749. end if
  1750. !
  1751. ! tendency of surface pressure
  1752. !
  1753. ! dps 1 dp
  1754. ! --- = - int nabla ( v ---- ) deta = - IIOmega(:,:,bot)
  1755. ! dt eta=0 deta
  1756. ! parent levels downwards or upwards ?
  1757. if ( tmm%buf_levi%updo == 'd' ) then
  1758. tsp = -1.0 * IIOmega(:,:,nlev) ! kg/s
  1759. else
  1760. tsp = -1.0 * IIOmega(:,:,1) ! kg/s
  1761. end if
  1762. ! convert to Pa/s :
  1763. call AreaOper( lli, tsp, '/', 'm2', status ) ! kg/m2/s
  1764. IF_NOTOK_RETURN(status=1)
  1765. tsp = tsp * g ! Pa/s
  1766. !
  1767. ! compute vertical flux:
  1768. !
  1769. ! parent levels downwards or upwards ?
  1770. if ( tmm%buf_levi%updo == 'd' ) then
  1771. ! top hlev:
  1772. mfwX(:,:,1) = 0.0 ! kg/s
  1773. ! loop from top to bottom layer:
  1774. do l = 1, nlev
  1775. ! lay l bot hlev surflay bot hlev lay l bot hlev lay l bot hlev
  1776. ! 2 .. nlev+1 nlev 0 .. nlev-1 1 .. nlev
  1777. mfwX(:,:,l+1) = IIOmega(:,:,nlev) * tmm%buf_levi%b(l) - IIOmega(:,:,l)
  1778. end do
  1779. else
  1780. ! top hlev:
  1781. mfwX(:,:,nlev+1) = 0.0 ! kg/s
  1782. ! loop from top to bottom layer:
  1783. do l = nlev, 1, -1
  1784. ! lay l bot hlev surflay bot hlev lay l bot hlev lay l bot hlev
  1785. ! 1 .. nlev nlev 0 .. nlev-1 1 .. nlev
  1786. mfwX(:,:,l) = IIOmega(:,:,1) * tmm%buf_levi%b(l-1) - IIOmega(:,:,l)
  1787. end do
  1788. end if
  1789. ! check: fluxh through bottom should be zero ...
  1790. if ( maxval(abs(mfwX(:,:,1))) > 1.0 ) then
  1791. write (gol,'("vert.flux through bottom half level should be zero ...")'); call goErr
  1792. write (gol,'(" max value : ",es12.4)') maxval(abs(mfwX(:,:,1))); call goErr
  1793. TRACEBACK; status=1; return
  1794. end if
  1795. ! create history
  1796. call Init( tmi, 'mfw', 'kg/s', status, (/lnsp_tmi,div_tmi,u_tmi,v_tmi/) )
  1797. !
  1798. ! collect levels
  1799. !
  1800. ! average surface pressure
  1801. call IntArea( 'exp,aver', tmm%buf_shi, LNSP_sh%c, lli, sp, status )
  1802. IF_NOTOK_RETURN(status=1)
  1803. ! combine levels etc
  1804. call FillLevels( levi, 'w', sp, mfw, tmm%buf_levi, mfwX, 'bottom', status )
  1805. IF_NOTOK_RETURN(status=1)
  1806. call AddHistory( tmi, 'oper==collectlevels', status )
  1807. !
  1808. ! upward flux
  1809. !
  1810. ! flux should be upwards (in direction of increasing level):
  1811. mfw = - mfw
  1812. call AddHistory( tmi, 'oper==upwards', status )
  1813. !
  1814. ! done
  1815. !
  1816. call Done( LNSP_sh )
  1817. deallocate( VO_sh )
  1818. deallocate( D_sh )
  1819. deallocate( U_sh )
  1820. deallocate( V_sh )
  1821. deallocate( IIOmega )
  1822. deallocate( IIOmega2 )
  1823. deallocate( mfwX )
  1824. call Done( lnsp_tmi, status )
  1825. call Done( vo_tmi, status )
  1826. call Done( div_tmi, status )
  1827. call Done( u_tmi, status )
  1828. call Done( v_tmi, status )
  1829. case default
  1830. write (gol,'("unsupported source type `",a,"`")') trim(sourcetype); call goErr
  1831. TRACEBACK; status=1; return
  1832. end select
  1833. call goLabel()
  1834. status = 0
  1835. END SUBROUTINE TMM_READ_UVW
  1836. #endif
  1837. ! *****************************************************************
  1838. subroutine tmm_Read_TQ( tmm, archivekey_T, archivekey_Q, tday, t1, t2, lli, levi, &
  1839. sp, T, T_tmi, Q, Q_tmi, status )
  1840. use GO , only : goSplitLine
  1841. use Binas , only : p_global
  1842. use Phys , only : RealTemperature
  1843. use tmm_info, only : TMeteoInfo, Init, Done, AddHistory
  1844. ! --- in/out --------------------------------
  1845. type(TTmMeteo), intent(inout) :: tmm
  1846. character(len=*), intent(in) :: archivekey_T
  1847. character(len=*), intent(in) :: archivekey_Q
  1848. type(TDate), intent(in) :: tday, t1, t2
  1849. type(TllGridInfo), intent(in) :: lli
  1850. type(TLevelInfo), intent(in) :: levi
  1851. real, intent(out) :: sp(:,:) ! Pa
  1852. real, intent(out) :: T(:,:,:) ! K
  1853. type(TMeteoInfo), intent(out) :: T_tmi
  1854. real, intent(out) :: Q(:,:,:) ! kg/kg
  1855. type(TMeteoInfo), intent(out) :: Q_tmi
  1856. integer, intent(out) :: status
  1857. ! --- const ------------------------------------
  1858. character(len=*), parameter :: rname = mname//'/tmm_Read_TQ'
  1859. ! --- local -------------------------------
  1860. character(len=10) :: sourcetype
  1861. character(len=256) :: sourcename
  1862. ! --- begin -------------------------------
  1863. ! split source key in type and name:
  1864. call goSplitLine( archivekey_T, sourcetype, ':', sourcename, status )
  1865. IF_NOTOK_RETURN(status=1)
  1866. ! input TMPP fields or raw prism fields ?
  1867. select case ( sourcetype )
  1868. case ( 'standard' )
  1869. ! fill field with global mean pressure:
  1870. sp = p_global
  1871. ! dummy values:
  1872. Q = 0.0
  1873. T = 0.0
  1874. ! set history info
  1875. call Init( Q_tmi, 'Q', 'kg/kg', status )
  1876. call AddHistory( Q_tmi, 'standard', status )
  1877. call Init( T_tmi, 'T', 'K', status )
  1878. call AddHistory( T_tmi, 'standard', status )
  1879. case ( 'tmpp', 'tm5-hdf', 'tm5-nc', 'ecmwf-tmpp', 'ecmwf-tm5', 'msc-data' )
  1880. ! humidity:
  1881. call ReadField( tmm, archivekey_Q, 'Q', 'kg/kg', tday, t1, t2, &
  1882. lli, 'n', levi, 'n', sp, Q, Q_tmi, status )
  1883. IF_NOTOK_RETURN(status=1)
  1884. ! temperature:
  1885. call ReadField( tmm, archivekey_T, 'T', 'K', tday, t1, t2, &
  1886. lli, 'n', levi, 'n', sp, T, T_tmi, status )
  1887. IF_NOTOK_RETURN(status=1)
  1888. case ( 'ncep-cdc', 'ncep-gfs' )
  1889. ! humidity:
  1890. call ReadField( tmm, archivekey_Q, 'Q', 'kg/kg', tday, t1, t2, &
  1891. lli, 'n', levi, 'n', sp, Q, Q_tmi, status )
  1892. IF_NOTOK_RETURN(status=1)
  1893. ! virtual temperature:
  1894. call ReadField( tmm, archivekey_T, 'Tv', 'K', tday, t1, t2, &
  1895. lli, 'n', levi, 'n', sp, T, T_tmi, status )
  1896. IF_NOTOK_RETURN(status=1)
  1897. ! convert:
  1898. T = RealTemperature( T, Q )
  1899. ! info:
  1900. call AddHistory( T_tmi, 'convert from virtual temperature', status )
  1901. case default
  1902. write (gol,'("unsupported temper source type `",a,"`")') trim(sourcetype); call goErr
  1903. TRACEBACK; status=1; return
  1904. end select
  1905. !
  1906. ! done
  1907. !
  1908. ! ok
  1909. status = 0
  1910. end subroutine tmm_Read_TQ
  1911. ! *****************************************************************
  1912. subroutine tmm_Read_CloudCovers( tmm, archivekey, tday, t1, t2, lli, levi, &
  1913. sp, cc, cc_tmi, cco, cco_tmi, ccu, ccu_tmi, status )
  1914. use GO , only : goSplitLine
  1915. use Binas , only : p_global
  1916. use Grid , only : FillLevels
  1917. use Phys , only : cf_overhead
  1918. use tmm_info , only : TMeteoInfo, Init, AddHistory
  1919. use tmm_param, only : GetCombineKeys
  1920. ! --- in/out --------------------------------
  1921. type(TTmMeteo), intent(inout) :: tmm
  1922. character(len=*), intent(in) :: archivekey
  1923. type(TDate), intent(in) :: tday, t1, t2
  1924. type(TllGridInfo), intent(in) :: lli
  1925. type(TLevelInfo), intent(in) :: levi
  1926. real, intent(out) :: sp(:,:) ! Pa
  1927. real, intent(out) :: cc(:,:,:), cco(:,:,:), ccu(:,:,:) ! 0-1
  1928. type(TMeteoInfo), intent(out) :: cc_tmi, cco_tmi, ccu_tmi
  1929. integer, intent(out) :: status
  1930. ! --- const ------------------------------------
  1931. character(len=*), parameter :: rname = mname//'/tmm_Read_CloudCovers'
  1932. ! --- local -------------------------------
  1933. character(len=10) :: sourcetype
  1934. character(len=256) :: sourcename
  1935. integer :: i, j, l, lme
  1936. real, allocatable :: cc_col(:)
  1937. real, allocatable :: cco_col(:), ccoX(:,:,:)
  1938. real, allocatable :: ccu_col(:), ccuX(:,:,:)
  1939. character(len=10) :: hcomb, vcomb
  1940. ! --- begin -------------------------------
  1941. call goLabel(rname)
  1942. ! check ...
  1943. if ( any(shape(cco)/=shape(cc)) .or. any(shape(ccu)/=shape(cc)) ) then
  1944. write (gol,'("output arrays should have same shape:")'); call goErr
  1945. write (gol,'(" cc : ",3i4)') shape( cc); call goErr
  1946. write (gol,'(" cco : ",3i4)') shape(cco); call goErr
  1947. write (gol,'(" ccu : ",3i4)') shape(ccu); call goErr
  1948. TRACEBACK; status=1; return
  1949. end if
  1950. ! split source key in type and name:
  1951. call goSplitLine( archivekey, sourcetype, ':', sourcename, status )
  1952. IF_NOTOK_RETURN(status=1)
  1953. ! input TMPP fields or raw prism fields ?
  1954. select case ( sourcetype )
  1955. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1956. ! standard values
  1957. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1958. case ( 'standard' )
  1959. ! fill field with global mean pressure:
  1960. sp = p_global
  1961. ! no clouds ...
  1962. cc = 0.0
  1963. cco = 0.0
  1964. ccu = 0.0
  1965. ! set history info
  1966. call Init( cc_tmi, 'CC', '0-1', status )
  1967. call AddHistory( cc_tmi, 'standard', status )
  1968. call Init( cco_tmi, 'CCO', '0-1', status )
  1969. call AddHistory( cc_tmi, 'standard', status )
  1970. call Init( ccu_tmi, 'CCU', '0-1', status )
  1971. call AddHistory( cc_tmi, 'standard', status )
  1972. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1973. ! read directly from hdf file
  1974. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1975. case ( 'tmpp', 'tm5-hdf', 'tm5-nc', 'prism' )
  1976. ! cloud cover
  1977. call ReadField( tmm, archivekey, 'CC', '1', tday, t1, t2, &
  1978. lli, 'n', levi, 'n', sp, cc, cc_tmi, status )
  1979. IF_NOTOK_RETURN(status=1)
  1980. ! cloud cover overhead
  1981. call ReadField( tmm, archivekey, 'CCO', '1', tday, t1, t2, &
  1982. lli, 'n', levi, 'n', sp, cco, cco_tmi, status )
  1983. IF_NOTOK_RETURN(status=1)
  1984. ! cloud cover underfeet
  1985. call ReadField( tmm, archivekey, 'CCU', '1', tday, t1, t2, &
  1986. lli, 'n', levi, 'n', sp, ccu, ccu_tmi, status )
  1987. IF_NOTOK_RETURN(status=1)
  1988. ! set extrema; stored values could be slightly outside [0,1]
  1989. cc = max( 0.0, min( cc, 1.0 ) )
  1990. cco = max( 0.0, min( cco, 1.0 ) )
  1991. ccu = max( 0.0, min( ccu, 1.0 ) )
  1992. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1993. ! convert from raw gg fields
  1994. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1995. case ( 'ecmwf-tmpp', 'ecmwf-tm5' )
  1996. !DBG call wrtgol( ' tmm read : cc ', t1, ' - ', t2 ); call goPr
  1997. !
  1998. ! read cc: gg, all levels
  1999. !
  2000. call FillBuffer( tmm, archivekey, 'CC', '1', tday, t1, t2, 'n', 'n', status )
  2001. IF_NOTOK_RETURN(status=1)
  2002. ! 3d horizontal conversion; result is stored in tmm%llX
  2003. call Transform3Dh( tmm, lli, 'n', levi, 'n', sp, cc_tmi, status )
  2004. IF_NOTOK_RETURN(status=1)
  2005. !
  2006. ! compute cloudcover overhead using all levels
  2007. !
  2008. ! unreduced number of levels:
  2009. lme = tmm%buf_levi%nlev
  2010. ! storage:
  2011. allocate( cc_col(lme) )
  2012. allocate( cco_col(lme) )
  2013. allocate( ccoX(lli%nlon,lli%nlat,lme) )
  2014. allocate( ccu_col(lme) )
  2015. allocate( ccuX(lli%nlon,lli%nlat,lme) )
  2016. ! loop over grid cells
  2017. do j = 1, lli%nlat
  2018. do i = 1, lli%nlon
  2019. ! overhead cloud cover:
  2020. cc_col = tmm%llX(i,j,:)
  2021. call cf_overhead ( lme, cc_col, cco_col )
  2022. ccoX(i,j,:) = cco_col
  2023. ! underfeet cloud cover; first reverse layers:
  2024. do l = 1, lme
  2025. cc_col(l) = tmm%llX(i,j,lme+1-l)
  2026. end do
  2027. call cf_overhead( lme, cc_col, ccu_col )
  2028. do l = 1, lme
  2029. ccuX(i,j,l) = ccu_col(lme+1-l)
  2030. end do
  2031. end do
  2032. end do
  2033. ! clear
  2034. deallocate( cc_col )
  2035. deallocate( cco_col )
  2036. deallocate( ccu_col )
  2037. ! info on this operation:
  2038. call AddHistory( cco_tmi, 'oper==cf_overhead', status )
  2039. !
  2040. ! 3d vertical conversions
  2041. !
  2042. ! convert from tmm%buf_llX to cc
  2043. call Transform3Dv( tmm, levi, 'n', sp, cc, cc_tmi, status )
  2044. IF_NOTOK_RETURN(status=1)
  2045. ! store ccoX in buffer, convert from tmm%llX to cco
  2046. call GetCombineKeys( hcomb, vcomb, 'cco', status )
  2047. IF_NOTOK_RETURN(status=1)
  2048. call FillLevels( levi, 'n', sp, cco, tmm%buf_levi, ccoX, vcomb, status )
  2049. IF_NOTOK_RETURN(status=1)
  2050. call AddHistory( cco_tmi, 'oper==vcomb,'//trim(vcomb), status )
  2051. ! store ccuX in buffer, convert from tmm%llX to ccu
  2052. call GetCombineKeys( hcomb, vcomb, 'ccu', status )
  2053. IF_NOTOK_RETURN(status=1)
  2054. call FillLevels( levi, 'n', sp, ccu, tmm%buf_levi, ccuX, vcomb, status )
  2055. IF_NOTOK_RETURN(status=1)
  2056. call AddHistory( ccu_tmi, 'oper==vcomb,'//trim(vcomb), status )
  2057. ! clear
  2058. deallocate( ccoX )
  2059. deallocate( ccuX )
  2060. ! set extrema; stored values could be slightly outside [0,1]
  2061. cc = max( 0.0, min( cc, 1.0 ) )
  2062. cco = max( 0.0, min( cco, 1.0 ) )
  2063. ccu = max( 0.0, min( ccu, 1.0 ) )
  2064. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2065. ! error
  2066. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2067. case default
  2068. write (gol,'("unsupported source type `",a,"`")') trim(sourcetype); call goErr
  2069. TRACEBACK; status=1; return
  2070. end select
  2071. ! ok
  2072. call goLabel()
  2073. status = 0
  2074. end subroutine tmm_Read_CloudCovers
  2075. ! *****************************************************************
  2076. subroutine tmm_Read_Convec( tmm, archivekey, tday, t1, t2, lli, levi, &
  2077. omega, omega_tmi, &
  2078. gph, gph_tmi, &
  2079. sp, &
  2080. entu, entu_tmi, entd, entd_tmi, &
  2081. detu, detu_tmi, detd, detd_tmi, &
  2082. status )
  2083. use GO , only : operator(-), operator(+), rTotal
  2084. use GO , only : goSplitLine, goVarValue
  2085. use Binas , only : p_global
  2086. use tmm_info, only : TMeteoInfo, Init, AddHistory
  2087. ! --- in/out --------------------------------
  2088. type(TTmMeteo), intent(inout) :: tmm
  2089. character(len=*), intent(in) :: archivekey
  2090. type(TDate), intent(in) :: tday, t1, t2
  2091. type(TllGridInfo), intent(in) :: lli
  2092. type(TLevelInfo), intent(in) :: levi
  2093. real, intent(in) :: omega(:,:,:) ! Pa/s
  2094. type(TMeteoInfo), intent(in) :: omega_tmi
  2095. real, intent(in) :: gph(:,:,:) ! m
  2096. type(TMeteoInfo), intent(in) :: gph_tmi
  2097. real, intent(out) :: sp(:,:) ! Pa
  2098. real, intent(out) :: entu(:,:,:), entd(:,:,:) ! kg/m2/s
  2099. type(TMeteoInfo), intent(out) :: entu_tmi, entd_tmi
  2100. real, intent(out) :: detu(:,:,:), detd(:,:,:) ! kg/m2/s
  2101. type(TMeteoInfo), intent(out) :: detu_tmi, detd_tmi
  2102. integer, intent(out) :: status
  2103. ! --- const ------------------------------------
  2104. character(len=*), parameter :: rname = mname//'/tmm_Read_Convec'
  2105. ! --- local -------------------------------
  2106. character(len=10) :: sourcetype
  2107. character(len=256) :: sourcename
  2108. integer :: lout
  2109. real, allocatable :: ll(:,:,:)
  2110. character(len=8) :: method
  2111. ! --- begin -------------------------------
  2112. call goLabel(rname)
  2113. !DBG call wrtgol( ' tmm read convec ', t1, ' - ', t2 ); call goPr
  2114. ! number of levels in output arrays:
  2115. lout = size(entu,3)
  2116. ! check ...
  2117. if ( (size(entd,3)/=lout) .or. &
  2118. (size(detu,3)/=lout) .or. (size(detd,3)/=lout) ) then
  2119. write (gol,'("output arrays should have same number of levels:")'); call goErr
  2120. write (gol,'(" entu : ",i4)') size(entu,3); call goErr
  2121. write (gol,'(" entd : ",i4)') size(entd,3); call goErr
  2122. write (gol,'(" detu : ",i4)') size(detu,3); call goErr
  2123. write (gol,'(" detd : ",i4)') size(detd,3); call goErr
  2124. TRACEBACK; status=1; return
  2125. end if
  2126. ! split source key in type and name:
  2127. call goSplitLine( archivekey, sourcetype, ':', sourcename, status )
  2128. IF_NOTOK_RETURN(status=1)
  2129. ! input TMPP fields or raw prism fields ?
  2130. select case ( sourcetype )
  2131. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2132. ! standard values
  2133. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2134. case ( 'standard')
  2135. ! fill field with global mean pressure:
  2136. sp = p_global
  2137. ! no convection ...
  2138. entu = 0.0
  2139. entd = 0.0
  2140. detu = 0.0
  2141. detd = 0.0
  2142. ! set history info
  2143. call Init( entu_tmi, 'eu', 'kg/m2/s', status )
  2144. call AddHistory( entu_tmi, 'standard', status )
  2145. call Init( entd_tmi, 'ed', 'kg/m2/s', status )
  2146. call AddHistory( entd_tmi, 'standard', status )
  2147. call Init( detu_tmi, 'du', 'kg/m2/s', status )
  2148. call AddHistory( detu_tmi, 'standard', status )
  2149. call Init( entd_tmi, 'dd', 'kg/m2/s', status )
  2150. call AddHistory( detd_tmi, 'standard', status )
  2151. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2152. ! read directly from hdf file
  2153. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2154. case ( 'tmpp', 'tm5-hdf', 'tm5-nc' )
  2155. ! full level output:
  2156. allocate( ll(lli%nlon,lli%nlat,levi%nlev) )
  2157. ! entrement updraught
  2158. call ReadField( tmm, archivekey, 'eu', 'kg/m2/s', tday, t1, t2, &
  2159. lli, 'n', levi, 'n', sp, ll, entu_tmi, status )
  2160. IF_NOTOK_RETURN(status=1)
  2161. !
  2162. entu = ll(:,:,1:lout)
  2163. ! entrement downdraught
  2164. call ReadField( tmm, archivekey, 'ed', 'kg/m2/s', tday, t1, t2, &
  2165. lli, 'n', levi, 'n', sp, ll, entd_tmi, status )
  2166. IF_NOTOK_RETURN(status=1)
  2167. !
  2168. entd = ll(:,:,1:lout)
  2169. ! detrement updraught
  2170. call ReadField( tmm, archivekey, 'du', 'kg/m2/s', tday, t1, t2, &
  2171. lli, 'n', levi, 'n', sp, ll, detu_tmi, status )
  2172. IF_NOTOK_RETURN(status=1)
  2173. !
  2174. detu = ll(:,:,1:lout)
  2175. ! detrement downdraught
  2176. call ReadField( tmm, archivekey, 'dd', 'kg/m2/s', tday, t1, t2, &
  2177. lli, 'n', levi, 'n', sp, ll, detd_tmi, status )
  2178. IF_NOTOK_RETURN(status=1)
  2179. !
  2180. detd = ll(:,:,1:lout)
  2181. ! clear
  2182. deallocate( ll )
  2183. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2184. ! ecmwf convective stuff
  2185. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2186. case ( 'ecmwf-tm5','prism' )
  2187. method = 'raw'
  2188. #ifdef with_prism
  2189. method = 'ec-ll'
  2190. #endif
  2191. ! overwrite method if provided in "source"
  2192. call goVarValue( sourcename, ';', 'method', '=', method, status )
  2193. IF_ERROR_RETURN(status=1)
  2194. select case ( method )
  2195. #ifdef with_tmm_convec_raw
  2196. case ( 'raw' )
  2197. call tmm_Read_Convec_raw( tmm, archivekey, tday, t1, t2, lli, levi, &
  2198. omega, omega_tmi, &
  2199. sp, &
  2200. entu, entu_tmi, entd, entd_tmi, &
  2201. detu, detu_tmi, detd, detd_tmi, &
  2202. status )
  2203. IF_NOTOK_RETURN(status=1)
  2204. #endif
  2205. #ifdef with_tmm_convec_ec_gg
  2206. case ( 'ec-gg' )
  2207. ! read ec flux/detr, convert to tm entr/detr, average to tm ll
  2208. call tmm_Read_Convec_EC_gg( tmm, archivekey, tday, t1, t2, lli, levi, &
  2209. omega, omega_tmi, &
  2210. sp, &
  2211. entu, entu_tmi, entd, entd_tmi, &
  2212. detu, detu_tmi, detd, detd_tmi, &
  2213. status )
  2214. IF_NOTOK_RETURN(status=1)
  2215. #endif
  2216. #ifdef with_tmm_convec_ec
  2217. case ( 'ec-ll' )
  2218. ! read ec flux/detr, aver to tm ll, convert to tm entr/detr
  2219. ! note: gph instead of omega
  2220. call tmm_Read_Convec_EC( tmm, archivekey, tday, t1, t2, lli, levi, &
  2221. gph, gph_tmi, &
  2222. sp, &
  2223. entu, entu_tmi, entd, entd_tmi, &
  2224. detu, detu_tmi, detd, detd_tmi, &
  2225. status )
  2226. IF_NOTOK_RETURN(status=1)
  2227. #endif
  2228. case default
  2229. write (gol,'("unsupported convec method : ",a)') trim(method); call goErr
  2230. TRACEBACK; status=1; return
  2231. end select
  2232. #ifdef with_tmm_convec_raw
  2233. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2234. ! convert from raw fields (sh,gg)
  2235. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2236. case ( 'ecmwf-tmpp', 'ncep-cdc', 'ncep-gfs', 'msc-data' )
  2237. call tmm_Read_Convec_raw( tmm, archivekey, tday, t1, t2, lli, levi, &
  2238. omega, omega_tmi, &
  2239. sp, &
  2240. entu, entu_tmi, entd, entd_tmi, &
  2241. detu, detu_tmi, detd, detd_tmi, &
  2242. status )
  2243. IF_NOTOK_RETURN(status=1)
  2244. #endif
  2245. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2246. ! error
  2247. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2248. case default
  2249. write (gol,'("unsupported source type `",a,"`")') trim(sourcetype); call goErr
  2250. TRACEBACK; status=1; return
  2251. end select
  2252. ! ok
  2253. call goLabel()
  2254. status = 0
  2255. end subroutine tmm_Read_Convec
  2256. ! *****************************************************************
  2257. subroutine tmm_Read_Diffus( tmm, archivekey, tday, t1, t2, lli, levi, &
  2258. sp, Kzz, Kzz_tmi, &
  2259. status )
  2260. use GO , only : operator(-), operator(+), rTotal
  2261. use GO , only : goSplitLine, goVarValue
  2262. use Binas , only : p_global
  2263. use tmm_info, only : TMeteoInfo, Init, AddHistory
  2264. ! --- in/out --------------------------------
  2265. type(TTmMeteo), intent(inout) :: tmm
  2266. character(len=*), intent(in) :: archivekey
  2267. type(TDate), intent(in) :: tday, t1, t2
  2268. type(TllGridInfo), intent(in) :: lli
  2269. type(TLevelInfo), intent(in) :: levi
  2270. real, intent(out) :: sp(:,:) ! Pa
  2271. real, intent(out) :: Kzz(:,:,:) ! kg/m2/s
  2272. type(TMeteoInfo), intent(out) :: Kzz_tmi
  2273. integer, intent(out) :: status
  2274. ! --- const ------------------------------------
  2275. character(len=*), parameter :: rname = mname//'/tmm_Read_Diffus'
  2276. ! --- local -------------------------------
  2277. character(len=10) :: sourcetype
  2278. character(len=256) :: sourcename
  2279. integer :: lout
  2280. real, allocatable :: ll(:,:,:)
  2281. character(len=8) :: method
  2282. ! --- begin -------------------------------
  2283. call goLabel(rname)
  2284. !DBG call wrtgol( ' tmm read diffus ', t1, ' - ', t2 ); call goPr
  2285. ! number of levels in output arrays:
  2286. lout = size(Kzz,3)
  2287. ! split source key in type and name:
  2288. call goSplitLine( archivekey, sourcetype, ':', sourcename, status )
  2289. IF_NOTOK_RETURN(status=1)
  2290. ! input TMPP fields or raw prism fields ?
  2291. select case ( sourcetype )
  2292. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2293. ! standard values
  2294. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2295. case ( 'standard')
  2296. ! fill field with global mean pressure:
  2297. sp = p_global
  2298. ! no diffusion ...
  2299. Kzz = 0.0
  2300. ! set history info
  2301. call Init( Kzz_tmi, 'K', 'kg/m2/s', status )
  2302. call AddHistory( Kzz_tmi, 'standard', status )
  2303. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2304. ! read directly from hdf file
  2305. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2306. case ( 'tmpp', 'tm5-hdf', 'tm5-nc' )
  2307. ! half level output:
  2308. allocate( ll(lli%nlon,lli%nlat,levi%nlev+1) )
  2309. ! diffusion flux at half levels:
  2310. call ReadField( tmm, archivekey, 'K', 'kg/m2/s', tday, t1, t2, &
  2311. lli, 'n', levi, 'w', sp, ll, Kzz_tmi, status )
  2312. IF_NOTOK_RETURN(status=1)
  2313. !
  2314. Kzz = ll(:,:,1:lout)
  2315. ! clear
  2316. deallocate( ll )
  2317. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2318. ! ecmwf convective stuff
  2319. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2320. case ( 'ecmwf-tm5','prism' )
  2321. ! read ec flux/detr, aver to tm ll, convert to tm entr/detr
  2322. ! note: gph instead of omega
  2323. call tmm_Read_Diffus_EC( tmm, archivekey, tday, t1, t2, lli, levi, &
  2324. sp, &
  2325. Kzz, Kzz_tmi, &
  2326. status )
  2327. IF_NOTOK_RETURN(status=1)
  2328. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2329. ! error
  2330. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2331. case default
  2332. write (gol,'("unsupported source type `",a,"`")') trim(sourcetype); call goErr
  2333. TRACEBACK; status=1; return
  2334. end select
  2335. ! ok
  2336. call goLabel()
  2337. status = 0
  2338. end subroutine tmm_Read_Diffus
  2339. ! *****************************************************************
  2340. #ifdef with_tmm_convec_raw
  2341. subroutine tmm_Read_Convec_raw( tmm, archivekey, tday, t1, t2, lli, levi, &
  2342. omega, omega_tmi, &
  2343. sp, &
  2344. entu, entu_tmi, entd, entd_tmi, &
  2345. detu, detu_tmi, detd, detd_tmi, &
  2346. status )
  2347. use Binas , only : grav
  2348. use GO , only : Get, IncrDate
  2349. use GO , only : operator(-), operator(+), rTotal, iTotal
  2350. use GO , only : goSplitLine
  2351. use Phys , only : mid2bound_uv, mid2bound_w, mid2bound_t
  2352. use Phys , only : mid2bound_q, mid2bound_z, mid2bound_p
  2353. use Phys , only : subscal, phlev_ec_rev, geopot
  2354. use Phys , only : subscal_2d
  2355. use Phys , only : RealTemperature
  2356. use Phys , only : GeoPotentialHeightB
  2357. use Phys , only : ECconv_to_TMconv
  2358. use Grid , only : HPressure, FPressure, FillLevels
  2359. use Grid , only : TShGrid, VoD2UV
  2360. use Grid , only : InterpolMask, Divergence, Tgg2llFracs, FracSum, AreaOper
  2361. use Grid , only : Init, Done, Set, Interpol
  2362. use Grid , only : NewInterpol
  2363. use tmm_info, only : TMeteoInfo, Init, AddHistory
  2364. ! --- in/out --------------------------------
  2365. type(TTmMeteo), intent(inout) :: tmm
  2366. character(len=*), intent(in) :: archivekey
  2367. type(TDate), intent(in) :: tday, t1, t2
  2368. type(TllGridInfo), intent(in) :: lli
  2369. type(TLevelInfo), intent(in) :: levi
  2370. real, intent(in) :: omega(:,:,:) ! Pa/s
  2371. type(TMeteoInfo), intent(in) :: omega_tmi
  2372. real, intent(out) :: sp(:,:) ! Pa
  2373. real, intent(out) :: entu(:,:,:), entd(:,:,:) ! kg/m2/s
  2374. type(TMeteoInfo), intent(out) :: entu_tmi, entd_tmi
  2375. real, intent(out) :: detu(:,:,:), detd(:,:,:) ! kg/m2/s
  2376. type(TMeteoInfo), intent(out) :: detu_tmi, detd_tmi
  2377. integer, intent(out) :: status
  2378. ! --- const ------------------------------------
  2379. character(len=*), parameter :: rname = mname//'/tmm_Read_Convec_raw'
  2380. ! --- local -------------------------------
  2381. character(len=10) :: sourcetype
  2382. character(len=256) :: sourcename
  2383. integer :: lout
  2384. real, pointer :: ll(:,:,:)
  2385. ! timing
  2386. integer :: hour
  2387. real :: dhour
  2388. integer :: dth
  2389. type(TDate) :: t1s, t2s
  2390. type(TDate) :: t1m, t2m
  2391. logical :: skip_second
  2392. ! loops etc
  2393. integer :: l, nlev
  2394. integer :: i, i1, i2, j
  2395. ! spectral fields
  2396. type(TshGridInfo) :: shi
  2397. complex, pointer :: LNSP_sh(:)
  2398. complex, pointer :: D_sh(:,:), VO_sh(:,:)
  2399. complex, pointer :: U_sh(:), V_sh(:)
  2400. ! gaussian grids
  2401. integer :: ggN
  2402. logical :: reduced
  2403. type(TggGridInfo) :: ggi
  2404. real, pointer :: gg(:)
  2405. real, pointer :: slhf_gg(:)
  2406. real, pointer :: oro_gg(:)
  2407. real, pointer :: sp_gg(:)
  2408. real, pointer :: m_gg(:)
  2409. real, pointer :: u_gg(:,:)
  2410. real, pointer :: v_gg(:,:)
  2411. real, pointer :: w_gg(:,:)
  2412. real, pointer :: t_gg(:,:)
  2413. real, pointer :: q_gg(:,:)
  2414. real, pointer :: p_gg(:,:)
  2415. real, pointer :: z_gg(:,:)
  2416. logical, pointer :: ggmask(:)
  2417. real, pointer :: qam_gg(:,:), qac_gg(:,:)
  2418. real, pointer :: entu_gg(:,:)
  2419. real, pointer :: detu_gg(:,:)
  2420. real, pointer :: entd_gg(:,:)
  2421. real, pointer :: detd_gg(:,:)
  2422. type(Tgg2llFracs) :: gg2ll
  2423. real, pointer :: llX(:,:,:)
  2424. ! subgrid stuff
  2425. real :: dt_sec
  2426. real :: evap
  2427. real, pointer :: p_hlev(:)
  2428. ! extra info
  2429. type(TMeteoInfo) :: slhf_tmi, sp_tmi, oro_tmi
  2430. type(TMeteoInfo) :: vo_tmi, div_tmi, u_tmi, v_tmi
  2431. type(TMeteoInfo) :: w_tmi, t_tmi, q_tmi
  2432. ! reversed levels
  2433. type(TLevelInfo) :: leviX
  2434. real, pointer :: aX(:), bX(:)
  2435. real, pointer :: tmp_gg(:,:)
  2436. ! --- begin -------------------------------
  2437. ! number of levels in output arrays:
  2438. lout = size(entu,3)
  2439. ! check ...
  2440. if ( (size(entd,3)/=lout) .or. &
  2441. (size(detu,3)/=lout) .or. (size(detd,3)/=lout) ) then
  2442. write (gol,'("output arrays should have same number of levels:")'); call goErr
  2443. write (gol,'(" entu : ",i4)') size(entu,3); call goErr
  2444. write (gol,'(" entd : ",i4)') size(entd,3); call goErr
  2445. write (gol,'(" detu : ",i4)') size(detu,3); call goErr
  2446. write (gol,'(" detd : ",i4)') size(detd,3); call goErr
  2447. TRACEBACK; status=1; return
  2448. end if
  2449. ! split source key in type and name:
  2450. call goSplitLine( archivekey, sourcetype, ':', sourcename, status )
  2451. IF_NOTOK_RETURN(status=1)
  2452. ! length of time interval:
  2453. dth = iTotal( t2 - t1, 'hour' )
  2454. dt_sec = dth * 3600.0
  2455. ! 3 hourly or 6 hourly ?
  2456. select case ( dth )
  2457. !
  2458. ! ~~ 6 hourly
  2459. !
  2460. case ( 6 )
  2461. ! only around hours 00/06/12/ etc yet ...
  2462. call Get( t1, hour=hour )
  2463. if ( modulo(hour,6) /= 3 ) then
  2464. write (gol,'("6 hourly convection only for intervals [21,03], [03,09], ...")'); call goErr
  2465. TRACEBACK; status=1; return
  2466. end if
  2467. ! times for model level fields is mid of requested interval:
  2468. t1m = t1 + IncrDate(sec=nint(dt_sec/2))
  2469. t2m = t1m
  2470. ! use 6 hour interval around requested (instant!) time to read slhf;
  2471. ! for 3 hourly request, this means double reading
  2472. ! (no problem since slhf is time average anyway)
  2473. !
  2474. ! slhf (gg)
  2475. !
  2476. ! first interval: [t1-dt/2,t1]
  2477. t1s = t1 - IncrDate(sec=int(dt_sec/2))
  2478. t2s = t1
  2479. !call wrtgol( ' tmm read : slhf ', t1s, ' - ', t2s ); call goPr
  2480. ! read first slhf in buffer (W/m2 time aver):
  2481. call FillBuffer( tmm, archivekey, 'slhf', 'W/m2', tday, t1s, t2s, 'n', 'n', status )
  2482. IF_NOTOK_RETURN(status=1)
  2483. ! check ...
  2484. call CheckBuffer( tmm, status, gridtype='gg' )
  2485. IF_NOTOK_RETURN(status=1)
  2486. ! extract grid size
  2487. ggN = tmm%buf_ggi%N
  2488. reduced = tmm%buf_ggi%reduced
  2489. ! setup gg defintion from buffer:
  2490. call Init( ggi, ggN, reduced, status )
  2491. IF_NOTOK_RETURN(status=1)
  2492. ! allocate storage:
  2493. allocate( oro_gg(ggi%np) )
  2494. allocate( slhf_gg(ggi%np) )
  2495. allocate( sp_gg(ggi%np) )
  2496. ! store first half of slhf (accumulated over 3 hr):
  2497. slhf_gg = tmm%buf_gg(:,1) * dt_sec/2 ! W/m2 s
  2498. slhf_tmi = tmm%buf_tmi
  2499. ! second interval: [t1,t1+dt/2]
  2500. t1s = t1
  2501. t2s = t1 + IncrDate(sec=int(dt_sec/2))
  2502. !call wrtgol( ' tmm read : slhf ', t1s, ' - ', t2s ); call goPr
  2503. ! read first slhf in buffer (W/m2 time aver):
  2504. call FillBuffer( tmm, archivekey, 'slhf', 'W/m2', tday, t1s, t2s, 'n', 'n', status )
  2505. IF_NOTOK_RETURN(status=1)
  2506. ! check ...
  2507. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np )
  2508. IF_NOTOK_RETURN(status=1)
  2509. ! add second half of slhf (accumulated over 3 hr):
  2510. slhf_gg = slhf_gg + tmm%buf_gg(:,1) * dt_sec/2 ! W/m2 s
  2511. ! copy info
  2512. call AddHistory( slhf_tmi, tmm%buf_tmi, status )
  2513. !
  2514. ! ~~ 3 hourly
  2515. !
  2516. #ifdef with_tmm_ecearth
  2517. case ( 0 )
  2518. ! assume this is the 6 hourly meteo ...
  2519. ! only for times around 00, 06, ...
  2520. call Get( t1, hour=hour )
  2521. if ( modulo(hour,6) /= 0 ) then
  2522. write (gol,'("6 hourly convection only for intervals [00,06], [06,12], ...")'); call goErr
  2523. TRACEBACK; status=1; return
  2524. end if
  2525. ! times for model level fields is begin of requested interval
  2526. t1m = t1
  2527. t2m = t1m
  2528. ! use 12 hour interval around requested (instant!) time to read slhf;
  2529. !
  2530. ! slhf (gg), accumulated over [-6,6] hours
  2531. !
  2532. ! slhf will be valid for [-6,6]
  2533. dt_sec = 12*3600.0
  2534. ! second field should be read
  2535. skip_second = .false.
  2536. #else
  2537. case ( 0, 3 )
  2538. ! convective stuff for instant time;
  2539. ! assume this is the 3 hourly meteo ...
  2540. ! only for times around 00, 03, ...
  2541. call Get( t1, hour=hour )
  2542. if ( modulo(hour,3) /= 0 ) then
  2543. write (gol,'("3 hourly convection only for intervals [00,03], [03,06], ...")'); call goErr
  2544. TRACEBACK; status=1; return
  2545. end if
  2546. ! times for model level fields is begin of requested interval
  2547. ! (just a choice)
  2548. t1m = t1
  2549. t2m = t1m
  2550. ! use 6 hour interval around requested (instant!) time to read slhf;
  2551. ! for 3 hourly request, this means double reading
  2552. ! (no problem since slhf is time average anyway)
  2553. !
  2554. ! slhf (gg), accumulated over [-3,3] hours
  2555. !
  2556. ! slhf will be valid for [-3,3]
  2557. dt_sec = 6*3600.0
  2558. ! forecast for 72 hour or later ? then slhf for [-6,6]
  2559. if ( rTotal(t1-tday,'hour') >= 12.0+72.0 ) dt_sec = 12*3600.0
  2560. ! forecast for fcday 10 is only for [00:00,12:00] where 12:00 is 12+240,
  2561. ! thus no second interval; instead copy from first
  2562. skip_second = rTotal(t1-tday,'hour') >= 12.0+240.0
  2563. ! >>> adhoc: always skip second interval,
  2564. ! because of problems with setting tday;
  2565. ! for requested time, this could be previous day
  2566. ! while slhf is taken from two different days
  2567. ! (in fact routines should be called with two tdays rather than one)
  2568. !skip_second = .true.
  2569. !write (gol,'("WARNING - skipped second interval for slhf")'); call goPr
  2570. #endif
  2571. ! first interval: [t1-dt,t1]
  2572. t1s = t1 - IncrDate(sec=int(dt_sec/2))
  2573. t2s = t1
  2574. !call wrtgol( ' tmm read : slhf ', t1s, ' - ', t2s ); call goPr
  2575. ! read first slhf in buffer (W/m2 time aver):
  2576. call FillBuffer( tmm, archivekey, 'slhf', 'W/m2', tday, t1s, t2s, 'n', 'n', status )
  2577. IF_NOTOK_RETURN(status=1)
  2578. ! check ...
  2579. call CheckBuffer( tmm, status, gridtype='gg' )
  2580. IF_NOTOK_RETURN(status=1)
  2581. ! extract grid size
  2582. ggN = tmm%buf_ggi%N
  2583. reduced = tmm%buf_ggi%reduced
  2584. ! setup gg defintion from buffer:
  2585. call Init( ggi, ggN, reduced, status )
  2586. IF_NOTOK_RETURN(status=1)
  2587. ! allocate storage:
  2588. allocate( oro_gg(ggi%np) )
  2589. allocate( slhf_gg(ggi%np) )
  2590. allocate( sp_gg(ggi%np) )
  2591. ! store first half of slhf (accumulated over 3/6 hr):
  2592. slhf_gg = tmm%buf_gg(:,1) * dt_sec/2 ! W/m2 s
  2593. slhf_tmi = tmm%buf_tmi
  2594. ! second interval: [t1,t1+dt]
  2595. t1s = t1
  2596. t2s = t1 + IncrDate(sec=int(dt_sec/2))
  2597. ! skip seond interval ?
  2598. if ( skip_second ) then
  2599. !DBG call wrtgol( 'tmm copy : slhf ', t1s, ' - ', t2s ); call goPr
  2600. ! use for the second field the first:
  2601. slhf_gg = slhf_gg * 2
  2602. else
  2603. !call wrtgol( ' tmm read : slhf ', t1s, ' - ', t2s ); call goPr
  2604. ! read second slhf in buffer (W/m2 time aver):
  2605. call FillBuffer( tmm, archivekey, 'slhf', 'W/m2', tday, t1s, t2s, 'n', 'n', status )
  2606. IF_NOTOK_RETURN(status=1)
  2607. ! check ...
  2608. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np )
  2609. IF_NOTOK_RETURN(status=1)
  2610. ! add second half of slhf (accumulated over 3 hr):
  2611. slhf_gg = slhf_gg + tmm%buf_gg(:,1) * dt_sec/2 ! W/m2 s
  2612. ! copy info
  2613. call AddHistory( slhf_tmi, tmm%buf_tmi, status )
  2614. end if
  2615. !
  2616. ! ~~ error
  2617. !
  2618. case default
  2619. write (gol,'("unsupported lenght of time interval : ",i4)') dth; call goErr
  2620. TRACEBACK; status=1; return
  2621. end select
  2622. !
  2623. ! orography (gg)
  2624. !
  2625. !write (gol,'(" tmm read : oro")'); call goPr
  2626. ! read orography in buffer:
  2627. call FillBuffer( tmm, archivekey, 'oro', 'm m/s2', tday, t1, t1, 'n', 'n', status )
  2628. IF_NOTOK_RETURN(status=1)
  2629. ! interpol from sh ?
  2630. select case ( tmm%buf_gridtype )
  2631. case ( 'gg' )
  2632. ! copy from buffer:
  2633. oro_gg = tmm%buf_gg(:,1) ! m*[g]
  2634. case ( 'sh' )
  2635. ! interpol from sh to gg :
  2636. call Interpol( tmm%buf_shi, tmm%buf_sh(:,1), ggi, oro_gg, status )
  2637. IF_NOTOK_RETURN(status=1)
  2638. case default
  2639. write (gol,'("unsupported grid type `",a,"` for raw oro")') tmm%buf_gridtype
  2640. TRACEBACK; status=1; return
  2641. end select
  2642. ! store:
  2643. oro_tmi = tmm%buf_tmi
  2644. !
  2645. ! read raw 3d fields
  2646. !
  2647. ! ~~~
  2648. !call wrtgol( ' tmm read : u,v ', t1m, ' - ', t2m ); call goPr
  2649. ! read VO
  2650. call FillBuffer( tmm, archivekey, 'VO', '1/s', tday, t1m, t2m, 'n', 'n', status )
  2651. IF_NOTOK_RETURN(status=1)
  2652. ! check ...
  2653. call CheckBuffer( tmm, status, gridtype='sh' )
  2654. IF_NOTOK_RETURN(status=1)
  2655. ! extract other grid sizes
  2656. call Init( shi, tmm%buf_shi, status )
  2657. IF_NOTOK_RETURN(status=1)
  2658. nlev = tmm%buf_levi%nlev
  2659. ! allocate 3d storage:
  2660. allocate( u_gg(ggi%np,0:nlev) )
  2661. allocate( v_gg(ggi%np,0:nlev) )
  2662. allocate( w_gg(ggi%np,0:nlev) )
  2663. allocate( t_gg(ggi%np,0:nlev) )
  2664. allocate( q_gg(ggi%np,0:nlev) )
  2665. allocate( p_gg(ggi%np,0:nlev) )
  2666. allocate( z_gg(ggi%np,0:nlev) )
  2667. ! copy 3d spectral field from buffer:
  2668. allocate( VO_sh(shi%np,nlev) )
  2669. VO_sh = tmm%buf_sh
  2670. ! copy info
  2671. vo_tmi = tmm%buf_tmi
  2672. ! read D
  2673. call FillBuffer( tmm, archivekey, 'D', '1/s', tday, t1m, t2m, 'n', 'n', status )
  2674. IF_NOTOK_RETURN(status=1)
  2675. ! check ...
  2676. call CheckBuffer( tmm, status, gridtype='sh', shT=shi%T, nlev=nlev )
  2677. IF_NOTOK_RETURN(status=1)
  2678. ! copy 3d spectral field from buffer:
  2679. allocate( D_sh(shi%np,nlev) )
  2680. D_sh = tmm%buf_sh
  2681. ! copy info
  2682. div_tmi = tmm%buf_tmi
  2683. ! convert from sh VO/D to gg U/V
  2684. ! setup storage:
  2685. allocate( U_sh(shi%np) )
  2686. allocate( V_sh(shi%np) )
  2687. ! loop over levels:
  2688. !xOMP PARALLEL &
  2689. !xOMP default ( none ) &
  2690. !xOMP shared ( nlev, shi, VO_sh, D_sh ) &
  2691. !xOMP shared ( ggi, u_gg, v_gg ) &
  2692. !xOMP private ( l, U_sh, V_sh, status )
  2693. !xOMP DO
  2694. do l = 1, nlev
  2695. ! convert to U=u*cos(lat) and V=v*cos(lat) :
  2696. call vod2uv( shi, VO_sh(:,l), D_sh(:,l), shi, U_sh, V_sh )
  2697. ! convert to Gaussian grid:
  2698. call NewInterpol( shi, U_sh, ggi, u_gg(:,l), status )
  2699. !IF_NOTOK_RETURN(status=1)
  2700. call NewInterpol( shi, V_sh, ggi, v_gg(:,l), status )
  2701. !IF_NOTOK_RETURN(status=1)
  2702. end do
  2703. !xOMP END DO
  2704. !xOMP END PARALLEL
  2705. ! clear
  2706. call Done( shi )
  2707. deallocate( U_sh )
  2708. deallocate( V_sh )
  2709. ! history ...
  2710. call Init( u_tmi, 'u', 'm/s', status, (/vo_tmi,div_tmi/) )
  2711. call Init( v_tmi, 'u', 'm/s', status, (/vo_tmi,div_tmi/) )
  2712. call AddHistory( u_tmi, 'VoD to UV;;interpol to gg', status )
  2713. call AddHistory( v_tmi, 'VoD to UV;;interpol to gg', status )
  2714. ! clear
  2715. deallocate( VO_sh )
  2716. deallocate( D_sh )
  2717. ! remove cos(lat) factor:
  2718. do j = 1, ggi%nlat
  2719. i1 = ggi%i1(j)
  2720. i2 = ggi%im(j)
  2721. u_gg(i1:i2,1:nlev) = u_gg(i1:i2,1:nlev) / cos(ggi%lat(j))
  2722. v_gg(i1:i2,1:nlev) = v_gg(i1:i2,1:nlev) / cos(ggi%lat(j))
  2723. end do
  2724. call AddHistory( u_tmi, 'divide by cos(lat)', status )
  2725. call AddHistory( v_tmi, 'divide by cos(lat)', status )
  2726. ! ~~~
  2727. select case ( sourcetype )
  2728. case ( 'ecmwf-tmpp', 'msc-data' )
  2729. !call wrtgol( ' tmm read : Q ', t1m, ' - ', t2m ); call goPr
  2730. ! read humidity
  2731. call FillBuffer( tmm, archivekey, 'Q', 'kg/kg', tday, t1m, t2m, 'n', 'n', status )
  2732. IF_NOTOK_RETURN(status=1)
  2733. ! check ...
  2734. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=nlev )
  2735. IF_NOTOK_RETURN(status=1)
  2736. ! copy 3d gg field from buffer; copy info:
  2737. Q_gg(:,1:nlev) = tmm%buf_gg ! kg h2o / kg air
  2738. ! info ...
  2739. call Init( Q_tmi, tmm%buf_tmi, status )
  2740. ! copy surface pressure:
  2741. sp_gg = tmm%buf_sp_gg ! Pa
  2742. call Init( sp_tmi, 'sp', 'Pa', status, (/tmm%buf_tmi/) )
  2743. !call wrtgol( ' tmm read : T ', t1m, ' - ', t2m ); call goPr
  2744. ! read T
  2745. call FillBuffer( tmm, archivekey, 'T', 'K', tday, t1m, t2m, 'n', 'n', status )
  2746. IF_NOTOK_RETURN(status=1)
  2747. ! check ...
  2748. call CheckBuffer( tmm, status, gridtype='sh', shT=shi%T, nlev=nlev )
  2749. IF_NOTOK_RETURN(status=1)
  2750. do l = 1, nlev
  2751. call Interpol( tmm%buf_shi, tmm%buf_sh(:,l), ggi, T_gg(:,l), status )
  2752. IF_NOTOK_RETURN(status=1)
  2753. end do
  2754. ! info ...
  2755. call Init( T_tmi, tmm%buf_tmi, status )
  2756. call AddHistory( T_tmi, 'interpol to gg', status )
  2757. case ( 'ecmwf-tm5' )
  2758. !call wrtgol( ' tmm read : Q ', t1m, ' - ', t2m ); call goPr
  2759. ! read humidity
  2760. call FillBuffer( tmm, archivekey, 'Q', 'kg/kg', tday, t1m, t2m, 'n', 'n', status )
  2761. IF_NOTOK_RETURN(status=1)
  2762. ! check ...
  2763. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=nlev )
  2764. IF_NOTOK_RETURN(status=1)
  2765. ! copy 3d gg field from buffer::
  2766. Q_gg(:,1:nlev) = tmm%buf_gg ! kg h2o / kg air
  2767. ! info ...
  2768. call Init( Q_tmi, tmm%buf_tmi, status )
  2769. ! copy surface pressure:
  2770. sp_gg = tmm%buf_sp_gg ! Pa
  2771. call Init( sp_tmi, 'sp', 'Pa', status, (/tmm%buf_tmi/) )
  2772. !call wrtgol( ' tmm read : T ', t1m, ' - ', t2m ); call goPr
  2773. ! read T
  2774. call FillBuffer( tmm, archivekey, 'T', 'K', tday, t1m, t2m, 'n', 'n', status )
  2775. IF_NOTOK_RETURN(status=1)
  2776. ! check ...
  2777. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=nlev )
  2778. IF_NOTOK_RETURN(status=1)
  2779. ! copy 3d gg field from buffer::
  2780. T_gg(:,1:nlev) = tmm%buf_gg ! K
  2781. ! info ...
  2782. call Init( T_tmi, tmm%buf_tmi, status )
  2783. case ( 'ncep-cdc', 'ncep-gfs' )
  2784. !call wrtgol( ' tmm read : Q ', t1m, ' - ', t2m ); call goPr
  2785. ! read humidity
  2786. call FillBuffer( tmm, archivekey, 'Q', 'kg/kg', tday, t1m, t2m, 'n', 'n', status )
  2787. IF_NOTOK_RETURN(status=1)
  2788. ! check ...
  2789. call CheckBuffer( tmm, status, gridtype='sh', np=ggi%np, nlev=nlev )
  2790. IF_NOTOK_RETURN(status=1)
  2791. ! check ...
  2792. call CheckBuffer( tmm, status, gridtype='sh', shT=shi%T, nlev=nlev )
  2793. IF_NOTOK_RETURN(status=1)
  2794. ! convert from sh to gg
  2795. do l = 1, nlev
  2796. call Interpol( tmm%buf_shi, tmm%buf_sh(:,l), ggi, Q_gg(:,l), status ) ! kg h2o / kg air
  2797. IF_NOTOK_RETURN(status=1)
  2798. end do
  2799. ! prevent negatives ...
  2800. Q_gg = max( 0.0, Q_gg )
  2801. ! info ...
  2802. call Init( Q_tmi, tmm%buf_tmi, status )
  2803. call AddHistory( Q_tmi, 'interpol to gg', status )
  2804. call AddHistory( Q_tmi, 'truncate', status )
  2805. ! interpolate surface pressure:
  2806. call Interpol( tmm%buf_shi, tmm%buf_lnsp_sh, ggi, sp_gg, status ) ! ln(Pa)
  2807. IF_NOTOK_RETURN(status=1)
  2808. sp_gg = exp( sp_gg ) ! Pa
  2809. ! info ...
  2810. call Init( sp_tmi, 'sp', 'Pa', status, (/tmm%buf_tmi/) )
  2811. !call wrtgol( ' tmm read : T ', t1m, ' - ', t2m ); call goPr
  2812. ! read virtual temperature
  2813. call FillBuffer( tmm, archivekey, 'Tv', 'K', tday, t1m, t2m, 'n', 'n', status )
  2814. IF_NOTOK_RETURN(status=1)
  2815. ! check ...
  2816. call CheckBuffer( tmm, status, gridtype='sh', shT=shi%T, nlev=nlev )
  2817. IF_NOTOK_RETURN(status=1)
  2818. ! convert from sh to gg
  2819. do l = 1, nlev
  2820. call Interpol( tmm%buf_shi, tmm%buf_sh(:,l), ggi, T_gg(:,l), status )
  2821. IF_NOTOK_RETURN(status=1)
  2822. end do
  2823. ! convert from virtual to normal temperature:
  2824. T_gg = RealTemperature( T_gg, Q_gg )
  2825. ! info ...
  2826. call Init( T_tmi, tmm%buf_tmi, status )
  2827. call AddHistory( T_tmi, 'interpol to gg', status )
  2828. case default
  2829. write (gol,'("unsupported source type `",a,"` for raw surface fields")') trim(sourcetype); call goErr
  2830. TRACEBACK; status=1; return
  2831. end select
  2832. ! ~~~
  2833. write (gol,'(" interpol : W")'); call goPr
  2834. ! omega on gg and TM levels:
  2835. allocate( tmp_gg(ggi%np,levi%nlev+1) )
  2836. ! convert from ll to gg:
  2837. do l = 1, levi%nlev+1
  2838. call Interpol( lli, omega(:,:,l), ggi, tmp_gg(:,l), status )
  2839. IF_NOTOK_RETURN(status=1)
  2840. end do
  2841. ! convert to parent levels (buffer) from TM levels:
  2842. call FillLevels( tmm%buf_levi, 'w', sp_gg, w_gg, &
  2843. levi, tmp_gg, 'bottom', status )
  2844. IF_NOTOK_RETURN(status=1)
  2845. ! info ...
  2846. call Init( w_tmi, omega_tmi, status )
  2847. call AddHistory( w_tmi, 'interpol to gg and raw levels', status )
  2848. ! clear
  2849. deallocate( tmp_gg )
  2850. !
  2851. ! ensure that layers are in ecmwf order (top->down)
  2852. !
  2853. select case ( sourcetype )
  2854. case ( 'ecmwf-tmpp', 'ecmwf-tm5', 'msc-data' )
  2855. ! copy level info from buffer:
  2856. call Init( leviX, tmm%buf_levi%nlev, tmm%buf_levi%a, tmm%buf_levi%b, status )
  2857. IF_NOTOK_RETURN(status=1)
  2858. case ( 'ncep-cdc', 'ncep-gfs' )
  2859. ! revert level info from buffer:
  2860. allocate( aX(0:tmm%buf_levi%nlev) )
  2861. allocate( bX(0:tmm%buf_levi%nlev) )
  2862. do l = 0, tmm%buf_levi%nlev
  2863. aX(l) = tmm%buf_levi%a(tmm%buf_levi%nlev-l)
  2864. bX(l) = tmm%buf_levi%b(tmm%buf_levi%nlev-l)
  2865. end do
  2866. call Init( leviX, tmm%buf_levi%nlev, aX, bX, status )
  2867. IF_NOTOK_RETURN(status=1)
  2868. deallocate( aX )
  2869. deallocate( bX )
  2870. ! revert fields
  2871. allocate( tmp_gg(ggi%np,0:nlev) )
  2872. tmp_gg = u_gg
  2873. do l = 1, nlev
  2874. u_gg(:,l) = tmp_gg(:,nlev+1-l)
  2875. end do
  2876. tmp_gg = v_gg
  2877. do l = 1, nlev
  2878. v_gg(:,l) = tmp_gg(:,nlev+1-l)
  2879. end do
  2880. tmp_gg = w_gg
  2881. do l = 1, nlev
  2882. w_gg(:,l) = tmp_gg(:,nlev+1-l)
  2883. end do
  2884. tmp_gg = t_gg
  2885. do l = 1, nlev
  2886. t_gg(:,l) = tmp_gg(:,nlev+1-l)
  2887. end do
  2888. tmp_gg = q_gg
  2889. do l = 1, nlev
  2890. q_gg(:,l) = tmp_gg(:,nlev+1-l)
  2891. end do
  2892. deallocate( tmp_gg )
  2893. end select
  2894. !
  2895. ! updraughts/downdraughts
  2896. !
  2897. write (gol,'(" tmm updr/downdr")'); call goPr
  2898. !
  2899. ! WARNING: the TMPP2/tmpp_conv-gg on bsgi59 is probably not bugfree:
  2900. ! o oro not read
  2901. ! o pw = w/g [kg/m2/s], but tmpp_conv_tiedtke expects Pa/s ?
  2902. ! o factor to convert from lshf to evaporation
  2903. ! here : 1 m/s = 2.45e9 W/m2 (at 20 degrees C)
  2904. ! binas : lvap = 2.5 e6 J/kg
  2905. ! binas : Lc = 2.26e6 J/kg (at 0 deg C)
  2906. !
  2907. ! There are however good reasons to step over to the conv-gg code
  2908. ! by Dirk Olivie
  2909. ! o no unnecessary interpolations to half levels
  2910. ! o removed stuff that was based on the ec 19 levels
  2911. !
  2912. ! extra fields:
  2913. allocate( ggmask(ggi%np) )
  2914. allocate( qam_gg(ggi%np,0:nlev) )
  2915. allocate( qac_gg(ggi%np,0:nlev) )
  2916. allocate( entu_gg(ggi%np,nlev) )
  2917. allocate( detu_gg(ggi%np,nlev) )
  2918. allocate( entd_gg(ggi%np,nlev) )
  2919. allocate( detd_gg(ggi%np,nlev) )
  2920. ! Set mask for averaging over ll;
  2921. ! one extra row to compute derivatives.
  2922. ! This routine changes ggi: flag for each row to be processed or not
  2923. call InterpolMask( ggi, ggmask, lli, 1 )
  2924. ! calculate geopotential (z)
  2925. allocate( p_hlev(0:nlev) )
  2926. do i = 1, ggi%np
  2927. ! skip if not required for ll grid:
  2928. if ( .not. ggmask(i) ) cycle
  2929. ! compute pressure at half levels (surf -> top):
  2930. call phlev_ec_rev( nlev, leviX%a, leviX%b, sp_gg(i), p_hlev )
  2931. ! compute z for single column:
  2932. call GeoPot( nlev, oro_gg(i), T_gg(i,1:nlev), Q_gg(i,1:nlev), &
  2933. p_hlev, z_gg(i,1:nlev) )
  2934. end do
  2935. deallocate( p_hlev )
  2936. ! interpolate variables from the center of parent-model layers to the
  2937. ! boundaries of parent-model layers and save result in same memory location ..
  2938. call mid2bound_uv( nlev, ggi%np, u_gg, v_gg, sp_gg, ggmask, leviX%a, leviX%b )
  2939. call mid2bound_t ( nlev, ggi%np, t_gg, sp_gg, ggmask, leviX%a, leviX%b )
  2940. call mid2bound_q ( nlev, ggi%np, q_gg, sp_gg, ggmask, leviX%a, leviX%b, t_gg )
  2941. call mid2bound_z ( nlev, ggi%np, z_gg, sp_gg, ggmask, leviX%a, leviX%b, oro_gg )
  2942. ! already on half levels, since interpolated from omega ...
  2943. !!call mid2bound_w ( nlev, ggi%np, w_gg, sp_gg, ggmask, leviX%a, leviX%b )
  2944. ! NOTE: p is not filled on input, but filled with pressures on output
  2945. call mid2bound_p ( nlev, ggi%np, p_gg, sp_gg, ggmask, leviX%a, leviX%b )
  2946. ! divergence fields
  2947. do l = 0, nlev
  2948. call Divergence( ggi, q_gg(:,l)*u_gg(:,l), q_gg(:,l)*v_gg(:,l), qac_gg(:,l) )
  2949. call Divergence( ggi, u_gg(:,l), v_gg(:,l), qam_gg(:,l) )
  2950. end do
  2951. ! Convert from SLHF (W/m2*interval) to EVAP (m/s)
  2952. ! 1 m/s = 2.45e9 W/m2 (at 20 degrees C).
  2953. ! Don't forget to change sign from latent heatflux to evaporation!!!
  2954. ! evap = - slhf_gg(i) / dt_sec / 2.45e9 ! m/s
  2955. ! (apply in argument)
  2956. ! work routine:
  2957. call subscal_2d( ggi%np, nlev, leviX%a, leviX%b, &
  2958. z_gg, p_gg, w_gg, t_gg, &
  2959. q_gg, qac_gg, qam_gg, -1.0e3*slhf_gg/dt_sec/2.45e9, &
  2960. entu_gg, detu_gg, entd_gg, detd_gg )
  2961. ! clear
  2962. deallocate( ggmask )
  2963. deallocate( slhf_gg )
  2964. deallocate( oro_gg )
  2965. deallocate( u_gg )
  2966. deallocate( v_gg )
  2967. deallocate( w_gg )
  2968. deallocate( t_gg )
  2969. deallocate( q_gg )
  2970. deallocate( qam_gg )
  2971. deallocate( qac_gg )
  2972. deallocate( p_gg )
  2973. deallocate( z_gg )
  2974. ! history
  2975. call Init( entu_tmi, 'entu', 'kg/m2/s', status, &
  2976. (/sp_tmi,slhf_tmi,oro_tmi,T_tmi,Q_tmi,u_tmi,v_tmi,w_tmi/) )
  2977. call Init( entd_tmi, 'entd', 'kg/m2/s', status, &
  2978. (/sp_tmi,slhf_tmi,oro_tmi,T_tmi,Q_tmi,u_tmi,v_tmi,w_tmi/) )
  2979. call Init( detu_tmi, 'detu', 'kg/m2/s', status, &
  2980. (/sp_tmi,slhf_tmi,oro_tmi,T_tmi,Q_tmi,u_tmi,v_tmi,w_tmi/) )
  2981. call Init( detd_tmi, 'detd', 'kg/m2/s', status, &
  2982. (/sp_tmi,slhf_tmi,oro_tmi,T_tmi,Q_tmi,u_tmi,v_tmi,w_tmi/) )
  2983. !
  2984. ! convert from gg to ll
  2985. !
  2986. ! determine fraction
  2987. call Init( gg2ll, ggi, lli, status )
  2988. IF_NOTOK_RETURN(status=1)
  2989. ! take fractions of overlapping cells
  2990. call FracSum( gg2ll, sp_gg, sp, status, 'area-aver' )
  2991. IF_NOTOK_RETURN(status=1)
  2992. ! clear
  2993. deallocate( sp_gg )
  2994. ! full level output:
  2995. allocate( llX(lli%nlon,lli%nlat,nlev ) )
  2996. allocate( ll (lli%nlon,lli%nlat,levi%nlev) )
  2997. ! take fractions of overlapping cells
  2998. do l = 1, nlev
  2999. call FracSum( gg2ll, entu_gg(:,l), llX(:,:,l), status, 'area-aver' )
  3000. IF_NOTOK_RETURN(status=1)
  3001. end do
  3002. ! integrated variables might become slightly negative ...
  3003. llX = max( 0.0, llX )
  3004. ! combine levels from llX to ll:
  3005. call FillLevels( levi, 'n', sp, ll, leviX, llX, 'sum', status )
  3006. IF_NOTOK_RETURN(status=1)
  3007. ! truncate to number of output levels:
  3008. entu = ll(:,:,1:lout)
  3009. ! info ..
  3010. call AddHistory( entu_tmi, 'gg to ll, area aver;;sum levels', status )
  3011. ! take fractions of overlapping cells
  3012. do l = 1, nlev
  3013. call FracSum( gg2ll, entd_gg(:,l), llX(:,:,l), status, 'area-aver' )
  3014. IF_NOTOK_RETURN(status=1)
  3015. end do
  3016. ! integrated variables might become slightly negative ...
  3017. llX = max( 0.0, llX )
  3018. ! combine levels from llX to ll:
  3019. call FillLevels( levi, 'n', sp, ll, leviX, llX, 'sum', status )
  3020. IF_NOTOK_RETURN(status=1)
  3021. ! truncate to number of output levels:
  3022. entd = ll(:,:,1:lout)
  3023. ! info ..
  3024. call AddHistory( entd_tmi, 'gg to ll, area aver;;sum levels', status )
  3025. ! take fractions of overlapping cells
  3026. do l = 1, nlev
  3027. call FracSum( gg2ll, detu_gg(:,l), llX(:,:,l), status, 'area-aver' )
  3028. IF_NOTOK_RETURN(status=1)
  3029. end do
  3030. ! integrated variables might become slightly negative ...
  3031. llX = max( 0.0, llX )
  3032. ! combine levels from llX to ll:
  3033. call FillLevels( levi, 'n', sp, ll, leviX, llX, 'sum', status )
  3034. IF_NOTOK_RETURN(status=1)
  3035. ! truncate to number of output levels:
  3036. detu = ll(:,:,1:lout)
  3037. ! info ..
  3038. call AddHistory( detu_tmi, 'gg to ll, area aver;;sum levels', status )
  3039. ! take fractions of overlapping cells
  3040. do l = 1, nlev
  3041. call FracSum( gg2ll, detd_gg(:,l), llX(:,:,l), status, 'area-aver' )
  3042. IF_NOTOK_RETURN(status=1)
  3043. end do
  3044. ! integrated variables might become slightly negative ...
  3045. llX = max( 0.0, llX )
  3046. ! combine levels from llX to ll:
  3047. call FillLevels( levi, 'n', sp, ll, leviX, llX, 'sum', status )
  3048. IF_NOTOK_RETURN(status=1)
  3049. ! truncate to number of output levels:
  3050. detd = ll(:,:,1:lout)
  3051. ! info ..
  3052. call AddHistory( detd_tmi, 'gg to ll, area aver;;sum levels', status )
  3053. ! clear
  3054. call Done( gg2ll )
  3055. deallocate( entu_gg )
  3056. deallocate( entd_gg )
  3057. deallocate( detu_gg )
  3058. deallocate( detd_gg )
  3059. deallocate( llX )
  3060. deallocate( ll )
  3061. call Done( leviX, status )
  3062. IF_NOTOK_RETURN(status=1)
  3063. !
  3064. ! done
  3065. !
  3066. call Done( ggi, status )
  3067. IF_NOTOK_RETURN(status=1)
  3068. ! ok
  3069. status = 0
  3070. end subroutine tmm_Read_Convec_raw
  3071. #endif
  3072. ! *****************************************************************
  3073. #ifdef with_tmm_convec_ec_gg
  3074. subroutine tmm_Read_Convec_EC_gg( tmm, archivekey, tday, t1, t2, lli, levi, &
  3075. omega, omega_tmi, &
  3076. sp, &
  3077. entu, entu_tmi, entd, entd_tmi, &
  3078. detu, detu_tmi, detd, detd_tmi, &
  3079. status )
  3080. use Binas , only : grav
  3081. use GO , only : Get, IncrDate
  3082. use GO , only : operator(-), operator(+), rTotal
  3083. use GO , only : goSplitLine
  3084. use Phys , only : mid2bound_uv, mid2bound_w, mid2bound_t
  3085. use Phys , only : mid2bound_q, mid2bound_z, mid2bound_p
  3086. use Phys , only : subscal, phlev_ec_rev, geopot
  3087. use Phys , only : RealTemperature
  3088. use Phys , only : GeoPotentialHeightB
  3089. use Phys , only : ECconv_to_TMconv
  3090. use Grid , only : HPressure, FPressure, FillLevels
  3091. use Grid , only : TShGrid, VoD2UV
  3092. use Grid , only : InterpolMask, Divergence, Tgg2llFracs, FracSum, AreaOper
  3093. use Grid , only : Init, Done, Set, Interpol
  3094. use tmm_info, only : TMeteoInfo, Init, AddHistory
  3095. ! --- in/out --------------------------------
  3096. type(TTmMeteo), intent(inout) :: tmm
  3097. character(len=*), intent(in) :: archivekey
  3098. type(TDate), intent(in) :: tday, t1, t2
  3099. type(TllGridInfo), intent(in) :: lli
  3100. type(TLevelInfo), intent(in) :: levi
  3101. real, intent(in) :: omega(:,:,:) ! Pa/s
  3102. type(TMeteoInfo), intent(in) :: omega_tmi
  3103. real, intent(out) :: sp(:,:) ! Pa
  3104. real, intent(out) :: entu(:,:,:), entd(:,:,:) ! kg/m2/s
  3105. type(TMeteoInfo), intent(out) :: entu_tmi, entd_tmi
  3106. real, intent(out) :: detu(:,:,:), detd(:,:,:) ! kg/m2/s
  3107. type(TMeteoInfo), intent(out) :: detu_tmi, detd_tmi
  3108. integer, intent(out) :: status
  3109. ! --- const ------------------------------------
  3110. character(len=*), parameter :: rname = mname//'/tmm_Read_Convec_EC_gg'
  3111. ! --- local -------------------------------
  3112. character(len=10) :: sourcetype
  3113. character(len=256) :: sourcename
  3114. integer :: lout
  3115. real, allocatable :: ll(:,:,:)
  3116. ! timing
  3117. integer :: hour
  3118. real :: dhour
  3119. type(TDate) :: t1s, t2s
  3120. ! loops etc
  3121. integer :: l, nlev
  3122. integer :: i, i1, i2, j
  3123. ! gaussian grids
  3124. integer :: ggN
  3125. logical :: reduced
  3126. type(TggGridInfo) :: ggi
  3127. real, allocatable :: gg(:)
  3128. real, allocatable :: oro_gg(:)
  3129. real, allocatable :: sp_gg(:)
  3130. real, allocatable :: m_gg(:)
  3131. real, allocatable :: t_gg(:,:)
  3132. real, allocatable :: q_gg(:,:)
  3133. type(Tgg2llFracs) :: gg2ll
  3134. real, allocatable :: llX(:,:,:)
  3135. type(TLevelInfo) :: leviX
  3136. real, allocatable :: p_hlev(:)
  3137. ! e4 convection fields
  3138. real, allocatable :: udmf_gg(:,:)
  3139. real, allocatable :: ddmf_gg(:,:)
  3140. real, allocatable :: uddr_gg(:,:)
  3141. real, allocatable :: dddr_gg(:,:)
  3142. type(TMeteoInfo) :: udmf_tmi, ddmf_tmi, uddr_tmi, dddr_tmi
  3143. real, allocatable :: ph_ec(:)
  3144. real, allocatable :: zh_ec(:)
  3145. real, pointer :: entu_gg(:,:)
  3146. real, pointer :: detu_gg(:,:)
  3147. real, pointer :: entd_gg(:,:)
  3148. real, pointer :: detd_gg(:,:)
  3149. ! --- begin -------------------------------
  3150. ! number of levels in output arrays:
  3151. lout = size(entu,3)
  3152. ! check ...
  3153. if ( (size(entd,3)/=lout) .or. &
  3154. (size(detu,3)/=lout) .or. (size(detd,3)/=lout) ) then
  3155. write (gol,'("output arrays should have same number of levels:")'); call goErr
  3156. write (gol,'(" entu : ",i4)') size(entu,3); call goErr
  3157. write (gol,'(" entd : ",i4)') size(entd,3); call goErr
  3158. write (gol,'(" detu : ",i4)') size(detu,3); call goErr
  3159. write (gol,'(" detd : ",i4)') size(detd,3); call goErr
  3160. TRACEBACK; status=1; return
  3161. end if
  3162. ! split source key in type and name:
  3163. call goSplitLine( archivekey, sourcetype, ':', sourcename, status )
  3164. IF_NOTOK_RETURN(status=1)
  3165. !
  3166. ! Original parameters archived in MARS:
  3167. !
  3168. ! Parameter Surfaces Code Units Units
  3169. ! 1) 2) 3)
  3170. !
  3171. ! updraught mass flux half levels UDMF 101 kg/m2 kg/m2/s
  3172. ! downdraught mass flux half levels DDMF 102 kg/m2 kg/m2/s
  3173. ! updraught detrainment rate full levels UDDR 103 kg/m3 kg/m3/s
  3174. ! downdraught detrainment rate full levels DDDR 104 kg/m3 kg/m3/s
  3175. !
  3176. ! 1) GRIB code table 2 version 128
  3177. ! 2) original units, accumulated
  3178. ! 3) time averaged after reading
  3179. !
  3180. ! only hours 00/03/06/etc yet ...
  3181. call Get( t1, hour=hour )
  3182. dhour = rTotal( t2 - t1, 'hour' )
  3183. if ( (modulo(hour,3) /= 0) .or. (dhour /= 3.0) ) then
  3184. write (gol,'("convection only for 3hr intervals [0,3] etc.")'); call goErr
  3185. call wrtgol( ' requested : ', t1, ' - ', t2 ); call goErr
  3186. write (gol,'(" dhour : ",f8.4)') dhour; call goErr
  3187. TRACEBACK; status=1; return
  3188. end if
  3189. !
  3190. ! read gg fields
  3191. !
  3192. !call wrtgol( ' tmm read : UDMF ', t1, ' - ', t2 ); call goPr
  3193. ! read updraught mass flux
  3194. call FillBuffer( tmm, archivekey, 'UDMF', 'kg/m2/s', tday, t1, t2, 'n', 'n', status )
  3195. IF_NOTOK_RETURN(status=1)
  3196. ! check ...
  3197. call CheckBuffer( tmm, status, gridtype='gg' )
  3198. IF_NOTOK_RETURN(status=1)
  3199. ! extract grid sizes
  3200. ggN = tmm%buf_ggi%N
  3201. reduced = tmm%buf_ggi%reduced
  3202. ! copy level info from buffer:
  3203. call Init( leviX, tmm%buf_levi%nlev, tmm%buf_levi%a, tmm%buf_levi%b, status )
  3204. IF_NOTOK_RETURN(status=1)
  3205. ! setup gg defintion from buffer:
  3206. call Init( ggi, ggN, reduced, status )
  3207. IF_NOTOK_RETURN(status=1)
  3208. ! allocate storage:
  3209. allocate( udmf_gg(ggi%np,0:leviX%nlev) )
  3210. allocate( ddmf_gg(ggi%np,0:leviX%nlev) )
  3211. allocate( uddr_gg(ggi%np,1:leviX%nlev) )
  3212. allocate( dddr_gg(ggi%np,1:leviX%nlev) )
  3213. allocate( sp_gg(ggi%np) )
  3214. allocate( oro_gg(ggi%np) )
  3215. allocate( T_gg(ggi%np,1:leviX%nlev) )
  3216. allocate( Q_gg(ggi%np,1:leviX%nlev) )
  3217. ! copy 3d field, levels top down, surface implicit zero, copy info:
  3218. udmf_gg(:,0:nlev-1) = tmm%buf_gg ! kg/m2/s
  3219. udmf_gg(:, nlev) = 0.0
  3220. call AddHistory( udmf_tmi, tmm%buf_tmi, status )
  3221. !call wrtgol( ' tmm read : DDMF ', t1, ' - ', t2 ); call goPr
  3222. ! downdraught mass flux
  3223. call FillBuffer( tmm, archivekey, 'DDMF', 'kg/m2/s', tday, t1, t2, 'n', 'n', status )
  3224. IF_NOTOK_RETURN(status=1)
  3225. ! check ...
  3226. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=leviX%nlev )
  3227. IF_NOTOK_RETURN(status=1)
  3228. ! copy 3d field, levels top down, surface implicit zero, copy info:
  3229. ddmf_gg(:,0:nlev-1) = tmm%buf_gg ! kg/m2/s
  3230. ddmf_gg(:, nlev) = 0.0
  3231. call AddHistory( ddmf_tmi, tmm%buf_tmi, status )
  3232. !call wrtgol( ' tmm read : UDDR ', t1, ' - ', t2 ); call goPr
  3233. ! updraught detrainment rate
  3234. call FillBuffer( tmm, archivekey, 'UDDR', 'kg/m3/s', tday, t1, t2, 'n', 'n', status )
  3235. IF_NOTOK_RETURN(status=1)
  3236. ! check ...
  3237. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=leviX%nlev )
  3238. IF_NOTOK_RETURN(status=1)
  3239. ! copy 3d field, levels top down, copy info:
  3240. uddr_gg = tmm%buf_gg ! kg/m3/s
  3241. call AddHistory( uddr_tmi, tmm%buf_tmi, status )
  3242. !call wrtgol( ' tmm read : DDDR ', t1, ' - ', t2 ); call goPr
  3243. ! downdraught detrainment rate
  3244. call FillBuffer( tmm, archivekey, 'DDDR', 'kg/m3/s', tday, t1, t2, 'n', 'n', status )
  3245. IF_NOTOK_RETURN(status=1)
  3246. ! check ...
  3247. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=leviX%nlev )
  3248. IF_NOTOK_RETURN(status=1)
  3249. ! copy 3d field, levels top down, copy info:
  3250. dddr_gg = tmm%buf_gg ! kg/m3/s
  3251. call AddHistory( dddr_tmi, tmm%buf_tmi, status )
  3252. ! temperature at begin of interval
  3253. !call wrtgol( ' tmm read : T ', t1, ' - ', t1 ); call goPr
  3254. call FillBuffer( tmm, archivekey, 'T', 'K', tday, t1, t1, 'n', 'n', status )
  3255. IF_NOTOK_RETURN(status=1)
  3256. ! check ...
  3257. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=leviX%nlev )
  3258. IF_NOTOK_RETURN(status=1)
  3259. ! copy 3d field:
  3260. T_gg = tmm%buf_gg ! K
  3261. ! temperature at end of interval
  3262. !call wrtgol( ' tmm read : T ', t2, ' - ', t2 ); call goPr
  3263. call FillBuffer( tmm, archivekey, 'T', 'K', tday, t2, t2, 'n', 'n', status )
  3264. IF_NOTOK_RETURN(status=1)
  3265. ! check ...
  3266. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=leviX%nlev )
  3267. IF_NOTOK_RETURN(status=1)
  3268. ! add, average:
  3269. T_gg = ( T_gg + tmm%buf_gg )/2.0 ! K
  3270. ! humidity at begin of interval
  3271. !call wrtgol( ' tmm read : Q ', t1, ' - ', t1 ); call goPr
  3272. call FillBuffer( tmm, archivekey, 'Q', 'kg/kg', tday, t1, t1, 'n', 'n', status )
  3273. IF_NOTOK_RETURN(status=1)
  3274. ! check ...
  3275. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=leviX%nlev )
  3276. IF_NOTOK_RETURN(status=1)
  3277. ! copy 3d field:
  3278. Q_gg = tmm%buf_gg ! kg/kg
  3279. ! humidity at end of interval
  3280. !call wrtgol( ' tmm read : Q ', t2, ' - ', t2 ); call goPr
  3281. call FillBuffer( tmm, archivekey, 'Q', 'kg/kg', tday, t2, t2, 'n', 'n', status )
  3282. IF_NOTOK_RETURN(status=1)
  3283. ! check ...
  3284. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np, nlev=leviX%nlev )
  3285. IF_NOTOK_RETURN(status=1)
  3286. ! add, average:
  3287. Q_gg = ( Q_gg + tmm%buf_gg )/2.0 ! kg/kg
  3288. ! surface pressure at begin of interval
  3289. !call wrtgol( ' tmm read : sp ', t1, ' - ', t1 ); call goPr
  3290. call FillBuffer( tmm, archivekey, 'sp', 'Pa', tday, t1, t1, 'n', 'n', status )
  3291. IF_NOTOK_RETURN(status=1)
  3292. ! check ...
  3293. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np )
  3294. IF_NOTOK_RETURN(status=1)
  3295. ! copy 2d field:
  3296. sp_gg = tmm%buf_gg(:,1) ! Pa
  3297. ! surface pressure at end of interval
  3298. !call wrtgol( ' tmm read : sp ', t2, ' - ', t2 ); call goPr
  3299. call FillBuffer( tmm, archivekey, 'sp', 'Pa', tday, t2, t2, 'n', 'n', status )
  3300. IF_NOTOK_RETURN(status=1)
  3301. ! check ...
  3302. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np )
  3303. IF_NOTOK_RETURN(status=1)
  3304. ! add, average:
  3305. sp_gg = ( sp_gg + tmm%buf_gg(:,1) )/2.0 ! Pa
  3306. ! read orography in buffer:
  3307. !write (gol,'(" tmm read : oro")'); call goPr
  3308. call FillBuffer( tmm, archivekey, 'oro', 'm m/s2', tday, t1, t1, 'n', 'n', status )
  3309. IF_NOTOK_RETURN(status=1)
  3310. ! check ...
  3311. call CheckBuffer( tmm, status, gridtype='gg', np=ggi%np )
  3312. IF_NOTOK_RETURN(status=1)
  3313. ! copy from buffer:
  3314. oro_gg = tmm%buf_gg(:,1) ! m*[g]
  3315. !
  3316. ! convert
  3317. !
  3318. allocate( ph_ec(0:leviX%nlev) )
  3319. allocate( zh_ec(0:leviX%nlev) )
  3320. allocate( entu_gg(ggi%np,leviX%nlev) )
  3321. allocate( detu_gg(ggi%np,leviX%nlev) )
  3322. allocate( entd_gg(ggi%np,leviX%nlev) )
  3323. allocate( detd_gg(ggi%np,leviX%nlev) )
  3324. ! loop over gg cells:
  3325. do i = 1, ggi%np
  3326. ! half level pressure:
  3327. call HPressure( leviX, sp_gg(i), ph_ec, status )
  3328. IF_NOTOK_RETURN(status=1)
  3329. ! gph at half levels:
  3330. call GeoPotentialHeightB( nlev, ph_ec, T_gg(i,:), Q_gg(i,:), oro_gg(i)/grav, zh_ec )
  3331. ! convert from fluxes to rates:
  3332. call ECconv_to_TMconv( leviX%nlev, zh_ec, &
  3333. udmf_gg(i,:), uddr_gg(i,:), ddmf_gg(i,:), dddr_gg(i,:), &
  3334. entu_gg(i,:), detu_gg(i,:), entd_gg(i,:), detd_gg(i,:), &
  3335. status )
  3336. IF_NOTOK_RETURN(status=1)
  3337. end do
  3338. deallocate( ph_ec )
  3339. deallocate( zh_ec )
  3340. ! clear
  3341. deallocate( udmf_gg )
  3342. deallocate( ddmf_gg )
  3343. deallocate( uddr_gg )
  3344. deallocate( dddr_gg )
  3345. deallocate( oro_gg )
  3346. deallocate( T_gg )
  3347. deallocate( Q_gg )
  3348. ! history
  3349. call Init( entu_tmi, 'entu', 'kg/m2/s', status, (/udmf_tmi,ddmf_tmi,uddr_tmi,dddr_tmi/) )
  3350. call Init( entd_tmi, 'entd', 'kg/m2/s', status, (/udmf_tmi,ddmf_tmi,uddr_tmi,dddr_tmi/) )
  3351. call Init( detu_tmi, 'detu', 'kg/m2/s', status, (/udmf_tmi,ddmf_tmi,uddr_tmi,dddr_tmi/) )
  3352. call Init( detd_tmi, 'detd', 'kg/m2/s', status, (/udmf_tmi,ddmf_tmi,uddr_tmi,dddr_tmi/) )
  3353. !
  3354. ! convert from gg to ll
  3355. !
  3356. ! determine fraction
  3357. call Init( gg2ll, ggi, lli, status )
  3358. IF_NOTOK_RETURN(status=1)
  3359. ! take fractions of overlapping cells
  3360. call FracSum( gg2ll, sp_gg, sp, status, 'area-aver' )
  3361. IF_NOTOK_RETURN(status=1)
  3362. ! full level output:
  3363. allocate( llX(lli%nlon,lli%nlat,nlev ) )
  3364. allocate( ll (lli%nlon,lli%nlat,levi%nlev) )
  3365. ! take fractions of overlapping cells
  3366. do l = 1, nlev
  3367. call FracSum( gg2ll, entu_gg(:,l), llX(:,:,l), status, 'area-aver' )
  3368. IF_NOTOK_RETURN(status=1)
  3369. end do
  3370. ! integrated variables might become slightly negative ...
  3371. llX = max( 0.0, llX )
  3372. ! combine levels from llX to ll:
  3373. call FillLevels( levi, 'n', sp, ll, leviX, llX, 'sum', status )
  3374. IF_NOTOK_RETURN(status=1)
  3375. ! truncate to number of output levels:
  3376. entu = ll(:,:,1:lout)
  3377. ! info ..
  3378. call AddHistory( entu_tmi, 'gg to ll, area aver;;sum levels', status )
  3379. ! take fractions of overlapping cells
  3380. do l = 1, nlev
  3381. call FracSum( gg2ll, entd_gg(:,l), llX(:,:,l), status, 'area-aver' )
  3382. IF_NOTOK_RETURN(status=1)
  3383. end do
  3384. ! integrated variables might become slightly negative ...
  3385. llX = max( 0.0, llX )
  3386. ! combine levels from llX to ll:
  3387. call FillLevels( levi, 'n', sp, ll, leviX, llX, 'sum', status )
  3388. IF_NOTOK_RETURN(status=1)
  3389. ! truncate to number of output levels:
  3390. entd = ll(:,:,1:lout)
  3391. ! info ..
  3392. call AddHistory( entd_tmi, 'gg to ll, area aver;;sum levels', status )
  3393. ! take fractions of overlapping cells
  3394. do l = 1, nlev
  3395. call FracSum( gg2ll, detu_gg(:,l), llX(:,:,l), status, 'area-aver' )
  3396. IF_NOTOK_RETURN(status=1)
  3397. end do
  3398. ! integrated variables might become slightly negative ...
  3399. llX = max( 0.0, llX )
  3400. ! combine levels from llX to ll:
  3401. call FillLevels( levi, 'n', sp, ll, leviX, llX, 'sum', status )
  3402. IF_NOTOK_RETURN(status=1)
  3403. ! truncate to number of output levels:
  3404. detu = ll(:,:,1:lout)
  3405. ! info ..
  3406. call AddHistory( detu_tmi, 'gg to ll, area aver;;sum levels', status )
  3407. ! take fractions of overlapping cells
  3408. do l = 1, nlev
  3409. call FracSum( gg2ll, detd_gg(:,l), llX(:,:,l), status, 'area-aver' )
  3410. IF_NOTOK_RETURN(status=1)
  3411. end do
  3412. ! integrated variables might become slightly negative ...
  3413. llX = max( 0.0, llX )
  3414. ! combine levels from llX to ll:
  3415. call FillLevels( levi, 'n', sp, ll, leviX, llX, 'sum', status )
  3416. IF_NOTOK_RETURN(status=1)
  3417. ! truncate to number of output levels:
  3418. detd = ll(:,:,1:lout)
  3419. ! info ..
  3420. call AddHistory( detd_tmi, 'gg to ll, area aver;;sum levels', status )
  3421. ! clear
  3422. call Done( gg2ll )
  3423. deallocate( entu_gg )
  3424. deallocate( entd_gg )
  3425. deallocate( detu_gg )
  3426. deallocate( detd_gg )
  3427. deallocate( llX )
  3428. deallocate( ll )
  3429. ! clear
  3430. deallocate( sp_gg )
  3431. !
  3432. ! done
  3433. !
  3434. call Done( ggi, status )
  3435. IF_NOTOK_RETURN(status=1)
  3436. call Done( leviX, status )
  3437. IF_NOTOK_RETURN(status=1)
  3438. ! ok
  3439. status = 0
  3440. end subroutine tmm_Read_Convec_EC_gg
  3441. #endif
  3442. ! *****************************************************************
  3443. #ifdef with_tmm_convec_ec
  3444. !
  3445. ! Original parameters archived in MARS:
  3446. !
  3447. ! Parameter Surfaces Code Units Units
  3448. ! 1) 2) 3)
  3449. !
  3450. ! updraught mass flux half levels UDMF 101 kg/m2 kg/m2/s
  3451. ! downdraught mass flux half levels DDMF 102 kg/m2 kg/m2/s
  3452. ! updraught detrainment rate full levels UDDR 103 kg/m3 kg/m3/s
  3453. ! downdraught detrainment rate full levels DDDR 104 kg/m3 kg/m3/s
  3454. !
  3455. ! 1) GRIB code table 2 version 128
  3456. ! 2) original units, accumulated
  3457. ! 3) time averaged after reading
  3458. !
  3459. subroutine tmm_Read_Convec_EC( tmm, archivekey, tday, t1, t2, lli, levi, &
  3460. gph, gph_tmi, &
  3461. sp, &
  3462. entu, entu_tmi, entd, entd_tmi, &
  3463. detu, detu_tmi, detd, detd_tmi, &
  3464. status )
  3465. use Phys , only : convec_mfldet_to_entdet
  3466. use tmm_info, only : TMeteoInfo, Init, AddHistory
  3467. ! --- in/out --------------------------------
  3468. type(TTmMeteo), intent(inout) :: tmm
  3469. character(len=*), intent(in) :: archivekey
  3470. type(TDate), intent(in) :: tday, t1, t2
  3471. type(TllGridInfo), intent(in) :: lli
  3472. type(TLevelInfo), intent(in) :: levi
  3473. real, intent(in) :: gph(:,:,:) ! m (half levels)
  3474. type(TMeteoInfo), intent(in) :: gph_tmi
  3475. real, intent(out) :: sp(:,:) ! Pa
  3476. real, intent(out) :: entu(:,:,:), entd(:,:,:) ! kg/m2/s (full levels)
  3477. type(TMeteoInfo), intent(out) :: entu_tmi, entd_tmi
  3478. real, intent(out) :: detu(:,:,:), detd(:,:,:) ! kg/m2/s (full levels)
  3479. type(TMeteoInfo), intent(out) :: detu_tmi, detd_tmi
  3480. integer, intent(out) :: status
  3481. ! --- const ------------------------------------
  3482. character(len=*), parameter :: rname = mname//'/tmm_Read_Convec_EC'
  3483. ! --- local -------------------------------
  3484. integer :: lout
  3485. real, allocatable :: ll(:,:,:)
  3486. real, allocatable :: udmf(:,:,:)
  3487. real, allocatable :: ddmf(:,:,:)
  3488. real, allocatable :: uddr(:)
  3489. real, allocatable :: dddr(:)
  3490. integer :: i, j, k
  3491. ! --- begin -------------------------------
  3492. call goLabel(rname)
  3493. ! number of levels in output arrays:
  3494. lout = size(entu,3)
  3495. ! check ...
  3496. if ( (size(entd,3)/=lout) .or. &
  3497. (size(detu,3)/=lout) .or. (size(detd,3)/=lout) ) then
  3498. write (gol,'("output arrays should have same number of levels:")'); call goErr
  3499. write (gol,'(" entu : ",i4)') size(entu,3); call goErr
  3500. write (gol,'(" entd : ",i4)') size(entd,3); call goErr
  3501. write (gol,'(" detu : ",i4)') size(detu,3); call goErr
  3502. write (gol,'(" detd : ",i4)') size(detd,3); call goErr
  3503. TRACEBACK; status=1; return
  3504. end if
  3505. ! full level output:
  3506. allocate( ll(lli%nlon,lli%nlat,levi%nlev ) )
  3507. ! generalized for lout=lmax_conv < levi%nlev
  3508. allocate( udmf(lli%nlon,lli%nlat,lout+1) )
  3509. allocate( ddmf(lli%nlon,lli%nlat,lout+1) )
  3510. ! detrainment rates:
  3511. allocate( uddr(lout) )
  3512. allocate( dddr(lout) )
  3513. #ifdef with_ec_aver
  3514. ! ~~ archived fields are average over last hour
  3515. ! updraught mass flux, half levels !
  3516. call ReadField( tmm, archivekey, 'MUMF', 'kg/m2/s', tday, t1, t2, &
  3517. lli, 'n', levi, 'n', sp, ll, entu_tmi, status )
  3518. IF_NOTOK_RETURN(status=1)
  3519. ! store ...
  3520. udmf(:,:,2:lout+1) = ll(:,:,1:lout)
  3521. udmf(:,:,1) = 0.
  3522. ! updraught detraintment rate
  3523. call ReadField( tmm, archivekey, 'MUDR', 'kg/m3/s', tday, t1, t2, &
  3524. lli, 'n', levi, 'n', sp, ll, detu_tmi, status )
  3525. IF_NOTOK_RETURN(status=1)
  3526. ! store ...
  3527. detu = ll(:,:,1:lout)
  3528. ! downdraught mass flux, half levels !
  3529. call ReadField( tmm, archivekey, 'MDMF', 'kg/m2/s', tday, t1, t2, &
  3530. lli, 'n', levi, 'n', sp, ll, entd_tmi, status )
  3531. IF_NOTOK_RETURN(status=1)
  3532. ! store ...
  3533. ddmf(:,:,2:lout+1) = ll(:,:,1:lout)
  3534. ddmf(:,:,1) = 0.
  3535. ! downdraught detraintment rate
  3536. call ReadField( tmm, archivekey, 'MDDR', 'kg/m3/s', tday, t1, t2, &
  3537. lli, 'n', levi, 'n', sp, ll, detd_tmi, status )
  3538. IF_NOTOK_RETURN(status=1)
  3539. ! store ...
  3540. detd = ll(:,:,1:lout)
  3541. #else
  3542. ! ~~ fields are accumulated since start of run,
  3543. ! deaccumulated on reading
  3544. ! updraught mass flux, half levels !
  3545. call ReadField( tmm, archivekey, 'UDMF', 'kg/m2/s', tday, t1, t2, &
  3546. lli, 'n', levi, 'n', sp, ll, entu_tmi, status )
  3547. IF_NOTOK_RETURN(status=1)
  3548. ! store ...
  3549. udmf(:,:,2:lout+1) = ll(:,:,1:lout)
  3550. udmf(:,:,1) = 0.
  3551. ! updraught detraintment rate
  3552. call ReadField( tmm, archivekey, 'UDDR', 'kg/m3/s', tday, t1, t2, &
  3553. lli, 'n', levi, 'n', sp, ll, detu_tmi, status )
  3554. IF_NOTOK_RETURN(status=1)
  3555. ! store ...
  3556. detu = ll(:,:,1:lout)
  3557. ! downdraught mass flux, half levels !
  3558. call ReadField( tmm, archivekey, 'DDMF', 'kg/m2/s', tday, t1, t2, &
  3559. lli, 'n', levi, 'n', sp, ll, entd_tmi, status )
  3560. IF_NOTOK_RETURN(status=1)
  3561. ! store ...
  3562. ddmf(:,:,2:lout+1) = ll(:,:,1:lout)
  3563. ddmf(:,:,1) = 0.
  3564. ! downdraught detraintment rate
  3565. call ReadField( tmm, archivekey, 'DDDR', 'kg/m3/s', tday, t1, t2, &
  3566. lli, 'n', levi, 'n', sp, ll, detd_tmi, status )
  3567. IF_NOTOK_RETURN(status=1)
  3568. ! store ...
  3569. detd = ll(:,:,1:lout)
  3570. #endif
  3571. ! convert from flux/detr to entr/detr
  3572. do j = 1, lli%nlat
  3573. do i = 1, lli%nlon
  3574. ! copy detrainment rates:
  3575. uddr = detu(i,j,:)
  3576. dddr = detd(i,j,:)
  3577. ! convert:
  3578. call convec_mfldet_to_entdet( 'u', lout, gph(i,j,1:lout+1), &
  3579. udmf(i,j,1:lout+1), uddr , ddmf(i,j,1:lout+1), dddr , &
  3580. entu(i,j,: ), detu(i,j,:), entd(i,j,: ), detd(i,j,:), status )
  3581. IF_NOTOK_RETURN(status=1)
  3582. end do
  3583. end do
  3584. ! info ...
  3585. call AddHistory( entu_tmi, 'converted mflux/detr to entr/detr', status )
  3586. call AddHistory( detu_tmi, 'converted mflux/detr to entr/detr', status )
  3587. call AddHistory( entd_tmi, 'converted mflux/detr to entr/detr', status )
  3588. call AddHistory( detd_tmi, 'converted mflux/detr to entr/detr', status )
  3589. ! clear
  3590. deallocate( ll )
  3591. deallocate( udmf )
  3592. deallocate( ddmf )
  3593. deallocate( uddr )
  3594. deallocate( dddr )
  3595. ! ok
  3596. call goLabel()
  3597. status = 0
  3598. end subroutine tmm_Read_Convec_EC
  3599. #endif
  3600. ! *****************************************************************
  3601. !
  3602. ! Original parameters archived in MARS:
  3603. !
  3604. ! References
  3605. ! ERA-Interim archive plan
  3606. ! http://www.ecmwf.int/publications/library/ecpublications/_pdf/era/era_report_series/RS_1_v2.pdf
  3607. !
  3608. ! Parameter Surfaces Code Units
  3609. !
  3610. ! turbulent diffusion coefficient for heat half levels 162.109 m2 (accum)
  3611. !
  3612. subroutine tmm_Read_Diffus_EC( tmm, archivekey, tday, t1, t2, lli, levi, &
  3613. sp, kzz, kzz_tmi, status )
  3614. use tmm_info, only : TMeteoInfo, Init, AddHistory
  3615. ! --- in/out --------------------------------
  3616. type(TTmMeteo), intent(inout) :: tmm
  3617. character(len=*), intent(in) :: archivekey
  3618. type(TDate), intent(in) :: tday, t1, t2
  3619. type(TllGridInfo), intent(in) :: lli
  3620. type(TLevelInfo), intent(in) :: levi
  3621. real, intent(out) :: sp(:,:) ! Pa
  3622. real, intent(out) :: kzz(:,:,:) ! m2/s (half levels)
  3623. type(TMeteoInfo), intent(out) :: kzz_tmi
  3624. integer, intent(out) :: status
  3625. ! --- const ------------------------------------
  3626. character(len=*), parameter :: rname = mname//'/tmm_Read_Diffus_EC'
  3627. ! --- local -------------------------------
  3628. integer :: lout
  3629. real, allocatable :: ll(:,:,:)
  3630. ! --- begin -------------------------------
  3631. ! number of full levels in output arrays:
  3632. lout = size(kzz,3) - 1
  3633. ! full level output:
  3634. allocate( ll(lli%nlon,lli%nlat,levi%nlev ) )
  3635. #ifdef with_ec_aver
  3636. ! updraught mass flux, half levels, average over last hour:
  3637. call ReadField( tmm, archivekey, 'MTDCH', 'm2/s', tday, t1, t2, &
  3638. lli, 'n', levi, 'n', sp, ll, kzz_tmi, status )
  3639. IF_NOTOK_RETURN(status=1)
  3640. ! store ...
  3641. kzz(:,:,2:lout+1) = ll(:,:,1:lout)
  3642. kzz(:,:,1) = 0.0
  3643. #else
  3644. ! updraught mass flux, half levels, accumulated from start of run:
  3645. call ReadField( tmm, archivekey, 'K', 'm2/s', tday, t1, t2, &
  3646. lli, 'n', levi, 'n', sp, ll, kzz_tmi, status )
  3647. IF_NOTOK_RETURN(status=1)
  3648. ! store ...
  3649. kzz(:,:,2:lout+1) = ll(:,:,1:lout)
  3650. kzz(:,:,1) = 0.0
  3651. #endif
  3652. ! info ...
  3653. call AddHistory( kzz_tmi, 'implicit zero diffusion coefficient at surface', status )
  3654. ! clear
  3655. deallocate( ll )
  3656. ! ok
  3657. status = 0
  3658. end subroutine tmm_Read_Diffus_EC
  3659. ! ==================================================================
  3660. ! ===
  3661. ! === Olsson surface roughness
  3662. ! ===
  3663. ! ==================================================================
  3664. subroutine tmm_Read_SR_OLS( tmm, archivekey, tday, t1, t2, &
  3665. lli, ll, tmi, status )
  3666. use GO , only : Get, goSplitLine
  3667. use Grid , only : Init, Done, Interpol
  3668. use tmm_info, only : TMeteoInfo, Init, AddHistory
  3669. ! --- in/out --------------------------------
  3670. type(TTmMeteo), intent(inout) :: tmm
  3671. character(len=*), intent(in) :: archivekey
  3672. type(TDate), intent(in) :: tday, t1, t2
  3673. type(TllGridInfo), intent(in) :: lli
  3674. real, intent(out) :: ll(:,:)
  3675. type(TMeteoInfo), intent(out) :: tmi
  3676. integer, intent(out) :: status
  3677. ! --- const ------------------------------------
  3678. character(len=*), parameter :: rname = mname//'/tmm_Read_SR_OLS'
  3679. ! grid size
  3680. integer, parameter :: nlon = 361, nlat = 181
  3681. ! --- local -------------------------------
  3682. character(len=10) :: sourcetype
  3683. character(len=256) :: sourcename
  3684. integer :: month
  3685. character(len=256) :: fname
  3686. logical :: exist, opened
  3687. integer :: fu
  3688. type(TllGridInfo) :: lli_ols
  3689. real :: sr_ols(nlon,nlat)
  3690. integer :: i, j
  3691. ! --- begin -------------------------------
  3692. call goLabel(rname)
  3693. ! split source key in type and name:
  3694. call goSplitLine( archivekey, sourcetype, ':', sourcename, status )
  3695. IF_NOTOK_RETURN(status=1)
  3696. ! input TMPP fields or raw prism fields ?
  3697. select case ( sourcetype )
  3698. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3699. ! standard
  3700. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3701. case ( 'standard' )
  3702. ! dummy values:
  3703. ll = 0.0
  3704. ! set history info
  3705. call Init( tmi, 'srols', 'm', status )
  3706. call AddHistory( tmi, 'standard', status )
  3707. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3708. ! read directly from hdf file
  3709. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3710. case ( 'tmpp', 'tm5-hdf', 'tm5-nc' )
  3711. ! read from surf file:
  3712. call ReadField( tmm, archivekey, 'srols', 'm', tday, t1, t2, &
  3713. lli, 'n', ll, tmi, status )
  3714. IF_NOTOK_RETURN(status=1)
  3715. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3716. ! convert raw data:
  3717. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3718. case ( 'ecmwf-tmpp', 'ecmwf-tm5', 'ncep-cdc', 'ncep-gfs' )
  3719. !call wrtgol( ' tmm read : srols ', t1, ' - ', t2 ); call goPr
  3720. ! info ...
  3721. call Init( tmi, 'srols', 'm', status )
  3722. ! month
  3723. call Get( t1, month=month )
  3724. ! write filename:
  3725. write (fname,'(a,"/SR_OLSSON_360_180_",i2.2,".d")') trim(tmm%input_dir), month
  3726. ! info ...
  3727. call AddHistory( tmi, 'file=='//trim(fname), status )
  3728. ! exist ?
  3729. inquire( file=fname, exist=exist )
  3730. if ( .not. exist ) then
  3731. write (fname,'(a,"/OLSSON-SR_OLSSON_360_180_",i2.2,".d")') trim(tmm%input_dir), month
  3732. write(gol,*)" PLSPLS - using old filename for SR-OLSSON"; call goPr
  3733. inquire( file=fname, exist=exist )
  3734. if ( .not. exist ) then
  3735. write (gol,'("Olsson SR file not found:")'); call goErr
  3736. write (gol,'(" ",a)') trim(fname); call goErr
  3737. TRACEBACK; status=1; return
  3738. endif
  3739. end if
  3740. ! select free file unit:
  3741. fu = 1234
  3742. do
  3743. inquire( unit=fu, opened=opened )
  3744. if ( .not. opened ) exit
  3745. fu = fu + 1
  3746. end do
  3747. ! open data file:
  3748. open( fu, file=trim(fname), form='formatted', status='old', iostat=status )
  3749. if (status/=0) then
  3750. write (gol,'("while opening olsson data file:")'); call goErr
  3751. write (gol,'(" ",a)') trim(fname); call goErr
  3752. TRACEBACK; status=1; return
  3753. end if
  3754. ! read field:
  3755. read (fu,*,iostat=status) sr_ols
  3756. if (status/=0) then
  3757. write (gol,'("while reading from olsson data file:")'); call goErr
  3758. write (gol,'(" ",a)') trim(fname); call goErr
  3759. TRACEBACK; status=1; return
  3760. end if
  3761. ! close file:
  3762. close( fu, iostat=status )
  3763. if (status/=0) then
  3764. write (gol,'("while closing olsson data file:")'); call goErr
  3765. write (gol,'(" ",a)') trim(fname); call goErr
  3766. TRACEBACK; status=1; return
  3767. end if
  3768. ! setup grid definition:
  3769. ! lon : -180.0 -179.0 .. 180.0 ( 1 deg resolution; 360 points; date line twice)
  3770. ! lat : -90.0 -89.0 .. 90.0 ( 1 deg resolution; 180 points; includes poles)
  3771. call Init( lli_ols, -180.00, 360.0/(nlon-1), nlon, -90.0, 180.0/(nlat-1), nlat, status )
  3772. IF_NOTOK_RETURN(status=1)
  3773. ! interpol
  3774. do j = 1, lli%nlat
  3775. do i = 1, lli%nlon
  3776. call Interpol( lli_ols, sr_ols, lli%lon_deg(i), lli%lat_deg(j), ll(i,j) )
  3777. end do
  3778. end do
  3779. ! info ...
  3780. call AddHistory( tmi, 'horizontal_interpolation', status )
  3781. ! done
  3782. call Done( lli_ols, status )
  3783. IF_NOTOK_RETURN(status=1)
  3784. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3785. ! error ...
  3786. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3787. case default
  3788. write (gol,'("unsupported source type `",a,"`")') trim(sourcetype); call goErr
  3789. TRACEBACK; status=1; return
  3790. end select
  3791. ! ok
  3792. call goLabel()
  3793. status = 0
  3794. end subroutine tmm_Read_SR_OLS
  3795. ! ! ==================================================================
  3796. ! ! ===
  3797. ! ! === pv/theta -> eqv.lat.
  3798. ! ! ===
  3799. ! ! ==================================================================
  3800. !
  3801. !
  3802. ! subroutine tmm_ReadEqvLat( tmm, archivekey, &
  3803. ! tday, t1, t2, &
  3804. ! lli, levi, &
  3805. ! sp, pv, theta, eqvlatb, eqvinds, &
  3806. ! status )
  3807. !
  3808. ! use GO, only : TDate, operator(-), operator(+), operator(/), goSplitLine
  3809. ! use Grid, only : TllGridInfo, TLevelInfo
  3810. !
  3811. ! use tmm_mf , only : ReadEqvLatStuff
  3812. ! use tmm_info, only : TMeteoInfo
  3813. !
  3814. ! ! --- in/out --------------------------------
  3815. !
  3816. ! type(TTmMeteo), intent(inout) :: tmm
  3817. !
  3818. ! character(len=*), intent(in) :: archivekey
  3819. !
  3820. ! type(TDate), intent(in) :: tday, t1, t2
  3821. !
  3822. ! type(TllGridInfo), intent(in) :: lli
  3823. ! type(TLevelInfo), intent(in) :: levi
  3824. !
  3825. ! real, intent(out) :: sp(:,:) ! Pa
  3826. ! real, intent(out) :: pv(:,:,:)
  3827. ! real, intent(out) :: theta(:,:,:)
  3828. ! real, intent(out) :: eqvlatb(:,:)
  3829. ! integer, intent(out) :: eqvinds(:,:,:)
  3830. !
  3831. ! integer, intent(out) :: status
  3832. !
  3833. ! ! --- const --------------------------------------
  3834. !
  3835. ! character(len=*), parameter :: rname = mname//'/tmm_ReadEqvLat'
  3836. !
  3837. ! ! --- local -------------------------------
  3838. !
  3839. ! character(len=10) :: sourcetype
  3840. ! character(len=256) :: sourcename
  3841. !
  3842. ! integer :: imf
  3843. !
  3844. ! type(TMeteoInfo) :: tmi
  3845. !
  3846. ! ! --- begin -------------------------------
  3847. !
  3848. ! ! split source key in type and name:
  3849. ! call goSplitLine( archivekey, sourcetype, ':', sourcename )
  3850. !
  3851. ! ! input TMPP fields or raw prism fields ?
  3852. ! select case ( sourcetype )
  3853. !
  3854. ! case ( 'tmpp' )
  3855. !
  3856. ! ! pv valid for [t1,t2]
  3857. ! call ReadField( tmm, archivekey, 'PVo', tday, t1, t2, &
  3858. ! lli, 'n', levi, 'n', sp, pv, tmi, status )
  3859. ! IF_NOTOK_RETURN(status=1)
  3860. !
  3861. ! ! theta valid for [t1,t2]
  3862. ! call ReadField( tmm, archivekey, 'theta', tday, t1, t2, &
  3863. ! lli, 'n', levi, 'n', sp, theta, tmi, status )
  3864. ! IF_NOTOK_RETURN(status=1)
  3865. !
  3866. ! !
  3867. ! ! eqv lat bounds and indices
  3868. ! !
  3869. ! ! select (eventually retrieve first) the meteo file with this param:
  3870. ! call SelectMF( tmm, 'i', archivekey, 'eqvlatb', tday, t1, t2, imf, status )
  3871. ! IF_NOTOK_RETURN(status=1)
  3872. ! !
  3873. ! ! read from selected file
  3874. ! call ReadEqvLatStuff( tmm%mf(imf), t1, t2, eqvlatb, eqvinds, status )
  3875. ! IF_NOTOK_RETURN(status=1)
  3876. !
  3877. ! case default
  3878. !
  3879. ! write (gol,'("unsupported source type `",a,"`")') trim(sourcetype)
  3880. ! TRACEBACK; status=1; return
  3881. !
  3882. ! end select
  3883. !
  3884. ! ! ok
  3885. ! status = 0
  3886. !
  3887. ! end subroutine tmm_ReadEqvLat
  3888. ! ##########################################################################################
  3889. ! ###
  3890. ! ### output
  3891. ! ###
  3892. ! ##########################################################################################
  3893. !
  3894. ! call WriteField( tmmd, 'od-fc-ml60-glb3x2', 'T', 'K', tday, t1, t2, &
  3895. ! lli, 'n', sp, status )
  3896. !
  3897. subroutine tmm_WriteField_2d( tmm, archivekey, &
  3898. tmi, paramkey, unit, tday, t1, t2, &
  3899. lli, nuv, ll, status )
  3900. use tmm_mf , only : WriteRecord
  3901. use tmm_info, only : TMeteoInfo
  3902. ! --- in/out --------------------------------
  3903. type(TTmMeteo), intent(inout) :: tmm
  3904. character(len=*), intent(in) :: archivekey
  3905. type(TMeteoInfo), intent(in) :: tmi
  3906. character(len=*), intent(in) :: paramkey
  3907. character(len=*), intent(in) :: unit
  3908. type(TDate), intent(in) :: tday, t1, t2
  3909. type(TllGridInfo), intent(in) :: lli
  3910. character(len=1), intent(in) :: nuv
  3911. real, intent(inout) :: ll(:,:)
  3912. integer, intent(out) :: status
  3913. ! --- const ------------------------------------
  3914. character(len=*), parameter :: rname = mname//'/tmm_WriteField_2d'
  3915. ! --- local ----------------------------------------
  3916. integer :: imf
  3917. ! --- begin ----------------------------------
  3918. !call wrtgol( 'tmm write : '//trim(paramkey)//' ', t1, ' - ', t2 ); call goPr
  3919. ! check shape of grid:
  3920. if ( ((nuv == 'n') .and. ((size(ll,1) /= lli%nlon ) .or. (size(ll,2) /= lli%nlat ))) .or. &
  3921. ((nuv == 'u') .and. ((size(ll,1) /= lli%nlon+1) .or. (size(ll,2) /= lli%nlat ))) .or. &
  3922. ((nuv == 'v') .and. ((size(ll,1) /= lli%nlon ) .or. (size(ll,2) /= lli%nlat+1))) ) then
  3923. write (gol,'("2d array does not mach with grid definition:")'); call goErr
  3924. write (gol,'(" param : ",a )') paramkey ; call goErr
  3925. write (gol,'(" lli : ",i3," x ",i3)') lli%nlon, lli%nlat; call goErr
  3926. write (gol,'(" nuv : ",a )') nuv; call goErr
  3927. write (gol,'(" ll : ",i3," x ",i3)') shape(ll); call goErr
  3928. TRACEBACK; status=1; return
  3929. end if
  3930. ! select index of already open meteo file or setup access to new one;
  3931. call SelectMF( tmm, 'o', archivekey, paramkey, tday, t1, t2, imf, status )
  3932. IF_NOTOK_RETURN(status=1)
  3933. ! write
  3934. call WriteRecord( tmm%mf(imf), tmi, paramkey, unit, tday, t1, t2, &
  3935. lli, nuv, ll, status )
  3936. IF_NOTOK_RETURN(status=1)
  3937. ! ok
  3938. status = 0
  3939. end subroutine tmm_WriteField_2d
  3940. !
  3941. ! call WriteField( tmmd, 'od-fc-ml60-glb3x2', 'T', 'K', tday, t1, t2, &
  3942. ! lli, 'n', levi, spm, temper, status )
  3943. !
  3944. subroutine tmm_WriteField_3d( tmm, archivekey, &
  3945. tmi, spname, paramkey, unit, tday, t1, t2, &
  3946. lli, nuv, levi, nw, sp, ll, status )!, &
  3947. !nlev )
  3948. use tmm_mf , only : WriteRecord
  3949. use tmm_info, only : TMeteoInfo
  3950. ! --- in/out --------------------------------
  3951. type(TTmMeteo), intent(inout) :: tmm
  3952. character(len=*), intent(in) :: archivekey
  3953. type(TMeteoInfo), intent(in) :: tmi
  3954. character(len=*), intent(in) :: spname
  3955. character(len=*), intent(in) :: paramkey
  3956. character(len=*), intent(in) :: unit
  3957. type(TDate), intent(in) :: tday, t1, t2
  3958. type(TllGridInfo), intent(in) :: lli
  3959. character(len=1), intent(in) :: nuv
  3960. type(TLevelInfo), intent(in) :: levi
  3961. character(len=1), intent(in) :: nw
  3962. real, intent(in) :: sp(:,:) ! Pa
  3963. real, intent(inout) :: ll(:,:,:)
  3964. integer, intent(out) :: status
  3965. !integer, intent(in), optional :: nlev
  3966. ! --- const ------------------------------------
  3967. character(len=*), parameter :: rname = mname//'/tmm_WriteField_3d'
  3968. ! --- local ----------------------------------------
  3969. integer :: imf
  3970. ! --- begin ----------------------------------
  3971. !call wrtgol( 'tmm write : '//trim(paramkey)//' ', t1, ' - ', t2 ); call goPr
  3972. ! check shape of grid:
  3973. if ( ((nuv == 'n') .and. ((size(ll,1) /= lli%nlon ) .or. (size(ll,2) /= lli%nlat ))) .or. &
  3974. ((nuv == 'u') .and. ((size(ll,1) /= lli%nlon+1) .or. (size(ll,2) /= lli%nlat ))) .or. &
  3975. ((nuv == 'v') .and. ((size(ll,1) /= lli%nlon ) .or. (size(ll,2) /= lli%nlat+1))) .or. &
  3976. ((nuv == 'n') .and. ((size(sp,1) /= lli%nlon ) .or. (size(sp,2) /= lli%nlat ))) .or. &
  3977. ((nuv == 'u') .and. ((size(sp,1) /= lli%nlon+1) .or. (size(sp,2) /= lli%nlat ))) .or. &
  3978. ((nuv == 'v') .and. ((size(sp,1) /= lli%nlon ) .or. (size(sp,2) /= lli%nlat+1))) .or. &
  3979. ((nw == 'n') .and. (size(ll,3) > levi%nlev )) .or. &
  3980. ((nw == 'w') .and. (size(ll,3) > levi%nlev+1)) ) then
  3981. write (gol,'("3d arrays do not match with grid definition:")'); call goErr
  3982. write (gol,'(" param : ",a )') paramkey; call goErr
  3983. write (gol,'(" lli : ",i3," x ",i3 )') lli%nlon, lli%nlat; call goErr
  3984. write (gol,'(" nuv : ",a )') nuv; call goErr
  3985. write (gol,'(" levi : ",i3 )') levi%nlev; call goErr
  3986. write (gol,'(" nw : ",a )') nw; call goErr
  3987. write (gol,'(" sp : ",i3," x ",i3 )') shape(sp); call goErr
  3988. write (gol,'(" ll : ",i3," x ",i3," x ",i3)') shape(ll); call goErr
  3989. TRACEBACK; status=1; return
  3990. end if
  3991. ! select index of already open meteo file or setup access to new one;
  3992. call SelectMF( tmm, 'o', archivekey, paramkey, tday, t1, t2, imf, status )
  3993. IF_NOTOK_RETURN(status=1)
  3994. ! write
  3995. call WriteRecord( tmm%mf(imf), tmi, spname, paramkey, unit, tday, t1, t2, &
  3996. lli, nuv, levi, nw, sp, ll, status )!, &
  3997. !nlev=nlev )
  3998. IF_NOTOK_RETURN(status=1)
  3999. ! ok
  4000. status = 0
  4001. end subroutine tmm_WriteField_3d
  4002. end module TMM