tmm.F90 165 KB

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