meteo.F90 233 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109
  1. !### macro's #####################################################
  2. !
  3. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  4. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  5. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  6. !
  7. #include "tm5.inc"
  8. #include "tmm.inc"
  9. !
  10. !------------------------------------------------------------------------------
  11. ! TM5 !
  12. !------------------------------------------------------------------------------
  13. !BOP
  14. !
  15. ! !MODULE: METEO
  16. !
  17. ! !DESCRIPTION: Routines to initialize/finalize meteo grids and data, allocate
  18. ! datasets, and fill them. Include wrappers around read/write
  19. ! meteo files.
  20. ! Perform some meteo dependend calculations (omega, gph,
  21. ! mass <=> pressure, ...)
  22. !
  23. !
  24. ! !REVISION HISTORY:
  25. !
  26. ! 09 Jun 2010 - P. Le Sager
  27. ! - Fix in METEO_SETUP_MASS when reading restart files.
  28. ! - Added some (protex) doc.
  29. ! - Merge updates from EC-Earth project.
  30. !
  31. ! 10 Aug 2010 - Arjo Segers
  32. ! - Reset previous fix since it gives differences after a restart.
  33. ! - Use 'pw_dat' instead of 'mfw_dat' for massflux balancing;
  34. ! otherwise 'mfw_dat' is changed by matching its values in a zoom
  35. ! region with the parent, and this would give tiny differences
  36. ! between a long run and two smaller runs with a restart in between.
  37. ! - Reformatted protex comments.
  38. !
  39. ! 10 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  40. !
  41. ! !REMARKS:
  42. !
  43. ! (1) Several surface pressure fields are used:
  44. !
  45. ! sp1,sp2 : Surface pressures at begin and end of dynamic time step.
  46. ! Their values are interpolated between surface pressures
  47. ! read from the meteorological archive (in real(4) !)
  48. ! or received from the meteorological model.
  49. ! Fields from the meteorological archive are stored into
  50. ! the 'sp2' structure, and copied from there into 'sp1'.
  51. !
  52. ! sp : Actual surface pressure due to advection.
  53. ! In theory this field is equal to 'sp1' at the begin of a timestep,
  54. ! but due to numerical inacuracies ( real(4) vs real(8) )
  55. ! tiny differeces occur.
  56. ! Therefore, this field is stored and restored in case of restart.
  57. !
  58. ! spm Surface pressure for the mid of the time interval,
  59. ! thus in between 'sp1' and 'sp2' .
  60. !
  61. ! !INTERFACE:
  62. !
  63. MODULE METEO
  64. !
  65. ! !USES:
  66. !
  67. use GO, only : gol, goErr, goPr, goLabel
  68. use GO, only : TDate
  69. use partools, only : isRoot
  70. use grid, only : TllGridInfo, TLevelInfo
  71. use tmm, only : TtmMeteo
  72. !
  73. use dims, only : nregions, nregions_all, okdebug
  74. use tm5_distgrid, only : dgrid, Get_DistGrid, GATHER, SCATTER, UPDATE_HALO
  75. use tm5_distgrid, only : SCATTER_J_BAND, SCATTER_I_BAND
  76. USE METEODATA
  77. IMPLICIT NONE
  78. PRIVATE
  79. !
  80. ! !PUBLIC MEMBER FUNCTIONS:
  81. !
  82. public :: Meteo_Init_Grids, Meteo_Done_Grids
  83. public :: Meteo_Init, Meteo_Done, Meteo_Alloc
  84. public :: Meteo_Setup_Mass, Meteo_Setup_Other
  85. public :: Set, Check
  86. public :: TimeInterpolation
  87. !
  88. ! !PRIVATE TYPES:
  89. !
  90. type TMeteoField ! storage for a single meteo field:
  91. logical :: used
  92. character(len=16) :: name
  93. character(len=16) :: unit
  94. integer :: is(2), js(2), ls(2) ! shapes
  95. real, pointer :: data(:,:,:)
  96. end type TMeteoField
  97. !
  98. ! !INTERFACE:
  99. !
  100. ! diff b/w para & serial: serial has LLI argument
  101. ! diff b/w 2d and 2d_n : size of 1st argument (TMeteoData)
  102. ! diff b/w 2d and 3d : two extra arguments for levels info
  103. interface Setup
  104. module procedure Setup_2d_para
  105. module procedure Setup_2d_n_para
  106. module procedure Setup_3d_para
  107. module procedure Setup_2d_serial
  108. module procedure Setup_2d_n_serial
  109. module procedure Setup_3d_serial
  110. end interface
  111. interface Setup_CONVEC
  112. module procedure Setup_CONVEC_para
  113. module procedure Setup_CONVEC_serial
  114. end interface
  115. interface Setup_CLOUDCOVERS
  116. module procedure Setup_CLOUDCOVERS_para
  117. module procedure Setup_CLOUDCOVERS_serial
  118. end interface
  119. !
  120. ! !PRIVATE DATA MEMBERS:
  121. !
  122. character(len=*), parameter :: mname = 'Meteo'
  123. type(TtmMeteo), save :: tmmd ! interface to TM meteo data
  124. real :: sp_region0(1,1) ! single cell global surface pressure (region 0)
  125. !
  126. !EOP
  127. !------------------------------------------------------------------------
  128. CONTAINS
  129. !--------------------------------------------------------------------------
  130. ! TM5 !
  131. !--------------------------------------------------------------------------
  132. !BOP
  133. !
  134. ! !IROUTINE: METEO_INIT_GRIDS
  135. !
  136. ! !DESCRIPTION: initialize grids and levels for each region. Grids on the
  137. ! local domain are simply copied from the DistGrid object.
  138. !\\
  139. !\\
  140. ! !INTERFACE:
  141. !
  142. SUBROUTINE METEO_INIT_GRIDS( status )
  143. !
  144. ! !USES:
  145. !
  146. use Grid, only : Init
  147. use dims, only : region_name
  148. use dims, only : xbeg, xend, dx, xref, im
  149. use dims, only : ybeg, yend, dy, yref, jm
  150. use dims, only : echlevs, lme, a_ec, b_ec
  151. use geometry, only : geomtryv
  152. !
  153. ! !OUTPUT PARAMETERS:
  154. !
  155. integer, intent(out) :: status
  156. !
  157. ! !REVISION HISTORY:
  158. ! 19 Oct 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  159. !
  160. !EOP
  161. !------------------------------------------------------------------------
  162. !BOC
  163. character(len=*), parameter :: rname = mname//'/Meteo_Init_Grids'
  164. integer :: n
  165. real :: dlon, dlat
  166. ! --- begin ----------------------------
  167. call goLabel(rname)
  168. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  169. ! setup horizontal grids for the 0th one-cell grid
  170. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  171. ! grid spacing:
  172. dlon = real(xend(0)-xbeg(0))/im(0)
  173. dlat = real(yend(0)-ybeg(0))/jm(0)
  174. ! define grid:
  175. call Init( lli(0), xbeg(0)+dlon/2.0, dlon, im(0), &
  176. ybeg(0)+dlat/2.0, dlat, jm(0), status, &
  177. name=trim(region_name(0)) )
  178. IF_NOTOK_RETURN(status=1)
  179. ! zonal grids
  180. dlat = real(yend(0)-ybeg(0))/jm(0)
  181. call Init( lli_z(0), 0.0, 360.0, 1, &
  182. ybeg(0)+dlat/2.0, dlat, jm(0), status, &
  183. name=trim(region_name(0))//'_z' )
  184. IF_NOTOK_RETURN(status=1)
  185. global_lli(0) = lli(0)
  186. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  187. ! local horizontal grid : get info from Distributed Grid
  188. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  189. do n=1, nregions_all
  190. call Get_DistGrid( dgrid(n), lli=lli(n), lli_z=lli_z(n), global_lli=global_lli(n) )
  191. ! correct name (it defines file to read data)
  192. lli(n)%name = trim(region_name(n))
  193. lli_z(n)%name = trim(region_name(n))//'_z'
  194. global_lli(n)%name = trim(region_name(n))
  195. end do
  196. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  197. ! level definition
  198. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  199. ! setup parent level definition:
  200. call Init( levi_ec, lme, a_ec, b_ec, status ) ! ecmwf levels
  201. IF_NOTOK_RETURN(status=1)
  202. ! setup level definition:
  203. call Init( levi, levi_ec, echlevs, status ) ! tm half level selection
  204. IF_NOTOK_RETURN(status=1)
  205. ! determine "old" at, bt of dims module
  206. call geomtryv( )
  207. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  208. ! done
  209. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  210. status = 0
  211. call goLabel()
  212. END SUBROUTINE METEO_INIT_GRIDS
  213. !EOC
  214. !--------------------------------------------------------------------------
  215. ! TM5 !
  216. !--------------------------------------------------------------------------
  217. !BOP
  218. !
  219. ! !IROUTINE: METEO_DONE_GRIDS
  220. !
  221. ! !DESCRIPTION: finalize all grids and levels used for met fields.
  222. !\\
  223. !\\
  224. ! !INTERFACE:
  225. !
  226. SUBROUTINE METEO_DONE_GRIDS( status )
  227. !
  228. ! !USES:
  229. !
  230. use Grid, only : Done
  231. !
  232. ! !OUTPUT PARAMETERS:
  233. !
  234. integer, intent(out) :: status
  235. !
  236. ! !REVISION HISTORY:
  237. ! 19 Oct 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  238. !
  239. !EOP
  240. !------------------------------------------------------------------------
  241. !BOC
  242. character(len=*), parameter :: rname = mname//'/Meteo_Done_Grids'
  243. integer :: n
  244. ! --- begin --------------------------------
  245. call goLabel(rname)
  246. ! horizontal (local) and zonal grids
  247. do n = 0, nregions_all
  248. call Done( lli(n), status )
  249. IF_NOTOK_RETURN(status=1)
  250. call Done( lli_z(n), status )
  251. IF_NOTOK_RETURN(status=1)
  252. end do
  253. ! horizontal (global) grids
  254. do n = 1, nregions_all
  255. call Done( global_lli(n), status )
  256. IF_NOTOK_RETURN(status=1)
  257. end do
  258. ! done parent level definition:
  259. call Done( levi_ec, status )
  260. IF_NOTOK_RETURN(status=1)
  261. ! level definition:
  262. call Done( levi, status )
  263. IF_NOTOK_RETURN(status=1)
  264. ! done
  265. status = 0
  266. call goLabel()
  267. END SUBROUTINE METEO_DONE_GRIDS
  268. !EOC
  269. !--------------------------------------------------------------------------
  270. ! TM5 !
  271. !--------------------------------------------------------------------------
  272. !BOP
  273. !
  274. ! !IROUTINE: METEO_INIT
  275. !
  276. ! !DESCRIPTION: Init met fields, i.e. nullify pointers, store shape, and set
  277. ! if needed (ie used) according to meteo.rc.
  278. !\\
  279. !\\
  280. ! !INTERFACE:
  281. !
  282. SUBROUTINE METEO_INIT( status )
  283. !
  284. ! !USES:
  285. !
  286. use GO, only : TrcFile, Init, Done, ReadRc
  287. use Binas, only : p_global
  288. use TMM, only : Init
  289. use dims, only : im, jm, lm, lmax_conv
  290. use meteodata, only : Init
  291. use global_data, only : rcfile
  292. !
  293. ! !OUTPUT PARAMETERS:
  294. !
  295. integer, intent(out) :: status
  296. !
  297. ! !REVISION HISTORY:
  298. ! 9 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  299. !
  300. !EOP
  301. !------------------------------------------------------------------------
  302. !BOC
  303. character(len=*), parameter :: rname = mname//'/Meteo_Init'
  304. ! --- local -----------------------------
  305. integer :: region, n
  306. integer :: imr, jmr, lmr
  307. integer :: halo
  308. type(TrcFile) :: rcF
  309. integer :: iveg
  310. character(len=4) :: sveg
  311. integer :: i01, i02, j01, j02
  312. ! --- begin ----------------------------
  313. call goLabel(rname)
  314. ! open rcfile:
  315. call Init( rcF, rcfile, status )
  316. IF_NOTOK_RETURN(status=1)
  317. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  318. ! meteo database
  319. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  320. ! setup interface to TM meteo:
  321. call Init( tmmd, rcF, status )
  322. IF_NOTOK_RETURN(status=1)
  323. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  324. ! define meteo data
  325. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  326. ! global mean surface pressure
  327. sp_region0 = p_global
  328. ! setup meteo fields: not in use, not allocated:
  329. do region = 1, nregions_all
  330. call Get_DistGrid( dgrid(region), I_STRT=i01, I_STOP=i02, J_STRT=j01, J_STOP=j02 )
  331. lmr = lm(region)
  332. !
  333. ! ** surface pressure *************************************
  334. !
  335. ! two extra horizontal cells
  336. halo = 2
  337. ! end of interval; also reads for sp1 and spm :
  338. call Init_MeteoData( sp2_dat(region), 'sp', 'Pa', &
  339. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  340. rcF, (/'* ','ml','sp'/), region, status )
  341. IF_NOTOK_RETURN(status=1)
  342. ! check time interpolation:
  343. if ( sp2_dat(region)%tinterp(1:6) /= 'interp' ) then
  344. write (gol,'("surface pressure should be interpolated:")'); call goErr
  345. write (gol,'(" requested tinterp : ",a)') trim(sp2_dat(region)%tinterp); call goErr
  346. call goErr; status=1; return
  347. end if
  348. ! start of interval (copied from sp2_dat):
  349. call Init( sp1_dat(region), 'sp', 'Pa', 'computed', &
  350. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  351. 'no-sourcekey', .false., 'no-destkey', status )
  352. IF_NOTOK_RETURN(status=1)
  353. ! current pressure:
  354. call Init( sp_dat(region), 'sp', 'Pa', 'computed', &
  355. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  356. 'no-sourcekey', .false., 'no-destkey', status )
  357. IF_NOTOK_RETURN(status=1)
  358. ! surface pressure at mid of dynamic time interval:
  359. call Init( spm_dat(region), 'sp', 'Pa', 'computed', &
  360. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  361. 'no-sourcekey', .false., 'no-destkey', status )
  362. IF_NOTOK_RETURN(status=1)
  363. !
  364. ! ** 3D pressure and mass **************************
  365. !
  366. ! two extra horizontal cells (same as surface pressures)
  367. halo = 2
  368. ! pressure at half levels (lm+1):
  369. call Init( phlb_dat(region), 'phlb', 'Pa', 'computed', &
  370. (/i01,i02/), (/j01,j02/), halo, (/1,lmr+1/), &
  371. 'no-sourcekey', .false., 'no-destkey', status )
  372. IF_NOTOK_RETURN(status=1)
  373. ! air mass:
  374. call Init( m_dat(region), 'm', 'kg', 'computed', &
  375. (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
  376. 'no-sourcekey', .false., 'no-destkey', status )
  377. IF_NOTOK_RETURN(status=1)
  378. !
  379. ! ** massfluxes *************************************
  380. !
  381. ! ~~ vertical
  382. ! no extra cells
  383. halo = 0
  384. ! vertical flux (kg/s)
  385. call Init_MeteoData( mfw_dat(region), 'mfw', 'kg/s', &
  386. (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
  387. rcF, (/'* ','ml ','mflux_w'/), region, status )
  388. IF_NOTOK_RETURN(status=1)
  389. ! vertical flux (kg/s) : BALANCED
  390. ! NOTE: data is copied from mfw, thus use same tinterp
  391. ! for correct allocation of data arrays
  392. call Init( pw_dat(region), 'pw', 'kg/s', mfw_dat(region)%tinterp, &
  393. (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
  394. 'no-sourcekey', .false., 'no-destkey', status )
  395. IF_NOTOK_RETURN(status=1)
  396. ! tendency of surface pressure:
  397. call Init_MeteoData( tsp_dat(region), 'tsp', 'Pa/s', &
  398. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  399. rcF, (/'* ','ml ','mflux_w'/), region, status )
  400. IF_NOTOK_RETURN(status=1)
  401. ! ~~ horizontal
  402. ! NOTE: strange old indexing:
  403. ! pu_tmpp --> pu(0:imr,1:jmr ,1:lmr) in pu_t(0:imr+1,0:jmr+1,0:lmr)
  404. ! ^ ^ ^ ^ too large !
  405. ! pv_tmpp --> pv(1:imr,1:jmr+1,1:lmr) in pv_t(0:imr+1,0:jmr+1,0:lmr)
  406. ! ^ ^ ^ ^ too large !
  407. ! The extra cells are implemented below as halo cells.
  408. ! one extra cell
  409. halo = 1
  410. !! east/west flux (kg/s)
  411. !call Init( mfu_dat(region), 'mfu', 'kg/s', tinterp_curr, &
  412. ! (/0,imr/), (/1,jmr/), halo, (/1,lmr/), &
  413. ! sourcekey_curr, write_meteo, status, default=destkey_curr )
  414. !IF_NOTOK_RETURN(status=1)
  415. !! south/north flux (kg/s)
  416. !call Init( mfv_dat(region), 'mfv', 'kg/s', tinterp_curr, &
  417. ! (/1,imr/), (/0,jmr/), halo, (/1,lmr/), &
  418. ! sourcekey_curr, write_meteo, status, default=destkey_curr )
  419. !IF_NOTOK_RETURN(status=1)
  420. ! east/west flux (kg/s)
  421. call Init_MeteoData( mfu_dat(region), 'mfu', 'kg/s', &
  422. (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
  423. rcF, (/'* ','ml ','mflux_uv'/), region, status )
  424. IF_NOTOK_RETURN(status=1)
  425. ! south/north flux (kg/s)
  426. call Init_MeteoData( mfv_dat(region), 'mfv', 'kg/s', &
  427. (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
  428. rcF, (/'* ','ml ','mflux_uv'/), region, status )
  429. IF_NOTOK_RETURN(status=1)
  430. !! east/west flux (kg/s) : BALANCED
  431. !call Init( pu_dat(region), 'pu', 'kg/s', 'computed', &
  432. ! (/0,imr/), (/1,jmr/), halo, (/1,lmr/), &
  433. ! 'no-sourcekey', .false., 'no-destkey', status )
  434. !IF_NOTOK_RETURN(status=1)
  435. !
  436. !! south/north flux (kg/s) : BALANCED
  437. !call Init( pv_dat(region), 'pv', 'kg/s', 'computed', &
  438. ! (/1,imr/), (/0,jmr/), halo, (/1,lmr/), &
  439. ! 'no-sourcekey', .false., 'no-destkey', status )
  440. !IF_NOTOK_RETURN(status=1)
  441. halo = 1
  442. ! east/west flux (kg/s) : BALANCED
  443. ! NOTE: data is copied from mfu, thus use same tinterp
  444. ! for correct allocation of data arrays
  445. call Init( pu_dat(region), 'pu', 'kg/s', mfu_dat(region)%tinterp, &
  446. (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
  447. 'no-sourcekey', .false., 'no-destkey', status )
  448. IF_NOTOK_RETURN(status=1)
  449. ! south/north flux (kg/s) : BALANCED
  450. ! NOTE: data is copied from mfv, thus use same tinterp
  451. ! for correct allocation of data arrays
  452. call Init( pv_dat(region), 'pv', 'kg/s', mfv_dat(region)%tinterp, &
  453. (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
  454. 'no-sourcekey', .false., 'no-destkey', status )
  455. IF_NOTOK_RETURN(status=1)
  456. !
  457. ! ** temperature *************************************
  458. !
  459. ! no extra cells
  460. halo = 0
  461. ! temperature (K) (halo=0)
  462. call Init_MeteoData( temper_dat(region), 'T', 'K', &
  463. (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
  464. rcF, (/'* ','ml ','temper'/), region, status )
  465. IF_NOTOK_RETURN(status=1)
  466. !
  467. ! ** humidity *************************************
  468. !
  469. ! no extra cells
  470. halo = 0
  471. ! humidity (kg/kg) (halo = 0)
  472. call Init_MeteoData( humid_dat(region), 'Q', 'kg/kg', &
  473. (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
  474. rcF, (/'* ','ml ','humid'/), region, status )
  475. IF_NOTOK_RETURN(status=1)
  476. !
  477. ! ** computed *************************************
  478. !
  479. halo = 1 ! halo needed for station output in USER_OUTPUT_AEROCOM
  480. ! geopotential height(m) (lm+1, halo=0)
  481. call Init( gph_dat(region), 'gph', 'm', 'computed', &
  482. (/i01,i02/), (/j01,j02/), halo, (/1,lmr+1/), &
  483. 'no-sourcekey', .false., 'no-destkey', status )
  484. IF_NOTOK_RETURN(status=1)
  485. ! no extra cells
  486. halo = 0
  487. ! vertical velocity (Pa/s) (lm+1, halo=0)
  488. call Init( omega_dat(region), 'omega', 'Pa/s', 'computed', &
  489. (/i01,i02/), (/j01,j02/), halo, (/1,lmr+1/), &
  490. 'no-sourcekey', .false., 'no-destkey', status )
  491. IF_NOTOK_RETURN(status=1)
  492. !
  493. ! ** clouds *************************************
  494. !
  495. ! no extra cells
  496. halo = 0
  497. ! lwc liquid water content (kg/kg) (halo=0)
  498. call Init_MeteoData( lwc_dat(region), 'CLWC', 'kg/kg', &
  499. (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
  500. rcF, (/'* ','ml ','cloud'/), region, status )
  501. IF_NOTOK_RETURN(status=1)
  502. ! iwc ice water content (kg/kg) (halo=0)
  503. call Init_MeteoData( iwc_dat(region), 'CIWC', 'kg/kg', &
  504. (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
  505. rcF, (/'* ','ml ','cloud'/), region, status )
  506. IF_NOTOK_RETURN(status=1)
  507. ! cc cloud cover (fraction) (halo=0)
  508. call Init_MeteoData( cc_dat(region), 'CC', '1', &
  509. (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
  510. rcF, (/'* ','ml ','cloud'/), region, status )
  511. IF_NOTOK_RETURN(status=1)
  512. ! cco cloud cover overhead = above bottom of box (fraction) (halo=0)
  513. call Init_MeteoData( cco_dat(region), 'CCO', '1', &
  514. (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
  515. rcF, (/'* ','ml ','cloud'/), region, status )
  516. IF_NOTOK_RETURN(status=1)
  517. ! ccu cloud cover underfeet = below top of box (fraction) (halo=0)
  518. call Init_MeteoData( ccu_dat(region), 'CCU', '1', &
  519. (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
  520. rcF, (/'* ','ml ','cloud'/), region, status )
  521. IF_NOTOK_RETURN(status=1)
  522. !
  523. ! ** convection *************************************
  524. !
  525. ! no extra cells
  526. halo = 0
  527. ! entu entrainement updraft
  528. call Init_MeteoData( entu_dat(region), 'eu', 'kg/m2/s', &
  529. (/i01,i02/), (/j01,j02/), halo, (/1,lmax_conv/), &
  530. rcF, (/'* ','ml ','convec'/), region, status )
  531. IF_NOTOK_RETURN(status=1)
  532. ! entd entrainement downdraft (im,jm,lmax_conv)
  533. call Init_MeteoData( entd_dat(region), 'ed', 'kg/m2/s', &
  534. (/i01,i02/), (/j01,j02/), halo, (/1,lmax_conv/), &
  535. rcF, (/'* ','ml ','convec'/), region, status )
  536. IF_NOTOK_RETURN(status=1)
  537. ! detu detrainement updraft
  538. call Init_MeteoData( detu_dat(region), 'du', 'kg/m2/s', &
  539. (/i01,i02/), (/j01,j02/), halo, (/1,lmax_conv/), &
  540. rcF, (/'* ','ml ','convec'/), region, status )
  541. IF_NOTOK_RETURN(status=1)
  542. ! detd detrainement downdraft
  543. call Init_MeteoData( detd_dat(region), 'dd', 'kg/m2/s', &
  544. (/i01,i02/), (/j01,j02/), halo, (/1,lmax_conv/), &
  545. rcF, (/'* ','ml ','convec'/), region, status )
  546. IF_NOTOK_RETURN(status=1)
  547. !
  548. ! *** surface fields
  549. !
  550. ! no extra cells
  551. halo = 0
  552. ! orography (m*[g])
  553. call Init_MeteoData( oro_dat(region), 'oro', 'm m/s2', &
  554. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  555. rcF, (/'* ','sfc ','sfc.const','sfc.an ','oro '/), region, status )
  556. IF_NOTOK_RETURN(status=1)
  557. ! land/sea mask (%)
  558. call Init_MeteoData( lsmask_dat(region), 'lsm', '%', &
  559. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  560. rcF, (/'* ','sfc ','sfc.const','sfc.an ','lsm '/), region, status )
  561. IF_NOTOK_RETURN(status=1)
  562. ! ~~~ instantaneous fields
  563. ! sea surface temperatue:
  564. call Init_MeteoData( sst_dat(region), 'sst', 'K', &
  565. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  566. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','sst '/), region, status )
  567. IF_NOTOK_RETURN(status=1)
  568. ! 10m u wind (m/s)
  569. call Init_MeteoData( u10m_dat(region), 'u10m', 'm/s', &
  570. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  571. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','u10m '/), region, status )
  572. IF_NOTOK_RETURN(status=1)
  573. ! 10m v wind (m/s)
  574. call Init_MeteoData( v10m_dat(region), 'v10m', 'm/s', &
  575. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  576. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','v10m '/), region, status )
  577. IF_NOTOK_RETURN(status=1)
  578. ! skin reservoir content (m water) ; instant
  579. call Init_MeteoData( src_dat(region), 'src', 'm', &
  580. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  581. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','src '/), region, status )
  582. IF_NOTOK_RETURN(status=1)
  583. ! 2 meter dewpoint temperature (K) ; instant
  584. call Init_MeteoData( d2m_dat(region), 'd2m', 'K', &
  585. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  586. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','d2m '/), region, status )
  587. IF_NOTOK_RETURN(status=1)
  588. ! 2 meter temperature (K) ; instant
  589. call Init_MeteoData( t2m_dat(region), 't2m', 'K', &
  590. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  591. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','t2m '/), region, status )
  592. IF_NOTOK_RETURN(status=1)
  593. ! skin temperature (K) ; instant
  594. call Init_MeteoData( skt_dat(region), 'skt', 'K', &
  595. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  596. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','skt '/), region, status )
  597. IF_NOTOK_RETURN(status=1)
  598. ! boundary layer height (m) ; instant
  599. call Init_MeteoData( blh_dat(region), 'blh', 'm', &
  600. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  601. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','blh '/), region, status )
  602. IF_NOTOK_RETURN(status=1)
  603. ! ~~~ average field (accumulated)
  604. ! surface sensible heat flux (W/m2) ; time aver
  605. call Init_MeteoData( sshf_dat(region), 'sshf', 'W/m2', &
  606. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  607. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','sshf '/), region, status )
  608. IF_NOTOK_RETURN(status=1)
  609. ! surface latent heat flux (W/m2) ; time aver
  610. call Init_MeteoData( slhf_dat(region), 'slhf', 'W/m2', &
  611. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  612. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','slhf '/), region, status )
  613. IF_NOTOK_RETURN(status=1)
  614. ! east-west surface stress (N/m2); time aver
  615. call Init_MeteoData( ewss_dat(region), 'ewss', 'N/m2', &
  616. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  617. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','ewss '/), region, status )
  618. IF_NOTOK_RETURN(status=1)
  619. ! north-south surface stress (N/m2) ; time aver
  620. call Init_MeteoData( nsss_dat(region), 'nsss', 'N/m2', &
  621. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  622. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','nsss '/), region, status )
  623. IF_NOTOK_RETURN(status=1)
  624. ! convective precipitation (m/s) ; time aver
  625. call Init_MeteoData( cp_dat(region), 'cp', 'm/s', &
  626. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  627. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','cp '/), region, status )
  628. IF_NOTOK_RETURN(status=1)
  629. ! large scale stratiform precipitation (m/s) ; time aver
  630. call Init_MeteoData( lsp_dat(region), 'lsp', 'm/s', &
  631. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  632. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','lsp '/), region, status )
  633. IF_NOTOK_RETURN(status=1)
  634. ! surface solar radiation ( W/m2 ) ; time aver
  635. call Init_MeteoData( ssr_dat(region), 'ssr', 'W/m2', &
  636. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  637. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','ssr '/), region, status )
  638. IF_NOTOK_RETURN(status=1)
  639. ! surface solar radiation downwards ( W/m2 ) ; time aver
  640. call Init_MeteoData( ssrd_dat(region), 'ssrd', 'W/m2', &
  641. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  642. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','ssrd '/), region, status )
  643. IF_NOTOK_RETURN(status=1)
  644. ! surface thermal radiation ( W/m2 ) ; time aver
  645. call Init_MeteoData( str_dat(region), 'str', 'W/m2', &
  646. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  647. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','str '/), region, status )
  648. IF_NOTOK_RETURN(status=1)
  649. ! surface thermal radiation downwards ( W/m2 ) ; time aver
  650. call Init_MeteoData( strd_dat(region), 'strd', 'W/m2', &
  651. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  652. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','strd '/), region, status )
  653. IF_NOTOK_RETURN(status=1)
  654. ! snow fall (m water eqv); time aver
  655. call Init_MeteoData( sf_dat(region), 'sf', 'm', &
  656. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  657. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','sf '/), region, status )
  658. IF_NOTOK_RETURN(status=1)
  659. ! ~~~ time averages in grib files tfc+[12,15] etc
  660. ! 10m wind gust (m/s)
  661. call Init_MeteoData( g10m_dat(region), 'g10m', 'm/s', &
  662. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  663. rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','g10m '/), region, status )
  664. IF_NOTOK_RETURN(status=1)
  665. ! ~~~ in tmpp daily averages
  666. ! sea ice:
  667. call Init_MeteoData( ci_dat(region), 'ci', '1', &
  668. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  669. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.fc ','ci '/), region, status )
  670. IF_NOTOK_RETURN(status=1)
  671. ! snow depth (m water eqv); day aver ?
  672. call Init_MeteoData( sd_dat(region), 'sd', 'm', &
  673. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  674. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.fc ','sd '/), region, status )
  675. IF_NOTOK_RETURN(status=1)
  676. ! volumetric soil water layer 1 ( m3 water / m3 soil) ; day aver ?
  677. call Init_MeteoData( swvl1_dat(region), 'swvl1', '1', &
  678. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  679. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.fc ','swvl1 '/), region, status )
  680. IF_NOTOK_RETURN(status=1)
  681. ! vegetation type (%) ; day aver
  682. do iveg = 1, nveg
  683. write (sveg,'("tv",i2.2)') iveg
  684. call Init_MeteoData( tv_dat(region,iveg), sveg, '%', &
  685. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  686. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','veg '/), region, status )
  687. IF_NOTOK_RETURN(status=1)
  688. end do
  689. ! low vegetation cover (0-1) ; day aver
  690. call Init_MeteoData( cvl_dat(region), 'cvl', '1', &
  691. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  692. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','veg '/), region, status )
  693. IF_NOTOK_RETURN(status=1)
  694. ! high vegetation cover (0-1) ; day aver
  695. call Init_MeteoData( cvh_dat(region), 'cvh', '1', &
  696. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  697. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','veg '/), region, status )
  698. IF_NOTOK_RETURN(status=1)
  699. ! albedo ; daily average
  700. call Init_MeteoData( albedo_dat(region), 'albedo', '1', &
  701. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  702. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','albedo '/), region, status )
  703. IF_NOTOK_RETURN(status=1)
  704. ! surface roughness (ecmwf,ncep)
  705. call Init_MeteoData( sr_ecm_dat(region), 'sr', 'm', &
  706. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  707. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','sr '/), region, status )
  708. IF_NOTOK_RETURN(status=1)
  709. ! ~~~ monthly data
  710. ! surface roughness (olsson) ; monthly
  711. call Init_MeteoData( sr_ols_dat(region), 'srols', 'm', &
  712. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  713. rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','srols '/), region, status )
  714. IF_NOTOK_RETURN(status=1)
  715. ! ~~~ macc emissions
  716. ! wildfire emissions of CH4
  717. call Init_MeteoData( ch4fire_dat(region), 'ch4fire', 'kg m**-2 s**-1', &
  718. (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
  719. rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','ch4fire '/), region, status )
  720. IF_NOTOK_RETURN(status=1)
  721. end do ! regions
  722. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  723. ! done
  724. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  725. ! close rcfile:
  726. call Done( rcF, status )
  727. IF_NOTOK_RETURN(status=1)
  728. ! ok
  729. status = 0
  730. call goLabel()
  731. END SUBROUTINE METEO_INIT
  732. !EOC
  733. !
  734. ! Read multiple keys in rcfile to setup meteodata structure.
  735. ! The following keys are read:
  736. !
  737. ! meteo.tinterp.<param> <-- time interpolation
  738. ! tmm.sourcekey.<grid>.<param> <-- input file name description
  739. ! tmm.output.<grid>.<param> <-- write meteo ?
  740. ! tmm.destkey.<grid>.<param> <-- output file name description
  741. !
  742. ! where <grid> is first '*' and then set to the grid name,
  743. ! and <param> is set to each of the provided keys.
  744. !
  745. ! Called for region=1..nregions_all
  746. SUBROUTINE INIT_METEODATA( md, name, unit, is, js, halo, ls, &
  747. rcF, rcs, region, status )
  748. use GO, only : TRcFile, ReadRc
  749. use Dims, only : nregions, nregions_max
  750. use MeteoData, only : TMeteoData, Init, Set
  751. ! --- in/out -------------------------------------
  752. type(TMeteoData), intent(out) :: md
  753. character(len=*), intent(in) :: name, unit
  754. integer, intent(in) :: is(2), js(2)
  755. integer, intent(in) :: halo
  756. integer, intent(in) :: ls(2)
  757. type(TRcFile), intent(inout) :: rcF
  758. character(len=*), intent(in) :: rcs(:)
  759. integer, intent(in) :: region
  760. integer, intent(out) :: status
  761. ! --- const --------------------------------------
  762. character(len=*), parameter :: rname = mname//'/Init_MeteoData'
  763. ! --- local -------------------------------------
  764. character(len=10) :: tinterp
  765. character(len=256) :: sourcekey
  766. logical :: write_meteo
  767. character(len=256) :: destkey
  768. logical :: used
  769. ! --- begin -------------------------------------
  770. ! time interpolation :
  771. call ReadRc( rcF, 'meteo.tinterp', rcs, tinterp, status )
  772. IF_NOTOK_RETURN(status=1)
  773. ! source filenames:
  774. call ReadRc( rcF, 'tmm.sourcekey.*', rcs, sourcekey, status, default='no-sourcekey' )
  775. IF_ERROR_RETURN(status=1)
  776. call ReadRc( rcF, 'tmm.sourcekey.'//trim(lli(region)%name), rcs, sourcekey, status, default=sourcekey )
  777. IF_ERROR_RETURN(status=1)
  778. ! write flag:
  779. call ReadRc( rcF, 'tmm.output.*', rcs, write_meteo, status, default=.false. )
  780. IF_ERROR_RETURN(status=1)
  781. call ReadRc( rcF, 'tmm.output.'//trim(lli(region)%name), rcs, write_meteo, status, default=write_meteo )
  782. IF_ERROR_RETURN(status=1)
  783. ! destination filenames:
  784. if ( write_meteo ) then
  785. call ReadRc( rcF, 'tmm.destkey.*', rcs, destkey, status, default='no-destkey' )
  786. IF_ERROR_RETURN(status=1)
  787. call ReadRc( rcF, 'tmm.destkey.'//trim(lli(region)%name), rcs, destkey, status, default=destkey )
  788. IF_ERROR_RETURN(status=1)
  789. else
  790. destkey = 'no-destkey'
  791. end if
  792. ! define meteo data,
  793. ! but should be marked as 'used' to be allocated and filled:
  794. call Init( md, name, unit, tinterp, is, js, halo, ls, &
  795. sourcekey, write_meteo, destkey, status )
  796. IF_NOTOK_RETURN(status=1)
  797. ! read this type of meteo ?
  798. ! only regions 1..nregions or the extra fiels above nregions_max
  799. ! could be in use:
  800. ! [all regions, but do "if test", because nregions may be different from nregions_max]
  801. if ( (region <= nregions) .or. (region > nregions_max) ) then
  802. call ReadRc( rcF, 'meteo.read.*', rcs, used, status, default=.false. )
  803. IF_ERROR_RETURN(status=1)
  804. call ReadRc( rcF, 'meteo.read.'//trim(lli(region)%name), rcs, used, status, default=used )
  805. IF_ERROR_RETURN(status=1)
  806. else
  807. used = .false.
  808. end if
  809. ! in use ?
  810. call Set( md, status, used=used )
  811. IF_NOTOK_RETURN(status=1)
  812. ! ok
  813. status = 0
  814. END SUBROUTINE INIT_METEODATA
  815. ! ***
  816. SUBROUTINE METEO_DONE( status )
  817. use TMM, only : Done
  818. use Dims, only : nregions_all
  819. use meteodata, only : Done
  820. ! --- in/out -------------------------------
  821. integer, intent(out) :: status
  822. ! --- const --------------------------------------
  823. character(len=*), parameter :: rname = mname//'/Meteo_Done'
  824. ! --- local -----------------------------
  825. integer :: n
  826. integer :: iveg
  827. ! --- begin --------------------------------
  828. call goLabel(rname)
  829. ! interface to TM meteo:
  830. call Done( tmmd, status )
  831. IF_NOTOK_RETURN(status=1)
  832. !
  833. ! done meteo data
  834. !
  835. ! destroy meteo fields:
  836. do n = 1, nregions_all
  837. ! ***
  838. call Done( sp1_dat(n), status )
  839. IF_NOTOK_RETURN(status=1)
  840. call Done( sp2_dat(n), status )
  841. IF_NOTOK_RETURN(status=1)
  842. call Done( sp_dat(n), status )
  843. IF_NOTOK_RETURN(status=1)
  844. call Done( spm_dat(n), status )
  845. IF_NOTOK_RETURN(status=1)
  846. ! ***
  847. call Done( phlb_dat(n), status )
  848. IF_NOTOK_RETURN(status=1)
  849. call Done( m_dat(n), status )
  850. IF_NOTOK_RETURN(status=1)
  851. ! ***
  852. call Done( mfu_dat(n), status )
  853. IF_NOTOK_RETURN(status=1)
  854. call Done( mfv_dat(n), status )
  855. IF_NOTOK_RETURN(status=1)
  856. call Done( mfw_dat(n), status )
  857. IF_NOTOK_RETURN(status=1)
  858. call Done( tsp_dat(n), status )
  859. IF_NOTOK_RETURN(status=1)
  860. call Done( pu_dat(n), status )
  861. IF_NOTOK_RETURN(status=1)
  862. call Done( pv_dat(n), status )
  863. IF_NOTOK_RETURN(status=1)
  864. call Done( pw_dat(n), status )
  865. IF_NOTOK_RETURN(status=1)
  866. ! ***
  867. call Done( temper_dat(n), status )
  868. IF_NOTOK_RETURN(status=1)
  869. call Done( humid_dat(n), status )
  870. IF_NOTOK_RETURN(status=1)
  871. call Done( gph_dat(n), status )
  872. IF_NOTOK_RETURN(status=1)
  873. call Done( omega_dat(n), status )
  874. IF_NOTOK_RETURN(status=1)
  875. ! ***
  876. call Done( lwc_dat(n), status )
  877. IF_NOTOK_RETURN(status=1)
  878. call Done( iwc_dat(n), status )
  879. IF_NOTOK_RETURN(status=1)
  880. call Done( cc_dat(n), status )
  881. IF_NOTOK_RETURN(status=1)
  882. call Done( cco_dat(n), status )
  883. IF_NOTOK_RETURN(status=1)
  884. call Done( ccu_dat(n), status )
  885. IF_NOTOK_RETURN(status=1)
  886. ! ***
  887. call Done( entu_dat(n), status )
  888. IF_NOTOK_RETURN(status=1)
  889. call Done( entd_dat(n), status )
  890. IF_NOTOK_RETURN(status=1)
  891. call Done( detu_dat(n), status )
  892. IF_NOTOK_RETURN(status=1)
  893. call Done( detd_dat(n), status )
  894. IF_NOTOK_RETURN(status=1)
  895. ! ***
  896. call Done( oro_dat(n), status )
  897. IF_NOTOK_RETURN(status=1)
  898. call Done( lsmask_dat(n), status )
  899. IF_NOTOK_RETURN(status=1)
  900. call Done( albedo_dat(n), status )
  901. IF_NOTOK_RETURN(status=1)
  902. call Done( sr_ecm_dat(n), status )
  903. IF_NOTOK_RETURN(status=1)
  904. call Done( sr_ols_dat(n), status )
  905. IF_NOTOK_RETURN(status=1)
  906. call Done( ci_dat(n), status )
  907. IF_NOTOK_RETURN(status=1)
  908. call Done( sst_dat(n), status )
  909. IF_NOTOK_RETURN(status=1)
  910. call Done( u10m_dat(n), status )
  911. IF_NOTOK_RETURN(status=1)
  912. call Done( v10m_dat(n), status )
  913. IF_NOTOK_RETURN(status=1)
  914. call Done( g10m_dat(n), status )
  915. IF_NOTOK_RETURN(status=1)
  916. call Done( src_dat(n), status )
  917. IF_NOTOK_RETURN(status=1)
  918. call Done( d2m_dat(n), status )
  919. IF_NOTOK_RETURN(status=1)
  920. call Done( t2m_dat(n), status )
  921. IF_NOTOK_RETURN(status=1)
  922. call Done( blh_dat(n), status )
  923. IF_NOTOK_RETURN(status=1)
  924. call Done( sshf_dat(n), status )
  925. IF_NOTOK_RETURN(status=1)
  926. call Done( slhf_dat(n), status )
  927. IF_NOTOK_RETURN(status=1)
  928. call Done( ewss_dat(n), status )
  929. IF_NOTOK_RETURN(status=1)
  930. call Done( nsss_dat(n), status )
  931. IF_NOTOK_RETURN(status=1)
  932. call Done( cp_dat(n), status )
  933. IF_NOTOK_RETURN(status=1)
  934. call Done( lsp_dat(n), status )
  935. IF_NOTOK_RETURN(status=1)
  936. call Done( ssr_dat(n), status )
  937. IF_NOTOK_RETURN(status=1)
  938. call Done( ssrd_dat(n), status )
  939. IF_NOTOK_RETURN(status=1)
  940. call Done( str_dat(n), status )
  941. IF_NOTOK_RETURN(status=1)
  942. call Done( strd_dat(n), status )
  943. IF_NOTOK_RETURN(status=1)
  944. call Done( skt_dat(n), status )
  945. IF_NOTOK_RETURN(status=1)
  946. call Done( sd_dat(n), status )
  947. IF_NOTOK_RETURN(status=1)
  948. call Done( sf_dat(n), status )
  949. IF_NOTOK_RETURN(status=1)
  950. call Done( swvl1_dat(n), status )
  951. IF_NOTOK_RETURN(status=1)
  952. do iveg = 1, nveg
  953. call Done( tv_dat(n,iveg), status )
  954. IF_NOTOK_RETURN(status=1)
  955. end do
  956. call Done( cvl_dat(n), status )
  957. IF_NOTOK_RETURN(status=1)
  958. call Done( cvh_dat(n), status )
  959. IF_NOTOK_RETURN(status=1)
  960. ! ***
  961. call Done( ch4fire_dat(n), status )
  962. IF_NOTOK_RETURN(status=1)
  963. ! ***
  964. end do ! regions
  965. ! ok
  966. status = 0
  967. call goLabel()
  968. END SUBROUTINE METEO_DONE
  969. ! ***
  970. SUBROUTINE METEO_ALLOC( status )
  971. use dims, only : nregions_all
  972. use meteodata, only : Alloc
  973. ! --- in/out -------------------------------
  974. integer, intent(out) :: status
  975. ! --- const --------------------------------------
  976. character(len=*), parameter :: rname = mname//'/Meteo_Alloc'
  977. ! --- local -----------------------------
  978. integer :: region
  979. integer :: iveg
  980. ! --- begin --------------------------------
  981. call goLabel(rname)
  982. ! allocate meteo fields if in use:
  983. do region = 1, nregions_all
  984. ! ***
  985. call Alloc( sp1_dat(region), status )
  986. IF_NOTOK_RETURN(status=1)
  987. call Alloc( sp2_dat(region), status )
  988. IF_NOTOK_RETURN(status=1)
  989. call Alloc( sp_dat(region), status )
  990. IF_NOTOK_RETURN(status=1)
  991. call Alloc( spm_dat(region), status )
  992. IF_NOTOK_RETURN(status=1)
  993. ! ***
  994. call Alloc( phlb_dat(region), status )
  995. IF_NOTOK_RETURN(status=1)
  996. call Alloc( m_dat(region), status )
  997. IF_NOTOK_RETURN(status=1)
  998. ! ***
  999. call Alloc( mfu_dat(region), status )
  1000. IF_NOTOK_RETURN(status=1)
  1001. call Alloc( mfv_dat(region), status )
  1002. IF_NOTOK_RETURN(status=1)
  1003. call Alloc( mfw_dat(region), status )
  1004. IF_NOTOK_RETURN(status=1)
  1005. call Alloc( tsp_dat(region), status )
  1006. IF_NOTOK_RETURN(status=1)
  1007. call Alloc( pu_dat(region), status )
  1008. IF_NOTOK_RETURN(status=1)
  1009. call Alloc( pv_dat(region), status )
  1010. IF_NOTOK_RETURN(status=1)
  1011. call Alloc( pw_dat(region), status )
  1012. IF_NOTOK_RETURN(status=1)
  1013. ! ***
  1014. call Alloc( temper_dat(region), status )
  1015. IF_NOTOK_RETURN(status=1)
  1016. call Alloc( humid_dat(region), status )
  1017. IF_NOTOK_RETURN(status=1)
  1018. call Alloc( gph_dat(region), status )
  1019. IF_NOTOK_RETURN(status=1)
  1020. call Alloc( omega_dat(region), status )
  1021. IF_NOTOK_RETURN(status=1)
  1022. ! ***
  1023. call Alloc( lwc_dat(region), status )
  1024. IF_NOTOK_RETURN(status=1)
  1025. call Alloc( iwc_dat(region), status )
  1026. IF_NOTOK_RETURN(status=1)
  1027. call Alloc( cc_dat(region), status )
  1028. IF_NOTOK_RETURN(status=1)
  1029. call Alloc( cco_dat(region), status )
  1030. IF_NOTOK_RETURN(status=1)
  1031. call Alloc( ccu_dat(region), status )
  1032. IF_NOTOK_RETURN(status=1)
  1033. ! ***
  1034. call Alloc( entu_dat(region), status )
  1035. IF_NOTOK_RETURN(status=1)
  1036. call Alloc( entd_dat(region), status )
  1037. IF_NOTOK_RETURN(status=1)
  1038. call Alloc( detu_dat(region), status )
  1039. IF_NOTOK_RETURN(status=1)
  1040. call Alloc( detd_dat(region), status )
  1041. IF_NOTOK_RETURN(status=1)
  1042. ! ***
  1043. call Alloc( oro_dat(region), status )
  1044. IF_NOTOK_RETURN(status=1)
  1045. call Alloc( lsmask_dat(region), status )
  1046. IF_NOTOK_RETURN(status=1)
  1047. call Alloc( albedo_dat(region), status )
  1048. IF_NOTOK_RETURN(status=1)
  1049. call Alloc( sr_ecm_dat(region), status )
  1050. IF_NOTOK_RETURN(status=1)
  1051. call Alloc( sr_ols_dat(region), status )
  1052. IF_NOTOK_RETURN(status=1)
  1053. call Alloc( ci_dat(region), status )
  1054. IF_NOTOK_RETURN(status=1)
  1055. call Alloc( sst_dat(region), status )
  1056. IF_NOTOK_RETURN(status=1)
  1057. call Alloc( u10m_dat(region), status )
  1058. IF_NOTOK_RETURN(status=1)
  1059. call Alloc( v10m_dat(region), status )
  1060. IF_NOTOK_RETURN(status=1)
  1061. call Alloc( src_dat(region), status )
  1062. IF_NOTOK_RETURN(status=1)
  1063. call Alloc( d2m_dat(region), status )
  1064. IF_NOTOK_RETURN(status=1)
  1065. call Alloc( t2m_dat(region), status )
  1066. IF_NOTOK_RETURN(status=1)
  1067. call Alloc( skt_dat(region), status )
  1068. IF_NOTOK_RETURN(status=1)
  1069. call Alloc( blh_dat(region), status )
  1070. IF_NOTOK_RETURN(status=1)
  1071. call Alloc( sshf_dat(region), status )
  1072. IF_NOTOK_RETURN(status=1)
  1073. call Alloc( slhf_dat(region), status )
  1074. IF_NOTOK_RETURN(status=1)
  1075. call Alloc( ewss_dat(region), status )
  1076. IF_NOTOK_RETURN(status=1)
  1077. call Alloc( nsss_dat(region), status )
  1078. IF_NOTOK_RETURN(status=1)
  1079. call Alloc( cp_dat(region), status )
  1080. IF_NOTOK_RETURN(status=1)
  1081. call Alloc( lsp_dat(region), status )
  1082. IF_NOTOK_RETURN(status=1)
  1083. call Alloc( ssr_dat(region), status )
  1084. IF_NOTOK_RETURN(status=1)
  1085. call Alloc( ssrd_dat(region), status )
  1086. IF_NOTOK_RETURN(status=1)
  1087. call Alloc( str_dat(region), status )
  1088. IF_NOTOK_RETURN(status=1)
  1089. call Alloc( strd_dat(region), status )
  1090. IF_NOTOK_RETURN(status=1)
  1091. call Alloc( sd_dat(region), status )
  1092. IF_NOTOK_RETURN(status=1)
  1093. call Alloc( sf_dat(region), status )
  1094. IF_NOTOK_RETURN(status=1)
  1095. call Alloc( g10m_dat(region), status )
  1096. IF_NOTOK_RETURN(status=1)
  1097. call Alloc( swvl1_dat(region), status )
  1098. IF_NOTOK_RETURN(status=1)
  1099. do iveg = 1, nveg
  1100. call Alloc( tv_dat(region,iveg), status )
  1101. IF_NOTOK_RETURN(status=1)
  1102. end do
  1103. call Alloc( cvl_dat(region), status )
  1104. IF_NOTOK_RETURN(status=1)
  1105. call Alloc( cvh_dat(region), status )
  1106. IF_NOTOK_RETURN(status=1)
  1107. ! ***
  1108. call Alloc( ch4fire_dat(region), status )
  1109. IF_NOTOK_RETURN(status=1)
  1110. ! ***
  1111. end do ! regions
  1112. ! ok
  1113. status = 0
  1114. call goLabel()
  1115. END SUBROUTINE METEO_ALLOC
  1116. !------------------------------------------------------------------------------
  1117. ! TM5 !
  1118. !------------------------------------------------------------------------------
  1119. !BOP
  1120. !
  1121. ! !IROUTINE: METEO_SETUP_MASS
  1122. !
  1123. ! !DESCRIPTION: Set up Mass FLuxes and Surface Pressures
  1124. !\\
  1125. !\\
  1126. ! !INTERFACE:
  1127. !
  1128. SUBROUTINE METEO_SETUP_MASS( tr1, tr2, status, isfirst, check_pressure )
  1129. !
  1130. ! !USES:
  1131. !
  1132. use go, only : TDate, rTotal, operator(-), wrtgol
  1133. use go, only : IncrDate, operator(+), Get
  1134. use grid, only : Match, TllGridInfo, assignment(=), Done
  1135. use Grid, only : FillMassChange, BalanceMassFluxes, CheckMassBalance
  1136. use dims, only : nregions, im, jm, lm, parent
  1137. use dims, only : xcyc
  1138. use meteodata, only : SetData ! to copy %data and %tr from one MD to another
  1139. #ifdef with_prism
  1140. use meteodata, only : TimeInterpolation
  1141. #endif
  1142. use restart, only : Restart_Read
  1143. !
  1144. ! !INPUT PARAMETERS:
  1145. !
  1146. type(TDate), intent(in) :: tr1, tr2
  1147. !
  1148. ! !OUTPUT PARAMETERS:
  1149. !
  1150. integer, intent(out) :: status
  1151. logical, intent(in), optional :: check_pressure
  1152. logical, intent(in), optional :: isfirst
  1153. !
  1154. ! !REVISION HISTORY:
  1155. !
  1156. ! 12 Mar 2010 - P. Le Sager - Fix when reading restart files. Added
  1157. ! protex doc. Added comments.
  1158. ! 9 Jun 2010 - P. Le Sager - Merged with updates for EC-Earth project.
  1159. !
  1160. ! 10 Aug 2010, Arjo Segers
  1161. ! Reset previous fix since it makes a restart different from a long run.
  1162. ! Use 'pw_dat' instead of 'mfw_dat' since otherwise the later changed
  1163. ! while matching a zoom region with its parent, and this would give
  1164. ! tiny differences during a restart of a zoomed run.
  1165. !
  1166. ! 9 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  1167. !
  1168. ! !REMARKS:
  1169. !
  1170. ! push of Surf Press is done with sp2 (the only one on which we call
  1171. ! setup -ie the only one for which %data1 and %data2 matter). Only %data
  1172. ! of SP and SP1 are updated and used, and not their %data1 and %data2.
  1173. !
  1174. !------------------------------------------------------------------------------
  1175. !EOP
  1176. character(len=*), parameter :: rname = mname//'/Meteo_Setup_Mass'
  1177. logical :: do_check_pressure, WestBorder, NorthBorder
  1178. logical :: do_isfirst
  1179. integer :: n, p
  1180. integer :: idater(6)
  1181. real, allocatable :: dm_dt(:,:,:)
  1182. real :: dt_sec
  1183. integer :: l, i0, i1, j0, j1, is, js, ie, je
  1184. real :: tol_rms, tol_diff
  1185. type(TllGridInfo) :: L_lli
  1186. real, pointer :: field(:,:), field_parent(:,:) ! work arrays
  1187. real, allocatable :: islice(:,:), jslice(:,:), bigIslice(:,:), bigJslice(:,:)
  1188. real, allocatable :: full_pu(:,:,:), full_pv(:,:,:), full_pw(:,:,:), full_dm_dt(:,:,:)
  1189. #ifdef with_prism
  1190. integer :: hour1, dhour
  1191. #endif
  1192. ! --- begin --------------------------------
  1193. call goLabel(rname)
  1194. ! check pressure ?
  1195. if ( present(check_pressure) ) then
  1196. do_check_pressure = check_pressure
  1197. else
  1198. do_check_pressure = .false.
  1199. end if
  1200. ! EC-EARTH do not check pressure since we would compare pressure from
  1201. ! restart file at 00 ( as written by previous chunk) with the one received
  1202. ! at 06 (or whatever the coupling period is) from IFS
  1203. do_check_pressure = .false.
  1204. ! initial call ?
  1205. if ( present(isfirst) ) then
  1206. do_isfirst = isfirst
  1207. else
  1208. do_isfirst = .false.
  1209. end if
  1210. !
  1211. ! ** MASS FLUXES *************************************
  1212. !
  1213. do n = 1, nregions_all
  1214. L_lli = global_lli(n)
  1215. call Setup_UVW( n, mfu_dat(n), mfv_dat(n), mfw_dat(n), tsp_dat(n),&
  1216. (/tr1,tr2/), L_lli, 'n', levi, 'w', status)
  1217. IF_NOTOK_RETURN(status=1)
  1218. end do
  1219. !
  1220. ! ** SURFACE PRESSURES : SP1, SP *****************************
  1221. !
  1222. REG: do n = 1, nregions_all
  1223. if ( .not. sp1_dat(n)%used ) cycle
  1224. L_lli = global_lli(n)
  1225. ! Advance 'next' surface pressure (a/k/a sp2%data) to start of
  1226. ! new interval tr1. If start of a new meteo interval, then data
  1227. ! is automatically read from file, or recieved from coupler
  1228. ! with OASIS/prism
  1229. call Setup( n, sp2_dat(n), (/tr1,tr1/), L_lli, 'n', status )
  1230. IF_NOTOK_RETURN(status=1)
  1231. ! copy SP2 into SP1 (%data and %tr)
  1232. call SetData( sp1_dat(n), sp2_dat(n), status )
  1233. IF_NOTOK_RETURN(status=1)
  1234. ! GATHER sp1 array (dummy if not root)
  1235. !-----------------
  1236. ! ...of parent region, if any:
  1237. if ( n /= 1 ) then
  1238. p = parent(n)
  1239. if (isRoot) then
  1240. allocate( field_parent(im(p), jm(p)) )
  1241. else
  1242. allocate( field_parent(1,1) )
  1243. end if
  1244. call GATHER( dgrid(p), sp1_dat(p)%data(:,:,1), field_parent, sp1_dat(p)%halo, status )
  1245. IF_NOTOK_RETURN(status=1)
  1246. end if
  1247. ! ...of current region:
  1248. if (isRoot) then
  1249. allocate( field(im(n), jm(n)) )
  1250. else
  1251. allocate( field(1,1) )
  1252. end if
  1253. call GATHER( dgrid(n), sp1_dat(n)%data(:,:,1), field, sp1_dat(n)%halo, status )
  1254. IF_NOTOK_RETURN(status=1)
  1255. ! MATCH surface pressures to ensure mass balance
  1256. !-----------------
  1257. if (isRoot) then
  1258. ! IF global field (i.e first region) : match global region with one-cell
  1259. ! world value (average global surface pressure), ELSE match with parent
  1260. if ( n == 1 ) then
  1261. call Match( 'area-aver', 'n', lli(0), sp_region0, &
  1262. global_lli(n), field, status )
  1263. IF_NOTOK_RETURN(status=1)
  1264. else
  1265. call Match( 'area-aver', 'n', global_lli(p), field_parent, &
  1266. global_lli(n), field, status )
  1267. IF_NOTOK_RETURN(status=1)
  1268. endif
  1269. end if
  1270. ! SCATTER sp1 array, and clean
  1271. !-----------------
  1272. call SCATTER( dgrid(n), sp1_dat(n)%data(:,:,1), field, sp1_dat(n)%halo, status )
  1273. IF_NOTOK_RETURN(status=1)
  1274. deallocate(field)
  1275. if ( n /= 1 ) then
  1276. if (associated(field_parent)) deallocate(field_parent)
  1277. endif
  1278. ! Set SP
  1279. !-----------------
  1280. ! Initial call ? then set current surface pressure to just
  1281. ! read/advanced sp1.
  1282. ! otherwise, sp remains filled with the advected pressure.
  1283. if ( do_isfirst ) then
  1284. !write (gol,'(" copy SP1 to SP ...")'); call goPr
  1285. !pls ! PLS - (not working in the current OASIS/IFS setup. Kept for reference.
  1286. !pls ! If no_restart and is_first then sp2 is filled with
  1287. !pls ! t+dhour sp. Get SP from SP2 then:
  1288. !pls #ifdef with_prism
  1289. !pls
  1290. !pls select case ( sp2_dat(n)%tinterp )
  1291. !pls case ( 'interp6' ) ; dhour = 6
  1292. !pls case ( 'interp3' ) ; dhour = 3
  1293. !pls case ( 'interp2' ) ; dhour = 2
  1294. !pls case ( 'interp1' ) ; dhour = 1
  1295. !pls case default
  1296. !pls write (gol,'("unsupported time interpolation:")'); call goErr
  1297. !pls write (gol,'(" md%tinterp : ",a)') trim(sp2_dat(n)%tinterp); call goErr
  1298. !pls TRACEBACK; status=1; return
  1299. !pls end select
  1300. !pls dt_sec = dhour * 3600.0 ! sec
  1301. !pls
  1302. !pls sp_dat(n)%data(1:im(n),1:jm(n),1) = &
  1303. !pls sp2_dat(n)%data(1:im(n),1:jm(n),1) - &
  1304. !pls tsp_dat(n)%data(1:im(n),1:jm(n),1) * dt_sec
  1305. !pls
  1306. !pls sp_dat(n)%tr = tr1
  1307. !pls
  1308. !pls ! copy sp into sp1 :
  1309. !pls call SetData( sp1_dat(n), sp_dat(n), status )
  1310. !pls IF_NOTOK_RETURN(status=1)
  1311. !pls
  1312. !pls #else
  1313. ! copy sp1 into sp :
  1314. call SetData( sp_dat(n), sp1_dat(n), status )
  1315. IF_NOTOK_RETURN(status=1)
  1316. !pls #endif
  1317. ! fill pressure and mass from sp
  1318. call Pressure_to_Mass( n, status )
  1319. IF_NOTOK_RETURN(status=1)
  1320. ! eventually replace by fields in restart file, since meteo
  1321. ! from hdf meteo files is in real(4) while computed
  1322. ! pressures and mass are probably in real(8) ;
  1323. ! The '#ifndef with_prism' was to not do that for coupled run, since this receives pressures from
  1324. ! ifs. However: in EC-Earth 2.xx the initial surface pressure is also read from the restart file
  1325. #ifndef oasis4
  1326. !#ifndef with_prism
  1327. call Restart_Read( status, surface_pressure=.true., pressure=.true., air_mass=.true. )
  1328. IF_NOTOK_RETURN(status=1)
  1329. !AJS>>> don't do this! sp1 contains data interpolated between
  1330. ! fields received from the archive or the coupled model,
  1331. ! while sp contains the actual pressure after advection.
  1332. !! copy sp into sp1 (PLS, 29-3-2010)
  1333. !call SetData( sp1_dat(n), sp_dat(n), status )
  1334. !IF_NOTOK_RETURN(status=1)
  1335. !<<<
  1336. #endif
  1337. end if ! end first
  1338. !! fill initial pressure and mass arrays,
  1339. !! eventually apply cyclic boundaries to mass
  1340. !call Meteo_SetupMass( n, status )
  1341. !IF_NOTOK_RETURN(status=1)
  1342. ! check 'advected' pressure ?
  1343. if ( do_check_pressure) then
  1344. ! compare 'advected' pressure still in sp with just read
  1345. ! pressure sp1 : diff b/w sp%data and sp1%data
  1346. call Meteo_CheckPressure( n, status )
  1347. IF_NOTOK_RETURN(status=1)
  1348. end if
  1349. END DO REG ! regions
  1350. !
  1351. ! ** SURFACE PRESSURES : SP2 *****************************
  1352. !
  1353. REG2: do n = 1, nregions_all
  1354. if ( .not. sp2_dat(n)%used ) cycle
  1355. ! grid and bounds
  1356. L_lli = global_lli(n)
  1357. i0 = sp2_dat(n)%is(1)
  1358. i1 = sp2_dat(n)%is(2)
  1359. j0 = sp2_dat(n)%js(1)
  1360. j1 = sp2_dat(n)%js(2)
  1361. #ifdef with_prism
  1362. ! sp2 for prism coupler is computed from : sp(t2) = sp(t1) + tsp*(t2-t1)
  1363. if ( sp2_dat(n)%sourcekey(1:6) == 'prism:' ) then
  1364. select case ( sp2_dat(n)%tinterp )
  1365. case ( 'interp6' ) ; dhour = 6
  1366. case ( 'interp3' ) ; dhour = 3
  1367. case ( 'interp2' ) ; dhour = 2
  1368. case ( 'interp1' ) ; dhour = 1
  1369. case default
  1370. write (gol,'("unsupported time interpolation:")'); call goErr
  1371. write (gol,'(" md%tinterp : ",a)') trim(sp2_dat(n)%tinterp); call goErr
  1372. TRACEBACK; status=1; return
  1373. end select
  1374. ! current interval [tr1,tr2] at begin of dhour interval ?
  1375. call Get( tr1, hour=hour1 )
  1376. if ( modulo(hour1,dhour) == 0 ) then
  1377. ! reset sp2_dat%data1 and sp2_dat%data2:
  1378. !PLS ---- original code -----
  1379. !PLS
  1380. !PLS ! o data1 : surface pressure received for tr1
  1381. !PLS write (gol,'(" fill sp2%data1 with prism received field ...")'); call goPr
  1382. !PLS ! set filled flags to false to force re-reading if necessary;
  1383. !PLS ! prism received lnsp fields are stored in cache
  1384. !PLS ! thus re-reading is fast and error-free
  1385. !PLS sp2_dat(n)%filled1 = .false.
  1386. !PLS sp2_dat(n)%filled2 = .false.
  1387. !PLS ! now (re)read :
  1388. !PLS write (gol,'("PLS - (re)setup SP2_dat at ",i2)') tr1%hour; call goPr
  1389. !PLS call Setup( sp2_dat(n), (/tr1,tr1/), lli(n), 'n', status )
  1390. !PLS IF_NOTOK_RETURN(status=1)
  1391. !PLS
  1392. !PLS ! o data2 : data1 + tsp * dhour*3600.0 with dhour 3 or 1 hour
  1393. !PLS write (gol,'(" compute sp2%data2 from sp2%data1 and sp tendency ...")'); call goPr
  1394. !PLS dt_sec = dhour * 3600.0 ! sec
  1395. !PLS sp2_dat(n)%data2(1:im(n),1:jm(n),1) = &
  1396. !PLS sp2_dat(n)%data1(1:im(n),1:jm(n),1) + tsp_dat(n)%data(1:im(n),1:jm(n),1) * dt_sec
  1397. !PLS sp2_dat(n)%tr2 = tr1 + IncrDate(sec=nint(dt_sec))
  1398. !PLS
  1399. !PLS ! o data : interpolation between data1 and data2
  1400. !PLS call wrtgol( ' interpolate sp2%data to : ', tr2 ); call goPr
  1401. !PLS call TimeInterpolation( sp2_dat(n), (/tr2,tr2/), status )
  1402. !PLS IF_NOTOK_RETURN(status=1)
  1403. ! Read into sp2%data1 : surface pressure received for
  1404. ! tr1 (truly tr1+dhour)
  1405. !write (gol,'(" fill sp2%data1 with prism received field ...")'); call goPr
  1406. ! set filled flags to false to force re-reading if necessary;
  1407. ! prism received lnsp fields are stored in cache
  1408. ! thus re-reading is fast and error-free
  1409. !PLS: read sp from prism for t=tr1 into SP2%DATA1. This
  1410. ! is truly sp at t = tr1 + dhour, according to the
  1411. ! coupler settings.
  1412. sp2_dat(n)%filled1 = .false.
  1413. sp2_dat(n)%filled2 = .false.
  1414. call Setup( n, sp2_dat(n), (/tr1,tr1/), L_lli, 'n', status )
  1415. IF_NOTOK_RETURN(status=1)
  1416. ! move %data1 to %data2, and get %data1 from %data2:
  1417. ! data1 = data2 - tsp * dhour*3600.0
  1418. !write (gol,'(" compute sp2%data1 from sp2%data2 and sp tendency ...")'); call goPr
  1419. dt_sec = dhour * 3600.0 ! sec
  1420. sp2_dat(n)%data2(i0:i1,j0:j1,1) = sp2_dat(n)%data1(i0:i1,j0:j1,1)
  1421. sp2_dat(n)%tr2 = tr1 + IncrDate(sec=nint(dt_sec))
  1422. sp2_dat(n)%data1(i0:i1,j0:j1,1) = &
  1423. sp2_dat(n)%data2(i0:i1,j0:j1,1) - tsp_dat(n)%data(i0:i1,j0:j1,1) * dt_sec
  1424. endif ! endif "it is beginning of coupling interval"
  1425. ! Once SP2_DAT contains data1 and data2 valid for a dhour
  1426. ! interval, %data is simply interpolated between %data1 and
  1427. ! %data2:
  1428. !call wrtgol( ' interpolate sp2%data to : ', tr2 ); call goPr
  1429. call TimeInterpolation( sp2_dat(n), (/tr2,tr2/), status )
  1430. IF_NOTOK_RETURN(status=1)
  1431. !pls else
  1432. !pls
  1433. !pls ! sp2_dat contains data1 and data2 valid for a dhour interval;
  1434. !pls ! set %data to interpolation between %data1 and %data2:
  1435. !pls call wrtgol( ' interpolate sp2%data to : ', tr2 ); call goPr
  1436. !pls call TimeInterpolation( sp2_dat(n), (/tr2,tr2/), status )
  1437. !pls IF_NOTOK_RETURN(status=1)
  1438. !pls
  1439. !pls end if
  1440. else
  1441. ! PLS: this one is never used apparently...
  1442. ! AJS: it might be used in a partial coupling with only some fields
  1443. ! exchanged and others read; this was often the case during the
  1444. ! first coupling experiments, and might be useful for testing
  1445. ! advance 'next' surface pressure to end of interval:
  1446. call Setup( n, sp2_dat(n), (/tr2,tr2/), L_lli, 'n', status )
  1447. IF_NOTOK_RETURN(status=1)
  1448. end if ! endif "it is prism sourcekey"
  1449. #else
  1450. ! advance 'next' surface pressure to end of interval:
  1451. call Setup( n, sp2_dat(n), (/tr2,tr2/), L_lli, 'n', status )
  1452. IF_NOTOK_RETURN(status=1)
  1453. #endif /* WITH_PRISM */
  1454. ! GATHER sp2 array (dummy if not root)
  1455. !-----------------
  1456. ! ...of parent region, if any:
  1457. if ( n /= 1 ) then
  1458. p = parent(n)
  1459. if (isRoot) then
  1460. allocate( field_parent(im(p), jm(p)) )
  1461. else
  1462. allocate( field_parent(1,1) )
  1463. end if
  1464. call GATHER( dgrid(p), sp2_dat(p)%data(:,:,1), field_parent, sp2_dat(p)%halo, status )
  1465. IF_NOTOK_RETURN(status=1)
  1466. end if
  1467. ! ...of current region:
  1468. if (isRoot) then
  1469. allocate( field(im(n), jm(n)) )
  1470. else
  1471. allocate( field(1,1) )
  1472. end if
  1473. call GATHER( dgrid(n), sp2_dat(n)%data(:,:,1), field, sp2_dat(n)%halo, status )
  1474. IF_NOTOK_RETURN(status=1)
  1475. ! MATCH surface pressures to ensure mass balance
  1476. !-----------------
  1477. if (isRoot) then
  1478. ! IF global field (i.e first region) : match global region with one-cell
  1479. ! world value (average global surface pressure), ELSE match with parent
  1480. if ( n == 1 ) then
  1481. call Match( 'area-aver', 'n', lli(0), sp_region0, &
  1482. global_lli(n), field, status )
  1483. IF_NOTOK_RETURN(status=1)
  1484. else
  1485. call Match( 'area-aver', 'n', global_lli(p), field_parent, &
  1486. global_lli(n), field, status )
  1487. IF_NOTOK_RETURN(status=1)
  1488. endif
  1489. end if
  1490. ! SCATTER sp2 array, and clean
  1491. !-----------------
  1492. call SCATTER( dgrid(n), sp2_dat(n)%data(:,:,1), field, sp2_dat(n)%halo, status )
  1493. IF_NOTOK_RETURN(status=1)
  1494. deallocate(field)
  1495. if ( n /= 1 ) then
  1496. if (associated(field_parent)) deallocate(field_parent)
  1497. endif
  1498. END DO REG2 ! regions
  1499. #ifndef without_advection
  1500. !
  1501. ! ** MASS BALANCE *****************************
  1502. !
  1503. ! NOTE: since only the surface pressure gradient is used,
  1504. ! it is not necessary to use the data1 and data2 arrays
  1505. do n = 1, nregions_all
  1506. if ( .not. pu_dat(n)%used ) cycle
  1507. if ( .not. pv_dat(n)%used ) cycle
  1508. if ( .not. pw_dat(n)%used ) cycle
  1509. L_lli = global_lli(n)
  1510. i0 = sp2_dat(n)%is(1)
  1511. i1 = sp2_dat(n)%is(2)
  1512. j0 = sp2_dat(n)%js(1)
  1513. j1 = sp2_dat(n)%js(2)
  1514. ! local indices and tile location (is, ie, js, je must be equal to i0, i1, j0, j1 BTW)
  1515. CALL GET_DISTGRID( dgrid(n), &
  1516. I_STRT=is, I_STOP=ie, &
  1517. J_STRT=js, J_STOP=je, &
  1518. hasWestBorder=WestBorder, hasNorthBorder=NorthBorder)
  1519. ! length of time step between sp1 and sp2:
  1520. dt_sec = rTotal( sp2_dat(n)%tr(1) - sp1_dat(n)%tr(1), 'sec' )
  1521. ! allocate temporary array:
  1522. allocate(dm_dt(i0:i1,j0:j1,lm(n)))
  1523. ! mass change (kg) :
  1524. call FillMassChange( dm_dt, lli(n), levi, &
  1525. sp1_dat(n)%data(i0:i1,j0:j1,1), &
  1526. sp2_dat(n)%data(i0:i1,j0:j1,1), &
  1527. status )
  1528. IF_NOTOK_RETURN(status=1)
  1529. ! mass tendency (kg/s) :
  1530. dm_dt = dm_dt / dt_sec ! kg/s
  1531. ! >>> data1 >>>
  1532. ! initial guess for balanced fluxes are unbalanced fluxes:
  1533. pu_dat(n)%data1 = mfu_dat(n)%data1
  1534. pu_dat(n)%filled1 = mfu_dat(n)%filled1
  1535. pu_dat(n)%tr1 = mfu_dat(n)%tr1
  1536. pv_dat(n)%data1 = mfv_dat(n)%data1
  1537. pv_dat(n)%filled1 = mfv_dat(n)%filled1
  1538. pv_dat(n)%tr1 = mfv_dat(n)%tr1
  1539. pw_dat(n)%data1 = mfw_dat(n)%data1
  1540. pw_dat(n)%filled1 = mfw_dat(n)%filled1
  1541. pw_dat(n)%tr1 = mfw_dat(n)%tr1
  1542. !#ifdef with_prism
  1543. ! skip initial mass balance; relative large differences might exist
  1544. ! between pressure imposed by mass fluxes and pressure according to
  1545. ! surface pressure tendencies since the later is based on:
  1546. !
  1547. ! sp(t-1)+tsp(t-1) _ *
  1548. ! _ - o-------* sp(t), sp(t)+tsp(t)
  1549. ! sp(t-1) o
  1550. !
  1551. ! PLS : I do not understand that diagram... tsp is for an
  1552. ! interval, and sp for a point in time. This may be
  1553. ! wrong then. What we had at the first time step was:
  1554. !
  1555. ! sp(t+1)+tsp(t:t+1) _ *
  1556. ! _ - => sp(t) to sp(t)+tsp(t:t+1)
  1557. ! sp(t+1) o
  1558. !
  1559. ! AJS : This describes what the CTM received before the above
  1560. ! described update. The 'tsp' was *not* for an interval but
  1561. ! an instantaneous field describing the 'direction' of the surface
  1562. ! pressure in time (you might call this 'tendency', but that is a
  1563. ! dangerous word in GEMS IFS-CTM coupling context).
  1564. ! Thus, at time 't-1' the only estimate of 'sp(t)' we could make was:
  1565. ! sp(t-1)+tsp(t-1)
  1566. ! At time 't' we received the actual 'sp(t)' and this was of course
  1567. ! different from the initial guess.
  1568. !
  1569. ! PLS : Just need to be sure that we have the correct sp to start
  1570. ! with. Code above has been modified, so that we have:
  1571. !
  1572. ! sp(t)+tsp(t:t+1) _ *
  1573. ! _ - => sp(t) to sp(t)+tsp(t:t+1)
  1574. ! sp(t) o
  1575. !
  1576. !#else
  1577. ! CHECK INITIAL MASS BALANCE:
  1578. ! -----------------------------------
  1579. ! NOTE: strange old indexing:
  1580. ! pu_tmpp --> pu(0:im(n),1:jm(n) ,1:lm(n)) in pu_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1581. ! pv_tmpp --> pv(1:im(n),1:jm(n)+1,1:lm(n)) in pv_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1582. ! tolerance for difference between sp from mass fluxes and sp from tendency:
  1583. tol_rms = 1.0e-4 ! max rms
  1584. tol_diff = 1.0e-3 ! max absolute difference
  1585. CALL UPDATE_HALO( dgrid(n), pu_dat(n)%data1, pu_dat(n)%halo, status)
  1586. IF_NOTOK_RETURN(status=1)
  1587. CALL UPDATE_HALO( dgrid(n), pv_dat(n)%data1, pv_dat(n)%halo, status)
  1588. IF_NOTOK_RETURN(status=1)
  1589. call CheckMassBalance( lli(n), &
  1590. pu_dat(n)%data1(i0-1:i1, j0:j1 , 1:lm(n) ), &
  1591. pv_dat(n)%data1( i0:i1, j0:j1+1, 1:lm(n) ), &
  1592. sp1_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
  1593. sp2_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
  1594. dt_sec, tol_rms, tol_diff, status )
  1595. if (status/=0) then
  1596. write (gol,'("initial mass imbalance too large for region ",i2)') n; call goErr
  1597. call goErr; status=1; return
  1598. end if
  1599. !#endif
  1600. ! BALANCE HORIZONTAL FLUXES
  1601. ! -----------------------------------
  1602. ! NOTE: strange old indexing:
  1603. ! pu_tmpp --> pu(0:im(n),1:jm(n) ,1:lm(n)) in pu_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1604. ! pv_tmpp --> pv(1:im(n),1:jm(n)+1,1:lm(n)) in pv_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1605. ! needs to be done globally... so gather data
  1606. if (isRoot) then
  1607. allocate(full_pu( 0:im(n), 1:jm(n), 0:lm(n)) ) ! must have same number of levels as mfu
  1608. allocate(full_pv( 1:im(n), 1:jm(n)+1, 0:lm(n)) )
  1609. allocate(full_pw( 1:im(n), 1:jm(n), 0:lm(n)) ) ! used also as temp arr in comm
  1610. allocate(full_dm_dt(im(n), jm(n), lm(n)) )
  1611. else
  1612. allocate( full_pu(1,1,1) )
  1613. allocate( full_pv(1,1,1) )
  1614. allocate( full_pw(1,1,1) )
  1615. allocate( full_dm_dt(1,1,1))
  1616. end if
  1617. !for slice scattering
  1618. allocate(islice(j0:j1,0:lm(n)))
  1619. allocate(jslice(i0:i1,0:lm(n)))
  1620. if (isRoot) then
  1621. allocate(bigIslice(1:jm(n),0:lm(n)))
  1622. allocate(bigJslice(1:im(n),0:lm(n)))
  1623. else
  1624. allocate(bigIslice(1,1))
  1625. allocate(bigJslice(1,1))
  1626. end if
  1627. call GATHER( dgrid(n), pu_dat(n)%data1, full_pw, pu_dat(n)%halo, status )
  1628. IF_NOTOK_RETURN(status=1)
  1629. if (isRoot) then
  1630. full_pu(1:im(n),1:jm(n),:) = full_pw
  1631. full_pu(0,:,:) = full_pu(im(n),:,:) ! East-West periodicity
  1632. end if
  1633. call GATHER( dgrid(n), pv_dat(n)%data1, full_pw, pv_dat(n)%halo, status )
  1634. IF_NOTOK_RETURN(status=1)
  1635. if (isRoot) then
  1636. full_pv(1:im(n),1:jm(n),:) = full_pw
  1637. full_pv(:,jm(n)+1,:) = full_pv(:,1,:) ! donut periodicity
  1638. end if
  1639. call GATHER( dgrid(n), dm_dt, full_dm_dt, 0, status )
  1640. IF_NOTOK_RETURN(status=1)
  1641. call GATHER( dgrid(n), pw_dat(n)%data1, full_pw, pw_dat(n)%halo, status )
  1642. IF_NOTOK_RETURN(status=1)
  1643. if (isRoot) then
  1644. call BalanceMassFluxes( global_lli(n), &
  1645. full_pu(0:im(n),1:jm(n) ,1:lm(n)), &
  1646. full_pv(1:im(n),1:jm(n)+1,1:lm(n)), &
  1647. full_pw, full_dm_dt, global_lli(parent(n)), dt_sec, status )
  1648. IF_NOTOK_RETURN(status=1)
  1649. end if
  1650. call SCATTER( dgrid(n), pw_dat(n)%data1, full_pw, pw_dat(n)%halo, status )
  1651. IF_NOTOK_RETURN(status=1)
  1652. if(isRoot) full_pw = full_pu(1:im(n),1:jm(n),:)
  1653. call SCATTER( dgrid(n), pu_dat(n)%data1, full_pw, pu_dat(n)%halo, status )
  1654. IF_NOTOK_RETURN(status=1)
  1655. ! scatter extra column full_pu(0,:,:) - needed only for noncyclic zoom
  1656. ! region, for others update_halo takes care of it [FIXME: could had a
  1657. ! test around these 3 lines ]
  1658. if(isRoot) bigIslice = full_pu(0,1:jm(n),:)
  1659. CALL SCATTER_I_BAND( dgrid(n), islice, bigIslice, status, iref=1)
  1660. if(WestBorder)pu_dat(n)%data1(0,j0:j1,0:lm(n)) = islice
  1661. if(isRoot) full_pw = full_pv(1:im(n),1:jm(n),:)
  1662. call SCATTER( dgrid(n), pv_dat(n)%data1, full_pw, pv_dat(n)%halo, status )
  1663. IF_NOTOK_RETURN(status=1)
  1664. ! Scatter PV(:,jm+1,:)
  1665. if(isroot) bigJslice=full_pv(1:im(n),jm(n)+1,:)
  1666. CALL SCATTER_J_BAND( dgrid(n), jslice, bigJslice, status, jref=jm(n))
  1667. if(NorthBorder)pv_dat(n)%data1(i0:i1,jm(n)+1,0:lm(n))=jslice
  1668. ! CHECK FINAL MASS BALANCE:
  1669. ! -----------------------------------
  1670. ! NOTE: strange old indexing:
  1671. ! pu_tmpp --> pu(0:im(n),1:jm(n) ,1:lm(n)) in pu_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1672. ! pv_tmpp --> pv(1:im(n),1:jm(n)+1,1:lm(n)) in pv_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1673. ! tolerance for difference between sp from mass fluxes and sp from tendency:
  1674. tol_rms = 1.0e-7 ! max rms
  1675. tol_diff = 1.0e-6 ! max absolute difference
  1676. CALL UPDATE_HALO( dgrid(n), pu_dat(n)%data1, pu_dat(n)%halo, status)
  1677. IF_NOTOK_RETURN(status=1)
  1678. CALL UPDATE_HALO( dgrid(n), pv_dat(n)%data1, pv_dat(n)%halo, status)
  1679. IF_NOTOK_RETURN(status=1)
  1680. call CheckMassBalance( lli(n), &
  1681. pu_dat(n)%data1(i0-1:i1, j0:j1 , 1:lm(n) ), &
  1682. pv_dat(n)%data1( i0:i1, j0:j1+1, 1:lm(n) ), &
  1683. sp1_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
  1684. sp2_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
  1685. dt_sec, tol_rms, tol_diff, status )
  1686. if (status/=0) then
  1687. write (gol,'("final mass imbalance too large for region ",i2)') n; call goErr
  1688. call goErr; status=1; return
  1689. end if
  1690. !done
  1691. deallocate(full_pw, full_pu, full_pv, full_dm_dt, bigJslice, bigIslice,&
  1692. jslice, islice)
  1693. ! >>> data2 >>>
  1694. if ( any((/mfu_dat%filled2,mfv_dat%filled2,mfw_dat%filled2/)) ) then
  1695. if ( .not. all((/mfu_dat(n)%filled2,mfv_dat(n)%filled2,mfw_dat(n)%filled2/)) ) then
  1696. write (gol,'("either none or all secondary data should be in use:")'); call goErr
  1697. write (gol,'(" mfu_dat%filled2 : ",l1)') mfu_dat(n)%filled2; call goErr
  1698. write (gol,'(" mfv_dat%filled2 : ",l1)') mfv_dat(n)%filled2; call goErr
  1699. write (gol,'(" mfw_dat%filled2 : ",l1)') mfw_dat(n)%filled2; call goErr
  1700. call goErr; status=1; return
  1701. end if
  1702. ! initial guess for balanced fluxes are unbalanced fluxes:
  1703. pu_dat(n)%data2 = mfu_dat(n)%data2
  1704. pu_dat(n)%filled2 = .true.
  1705. pu_dat(n)%tr2 = mfu_dat(n)%tr2
  1706. pv_dat(n)%data2 = mfv_dat(n)%data2
  1707. pv_dat(n)%filled2 = .true.
  1708. pv_dat(n)%tr2 = mfv_dat(n)%tr2
  1709. pw_dat(n)%data2 = mfw_dat(n)%data2
  1710. pw_dat(n)%filled2 = .true.
  1711. pw_dat(n)%tr2 = mfw_dat(n)%tr2
  1712. ! CHECK INITIAL MASS BALANCE:
  1713. ! -----------------------------------
  1714. ! NOTE: strange old indexing:
  1715. ! pu_tmpp --> pu(0:im(n),1:jm(n) ,1:lm(n)) in pu_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1716. ! pv_tmpp --> pv(1:im(n),1:jm(n)+1,1:lm(n)) in pv_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1717. CALL UPDATE_HALO( dgrid(n), pu_dat(n)%data2, pu_dat(n)%halo, status)
  1718. IF_NOTOK_RETURN(status=1)
  1719. CALL UPDATE_HALO( dgrid(n), pv_dat(n)%data2, pv_dat(n)%halo, status)
  1720. IF_NOTOK_RETURN(status=1)
  1721. call CheckMassBalance( lli(n), &
  1722. pu_dat(n)%data2(i0-1:i1, j0:j1 , 1:lm(n) ), &
  1723. pv_dat(n)%data2( i0:i1, j0:j1+1, 1:lm(n) ), &
  1724. sp1_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
  1725. sp2_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
  1726. dt_sec, 1.0e-4, 1.0e-3, status )
  1727. if (status/=0) then
  1728. write (gol,'("initial mass imbalance too large for region ",i2)') n; call goErr
  1729. call goErr; status=1; return
  1730. end if
  1731. ! BALANCE HORIZONTAL FLUXES
  1732. ! -----------------------------------
  1733. ! balance horizontal fluxes:
  1734. ! NOTE: strange old indexing:
  1735. ! pu_tmpp --> pu(0:im(n),1:jm(n) ,1:lm(n)) in pu_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1736. ! pv_tmpp --> pv(1:im(n),1:jm(n)+1,1:lm(n)) in pv_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1737. if (isRoot) then
  1738. allocate(full_pu( 0:im(n), 1:jm(n), 0:lm(n)) ) ! must have same number of levels as mfu
  1739. allocate(full_pv( 1:im(n), 1:jm(n)+1, 0:lm(n)) )
  1740. allocate(full_pw( 1:im(n), 1:jm(n), 0:lm(n)) ) ! used also as temp arr in comm
  1741. allocate(full_dm_dt(im(n), jm(n), lm(n)) )
  1742. else
  1743. allocate( full_pu(1,1,1) )
  1744. allocate( full_pv(1,1,1) )
  1745. allocate( full_pw(1,1,1) )
  1746. allocate( full_dm_dt(1,1,1))
  1747. end if
  1748. !for slice scattering
  1749. allocate(islice(j0:j1,0:lm(n)))
  1750. allocate(jslice(i0:i1,0:lm(n)))
  1751. if (isRoot) then
  1752. allocate(bigIslice(1:jm(n),0:lm(n)))
  1753. allocate(bigJslice(1:im(n),0:lm(n)))
  1754. else
  1755. allocate(bigIslice(1,1))
  1756. allocate(bigJslice(1,1))
  1757. end if
  1758. call GATHER( dgrid(n), pu_dat(n)%data2, full_pw, pu_dat(n)%halo, status )
  1759. IF_NOTOK_RETURN(status=1)
  1760. if (isRoot) then
  1761. full_pu(1:im(n),1:jm(n),:) = full_pw
  1762. full_pu(0,:,:) = full_pu(im(n),:,:) ! East-West periodicity
  1763. end if
  1764. call GATHER( dgrid(n), pv_dat(n)%data2, full_pw, pv_dat(n)%halo, status )
  1765. IF_NOTOK_RETURN(status=1)
  1766. if (isRoot) then
  1767. full_pv(1:im(n),1:jm(n),:) = full_pw
  1768. full_pv(:,jm(n)+1,:) = full_pv(:,1,:) ! donut periodicity
  1769. end if
  1770. call GATHER( dgrid(n), dm_dt, full_dm_dt, 0, status )
  1771. IF_NOTOK_RETURN(status=1)
  1772. call GATHER( dgrid(n), pw_dat(n)%data2, full_pw, pw_dat(n)%halo, status )
  1773. IF_NOTOK_RETURN(status=1)
  1774. if (isRoot) then
  1775. call BalanceMassFluxes( global_lli(n), &
  1776. full_pu(0:im(n),1:jm(n) ,1:lm(n)), &
  1777. full_pv(1:im(n),1:jm(n)+1,1:lm(n)), &
  1778. full_pw, full_dm_dt, global_lli(parent(n)), dt_sec, status )
  1779. IF_NOTOK_RETURN(status=1)
  1780. end if
  1781. call SCATTER( dgrid(n), pw_dat(n)%data2, full_pw, pw_dat(n)%halo, status )
  1782. IF_NOTOK_RETURN(status=1)
  1783. if(isRoot) full_pw = full_pu(1:im(n),1:jm(n),:)
  1784. call SCATTER( dgrid(n), pu_dat(n)%data2, full_pw, pu_dat(n)%halo, status )
  1785. IF_NOTOK_RETURN(status=1)
  1786. ! scatter extra column full_pu(0,:,:) - needed only for noncyclic zoom
  1787. ! regions, for others update_halo takes care of it [FIXME: could had a
  1788. ! test around these 3 lines ]
  1789. if(isRoot) bigIslice = full_pu(0,1:jm(n),:)
  1790. CALL SCATTER_I_BAND( dgrid(n), islice, bigIslice, status, iref=1)
  1791. if(WestBorder) pu_dat(n)%data2(0,j0:j1,:) = islice
  1792. if(isRoot) full_pw = full_pv(1:im(n),1:jm(n),:)
  1793. call SCATTER( dgrid(n), pv_dat(n)%data2, full_pw, pv_dat(n)%halo, status )
  1794. IF_NOTOK_RETURN(status=1)
  1795. ! Scatter PV(:,jm+1,:)
  1796. if(isroot) bigJslice=full_pv(1:im(n),jm(n)+1,:)
  1797. CALL SCATTER_J_BAND( dgrid(n), jslice, bigJslice, status, jref=jm(n))
  1798. if(NorthBorder)pv_dat(n)%data2(i0:i1,jm(n)+1,:)=jslice
  1799. ! CHECK FINAL MASS BALANCE:
  1800. ! -----------------------------------
  1801. ! NOTE: strange old indexing:
  1802. ! pu_tmpp --> pu(0:im(n),1:jm(n) ,1:lm(n)) in pu_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1803. ! pv_tmpp --> pv(1:im(n),1:jm(n)+1,1:lm(n)) in pv_t(0:im(n)+1,0:jm(n)+1,0:lm(n))
  1804. CALL UPDATE_HALO( dgrid(n), pu_dat(n)%data2, pu_dat(n)%halo, status)
  1805. IF_NOTOK_RETURN(status=1)
  1806. CALL UPDATE_HALO( dgrid(n), pv_dat(n)%data2, pv_dat(n)%halo, status)
  1807. IF_NOTOK_RETURN(status=1)
  1808. call CheckMassBalance( lli(n), &
  1809. pu_dat(n)%data2(i0-1:i1, j0:j1 , 1:lm(n) ), &
  1810. pv_dat(n)%data2( i0:i1, j0:j1+1, 1:lm(n) ), &
  1811. sp1_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
  1812. sp2_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
  1813. dt_sec, 1.0e-7, 1.0e-6, status )
  1814. if (status/=0) then
  1815. write (gol,'("final mass imbalance too large for region ",i2)') n; call goErr
  1816. call goErr; status=1; return
  1817. end if
  1818. deallocate(full_pw, full_pu, full_pv, full_dm_dt, bigJslice, bigIslice,&
  1819. jslice, islice)
  1820. end if ! filled2
  1821. ! >>>
  1822. ! clear
  1823. deallocate( dm_dt )
  1824. end do ! regions
  1825. #endif /* ADVECTION */
  1826. !------------
  1827. ! Done
  1828. !------------
  1829. call done(l_lli, status)
  1830. IF_NOTOK_RETURN(status=1)
  1831. status = 0
  1832. call goLabel()
  1833. END SUBROUTINE METEO_SETUP_MASS
  1834. !--------------------------------------------------------------------------
  1835. ! TM5 !
  1836. !--------------------------------------------------------------------------
  1837. !BOP
  1838. !
  1839. ! !IROUTINE: METEO_SETUP_OTHER
  1840. !
  1841. ! !DESCRIPTION:
  1842. !\\
  1843. !\\
  1844. ! !INTERFACE:
  1845. !
  1846. SUBROUTINE METEO_SETUP_OTHER( tr1, tr2, status, isfirst )
  1847. !
  1848. ! !USES:
  1849. !
  1850. use GO, only : TDate, NewDate, rTotal, wrtgol
  1851. use GO, only : operator(-), operator(+), operator(/)
  1852. use GO, only : InterpolFractions
  1853. use dims, only : nregions, im, jm, lm
  1854. use dims, only : lmax_conv
  1855. use dims, only : xcyc
  1856. use Dims, only : czeta
  1857. use global_data, only : region_dat
  1858. #ifndef without_convection
  1859. use global_data, only : conv_dat
  1860. #endif
  1861. use Phys, only : ConvCloudDim
  1862. !
  1863. ! !INPUT PARAMETERS:
  1864. !
  1865. type(TDate), intent(in) :: tr1, tr2
  1866. logical, intent(in), optional :: isfirst
  1867. !
  1868. ! !OUTPUT PARAMETERS:
  1869. !
  1870. integer, intent(out) :: status
  1871. !
  1872. ! !REVISION HISTORY:
  1873. ! 9 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  1874. !
  1875. !EOP
  1876. !------------------------------------------------------------------------
  1877. !BOC
  1878. character(len=*), parameter :: rname = mname//'/Meteo_Setup_Other'
  1879. logical :: do_isfirst
  1880. integer :: n, p
  1881. integer :: i, j, l
  1882. integer :: lsave, i0, i1, j0, j1
  1883. real :: tote, totd, maxe
  1884. real, pointer :: dxyp(:)
  1885. type(TDate) :: tmid
  1886. real :: alfa1, alfa2
  1887. integer :: iveg
  1888. ! --- begin --------------------------------
  1889. call goLabel(rname)
  1890. ! initial call ?
  1891. if ( present(isfirst) ) then
  1892. do_isfirst = isfirst
  1893. else
  1894. do_isfirst = .false.
  1895. end if
  1896. !
  1897. ! ** orography *****************************
  1898. !
  1899. ! read orographies (if necessary):
  1900. do n = 1, nregions_all
  1901. #ifdef parallel_cplng
  1902. call setup( n, oro_dat(n), (/tr1,tr2/), 'n', status )
  1903. #else
  1904. call setup( n, oro_dat(n), (/tr1,tr2/), global_lli(n), 'n', status )
  1905. #endif
  1906. IF_NOTOK_RETURN(status=1)
  1907. end do
  1908. !
  1909. ! ** spm **************************************
  1910. !
  1911. do n = 1, nregions
  1912. ! skip ?
  1913. if ( .not. spm_dat(n)%used ) cycle
  1914. ! mid time:
  1915. tmid = tr1 + ( tr2 - tr1 )/2
  1916. ! deterimine weights to sp1 and sp2 :
  1917. call InterpolFractions( tmid, sp1_dat(n)%tr(1), sp2_dat(n)%tr(1), alfa1, alfa2, status )
  1918. IF_NOTOK_RETURN(status=1)
  1919. call Get_DistGrid( dgrid(n), I_STRT=i0, I_STOP=i1, J_STRT=j0, J_STOP=j1 )
  1920. ! interpolate:
  1921. spm_dat(n)%data(i0:i1,j0:j1,1) = alfa1 * sp1_dat(n)%data(i0:i1,j0:j1,1) + &
  1922. alfa2 * sp2_dat(n)%data(i0:i1,j0:j1,1)
  1923. ! store time:
  1924. spm_dat(n)%tr = (/tr1,tr2/)
  1925. end do ! regions
  1926. !
  1927. ! ** omega **************************************
  1928. !
  1929. do n = 1, nregions_all
  1930. ! re-compute omega from vertical mass flux:
  1931. call Compute_Omega( omega_dat(n), lli(n), mfw_dat(n), status )
  1932. IF_NOTOK_RETURN(status=1)
  1933. end do ! regions
  1934. !
  1935. ! ** temperature and humid **************************************
  1936. !
  1937. do n = 1, nregions_all
  1938. ! ncep meteo requires conversion of virtual temperature using humidity ...
  1939. if ( (temper_dat(n)%sourcekey(1:4) == 'ncep') .or. (humid_dat(n)%sourcekey(1:4) == 'ncep') ) then
  1940. ! read temperature and humidity (if necessary):
  1941. call setup_TQ( n, temper_dat(n), humid_dat(n), (/tr1,tr2/), global_lli(n), levi, status)
  1942. IF_NOTOK_RETURN(status=1)
  1943. else
  1944. ! read temperature (if necessary):
  1945. #ifdef parallel_cplng
  1946. call setup( n, temper_dat(n), (/tr1,tr2/), 'n', levi, 'n', status)
  1947. IF_NOTOK_RETURN(status=1)
  1948. ! read humidity (if necessary):
  1949. call setup( n, humid_dat(n), (/tr1,tr2/), 'n', levi, 'n', status)
  1950. IF_NOTOK_RETURN(status=1)
  1951. #else
  1952. call setup( n, temper_dat(n), (/tr1,tr2/), global_lli(n), 'n', levi, 'n', status)
  1953. IF_NOTOK_RETURN(status=1)
  1954. ! read humidity (if necessary):
  1955. call setup( n, humid_dat(n), (/tr1,tr2/), global_lli(n), 'n', levi, 'n', status)
  1956. IF_NOTOK_RETURN(status=1)
  1957. #endif
  1958. end if
  1959. end do ! regions
  1960. !
  1961. ! ** gph **************************************
  1962. !
  1963. do n = 1, nregions_all
  1964. ! re-compute gph from pressure, temperature, and humidity:
  1965. call compute_gph( n, status )
  1966. IF_NOTOK_RETURN(status=1)
  1967. end do
  1968. !
  1969. ! ** clouds **************************************
  1970. !
  1971. do n = 1, nregions
  1972. #ifdef parallel_cplng
  1973. call setup( n, lwc_dat(n), (/tr1,tr2/), 'n', levi, 'n', status)
  1974. IF_NOTOK_RETURN(status=1)
  1975. call setup( n, iwc_dat(n), (/tr1,tr2/), 'n', levi, 'n', status)
  1976. IF_NOTOK_RETURN(status=1)
  1977. call setup_CloudCovers( n, cc_dat(n), cco_dat(n), ccu_dat(n), (/tr1,tr2/), levi, status)
  1978. IF_NOTOK_RETURN(status=1)
  1979. #else
  1980. call setup( n, lwc_dat(n), (/tr1,tr2/), global_lli(n), 'n', levi, 'n', status)
  1981. IF_NOTOK_RETURN(status=1)
  1982. call setup( n, iwc_dat(n), (/tr1,tr2/), global_lli(n), 'n', levi, 'n', status)
  1983. IF_NOTOK_RETURN(status=1)
  1984. call setup_CloudCovers( n, cc_dat(n), cco_dat(n), ccu_dat(n), (/tr1,tr2/), global_lli(n), levi, status)
  1985. IF_NOTOK_RETURN(status=1)
  1986. #endif
  1987. end do
  1988. !
  1989. ! ** convection **************************************
  1990. !
  1991. do n = 1, nregions
  1992. #ifdef parallel_cplng
  1993. call setup_Convec( n, entu_dat(n), entd_dat(n), detu_dat(n), detd_dat(n), &
  1994. omega_dat(n), gph_dat(n), (/tr1,tr2/), levi, status )
  1995. IF_NOTOK_RETURN(status=1)
  1996. #else
  1997. call setup_Convec( n, entu_dat(n), entd_dat(n), detu_dat(n), detd_dat(n), &
  1998. omega_dat(n), gph_dat(n), (/tr1,tr2/), global_lli(n), levi, status )
  1999. IF_NOTOK_RETURN(status=1)
  2000. #endif
  2001. end do
  2002. #ifndef without_convection
  2003. ! ~~ convective clouds
  2004. do n = 1, nregions
  2005. if ( .not. entu_dat(n)%used ) cycle
  2006. if ( .not. entd_dat(n)%used ) cycle
  2007. ! update necessary ?
  2008. if ( any((/entu_dat(n)%changed,entd_dat(n)%changed/)) ) then
  2009. call Get_DistGrid( dgrid(n), I_STRT=i0, I_STOP=i1, J_STRT=j0, J_STOP=j1 )
  2010. do j = j0, j1
  2011. do i = i0, i1
  2012. ! compute convective cloud dimensions for this column:
  2013. call ConvCloudDim( 'u', size(detu_dat(n)%data,3), &
  2014. detu_dat(n)%data(i,j,:), entd_dat(n)%data(i,j,:),&
  2015. conv_dat(n)%cloud_base(i,j), &
  2016. conv_dat(n)%cloud_top (i,j), &
  2017. conv_dat(n)%cloud_lfs (i,j), &
  2018. status )
  2019. IF_NOTOK_RETURN(status=1)
  2020. end do
  2021. end do
  2022. end if ! changed
  2023. end do ! regions
  2024. #endif
  2025. ! ~~ unit conversion
  2026. do n = 1, nregions
  2027. if ( .not. entu_dat(n)%used ) cycle
  2028. if ( .not. entd_dat(n)%used ) cycle
  2029. if ( .not. detu_dat(n)%used ) cycle
  2030. if ( .not. detd_dat(n)%used ) cycle
  2031. ! update necessary ?
  2032. if ( any((/ entu_dat(n)%changed, entd_dat(n)%changed, &
  2033. detu_dat(n)%changed, detd_dat(n)%changed /)) ) then
  2034. call Get_DistGrid( dgrid(n), I_STRT=i0, I_STOP=i1, J_STRT=j0, J_STOP=j1 )
  2035. !cmk calculate the rates in kg/gridbox and scale with czeta
  2036. dxyp => region_dat(n)%dxyp
  2037. do j = j0, j1
  2038. do i = i0, i1
  2039. ! kg/m2/s -> kg/gridbox/s * scale_factor
  2040. entu_dat(n)%data(i,j,:) = entu_dat(n)%data(i,j,:)*dxyp(j)*czeta
  2041. detu_dat(n)%data(i,j,:) = detu_dat(n)%data(i,j,:)*dxyp(j)*czeta
  2042. ! ensure netto zero tracer transport by updraught in column
  2043. ! (add difference between total entrement and detrement
  2044. ! to level where entrement reaches maximum):
  2045. tote = sum( entu_dat(n)%data(i,j,:) )
  2046. totd = sum( detu_dat(n)%data(i,j,:) )
  2047. maxe = entu_dat(n)%data(i,j,1) ! changed: reported by PB feb 2003
  2048. lsave = 1
  2049. do l = 2, lmax_conv
  2050. if ( entu_dat(n)%data(i,j,l) > maxe ) then
  2051. maxe = entu_dat(n)%data(i,j,l)
  2052. lsave = l
  2053. end if
  2054. end do
  2055. entu_dat(n)%data(i,j,lsave) = entu_dat(n)%data(i,j,lsave) - tote + totd
  2056. ! kg/m2/s -> kg/gridbox/s * scale_factor
  2057. entd_dat(n)%data(i,j,:) = entd_dat(n)%data(i,j,:)*dxyp(j)*czeta
  2058. detd_dat(n)%data(i,j,:) = detd_dat(n)%data(i,j,:)*dxyp(j)*czeta
  2059. ! ensure netto zero tracer transport by downdraught in column
  2060. ! (add difference between total entrement and detrement
  2061. ! to level where entrement reaches maximum):
  2062. tote = sum( entd_dat(n)%data(i,j,:) ) ! total entrainement
  2063. totd = sum( detd_dat(n)%data(i,j,:) ) ! total detrainement
  2064. maxe = 0.0
  2065. lsave = lmax_conv
  2066. do l = 1, lmax_conv
  2067. if ( entd_dat(n)%data(i,j,l) > maxe ) then
  2068. maxe = entd_dat(n)%data(i,j,l)
  2069. lsave = l
  2070. end if
  2071. end do
  2072. entd_dat(n)%data(i,j,lsave) = entd_dat(n)%data(i,j,lsave) - tote + totd
  2073. end do
  2074. end do
  2075. end if ! changed ?
  2076. end do ! regions
  2077. !
  2078. ! ** surface fields *****************************
  2079. !
  2080. #ifdef parallel_cplng
  2081. ! * lsmask
  2082. call setup( lsmask_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2083. IF_NOTOK_RETURN(status=1)
  2084. ! * albedo
  2085. call setup( albedo_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2086. IF_NOTOK_RETURN(status=1)
  2087. ! * sr_ecm
  2088. call setup( sr_ecm_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2089. IF_NOTOK_RETURN(status=1)
  2090. #else
  2091. ! * lsmask
  2092. call setup( lsmask_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2093. IF_NOTOK_RETURN(status=1)
  2094. ! * albedo
  2095. call setup( albedo_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2096. IF_NOTOK_RETURN(status=1)
  2097. ! * sr_ecm
  2098. call setup( sr_ecm_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2099. IF_NOTOK_RETURN(status=1)
  2100. #endif
  2101. ! * sr_ols
  2102. call setup( sr_ols_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2103. IF_NOTOK_RETURN(status=1)
  2104. #ifdef parallel_cplng
  2105. ! * sea ice
  2106. call setup( ci_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2107. IF_NOTOK_RETURN(status=1)
  2108. ! * sea surface temperature
  2109. call setup( sst_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2110. IF_NOTOK_RETURN(status=1)
  2111. ! * u10m
  2112. call setup( u10m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2113. IF_NOTOK_RETURN(status=1)
  2114. ! * v10m
  2115. call setup( v10m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2116. IF_NOTOK_RETURN(status=1)
  2117. ! * skin reservoir content
  2118. call setup( src_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2119. IF_NOTOK_RETURN(status=1)
  2120. ! * 2m dewpoint temperature
  2121. call setup( d2m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2122. IF_NOTOK_RETURN(status=1)
  2123. ! * 2m temperature
  2124. call setup( t2m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2125. IF_NOTOK_RETURN(status=1)
  2126. ! * slhf
  2127. call setup( slhf_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2128. IF_NOTOK_RETURN(status=1)
  2129. ! * sshf
  2130. call setup( sshf_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2131. IF_NOTOK_RETURN(status=1)
  2132. ! * surface stress
  2133. call setup( ewss_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2134. IF_NOTOK_RETURN(status=1)
  2135. call setup( nsss_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2136. IF_NOTOK_RETURN(status=1)
  2137. ! * convective precipitation
  2138. call setup( cp_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2139. IF_NOTOK_RETURN(status=1)
  2140. ! * large scale stratiform precipitation
  2141. call setup( lsp_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2142. IF_NOTOK_RETURN(status=1)
  2143. ! * surface solar radiation
  2144. call setup( ssr_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2145. IF_NOTOK_RETURN(status=1)
  2146. call setup( ssrd_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2147. IF_NOTOK_RETURN(status=1)
  2148. ! * surface thermal radiation
  2149. call setup( str_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2150. IF_NOTOK_RETURN(status=1)
  2151. call setup( strd_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2152. IF_NOTOK_RETURN(status=1)
  2153. ! * skin temperature
  2154. call setup( skt_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2155. IF_NOTOK_RETURN(status=1)
  2156. ! * boundary layer height
  2157. #ifndef with_tmm_ecearth
  2158. call setup( blh_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2159. IF_NOTOK_RETURN(status=1)
  2160. #endif
  2161. ! * snow fall and depth
  2162. call setup( sf_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2163. IF_NOTOK_RETURN(status=1)
  2164. call setup( sd_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2165. IF_NOTOK_RETURN(status=1)
  2166. ! * g10m
  2167. #ifndef with_tmm_ecearth
  2168. call setup( g10m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2169. IF_NOTOK_RETURN(status=1)
  2170. #endif
  2171. ! * soil water level 1
  2172. call setup( swvl1_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2173. IF_NOTOK_RETURN(status=1)
  2174. ! * vegetation types
  2175. do iveg = 1, nveg
  2176. select case ( iveg )
  2177. case ( 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 16, 17, 18, 19 )
  2178. call setup( tv_dat(1:nregions_all,iveg), (/tr1,tr2/), 'n', status)
  2179. IF_NOTOK_RETURN(status=1)
  2180. case ( 8, 12, 14, 15, 20 )
  2181. if ( tv_dat(n,iveg)%used ) tv_dat(n,iveg)%data = 0.0
  2182. case default
  2183. write (gol,'("do not know how to setup vegetation type ",i2)') iveg
  2184. call goErr; status=1; return
  2185. end select
  2186. end do
  2187. ! * low vegetation cover
  2188. call setup( cvl_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2189. IF_NOTOK_RETURN(status=1)
  2190. ! * high vegetation cover
  2191. call setup( cvh_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2192. IF_NOTOK_RETURN(status=1)
  2193. ! * MACC emissions
  2194. call setup( ch4fire_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
  2195. IF_NOTOK_RETURN(status=1)
  2196. #else
  2197. ! * sea ice
  2198. call setup( ci_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2199. IF_NOTOK_RETURN(status=1)
  2200. ! * sea surface temperature
  2201. call setup( sst_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2202. IF_NOTOK_RETURN(status=1)
  2203. ! * u10m
  2204. call setup( u10m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2205. IF_NOTOK_RETURN(status=1)
  2206. ! * v10m
  2207. call setup( v10m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2208. IF_NOTOK_RETURN(status=1)
  2209. ! * skin reservoir content
  2210. call setup( src_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2211. IF_NOTOK_RETURN(status=1)
  2212. ! * 2m dewpoint temperature
  2213. call setup( d2m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2214. IF_NOTOK_RETURN(status=1)
  2215. ! * 2m temperature
  2216. call setup( t2m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2217. IF_NOTOK_RETURN(status=1)
  2218. ! * slhf
  2219. call setup( slhf_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2220. IF_NOTOK_RETURN(status=1)
  2221. ! * sshf
  2222. call setup( sshf_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2223. IF_NOTOK_RETURN(status=1)
  2224. ! * surface stress
  2225. call setup( ewss_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2226. IF_NOTOK_RETURN(status=1)
  2227. call setup( nsss_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2228. IF_NOTOK_RETURN(status=1)
  2229. ! * convective precipitation
  2230. call setup( cp_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2231. IF_NOTOK_RETURN(status=1)
  2232. ! * large scale stratiform precipitation
  2233. call setup( lsp_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2234. IF_NOTOK_RETURN(status=1)
  2235. ! * surface solar radiation
  2236. call setup( ssr_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2237. IF_NOTOK_RETURN(status=1)
  2238. call setup( ssrd_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2239. IF_NOTOK_RETURN(status=1)
  2240. ! * surface thermal radiation
  2241. call setup( str_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2242. IF_NOTOK_RETURN(status=1)
  2243. call setup( strd_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2244. IF_NOTOK_RETURN(status=1)
  2245. ! * skin temperature
  2246. call setup( skt_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2247. IF_NOTOK_RETURN(status=1)
  2248. ! * boundary layer height
  2249. #ifndef with_tmm_ecearth
  2250. call setup( blh_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2251. IF_NOTOK_RETURN(status=1)
  2252. #endif
  2253. ! * snow fall and depth
  2254. call setup( sf_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2255. IF_NOTOK_RETURN(status=1)
  2256. call setup( sd_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2257. IF_NOTOK_RETURN(status=1)
  2258. ! * g10m
  2259. #ifndef with_tmm_ecearth
  2260. call setup( g10m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2261. IF_NOTOK_RETURN(status=1)
  2262. #endif
  2263. ! * soil water level 1
  2264. call setup( swvl1_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2265. IF_NOTOK_RETURN(status=1)
  2266. ! * vegetation types
  2267. do iveg = 1, nveg
  2268. select case ( iveg )
  2269. case ( 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 16, 17, 18, 19 )
  2270. call setup( tv_dat(1:nregions_all,iveg), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2271. IF_NOTOK_RETURN(status=1)
  2272. case ( 8, 12, 14, 15, 20 )
  2273. if ( tv_dat(n,iveg)%used ) tv_dat(n,iveg)%data = 0.0
  2274. case default
  2275. write (gol,'("do not know how to setup vegetation type ",i2)') iveg
  2276. call goErr; status=1; return
  2277. end select
  2278. end do
  2279. ! * low vegetation cover
  2280. call setup( cvl_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2281. IF_NOTOK_RETURN(status=1)
  2282. ! * high vegetation cover
  2283. call setup( cvh_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2284. IF_NOTOK_RETURN(status=1)
  2285. ! * MACC emissions
  2286. call setup( ch4fire_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
  2287. IF_NOTOK_RETURN(status=1)
  2288. #endif
  2289. !
  2290. ! ** done ********************************************
  2291. !
  2292. status = 0
  2293. call goLabel()
  2294. END SUBROUTINE METEO_SETUP_OTHER
  2295. !EOC
  2296. !------------------------------------------------------------------------------
  2297. ! TM5 !
  2298. !------------------------------------------------------------------------------
  2299. !BOP
  2300. !
  2301. ! !IROUTINE: SETUPSETUP
  2302. !
  2303. ! !DESCRIPTION: for one met data MD and one time range TR, returns the dates
  2304. ! at begining and end of the met field interval that
  2305. ! encompasses TR, and if the data for these dates (%data1 and
  2306. ! %data2, resp.) must be read or copied.
  2307. !\\
  2308. !\\
  2309. ! !INTERFACE:
  2310. !
  2311. SUBROUTINE SETUPSETUP( md, tr, &
  2312. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  2313. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  2314. status )
  2315. !
  2316. ! !USES:
  2317. !
  2318. use GO, only : TDate, NewDate, IncrDate, AnyDate, IsAnyDate, Get, Set, wrtgol
  2319. use GO, only : rTotal, iTotal
  2320. use GO, only : operator(+), operator(-), operator(/)
  2321. use GO, only : operator(==), operator(/=), operator(<), operator(<=)
  2322. use meteodata, only : TMeteoData
  2323. use global_data, only : fcmode, tfcday0
  2324. !
  2325. ! !INPUT/OUTPUT PARAMETERS:
  2326. !
  2327. type(TMeteoData), intent(inout) :: md
  2328. !
  2329. ! !INPUT PARAMETERS:
  2330. !
  2331. type(TDate), intent(in) :: tr(2)
  2332. !
  2333. ! !OUTPUT PARAMETERS:
  2334. !
  2335. logical, intent(out) :: data1_read, data1_copy
  2336. type(TDate), intent(out) :: data1_tref, data1_t1, data1_t2
  2337. logical, intent(out) :: data2_read, data2_copy
  2338. type(TDate), intent(out) :: data2_tref, data2_t1, data2_t2
  2339. integer, intent(out) :: status
  2340. !
  2341. ! !REVISION HISTORY:
  2342. ! 29 Mar 2010 - P. Le Sager -
  2343. !
  2344. !EOP
  2345. !------------------------------------------------------------------------------
  2346. !BOC
  2347. character(len=*), parameter :: rname = mname//'/SetupSetup'
  2348. integer :: dth, baseh
  2349. integer :: year, month, day, hour, minu
  2350. type(TDate) :: tmid
  2351. type(TDate) :: tc(2)
  2352. integer :: dth_int
  2353. type(TDate) :: tprev, tnext
  2354. real :: dhr
  2355. ! --- begin -----------------------------
  2356. call goLabel(rname)
  2357. ! default output:
  2358. data1_read = .false.
  2359. data1_copy = .false.
  2360. data2_read = .false.
  2361. data2_copy = .false.
  2362. !
  2363. ! trap constant fields ...
  2364. !
  2365. ! constant and already filled ? then leave
  2366. if ( (md%tinterp == 'const') .and. md%filled1 ) then
  2367. call goLabel()
  2368. status = 0; return
  2369. end if
  2370. !
  2371. ! fc stuff
  2372. !
  2373. ! 3 hourly data only available up to 72h, then 6 hourly
  2374. if ( fcmode ) then
  2375. ! number of hours from fcday 00:00 to end of requested interval:
  2376. dhr = rTotal( tr(2) - tfcday0, 'hour' )
  2377. ! lower time resolution after a while ...
  2378. if ( tfcday0 < NewDate(year=2006,month=03,day=14) ) then
  2379. ! after 12+72 hour ?
  2380. if ( dhr > 12.0 + 72.0 ) then
  2381. ! convert time interpolation:
  2382. select case ( md%tinterp )
  2383. case ( 'aver3' )
  2384. write (gol,'("WARNING - convert time interpolation from `aver3` to `aver6`")'); call goPr
  2385. md%tinterp = 'aver6'
  2386. case ( 'interp3' )
  2387. write (gol,'("WARNING - convert time interpolation from `interp3` to `interp6`")'); call goPr
  2388. md%tinterp = 'interp6'
  2389. end select
  2390. end if ! > 72 hour
  2391. else
  2392. ! after 12+96 hour ?
  2393. if ( dhr > 12.0 + 96.0 ) then
  2394. ! convert time interpolation:
  2395. select case ( md%tinterp )
  2396. case ( 'aver3' )
  2397. write (gol,'("WARNING - convert time interpolation from `aver3` to `aver6`")'); call goPr
  2398. md%tinterp = 'aver6'
  2399. case ( 'interp3' )
  2400. write (gol,'("WARNING - convert time interpolation from `interp3` to `interp6`")'); call goPr
  2401. md%tinterp = 'interp6'
  2402. end select
  2403. end if ! > 96 hour
  2404. end if ! change in fc resolution
  2405. end if ! fcmode
  2406. !
  2407. ! time stuff
  2408. !
  2409. ! basic time resolution in hours
  2410. select case ( md%tinterp )
  2411. case ( 'const', 'month' )
  2412. ! nothing to be set here ...
  2413. case ( 'aver24' )
  2414. ! constant fields produced valid for [00,24]
  2415. dth = 24
  2416. baseh = 00
  2417. case ( 'aver24_3' )
  2418. ! constant fields produced by tmpp valid for [21,21] = [09-12,09+12]
  2419. dth = 24
  2420. baseh = -3
  2421. case ( 'const3', 'interp3', 'aver3', 'cpl3' )
  2422. dth = 3
  2423. baseh = 0
  2424. case ( 'interp2', 'cpl2' )
  2425. dth = 2
  2426. baseh = 0
  2427. case ( 'const1', 'interp1', 'aver1', 'cpl1' )
  2428. dth = 1
  2429. baseh = 0
  2430. case ( 'const6', 'interp6', 'aver6', 'cpl6' )
  2431. dth = 6
  2432. baseh = 0
  2433. case ( 'interp6_3' )
  2434. dth = 6
  2435. baseh = 3
  2436. case default
  2437. write (gol,'("unsupported time interpolation : ",a)') md%tinterp; call goErr
  2438. call goErr; status=1; return
  2439. end select
  2440. ! set time parameters for field to be read:
  2441. select case ( md%tinterp )
  2442. !
  2443. ! ** constant fields
  2444. !
  2445. case ( 'const' )
  2446. ! read main field ?
  2447. data1_read = .not. md%filled1
  2448. ! read or leave ?
  2449. if ( data1_read ) then
  2450. data1_tref = tr(1) ! <--- used for file names
  2451. data1_t1 = AnyDate()
  2452. data1_t2 = AnyDate()
  2453. else
  2454. ! field valid around requested interval, thus leave:
  2455. call goLabel()
  2456. status=0; return
  2457. end if
  2458. !
  2459. ! ** constant fields, valid for complete month
  2460. !
  2461. case ( 'month' )
  2462. ! extract time values for begin of current interval:
  2463. call Get( tr(1), year=year, month=month )
  2464. ! interval for this month:
  2465. tc(1) = NewDate( year=year, month=month, day=01, hour=00 )
  2466. month = month + 1
  2467. if ( month > 12 ) then
  2468. month = 1
  2469. year = year + 1
  2470. end if
  2471. tc(2) = NewDate( year=year, month=month, day=01, hour=00 )
  2472. ! check for strange values:
  2473. if ( (tr(1) < tc(1)) .or. (tc(2) < tr(2)) ) then
  2474. write (gol,'("determined invalid constant interval:")'); call goErr
  2475. call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
  2476. call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
  2477. write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
  2478. call goErr; status=1; return
  2479. !write (gol,'(" WARNING - requested interval exceeds meteo interval; should be improved")')
  2480. end if
  2481. ! read main field ?
  2482. if ( md%filled1 ) then
  2483. data1_read = md%tr1(1) /= tc(1)
  2484. else
  2485. data1_read = .true.
  2486. end if
  2487. ! read or leave ?
  2488. if ( data1_read ) then
  2489. data1_tref = tr(1)
  2490. data1_t1 = tc(1)
  2491. data1_t2 = tc(2)
  2492. else
  2493. ! field valid around requested interval, thus leave:
  2494. call goLabel()
  2495. status=0; return
  2496. end if
  2497. !
  2498. ! ** constant fields, valid for 24hr intervals [21:00,21:00]
  2499. ! constant fields, valid for 6hr intervals [21:00,03:00] etc
  2500. ! constant fields, valid for 3hr intervals [22:30,01:30] etc
  2501. !
  2502. case ( 'const6', 'const3' )
  2503. ! extract time values for begin of current interval:
  2504. call Get( tr(1), year, month, day, hour, minu )
  2505. ! round hour to 00/06/12/18 or 00/03/06/09/12/15/18/21 or 09
  2506. hour = dth * nint(real(hour+minu/60.0-baseh)/real(dth)) + baseh
  2507. ! set mid of 3 or 6 hour interval:
  2508. tmid = NewDate( year, month, day, hour )
  2509. ! interval with constant field
  2510. tc(1) = tmid - IncrDate(hour=dth)/2
  2511. tc(2) = tmid + IncrDate(hour=dth)/2
  2512. ! check for strange values:
  2513. if ( (tr(1) < tc(1)) .or. (tc(2) < tr(2)) ) then
  2514. write (gol,'("determined invalid constant interval:")'); call goErr
  2515. call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
  2516. call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
  2517. write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
  2518. call goErr; status=1; return
  2519. end if
  2520. ! read main field ?
  2521. if ( md%filled1 ) then
  2522. data1_read = md%tr1(1) /= tmid
  2523. else
  2524. data1_read = .true.
  2525. end if
  2526. ! read or leave ?
  2527. if ( data1_read ) then
  2528. data1_tref = tmid
  2529. data1_t1 = tmid
  2530. data1_t2 = tmid
  2531. else
  2532. ! field valid around requested interval, thus leave:
  2533. call goLabel()
  2534. status=0; return
  2535. end if
  2536. !
  2537. ! ** couple fields, valid for 3hr intervals [00:00,03:00] etc
  2538. ! input filed valid for BEGIN of interval !
  2539. !
  2540. case ( 'cpl6', 'cpl3', 'cpl2', 'cpl1' )
  2541. ! extract time values for begin of current interval:
  2542. call Get( tr(1), year, month, day, hour, minu )
  2543. ! round hour to previous baseh + 00/03/06/09/12/15/18/21
  2544. hour = dth * floor(real(hour-baseh)/real(dth)) + baseh
  2545. ! interval with constant field
  2546. tc(1) = NewDate( year, month, day, hour )
  2547. tc(2) = tc(1) + IncrDate(hour=dth)
  2548. ! check for strange values:
  2549. if ( (tr(1) < tc(1)) .or. (tc(2) < tr(1)) ) then
  2550. write (gol,'("determined invalid first interval:")'); call goErr
  2551. call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
  2552. call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
  2553. write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
  2554. call goErr; status=1; return
  2555. end if
  2556. ! read primary field ?
  2557. if ( md%filled1 ) then
  2558. ! read new field if times are different:
  2559. data1_read = (md%tr1(1) /= tc(1)) .or. (md%tr1(2) /= tc(1))
  2560. else
  2561. ! not filled yet, thus must read:
  2562. data1_read = .true.
  2563. end if
  2564. ! read or leave ?
  2565. if ( data1_read ) then
  2566. data1_tref = tc(1) ! begin of time interval
  2567. data1_t1 = tc(1)
  2568. data1_t2 = tc(1)
  2569. end if
  2570. !
  2571. ! ** average fields, valid for 3hr intervals [00:00,03:00] etc
  2572. ! average fields, valid for 3hr intervals [00:00,06:00] etc
  2573. !
  2574. case ( 'aver1', 'aver3', 'aver6', 'aver24', 'aver24_3' )
  2575. ! extract time values for begin of current interval:
  2576. call Get( tr(1), year, month, day, hour, minu )
  2577. ! round hour to previous baseh + 00/03/06/09/12/15/18/21
  2578. hour = dth * floor(real(hour-baseh)/real(dth)) + baseh
  2579. ! interval with constant field
  2580. tc(1) = NewDate( year, month, day, hour )
  2581. tc(2) = tc(1) + IncrDate(hour=dth)
  2582. ! check for strange values:
  2583. if ( (tr(1) < tc(1)) .or. (tc(2) < tr(1)) ) then
  2584. write (gol,'("determined invalid first interval:")'); call goErr
  2585. call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
  2586. call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
  2587. write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
  2588. call goErr; status=1; return
  2589. end if
  2590. ! read primary field ?
  2591. if ( md%filled1 ) then
  2592. ! read new field if times are different:
  2593. data1_read = (md%tr1(1) /= tc(1)) .or. (md%tr1(2) /= tc(2))
  2594. else
  2595. ! not filled yet, thus must read:
  2596. data1_read = .true.
  2597. end if
  2598. if ( data1_read ) then
  2599. data1_tref = tc(1)
  2600. data1_t1 = tc(1)
  2601. data1_t2 = tc(2)
  2602. end if
  2603. ! setup reading of secondary data only if end of requested
  2604. ! interval is later than primary interval:
  2605. if ( tc(2) < tr(2) ) then
  2606. ! extract time values for end of requested interval:
  2607. call Get( tr(2), year, month, day, hour, minu )
  2608. ! round hour to next baseh + 00/03/06/09/12/15/18/21
  2609. hour = dth * floor(real(hour+minu/60.0-baseh)/real(dth)) + baseh
  2610. ! interval with constant field
  2611. tc(1) = NewDate( year, month, day ) + IncrDate(hour=hour)
  2612. tc(2) = tc(1) + IncrDate(hour=dth)
  2613. ! check for strange values:
  2614. if ( (tr(2) < tc(1)) .or. (tc(2) < tr(2)) ) then
  2615. write (gol,'("determined invalid second interval:")'); call goErr
  2616. call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
  2617. call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
  2618. write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
  2619. call goErr; status=1; return
  2620. end if
  2621. ! read secondary field ?
  2622. if ( md%filled2 ) then
  2623. ! read new field if times are different;
  2624. data2_read = (md%tr2(1) /= tc(1)) .or. (md%tr2(2) /= tc(2))
  2625. else
  2626. ! not filled yet, thus must read:
  2627. data2_read = .true.
  2628. end if
  2629. if ( data2_read ) then
  2630. data2_tref = tc(1)
  2631. data2_t1 = tc(1)
  2632. data2_t2 = tc(2)
  2633. end if
  2634. end if ! tr partly after primary interval
  2635. !
  2636. ! ** interpolated between 6 hourly times 00/06/12/18
  2637. ! interpolated between 6 hourly times 03/09/15/21
  2638. ! interpolated between 3 hourly times 00/03/06/09/12/15/18/21
  2639. !
  2640. case ( 'interp6', 'interp6_3', 'interp3', 'interp2', 'interp1' )
  2641. ! extract time values for begin of current interval:
  2642. call Get( tr(1), year, month, day, hour, minu )
  2643. ! truncate hour to previous 00/06/12/18, 03/09/15/21,
  2644. ! or 00/03/06/09/12/15/18/21
  2645. hour = dth * floor(real(hour+minu/60.0-baseh)/real(dth)) + baseh
  2646. ! set begin of 3 or 6 hour interval:
  2647. tprev = NewDate( year, month, day, hour )
  2648. ! extract time values for end of current interval:
  2649. call Get( tr(2), year, month, day, hour, minu )
  2650. ! truncate hour to previous 00/06/12/18
  2651. hour = dth * ceiling(real(hour+minu/60.0-baseh)/real(dth)) + baseh
  2652. ! set end of 3 or 6 hour interval:
  2653. tnext = NewDate( year, month, day, hour )
  2654. ! checks:
  2655. ! [tprev,tmax] should be dth hours
  2656. ! [tprev,tmax] should contain [tr(1),tr(2)]
  2657. dth_int = iTotal(tnext-tprev,'hour')
  2658. if ( (tr(1) < tprev) .or. (tnext < tr(2)) .or. &
  2659. ( (dth_int /= 0) .and. (dth_int /= dth) ) ) then
  2660. write (gol,'("determined invalid interpolation interval:")'); call goErr
  2661. call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
  2662. call wrtgol( ' guessed : ', tprev, ' - ', tnext ); call goErr
  2663. write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
  2664. call goErr; status=1; return
  2665. end if
  2666. !
  2667. ! . <-- previous field at dth hours
  2668. ! o <-- latest interpolated field
  2669. ! x <-- target
  2670. ! o <-- next field at dth hours
  2671. ! tr1 tr tr2
  2672. ! --+--------------+------
  2673. ! tprev tnext
  2674. !
  2675. ! read main field ?
  2676. if ( md%filled1 ) then
  2677. ! md%data should be defined in [tprev,tr]
  2678. data1_read = (md%tr1(1) < tprev) .or. (tr(2) < md%tr1(1))
  2679. else
  2680. data1_read = .true.
  2681. end if
  2682. if ( data1_read ) then
  2683. data1_tref = tprev
  2684. data1_t1 = tprev
  2685. data1_t2 = tprev
  2686. end if
  2687. ! read second field ?
  2688. if ( md%filled2 ) then
  2689. ! md%data should be defined for tnext
  2690. data2_read = md%tr2(1) /= tnext
  2691. else
  2692. data2_read = .true.
  2693. end if
  2694. if ( data2_read ) then
  2695. data2_tref = tnext
  2696. data2_t1 = tnext
  2697. data2_t2 = tnext
  2698. end if
  2699. !
  2700. ! ** error ...
  2701. !
  2702. case default
  2703. write (gol,'("unsupported time interpolation : ",a)') md%tinterp ; call goErr
  2704. call goErr; status=1; return
  2705. end select
  2706. !
  2707. ! set ref times
  2708. !
  2709. if ( fcmode ) then
  2710. ! in forecast mode, tfcday0 is 00:00 at the day the forecast starts;
  2711. data1_tref = tfcday0
  2712. data2_tref = tfcday0
  2713. else
  2714. ! dummy tref's : begin of day in which [data?_t1,data?_t2] starts:
  2715. data1_tref = data1_t1
  2716. if ( IsAnyDate(data1_tref) ) data1_tref = tr(1)
  2717. call Set( data1_tref, hour=0, min=0, sec=0, mili=0 )
  2718. data2_tref = data2_t1
  2719. if ( IsAnyDate(data2_tref) ) data2_tref = tr(1)
  2720. call Set( data2_tref, hour=0, min=0, sec=0, mili=0 )
  2721. end if
  2722. !
  2723. ! trap double reading
  2724. !
  2725. ! data already in data2 ?
  2726. if ( data1_read .and. md%filled2 ) then
  2727. if ( (data1_t1 == md%tr2(1)) .and. (data1_t2 == md%tr2(2)) ) then
  2728. data1_read = .false.
  2729. data1_copy = .true.
  2730. end if
  2731. end if
  2732. ! data2 just read ?
  2733. if ( data2_read .and. data1_read ) then
  2734. ! data2 is same as data ?
  2735. if ( (data2_tref == data1_tref) .and. &
  2736. (data2_t1 == data1_t1) .and. (data2_t2 == data1_t2) ) then
  2737. data2_read = .false.
  2738. data2_copy = .true.
  2739. end if
  2740. end if
  2741. !write (gol,'("SetupSetup:")'); call goPr
  2742. !write (gol,'(" fcmode : ",l1)') fcmode; call goPr
  2743. !call wrtgol( ' tfcday0 : ', tfcday0 ); call goPr
  2744. !write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goPr
  2745. !call wrtgol( ' tr(1) : ', tr(1) ); call goPr
  2746. !call wrtgol( ' tr(2) : ', tr(2) ); call goPr
  2747. !write (gol,'(" 1 read,copy : ",2l2)') data1_read, data1_copy; call goPr
  2748. !call wrtgol( ' 1 tref : ', data1_tref ); call goPr
  2749. !call wrtgol( ' 1 t1 : ', data1_t1 ); call goPr
  2750. !call wrtgol( ' 1 t2 : ', data1_t2 ); call goPr
  2751. !write (gol,'(" 2 read,copy : ",2l2)') data2_read, data2_copy; call goPr
  2752. !call wrtgol( ' 2 tref : ', data2_tref ); call goPr
  2753. !call wrtgol( ' 2 t1 : ', data2_t1 ); call goPr
  2754. !call wrtgol( ' 2 t2 : ', data2_t2 ); call goPr
  2755. ! ok
  2756. status = 0
  2757. call goLabel()
  2758. end subroutine SetupSetup
  2759. !EOC
  2760. !------------------------------------------------------------------------------
  2761. ! TM5 !
  2762. !------------------------------------------------------------------------------
  2763. !BOP
  2764. !
  2765. ! !IROUTINE: SETUP_2D_SERIAL
  2766. !
  2767. ! !DESCRIPTION: Fill md%data1 and md%data2 of a 2D met field type (md), with
  2768. ! data for date tr(1) and tr(2) respectively (and if needed)
  2769. ! through reading or copying. Also write to disk the met field
  2770. ! if requested.
  2771. !
  2772. ! Then set md%data according to its type of interpolation (see
  2773. ! TimeInterpolation in meteodata.F90).
  2774. ! For constant type, %data => %data1.
  2775. !\\
  2776. !\\
  2777. ! !INTERFACE:
  2778. !
  2779. SUBROUTINE SETUP_2D_SERIAL( region, md, tr, lli, nuv, status )
  2780. !
  2781. ! !USES:
  2782. !
  2783. use GO, only : TDate, wrtgol
  2784. use Grid, only : TllGridInfo
  2785. use TMM, only : ReadField, Read_SP, Read_SR_OLS, WriteField
  2786. use meteodata, only : TMeteoData, TimeInterpolation
  2787. use dims, only : im, jm
  2788. !
  2789. ! !INPUT/OUTPUT PARAMETERS:
  2790. !
  2791. type(TMeteoData), intent(inout) :: md ! met field
  2792. !
  2793. ! !INPUT PARAMETERS:
  2794. !
  2795. integer, intent(in) :: region ! region number
  2796. type(TDate), intent(in) :: tr(2) ! dates
  2797. type(TllGridInfo), intent(in) :: lli ! grid (GLOBAL)
  2798. character(len=1), intent(in) :: nuv ! staggering
  2799. !
  2800. ! !OUTPUT PARAMETERS:
  2801. !
  2802. integer, intent(out) :: status ! return code
  2803. !
  2804. ! !REVISION HISTORY:
  2805. ! 4 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  2806. !
  2807. !EOP
  2808. !------------------------------------------------------------------------------
  2809. !BOC
  2810. character(len=*), parameter :: rname = mname//'/Setup_2d_serial'
  2811. logical :: data1_read, data1_copy
  2812. type(TDate) :: data1_tref, data1_t1, data1_t2
  2813. logical :: data2_read, data2_copy
  2814. type(TDate) :: data2_tref, data2_t1, data2_t2
  2815. real, pointer :: field(:,:) ! work array
  2816. ! --- begin -----------------------------
  2817. call goLabel(rname)
  2818. ! leave if not in use:
  2819. if ( .not. md%used ) then
  2820. call goLabel()
  2821. status=0; return
  2822. end if
  2823. if (okdebug) then
  2824. write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md%name),trim(lli%name); call goPr
  2825. endif
  2826. ! not changed by default
  2827. md%changed = .false.
  2828. !------------------
  2829. ! time stuff
  2830. !------------------
  2831. ! get time interval of met field and check if data from start and/or end
  2832. ! of interval must be read or copy
  2833. call SetupSetup( md, tr, &
  2834. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  2835. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  2836. status )
  2837. IF_NOTOK_RETURN(status=1)
  2838. ! -------------------------
  2839. ! Read/write primary field
  2840. ! -------------------------
  2841. if ( data1_read ) then
  2842. ! Switch to global
  2843. if ( md%ls(1) /= md%ls(2) ) then
  2844. write (gol,'("SETUP_2D called instead of SETUP_3D, field is 3D:")'); call goErr
  2845. write (gol, '(" md%ls(1:2) : ",2i3)') md%ls; call goErr
  2846. status=1; IF_NOTOK_RETURN(status=1)
  2847. end if
  2848. ! Need whole region for I/O on root. Dummy else.
  2849. IF (isRoot) THEN
  2850. ALLOCATE( field( im(region), jm(region)) )
  2851. ELSE
  2852. ALLOCATE( field(1,1) )
  2853. END IF
  2854. ! Read/write
  2855. IOroot : IF (isRoot) THEN
  2856. select case ( md%name )
  2857. case ( 'sp', 'sps' )
  2858. ! special routine for surface pressure
  2859. call Read_SP( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  2860. data1_tref, data1_t1, data1_t2, &
  2861. lli, FIELD, md%tmi1, status )
  2862. IF_NOTOK_RETURN(status=1)
  2863. case ( 'srols' )
  2864. ! special routine for Olsson surface roughness:
  2865. call Read_SR_OLS( tmmd, md%sourcekey, &
  2866. data1_tref, data1_t1, data1_t2, &
  2867. lli, FIELD, md%tmi1, status )
  2868. IF_NOTOK_RETURN(status=1)
  2869. case default
  2870. ! general field
  2871. call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  2872. data1_tref, data1_t1, data1_t2, lli, &
  2873. nuv, FIELD, md%tmi1, status )
  2874. IF_NOTOK_RETURN(status=1)
  2875. end select
  2876. ! write meteofiles
  2877. if ( md%putout ) then
  2878. call WriteField( tmmd, md%destkey, &
  2879. md%tmi1, trim(md%name), trim(md%unit), &
  2880. data1_tref, data1_t1, data1_t2, &
  2881. lli, nuv, FIELD, status )
  2882. IF_NOTOK_RETURN(status=1)
  2883. end if
  2884. END IF IOroot
  2885. CALL SCATTER( dgrid(region), md%data1(:,:,1), FIELD, md%halo, status)
  2886. IF_NOTOK_RETURN(status=1)
  2887. DEALLOCATE( FIELD )
  2888. ! data array is filled now:
  2889. md%filled1 = .true.
  2890. md%tr1(1) = data1_t1
  2891. md%tr1(2) = data1_t2
  2892. md%changed = .true.
  2893. else if ( data1_copy ) then
  2894. ! copy data from secondary array:
  2895. md%data1 = md%data2
  2896. ! data array is filled now:
  2897. md%filled1 = .true.
  2898. md%tr1(1) = data1_t1
  2899. md%tr1(2) = data1_t2
  2900. md%changed = .true.
  2901. end if
  2902. ! -------------------------
  2903. ! Read/write (or copy or nothing) secondary field
  2904. ! -------------------------
  2905. if ( data2_read ) then
  2906. ! Need whole region for I/O on root. Dummy else.
  2907. IF (isRoot) THEN
  2908. ALLOCATE( field( im(region), jm(region)) )
  2909. ELSE
  2910. ALLOCATE( field(1,1) )
  2911. END IF
  2912. ! Read/write
  2913. IOroot2: IF (isRoot) THEN
  2914. select case ( md%name )
  2915. case ( 'sp', 'sps' )
  2916. ! special routine for surface pressure
  2917. call Read_SP( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  2918. data2_tref, data2_t1, data2_t2, &
  2919. lli, FIELD, md%tmi2, status )
  2920. IF_NOTOK_RETURN(status=1)
  2921. case default
  2922. ! general field
  2923. call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  2924. data2_tref, data2_t1, data2_t2, lli, &
  2925. nuv, FIELD, md%tmi2, status )
  2926. IF_NOTOK_RETURN(status=1)
  2927. end select
  2928. ! write meteo files
  2929. if ( md%putout ) then
  2930. call WriteField( tmmd, md%destkey, &
  2931. md%tmi2, trim(md%name), trim(md%unit), &
  2932. data2_tref, data2_t1, data2_t2, &
  2933. lli, nuv, FIELD, status )
  2934. IF_NOTOK_RETURN(status=1)
  2935. end if
  2936. END IF IOroot2
  2937. CALL SCATTER( dgrid(region), md%data2(:,:,1), FIELD, md%halo, status)
  2938. IF_NOTOK_RETURN(status=1)
  2939. DEALLOCATE( FIELD )
  2940. ! data array is filled now
  2941. md%filled2 = .true.
  2942. md%tr2(1) = data2_t1
  2943. md%tr2(2) = data2_t2
  2944. else if ( data2_copy ) then
  2945. ! copy data from secondary array
  2946. md%data2 = md%data1
  2947. ! data array is filled now
  2948. md%filled2 = .true.
  2949. md%tr2(1) = data2_t1
  2950. md%tr2(2) = data2_t2
  2951. end if
  2952. ! -------------------------
  2953. ! time interpolation
  2954. ! -------------------------
  2955. call TimeInterpolation( md, tr, status )
  2956. IF_NOTOK_RETURN(status=1)
  2957. ! -------------------------
  2958. ! done
  2959. ! -------------------------
  2960. status = 0
  2961. call goLabel()
  2962. END SUBROUTINE SETUP_2D_SERIAL
  2963. !EOC
  2964. !------------------------------------------------------------------------------
  2965. ! TM5 !
  2966. !------------------------------------------------------------------------------
  2967. !BOP
  2968. !
  2969. ! !IROUTINE: SETUP_2D_PARA
  2970. !
  2971. ! !DESCRIPTION: Same as SETUP_2D_SERIAL, except all processes get field from IFS
  2972. !\\
  2973. !\\
  2974. ! !INTERFACE:
  2975. !
  2976. SUBROUTINE SETUP_2D_PARA( region, md, tr, nuv, status )
  2977. !
  2978. ! !USES:
  2979. !
  2980. use GO, only : TDate, wrtgol
  2981. use Grid, only : TllGridInfo
  2982. use TMM, only : ReadField, Read_SP, Read_SR_OLS, WriteField
  2983. ! use meteodata, only : TMeteoData, TimeInterpolation
  2984. use dims, only : im, jm
  2985. !
  2986. ! !INPUT/OUTPUT PARAMETERS:
  2987. !
  2988. type(TMeteoData), intent(inout) :: md ! met field
  2989. !
  2990. ! !INPUT PARAMETERS:
  2991. !
  2992. integer, intent(in) :: region ! region number
  2993. type(TDate), intent(in) :: tr(2) ! dates
  2994. character(len=1), intent(in) :: nuv ! staggering
  2995. !
  2996. ! !OUTPUT PARAMETERS:
  2997. !
  2998. integer, intent(out) :: status ! return code
  2999. !
  3000. ! !REVISION HISTORY:
  3001. ! 18 Oct 2013 - Ph. Le Sager - v0
  3002. !
  3003. !EOP
  3004. !------------------------------------------------------------------------------
  3005. !BOC
  3006. character(len=*), parameter :: rname = mname//'/Setup_2d_para'
  3007. logical :: data1_read, data1_copy
  3008. type(TDate) :: data1_tref, data1_t1, data1_t2
  3009. logical :: data2_read, data2_copy
  3010. type(TDate) :: data2_tref, data2_t1, data2_t2
  3011. integer :: i1, i2, j1, j2
  3012. real, pointer :: field(:,:) ! work array
  3013. ! --- begin -----------------------------
  3014. call goLabel(rname)
  3015. ! leave if not in use:
  3016. if ( .not. md%used ) then
  3017. call goLabel()
  3018. status=0; return
  3019. end if
  3020. ! not changed by default
  3021. md%changed = .false.
  3022. !------------------
  3023. ! time stuff
  3024. !------------------
  3025. ! get time interval of met field and check if data from start and/or end
  3026. ! of interval must be read or copy
  3027. call SetupSetup( md, tr, &
  3028. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  3029. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  3030. status )
  3031. IF_NOTOK_RETURN(status=1)
  3032. ! -------------------------
  3033. ! Read/write primary field
  3034. ! -------------------------
  3035. if ( data1_read ) then
  3036. ! test
  3037. if ( md%ls(1) /= md%ls(2) ) then
  3038. write (gol,'("SETUP_2D called instead of SETUP_3D, field is 3D:")'); call goErr
  3039. write (gol, '(" md%ls(1:2) : ",2i3)') md%ls; call goErr
  3040. status=1; IF_NOTOK_RETURN(status=1)
  3041. end if
  3042. ! could get those bounds from md% directly
  3043. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3044. allocate( field( i1:i2, j1:j2) ) !! bonds are not strictly required, could as well do (i2-i1+1, ..)
  3045. ! Read/write
  3046. select case ( md%name )
  3047. case ( 'sp', 'sps' )
  3048. ! special routine for surface pressure
  3049. call Read_SP( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  3050. data1_tref, data1_t1, data1_t2, &
  3051. lli(region), FIELD, md%tmi1, status )
  3052. IF_NOTOK_RETURN(status=1)
  3053. case ( 'srols' )
  3054. ! special routine for Olsson surface roughness:
  3055. call Read_SR_OLS( tmmd, md%sourcekey, &
  3056. data1_tref, data1_t1, data1_t2, &
  3057. lli(region), FIELD, md%tmi1, status )
  3058. IF_NOTOK_RETURN(status=1)
  3059. case default
  3060. ! general field
  3061. call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  3062. data1_tref, data1_t1, data1_t2, lli(region), &
  3063. nuv, FIELD, md%tmi1, status )
  3064. IF_NOTOK_RETURN(status=1)
  3065. end select
  3066. md%data1(i1:i2, j1:j2, 1) = field
  3067. deallocate( field )
  3068. ! write meteofiles
  3069. if ( md%putout ) then
  3070. write(gol,*)"writing of remapped met field not tested yet.. SKIPPED." ; call goErr
  3071. TRACEBACK; status=1; return
  3072. end if
  3073. ! data array is filled now:
  3074. md%filled1 = .true.
  3075. md%tr1(1) = data1_t1
  3076. md%tr1(2) = data1_t2
  3077. md%changed = .true.
  3078. else if ( data1_copy ) then
  3079. ! copy data from secondary array:
  3080. md%data1 = md%data2
  3081. ! data array is filled now:
  3082. md%filled1 = .true.
  3083. md%tr1(1) = data1_t1
  3084. md%tr1(2) = data1_t2
  3085. md%changed = .true.
  3086. end if
  3087. ! -------------------------
  3088. ! Read/write (or copy or nothing) secondary field
  3089. ! -------------------------
  3090. if ( data2_read ) then
  3091. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3092. allocate( field( i1:i2, j1:j2) )
  3093. select case ( md%name )
  3094. case ( 'sp', 'sps' )
  3095. ! special routine for surface pressure
  3096. call Read_SP( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  3097. data2_tref, data2_t1, data2_t2, &
  3098. lli(region), FIELD, md%tmi2, status )
  3099. IF_NOTOK_RETURN(status=1)
  3100. case default
  3101. ! general field
  3102. call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  3103. data2_tref, data2_t1, data2_t2, lli(region), &
  3104. nuv, FIELD, md%tmi2, status )
  3105. IF_NOTOK_RETURN(status=1)
  3106. end select
  3107. md%data2(i1:i2, j1:j2, 1) = FIELD
  3108. deallocate( field )
  3109. ! data array is filled now
  3110. md%filled2 = .true.
  3111. md%tr2(1) = data2_t1
  3112. md%tr2(2) = data2_t2
  3113. else if ( data2_copy ) then
  3114. ! copy data from secondary array
  3115. md%data2 = md%data1
  3116. ! data array is filled now
  3117. md%filled2 = .true.
  3118. md%tr2(1) = data2_t1
  3119. md%tr2(2) = data2_t2
  3120. end if
  3121. ! -------------------------
  3122. ! time interpolation
  3123. ! -------------------------
  3124. call TimeInterpolation( md, tr, status )
  3125. IF_NOTOK_RETURN(status=1)
  3126. ! -------------------------
  3127. ! done
  3128. ! -------------------------
  3129. status = 0
  3130. call goLabel()
  3131. END SUBROUTINE SETUP_2D_PARA
  3132. !EOC
  3133. !------------------------------------------------------------------------------
  3134. ! TM5 !
  3135. !------------------------------------------------------------------------------
  3136. !BOP
  3137. !
  3138. ! !IROUTINE: SETUP_2D_N_SERIAL
  3139. !
  3140. ! !DESCRIPTION: wrapper around setup_2d to process several regions for the
  3141. ! same field.
  3142. !\\
  3143. !\\
  3144. ! !INTERFACE:
  3145. !
  3146. SUBROUTINE SETUP_2D_N_SERIAL( md, tr, lli, nuv, status )
  3147. !
  3148. ! !USES:
  3149. !
  3150. use GO , only : TDate
  3151. use Grid , only : TllGridInfo
  3152. use meteodata, only : TMeteoData
  3153. !
  3154. ! !INPUT/OUTPUT PARAMETERS:
  3155. !
  3156. type(TMeteoData), intent(inout) :: md(:)
  3157. !
  3158. ! !INPUT PARAMETERS:
  3159. !
  3160. type(TDate), intent(in) :: tr(2)
  3161. type(TllGridInfo), intent(in) :: lli(:)
  3162. character(len=1), intent(in) :: nuv
  3163. !
  3164. ! !OUTPUT PARAMETERS:
  3165. !
  3166. integer, intent(out) :: status
  3167. !
  3168. ! !REVISION HISTORY:
  3169. ! 6 Apr 2010 - P. Le Sager -
  3170. !
  3171. ! !REMARKS:
  3172. ! (1) Attention: we assume that the regions list start from #1.
  3173. !
  3174. !EOP
  3175. !------------------------------------------------------------------------------
  3176. !BOC
  3177. character(len=*), parameter :: rname = mname//'/Setup_2d_n_serial'
  3178. integer :: n
  3179. ! --- begin -----------------------------
  3180. ! check ...
  3181. if ( size(md) /= size(lli) ) then
  3182. write (gol,'("md and lli arrays should have same size:")' ) ; call goErr
  3183. write (gol,'(" size md : ",i6)' ) size(md) ; call goErr
  3184. write (gol,'(" size lli : ",i6)' ) size(lli) ; call goErr
  3185. TRACEBACK; status=1; return
  3186. end if
  3187. ! loop over regions:
  3188. do n = 1, size(md)
  3189. if (okdebug) then
  3190. write (gol,'(" ",a," ",a)') trim(md(n)%name), trim(lli(n)%name); call goPr
  3191. endif
  3192. call Setup( n, md(n), tr, lli(n), nuv, status )
  3193. IF_NOTOK_RETURN(status=1)
  3194. end do
  3195. status = 0
  3196. END SUBROUTINE SETUP_2D_N_SERIAL
  3197. !EOC
  3198. !------------------------------------------------------------------------------
  3199. ! TM5 !
  3200. !------------------------------------------------------------------------------
  3201. !BOP
  3202. !
  3203. ! !IROUTINE: SETUP_2D_N_PARA
  3204. !
  3205. ! !DESCRIPTION: wrapper around setup_2d to process several regions for the
  3206. ! same field.
  3207. !\\
  3208. !\\
  3209. ! !INTERFACE:
  3210. !
  3211. SUBROUTINE SETUP_2D_N_PARA( md, tr, nuv, status )
  3212. !
  3213. ! !USES:
  3214. !
  3215. use GO , only : TDate
  3216. use Grid , only : TllGridInfo
  3217. use meteodata, only : TMeteoData
  3218. !
  3219. ! !INPUT/OUTPUT PARAMETERS:
  3220. !
  3221. type(TMeteoData), intent(inout) :: md(:)
  3222. !
  3223. ! !INPUT PARAMETERS:
  3224. !
  3225. type(TDate), intent(in) :: tr(2)
  3226. character(len=1), intent(in) :: nuv
  3227. !
  3228. ! !OUTPUT PARAMETERS:
  3229. !
  3230. integer, intent(out) :: status
  3231. !
  3232. !EOP
  3233. !------------------------------------------------------------------------------
  3234. !BOC
  3235. character(len=*), parameter :: rname = mname//'/Setup_2d_n_para'
  3236. integer :: n
  3237. do n = 1, size(md)
  3238. if (okdebug) then
  3239. write (gol,'(" ",a," ",a)') trim(md(n)%name), trim(lli(n)%name); call goPr
  3240. endif
  3241. call Setup( n, md(n), tr, nuv, status )
  3242. IF_NOTOK_RETURN(status=1)
  3243. end do
  3244. status = 0
  3245. END SUBROUTINE SETUP_2D_N_PARA
  3246. !EOC
  3247. !--------------------------------------------------------------------------
  3248. ! TM5 !
  3249. !--------------------------------------------------------------------------
  3250. !BOP
  3251. !
  3252. ! !IROUTINE: SETUP_3D
  3253. !
  3254. ! !DESCRIPTION: same as SETUP_2D, but for 3D fields by accounting for levels
  3255. !\\
  3256. !\\
  3257. ! !INTERFACE:
  3258. !
  3259. SUBROUTINE SETUP_3D_SERIAL( region, md, tr, lli, nuv, levi, nw, status )
  3260. !
  3261. ! !USES:
  3262. !
  3263. use GO, only : TDate, wrtgol, operator(/=)
  3264. use Grid, only : TllGridInfo, TLevelInfo
  3265. use TMM, only : TMeteoInfo, ReadField, WriteField
  3266. use meteodata, only : TMeteoData, TimeInterpolation
  3267. use dims, only : im, jm
  3268. !
  3269. ! !INPUT/OUTPUT PARAMETERS:
  3270. !
  3271. type(TMeteoData), intent(inout) :: md ! met field
  3272. !
  3273. ! !INPUT PARAMETERS:
  3274. !
  3275. integer, intent(in) :: region ! region number
  3276. type(TDate), intent(in) :: tr(2) ! dates
  3277. type(TllGridInfo), intent(in) :: lli ! grid
  3278. character(len=1), intent(in) :: nuv ! horiz. staggering
  3279. type(TLevelInfo), intent(in) :: levi ! levels
  3280. character(len=1), intent(in) :: nw ! vertical staggering
  3281. !
  3282. ! !OUTPUT PARAMETERS:
  3283. !
  3284. integer, intent(out) :: status ! return code
  3285. !
  3286. ! !REVISION HISTORY:
  3287. ! 4 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  3288. !
  3289. !EOP
  3290. !------------------------------------------------------------------------
  3291. !BOC
  3292. character(len=*), parameter :: rname = mname//'/Setup_3d_serial'
  3293. logical :: data1_read, data1_copy
  3294. type(TDate) :: data1_tref, data1_t1, data1_t2
  3295. logical :: data2_read, data2_copy
  3296. type(TDate) :: data2_tref, data2_t1, data2_t2
  3297. real, allocatable :: tmp_sp(:,:)
  3298. real, pointer :: field(:,:,:) ! work array (data)
  3299. integer :: is(2), js(2) ! work arrays (bounds)
  3300. ! --- begin -----------------------------
  3301. call goLabel(rname)
  3302. ! leave if not in use:
  3303. if ( .not. md%used ) then
  3304. call goLabel()
  3305. status=0; return
  3306. end if
  3307. if (okdebug) then
  3308. write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md%name),trim(lli%name); call goPr
  3309. endif
  3310. ! not changed by default
  3311. md%changed = .false.
  3312. !------------------
  3313. ! time stuff
  3314. !------------------
  3315. ! get time interval of met field and check if data from start and/or end
  3316. ! of interval must be read or copy
  3317. call SetupSetup( md, tr, &
  3318. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  3319. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  3320. status )
  3321. IF_NOTOK_RETURN(status=1)
  3322. ! -------------------------
  3323. ! Read/write primary field
  3324. ! -------------------------
  3325. if ( data1_read ) then
  3326. ! Need whole region for I/O on root. Dummy else. Allocate global array for I/O
  3327. is = (/1,im(region)/)
  3328. js = (/1,jm(region)/)
  3329. IF (isRoot) THEN
  3330. ALLOCATE( FIELD( is(1):is(2), js(1):js(2), md%ls(1):md%ls(2) ))
  3331. ELSE
  3332. ALLOCATE( FIELD(1,1,1) )
  3333. END IF
  3334. ! Read/write on root
  3335. IOroot : IF (isRoot) THEN
  3336. ! safety check
  3337. if ( data1_t2 /= data1_t1 ) then
  3338. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  3339. call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
  3340. call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
  3341. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  3342. call goErr; status=1; return
  3343. end if
  3344. ! surface pressure
  3345. allocate( tmp_sp( is(1):is(2), js(1):js(2) ) )
  3346. ! fill data
  3347. call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  3348. data1_tref, data1_t1, data1_t2, &
  3349. lli, nuv, levi, nw, &
  3350. tmp_sp, FIELD, md%tmi1, status )
  3351. IF_NOTOK_RETURN(status=1)
  3352. ! write meteo file
  3353. if ( md%putout ) then
  3354. call WriteField( tmmd, md%destkey, &
  3355. md%tmi1, 'sp', trim(md%name), trim(md%unit), &
  3356. data1_tref, data1_t1, data1_t2, &
  3357. lli, nuv, levi, nw, &
  3358. tmp_sp, FIELD, status )
  3359. IF_NOTOK_RETURN(status=1)
  3360. end if
  3361. ! clear
  3362. deallocate( tmp_sp )
  3363. END IF IOroot
  3364. CALL SCATTER( dgrid(region), md%data1, FIELD, md%halo, status)
  3365. IF_NOTOK_RETURN(status=1)
  3366. DEALLOCATE( FIELD )
  3367. ! data array is filled now
  3368. md%filled1 = .true.
  3369. md%tr1(1) = data1_t1
  3370. md%tr1(2) = data1_t2
  3371. md%changed = .true.
  3372. else if ( data1_copy ) then
  3373. ! copy data from secondary array:
  3374. md%data1 = md%data2
  3375. ! data array is filled now:
  3376. md%filled1 = .true.
  3377. md%tr1(1) = data1_t1
  3378. md%tr1(2) = data1_t2
  3379. md%changed = .true.
  3380. end if
  3381. !--------------------------
  3382. ! read/write secondary field
  3383. !--------------------------
  3384. if ( data2_read ) then
  3385. ! Need whole region for I/O on root. Dummy else.
  3386. is = (/1,im(region)/)
  3387. js = (/1,jm(region)/)
  3388. IF (isRoot) THEN
  3389. ALLOCATE(field(im(region), jm(region), md%ls(1):md%ls(2)))
  3390. ELSE
  3391. ALLOCATE(field(1,1,1))
  3392. END IF
  3393. ! Read/write
  3394. IOroot2 : IF (isRoot) THEN
  3395. ! safety check ...
  3396. if ( data2_t2 /= data2_t1 ) then
  3397. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  3398. call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
  3399. call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
  3400. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  3401. call goErr; status=1; return
  3402. end if
  3403. ! surface pressure
  3404. allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
  3405. ! fill data
  3406. call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  3407. data2_tref, data2_t1, data2_t2, &
  3408. lli, nuv, levi, nw, &
  3409. tmp_sp, FIELD, md%tmi2, status )
  3410. IF_NOTOK_RETURN(status=1)
  3411. ! write meteofiles
  3412. if ( md%putout ) then
  3413. call WriteField( tmmd, md%destkey, &
  3414. md%tmi2, 'sp', trim(md%name), trim(md%unit), &
  3415. data2_tref, data2_t1, data2_t2, &
  3416. lli, nuv, levi, nw, &
  3417. tmp_sp, FIELD, status )
  3418. IF_NOTOK_RETURN(status=1)
  3419. end if
  3420. ! clear
  3421. deallocate( tmp_sp )
  3422. END IF IOroot2
  3423. CALL SCATTER( dgrid(region), md%data2, FIELD, md%halo, status)
  3424. IF_NOTOK_RETURN(status=1)
  3425. DEALLOCATE( FIELD )
  3426. ! data array is filled now
  3427. md%filled2 = .true.
  3428. md%tr2(1) = data2_t1
  3429. md%tr2(2) = data2_t2
  3430. else if ( data2_copy ) then
  3431. ! copy data from secondary array
  3432. md%data2 = md%data1
  3433. ! data array is filled now
  3434. md%filled2 = .true.
  3435. md%tr2(1) = data2_t1
  3436. md%tr2(2) = data2_t2
  3437. end if
  3438. ! -------------------------
  3439. ! time interpolation
  3440. ! -------------------------
  3441. call TimeInterpolation( md, tr, status )
  3442. IF_NOTOK_RETURN(status=1)
  3443. ! -------------------------
  3444. ! done
  3445. ! -------------------------
  3446. status = 0
  3447. call goLabel()
  3448. END SUBROUTINE SETUP_3D_SERIAL
  3449. !EOC
  3450. !--------------------------------------------------------------------------
  3451. ! TM5 !
  3452. !--------------------------------------------------------------------------
  3453. !BOP
  3454. !
  3455. ! !IROUTINE: SETUP_3D_PARA
  3456. !
  3457. ! !DESCRIPTION: same as SETUP_3D_SERIAL, except reading is done by every processes.
  3458. !\\
  3459. !\\
  3460. ! !INTERFACE:
  3461. !
  3462. SUBROUTINE SETUP_3D_PARA( region, md, tr, nuv, levi, nw, status )
  3463. !
  3464. ! !USES:
  3465. !
  3466. use GO, only : TDate, wrtgol, operator(/=)
  3467. use Grid, only : TllGridInfo, TLevelInfo
  3468. use TMM, only : TMeteoInfo, ReadField, WriteField
  3469. use meteodata, only : TMeteoData, TimeInterpolation
  3470. use dims, only : im, jm
  3471. !
  3472. ! !INPUT/OUTPUT PARAMETERS:
  3473. !
  3474. type(TMeteoData), intent(inout) :: md ! met field
  3475. !
  3476. ! !INPUT PARAMETERS:
  3477. !
  3478. integer, intent(in) :: region ! region number
  3479. type(TDate), intent(in) :: tr(2) ! dates
  3480. character(len=1), intent(in) :: nuv ! horiz. staggering
  3481. type(TLevelInfo), intent(in) :: levi ! levels
  3482. character(len=1), intent(in) :: nw ! vertical staggering
  3483. !
  3484. ! !OUTPUT PARAMETERS:
  3485. !
  3486. integer, intent(out) :: status ! return code
  3487. !
  3488. ! !REVISION HISTORY:
  3489. ! 18 Oct 2013 - Ph. Le Sager - v0
  3490. !
  3491. !EOP
  3492. !------------------------------------------------------------------------
  3493. !BOC
  3494. character(len=*), parameter :: rname = mname//'/Setup_3d_para'
  3495. logical :: data1_read, data1_copy
  3496. type(TDate) :: data1_tref, data1_t1, data1_t2
  3497. logical :: data2_read, data2_copy
  3498. type(TDate) :: data2_tref, data2_t1, data2_t2
  3499. integer :: i1, i2, j1, j2
  3500. real, allocatable :: tmp_sp(:,:)
  3501. real, pointer :: field(:,:,:) ! work array
  3502. ! --- begin -----------------------------
  3503. call goLabel(rname)
  3504. ! leave if not in use:
  3505. if ( .not. md%used ) then
  3506. call goLabel()
  3507. status=0; return
  3508. end if
  3509. ! not changed by default
  3510. md%changed = .false.
  3511. !------------------
  3512. ! time stuff
  3513. !------------------
  3514. ! get time interval of met field and check if data from start and/or end
  3515. ! of interval must be read or copy
  3516. call SetupSetup( md, tr, &
  3517. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  3518. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  3519. status )
  3520. IF_NOTOK_RETURN(status=1)
  3521. ! -------------------------
  3522. ! Read/write primary field
  3523. ! -------------------------
  3524. if ( data1_read ) then
  3525. ! could get those bounds from md% directly
  3526. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3527. allocate( field( i1:i2, j1:j2, md%ls(1):md%ls(2)))
  3528. ! safety check
  3529. if ( data1_t2 /= data1_t1 ) then
  3530. ! write (gol,'("not sure that this routine is correct for time intervals:")') ; call goErr
  3531. ! call wrtgol( ' data1_t1 : ', data1_t1 ) ; call goErr
  3532. ! call wrtgol( ' data1_t2 : ', data1_t2 ) ; call goErr
  3533. ! write (gol,'("please decide what to do with surface pressures ... ")') ; call goErr
  3534. ! TRACEBACK; status=1; return
  3535. write (gol,'("WARNING - using instant surface pressure for regridding temporal averaged 3D field ...")'); call goPr
  3536. end if
  3537. ! surface pressure
  3538. allocate( tmp_sp( i1:i2, j1:j2 ) )
  3539. ! read data
  3540. call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  3541. data1_tref, data1_t1, data1_t2, &
  3542. lli(region), nuv, levi, nw, &
  3543. tmp_sp, FIELD, md%tmi1, status )
  3544. IF_NOTOK_RETURN(status=1)
  3545. md%data1(i1:i2, j1:j2, md%ls(1):md%ls(2)) = field
  3546. ! write meteo file
  3547. if ( md%putout ) then
  3548. write(gol,*)"writing of remapped met field not finished yet.. Sorry." ; call goErr
  3549. TRACEBACK; status=1; return
  3550. endif
  3551. DEALLOCATE( TMP_SP )
  3552. DEALLOCATE( FIELD )
  3553. ! data array is filled now
  3554. md%filled1 = .true.
  3555. md%tr1(1) = data1_t1
  3556. md%tr1(2) = data1_t2
  3557. md%changed = .true.
  3558. else if ( data1_copy ) then
  3559. ! copy data from secondary array:
  3560. md%data1 = md%data2
  3561. ! data array is filled now:
  3562. md%filled1 = .true.
  3563. md%tr1(1) = data1_t1
  3564. md%tr1(2) = data1_t2
  3565. md%changed = .true.
  3566. end if
  3567. !--------------------------
  3568. ! read/write secondary field
  3569. !--------------------------
  3570. if ( data2_read ) then
  3571. ! could get those bounds from md% directly
  3572. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3573. allocate( field( i1:i2, j1:j2, md%ls(1):md%ls(2)))
  3574. ! safety check ...
  3575. if ( data2_t2 /= data2_t1 ) then
  3576. write (gol,'("not sure that this routine is correct for time intervals:")') ; call goErr
  3577. call wrtgol( ' data2_t1 : ', data2_t1 ) ; call goErr
  3578. call wrtgol( ' data2_t2 : ', data2_t2 ) ; call goErr
  3579. write (gol,'("please decide what to do with surface pressures ... ")') ; call goErr
  3580. TRACEBACK; status=1; return
  3581. end if
  3582. ! surface pressure
  3583. allocate( tmp_sp( i1:i2, j1:j2 ) )
  3584. ! read data
  3585. call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
  3586. data2_tref, data2_t1, data2_t2, &
  3587. lli(region), nuv, levi, nw, &
  3588. tmp_sp, FIELD, md%tmi2, status )
  3589. IF_NOTOK_RETURN(status=1)
  3590. md%data2(i1:i2, j1:j2, md%ls(1):md%ls(2)) = field
  3591. ! write meteofiles
  3592. if ( md%putout ) then
  3593. write(gol,*)"writing of remapped met field not finished yet.. Sorry. SKIPPED." ; call goErr
  3594. TRACEBACK; status=1; return
  3595. end if
  3596. ! clear
  3597. DEALLOCATE( TMP_SP )
  3598. DEALLOCATE( FIELD )
  3599. ! data array is filled now
  3600. md%filled2 = .true.
  3601. md%tr2(1) = data2_t1
  3602. md%tr2(2) = data2_t2
  3603. else if ( data2_copy ) then
  3604. ! copy data from secondary array
  3605. md%data2 = md%data1
  3606. ! data array is filled now
  3607. md%filled2 = .true.
  3608. md%tr2(1) = data2_t1
  3609. md%tr2(2) = data2_t2
  3610. end if
  3611. ! -------------------------
  3612. ! time interpolation
  3613. ! -------------------------
  3614. call TimeInterpolation( md, tr, status )
  3615. IF_NOTOK_RETURN(status=1)
  3616. ! -------------------------
  3617. ! done
  3618. ! -------------------------
  3619. status = 0
  3620. call goLabel()
  3621. END SUBROUTINE SETUP_3D_PARA
  3622. !EOC
  3623. ! **************************************************************
  3624. ! ***
  3625. ! *** Specific SETUP routines for MASS FLUXES - Only serial case
  3626. ! *** since it reads spectral fields from IFS
  3627. ! ***
  3628. ! **************************************************************
  3629. SUBROUTINE SETUP_UVW( region, md_mfu, md_mfv, md_mfw, md_tsp, tr, lli, nuv, levi, nw, status )
  3630. ! Set up MFU and MFV (horizontal fluxes)
  3631. ! Set up MFW (vertical flux) and TSP (tendency surface pressure)
  3632. ! Read or copy %data1 and %data2, and get %data through time interpolation
  3633. use GO, only : TDate, wrtgol, operator(/=)
  3634. use Grid, only : TllGridInfo, TLevelInfo
  3635. use TMM, only : TMeteoInfo, TMM_Read_UVW, WriteField
  3636. use meteodata, only : TMeteoData, TimeInterpolation
  3637. use dims, only : im, jm
  3638. ! --- in/out ----------------------------------
  3639. integer, intent(in) :: region ! region number
  3640. type(TMeteoData), intent(inout) :: md_mfu
  3641. type(TMeteoData), intent(inout) :: md_mfv
  3642. type(TMeteoData), intent(inout) :: md_mfw
  3643. type(TMeteoData), intent(inout) :: md_tsp
  3644. type(TDate), intent(in) :: tr(2) ! time range
  3645. type(TllGridInfo), intent(in) :: lli
  3646. character(len=1), intent(in) :: nuv
  3647. type(TLevelInfo), intent(in) :: levi
  3648. character(len=1), intent(in) :: nw
  3649. integer, intent(out) :: status
  3650. ! --- const --------------------------------------
  3651. character(len=*), parameter :: rname = mname//'/Setup_UVW'
  3652. ! --- local ----------------------------------
  3653. logical :: data1_read, data1_copy
  3654. type(TDate) :: data1_tref, data1_t1, data1_t2
  3655. logical :: data2_read, data2_copy
  3656. type(TDate) :: data2_tref, data2_t1, data2_t2
  3657. logical :: NorthBorder, WestBorder ! tile location
  3658. real, allocatable :: tmp_spu(:,:)
  3659. real, allocatable :: tmp_spv(:,:)
  3660. real, allocatable :: tmp_sp(:,:)
  3661. ! to read the entire region
  3662. real, pointer :: wrld_u(:,:,:), wrld_v(:,:,:), wrkarr(:,:,:)
  3663. real, pointer :: mfw(:,:,:), tsp(:,:) ! work arrays (data)
  3664. integer, dimension(2) :: is, js, ls
  3665. integer :: halo, i1, i2, j1, j2
  3666. real, allocatable :: bigIslice(:,:), bigJslice(:,:), Islice(:,:), Jslice(:,:)
  3667. ! --- begin -----------------------------
  3668. call goLabel(rname)
  3669. ! leave if not in use:
  3670. if ( md_mfu%used .neqv. md_mfv%used ) then
  3671. write (gol,'("either none or both mfu and mfv should be in use")'); call goErr
  3672. call goErr; status=1; return
  3673. end if
  3674. if ( .not. md_mfu%used ) then
  3675. call goLabel()
  3676. status=0; return
  3677. end if
  3678. if (okdebug) then
  3679. write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md_mfu%name),trim(lli%name); call goPr
  3680. write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md_mfv%name),trim(lli%name); call goPr
  3681. write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md_mfw%name),trim(lli%name); call goPr
  3682. endif
  3683. ! not changed by default
  3684. md_mfu%changed = .false.
  3685. md_mfv%changed = .false.
  3686. md_mfw%changed = .false.
  3687. md_tsp%changed = .false.
  3688. ! local indices and tile location
  3689. CALL GET_DISTGRID( dgrid(region), &
  3690. I_STRT=i1, I_STOP=i2, &
  3691. J_STRT=j1, J_STOP=j2, &
  3692. hasWestBorder=WestBorder, hasNorthBorder=NorthBorder)
  3693. !------------------
  3694. ! time stuff
  3695. !------------------
  3696. ! get time interval of met field and check if data from start and/or end
  3697. ! of interval must be read (sufficient to setup from mfu only)
  3698. call SetupSetup( md_mfu, tr, &
  3699. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  3700. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  3701. status )
  3702. IF_NOTOK_RETURN(status=1)
  3703. !--------------------------
  3704. ! read/write primary field
  3705. !--------------------------
  3706. if ( data1_read ) then
  3707. ! Use fact that mfu and mfv have been allocated with the same bounds and halo
  3708. ! Need whole region for I/O on root. Dummy else.
  3709. is = (/1,im(region)/)
  3710. js = (/1,jm(region)/)
  3711. ls = md_mfu%ls
  3712. halo = md_mfu%halo
  3713. IF (isRoot) THEN
  3714. ALLOCATE( wrld_u( is(1)-halo:is(2)+halo, js(1)-halo:js(2)+halo, ls(1):ls(2)) )
  3715. ALLOCATE( wrld_v( is(1)-halo:is(2)+halo, js(1)-halo:js(2)+halo, ls(1):ls(2)) )
  3716. ALLOCATE( wrkarr( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  3717. wrld_v = 0.
  3718. wrld_u = 0.
  3719. allocate( bigIslice(jm(region),ls(1):ls(2)))
  3720. allocate( bigJslice(im(region),ls(1):ls(2)))
  3721. allocate( mfw(is(1):is(2), js(1):js(2), ls(1):ls(2) ))
  3722. allocate( tsp(is(1):is(2), js(1):js(2)) )
  3723. ELSE
  3724. ALLOCATE(wrld_u(1,1,1), wrld_v(1,1,1), wrkarr(1,1,1))
  3725. ALLOCATE( bigIslice(1,1), bigJslice(1,1) )
  3726. allocate( mfw(1,1,1), tsp(1,1) )
  3727. END IF
  3728. ALLOCATE( Islice(j1:j2,ls(1):ls(2)) )
  3729. ALLOCATE( Jslice(i1:i2,ls(1):ls(2)) )
  3730. if (isRoot) then ! only root does IO
  3731. ! safety check ...
  3732. if ( data1_t2 /= data1_t1 ) then
  3733. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  3734. call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
  3735. call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
  3736. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  3737. call goErr; status=1; return
  3738. end if
  3739. ! surface pressure field:
  3740. allocate( tmp_spu(is(1)-1:is(2), js(1):js(2) ) )
  3741. allocate( tmp_spv( is(1):is(2), js(1):js(2)+1) )
  3742. allocate( tmp_sp ( is(1):is(2), js(1):js(2) ) )
  3743. ! NOTE: strange old indexing:
  3744. ! pu_tmpp --> pu(0:imr,1:jmr ,1:lmr) in pu_t(0:imr+1,0:jmr+1,0:lmr)
  3745. ! pv_tmpp --> pv(1:imr,1:jmr+1,1:lmr) in pv_t(0:imr+1,0:jmr+1,0:lmr)
  3746. ! fill data:
  3747. call TMM_READ_UVW( tmmd, md_mfu%sourcekey, &
  3748. data1_tref, data1_t1, data1_t2, lli, levi, &
  3749. tmp_spu, &
  3750. wrld_u( is(1)-1:is(2), js(1):js(2), ls(1)+1:ls(2) ), &
  3751. md_mfu%tmi1, &
  3752. tmp_spv, &
  3753. wrld_v( is(1):is(2), js(1):js(2)+1, ls(1)+1:ls(2) ), &
  3754. md_mfv%tmi1, &
  3755. tmp_sp, mfw, &
  3756. tsp, &
  3757. md_mfw%tmi1, status )
  3758. IF_NOTOK_RETURN(status=1)
  3759. ! write meteofiles
  3760. if ( md_mfu%putout ) then
  3761. call WriteField( tmmd, md_mfu%destkey, &
  3762. md_mfu%tmi1, 'spu', trim(md_mfu%name), trim(md_mfu%unit), &
  3763. data1_tref, data1_t1, data1_t2, &
  3764. lli, 'u', levi, 'n', &
  3765. tmp_spu, wrld_u(is(1)-1:is(2), js(1):js(2), ls(1)+1:ls(2) ), &
  3766. status )
  3767. IF_NOTOK_RETURN(status=1)
  3768. end if
  3769. if ( md_mfv%putout ) then
  3770. call WriteField( tmmd, md_mfv%destkey, &
  3771. md_mfv%tmi1, 'spv', trim(md_mfv%name), trim(md_mfv%unit), &
  3772. data1_tref, data1_t1, data1_t2, &
  3773. lli, 'v', levi, 'n', &
  3774. tmp_spv, wrld_v(is(1):is(2), js(1):js(2)+1, ls(1)+1:ls(2) ), &
  3775. status )
  3776. IF_NOTOK_RETURN(status=1)
  3777. end if
  3778. if ( md_mfw%putout ) then
  3779. call WriteField( tmmd, md_mfw%destkey, &
  3780. md_mfw%tmi1, 'sp', trim(md_mfw%name), trim(md_mfw%unit), &
  3781. data1_tref, data1_t1, data1_t2, &
  3782. lli, nuv, levi, nw, &
  3783. tmp_sp, mfw, status )
  3784. IF_NOTOK_RETURN(status=1)
  3785. end if
  3786. if ( md_tsp%putout ) then
  3787. ! use history from mfw ...
  3788. call WriteField( tmmd, md_tsp%destkey, &
  3789. md_mfw%tmi1, trim(md_tsp%name), trim(md_tsp%unit), &
  3790. data1_tref, data1_t1, data1_t2, &
  3791. lli, nuv, tsp, status )
  3792. IF_NOTOK_RETURN(status=1)
  3793. end if
  3794. ! clear
  3795. deallocate( tmp_spu )
  3796. deallocate( tmp_spv )
  3797. deallocate( tmp_sp )
  3798. end if ! root ?
  3799. ! Scatter U
  3800. if(isRoot) wrkarr = wrld_u(is(1):is(2),js(1):js(2),:)
  3801. CALL SCATTER( dgrid(region), md_mfu%data1, wrkarr, md_mfu%halo, status)
  3802. IF_NOTOK_RETURN(status=1)
  3803. ! manually scatter wrld_u(is(1)-1,:,:). This is needed only with non-cyclic
  3804. ! zoom regions, since any update_halo will overwrite is(1)-1. [FIXME: could had a
  3805. ! test around these 3 lines ]
  3806. !PLS if(isRoot) bigIslice = wrld_u(0,js(1):js(2),:)
  3807. !PLS CALL SCATTER_I_BAND( dgrid(region), islice, bigIslice, status, iref=1)
  3808. !PLS if (WestBorder) md_mfu%data1(0,j1:j2,:) = islice
  3809. ! Scatter V
  3810. if(isRoot) wrkarr = wrld_v(is(1):is(2),js(1):js(2),:)
  3811. CALL SCATTER( dgrid(region), md_mfv%data1, wrkarr, md_mfv%halo, status)
  3812. IF_NOTOK_RETURN(status=1)
  3813. ! manually SCATTER wrld_v( :, js(2)+1 , :) : NORTH POLE HALO
  3814. if(isroot) bigJslice=wrld_v(is(1):is(2),jm(region)+1,:)
  3815. CALL SCATTER_J_BAND( dgrid(region), jslice, bigJslice, status, jref=jm(region))
  3816. if (NorthBorder) md_mfv%data1(i1:i2,jm(region)+1,:)=jslice
  3817. deallocate(wrld_u, wrld_v, wrkarr, bigIslice, bigJslice, Islice, Jslice)
  3818. ! Scatter W
  3819. CALL SCATTER( dgrid(region), md_mfw%data1, MFW, md_mfw%halo, status)
  3820. IF_NOTOK_RETURN(status=1)
  3821. CALL SCATTER( dgrid(region), md_tsp%data1(:,:,1), TSP, md_tsp%halo, status)
  3822. IF_NOTOK_RETURN(status=1)
  3823. DEALLOCATE(MFW, TSP)
  3824. ! data array is filled now
  3825. md_mfu%filled1 = .true.
  3826. md_mfu%tr1(1) = data1_t1
  3827. md_mfu%tr1(2) = data1_t2
  3828. md_mfu%changed = .true.
  3829. md_mfv%filled1 = .true.
  3830. md_mfv%tr1(1) = data1_t1
  3831. md_mfv%tr1(2) = data1_t2
  3832. md_mfv%changed = .true.
  3833. md_mfw%filled1 = .true.
  3834. md_mfw%tr1(1) = data1_t1
  3835. md_mfw%tr1(2) = data1_t2
  3836. md_mfw%changed = .true.
  3837. md_tsp%filled1 = .true.
  3838. md_tsp%tr1(1) = data1_t1
  3839. md_tsp%tr1(2) = data1_t2
  3840. md_tsp%changed = .true.
  3841. else if ( data1_copy ) then
  3842. ! copy data from secondary array:
  3843. md_mfu%data1 = md_mfu%data2
  3844. md_mfv%data1 = md_mfv%data2
  3845. md_mfw%data1 = md_mfw%data2
  3846. ! data array is filled now:
  3847. md_mfu%filled1 = .true.
  3848. md_mfu%tr1(1) = data1_t1
  3849. md_mfu%tr1(2) = data1_t2
  3850. md_mfu%changed = .true.
  3851. md_mfv%filled1 = .true.
  3852. md_mfv%tr1(1) = data1_t1
  3853. md_mfv%tr1(2) = data1_t2
  3854. md_mfv%changed = .true.
  3855. md_mfw%filled1 = .true.
  3856. md_mfw%tr1(1) = data1_t1
  3857. md_mfw%tr1(2) = data1_t2
  3858. md_mfw%changed = .true.
  3859. md_tsp%filled1 = .true.
  3860. md_tsp%tr1(1) = data1_t1
  3861. md_tsp%tr1(2) = data1_t2
  3862. md_tsp%changed = .true.
  3863. end if
  3864. !--------------------------
  3865. ! read/write secondary field
  3866. !--------------------------
  3867. if ( data2_read ) then
  3868. ! Need whole region for I/O on root. Dummy else.
  3869. is = (/1,im(region)/)
  3870. js = (/1,jm(region)/)
  3871. ls = md_mfu%ls
  3872. halo = md_mfu%halo
  3873. IF (isRoot) THEN
  3874. allocate( wrld_u( is(1)-halo:is(2)+halo, js(1)-halo:js(2)+halo, ls(1):ls(2)) )
  3875. allocate( wrld_v( is(1)-halo:is(2)+halo, js(1)-halo:js(2)+halo, ls(1):ls(2)) )
  3876. allocate( wrkarr( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  3877. wrld_v = 0.
  3878. wrld_u = 0.
  3879. allocate( bigIslice(jm(region),ls(1):ls(2)))
  3880. allocate( bigJslice(im(region),ls(1):ls(2)))
  3881. allocate( mfw(is(1):is(2), js(1):js(2), ls(1):ls(2) ))
  3882. allocate( tsp(is(1):is(2), js(1):js(2)) )
  3883. ELSE
  3884. ALLOCATE(wrld_u(1,1,1), wrld_v(1,1,1), wrkarr(1,1,1))
  3885. ALLOCATE( bigIslice(1,1), bigJslice(1,1) )
  3886. allocate( mfw(1,1,1), tsp(1,1) )
  3887. END IF
  3888. ALLOCATE( Islice(j1:j2,ls(1):ls(2)) )
  3889. ALLOCATE( Jslice(i1:i2,ls(1):ls(2)) )
  3890. if (isRoot) then ! only root does IO
  3891. if ( data2_t2 /= data2_t1 ) then
  3892. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  3893. call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
  3894. call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
  3895. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  3896. call goErr; status=1; return
  3897. end if
  3898. ! surface pressure field:
  3899. allocate( tmp_spu(is(1)-1:is(2), js(1):js(2) ) )
  3900. allocate( tmp_spv( is(1):is(2), js(1):js(2)+1) )
  3901. allocate( tmp_sp ( is(1):is(2), js(1):js(2) ) )
  3902. ! NOTE: strange old indexing:
  3903. ! pu_tmpp --> pu(0:imr,1:jmr ,1:lmr) in pu_t(0:imr+1,0:jmr+1,0:lmr)
  3904. ! pv_tmpp --> pv(1:imr,1:jmr+1,1:lmr) in pv_t(0:imr+1,0:jmr+1,0:lmr)
  3905. ! fill data:
  3906. call TMM_READ_UVW( tmmd, md_mfu%sourcekey, &
  3907. data2_tref, data2_t1, data2_t2, lli, levi, &
  3908. tmp_spu, &
  3909. wrld_u( is(1)-1:is(2), js(1):js(2), ls(1)+1:ls(2) ), &
  3910. md_mfu%tmi2, &
  3911. tmp_spv, &
  3912. wrld_v( is(1):is(2), js(1):js(2)+1, ls(1)+1:ls(2) ), &
  3913. md_mfv%tmi2, &
  3914. tmp_sp, MFW, TSP, md_mfw%tmi2, status )
  3915. IF_NOTOK_RETURN(status=1)
  3916. ! write meteofiles
  3917. if ( md_mfu%putout ) then
  3918. call WriteField( tmmd, md_mfu%destkey, &
  3919. md_mfu%tmi2, 'spu', trim(md_mfu%name), trim(md_mfu%unit), &
  3920. data2_tref, data2_t1, data2_t2, &
  3921. lli, 'u', levi, 'n', &
  3922. tmp_spu, wrld_u( is(1)-1:is(2), js(1):js(2), ls(1)+1:ls(2) ), &
  3923. status )
  3924. IF_NOTOK_RETURN(status=1)
  3925. endif
  3926. if ( md_mfv%putout ) then
  3927. call WriteField( tmmd, md_mfv%destkey, &
  3928. md_mfv%tmi2, 'spv', trim(md_mfv%name), trim(md_mfv%unit), &
  3929. data2_tref, data2_t1, data2_t2, &
  3930. lli, 'v', levi, 'n', &
  3931. tmp_spv, wrld_v( is(1):is(2), js(1):js(2)+1, ls(1)+1:ls(2) ), &
  3932. status )
  3933. IF_NOTOK_RETURN(status=1)
  3934. end if
  3935. if ( md_mfw%putout ) then
  3936. call WriteField( tmmd, md_mfw%destkey, &
  3937. md_mfw%tmi2, 'sp', trim(md_mfw%name), trim(md_mfw%unit), &
  3938. data2_tref, data2_t1, data2_t2, &
  3939. lli, nuv, levi, nw, &
  3940. tmp_sp, MFW, status )
  3941. IF_NOTOK_RETURN(status=1)
  3942. end if
  3943. if ( md_tsp%putout ) then
  3944. ! use history from mfw ...
  3945. call WriteField( tmmd, md_tsp%destkey, &
  3946. md_mfw%tmi2, trim(md_tsp%name), trim(md_tsp%unit), &
  3947. data2_tref, data2_t1, data2_t2, &
  3948. lli, nuv, TSP, status )
  3949. IF_NOTOK_RETURN(status=1)
  3950. end if
  3951. ! clear
  3952. deallocate( tmp_spu )
  3953. deallocate( tmp_spv )
  3954. deallocate( tmp_sp )
  3955. end if ! root
  3956. ! Scatter U
  3957. if(isRoot) wrkarr = wrld_u(is(1):is(2),js(1):js(2),:)
  3958. CALL SCATTER( dgrid(region), md_mfu%data2, wrkarr, md_mfu%halo, status)
  3959. IF_NOTOK_RETURN(status=1)
  3960. ! important for zoom regions only, since any update_halo will overwrite is(1)-1. [FIXME: could had a
  3961. ! test around these 3 lines ]
  3962. !PLS if(isRoot) bigIslice = wrld_u(0,js(1):js(2),:)
  3963. !PLS CALL SCATTER_I_BAND( dgrid(region), islice, bigIslice, status, iref=1)
  3964. !PLS if (WestBorder) md_mfu%data2(0,j1:j2,:) = islice
  3965. ! Scatter V
  3966. if(isRoot) wrkarr = wrld_v(is(1):is(2),js(1):js(2),:)
  3967. CALL SCATTER( dgrid(region), md_mfv%data2, wrkarr, md_mfv%halo, status)
  3968. IF_NOTOK_RETURN(status=1)
  3969. ! manually SCATTER wrld_v( :, js(2)+1 , :) : NORTH POLE HALO
  3970. if(isroot) bigJslice=wrld_v(is(1):is(2),jm(region)+1,:)
  3971. CALL SCATTER_J_BAND( dgrid(region), jslice, bigJslice, status, jref=jm(region))
  3972. if (NorthBorder) md_mfv%data2(i1:i2,jm(region)+1,:)=jslice
  3973. DEALLOCATE(wrld_u, wrld_v, wrkarr, bigIslice, bigJslice, Islice, Jslice)
  3974. ! Scatter W
  3975. CALL SCATTER( dgrid(region), md_mfw%data2, MFW, md_mfw%halo, status)
  3976. IF_NOTOK_RETURN(status=1)
  3977. CALL SCATTER( dgrid(region), md_tsp%data2(:,:,1), TSP, md_tsp%halo, status)
  3978. IF_NOTOK_RETURN(status=1)
  3979. DEALLOCATE(MFW, TSP)
  3980. ! data array is filled now:
  3981. md_mfu%filled2 = .true.
  3982. md_mfu%tr2(1) = data2_t1
  3983. md_mfu%tr2(2) = data2_t2
  3984. md_mfv%filled2 = .true.
  3985. md_mfv%tr2(1) = data2_t1
  3986. md_mfv%tr2(2) = data2_t2
  3987. md_mfw%filled2 = .true.
  3988. md_mfw%tr2(1) = data2_t1
  3989. md_mfw%tr2(2) = data2_t2
  3990. md_tsp%filled2 = .true.
  3991. md_tsp%tr2(1) = data2_t1
  3992. md_tsp%tr2(2) = data2_t2
  3993. else if ( data2_copy ) then
  3994. ! copy data from primary array:
  3995. md_mfu%data2 = md_mfu%data
  3996. md_mfv%data2 = md_mfv%data
  3997. md_mfw%data2 = md_mfw%data1
  3998. ! data array is filled now:
  3999. md_mfu%filled2 = .true.
  4000. md_mfu%tr2(1) = data2_t1
  4001. md_mfu%tr2(2) = data2_t2
  4002. md_mfv%filled2 = .true.
  4003. md_mfv%tr2(1) = data2_t1
  4004. md_mfv%tr2(2) = data2_t2
  4005. md_mfw%filled2 = .true.
  4006. md_mfw%tr2(1) = data2_t1
  4007. md_mfw%tr2(2) = data2_t2
  4008. md_tsp%filled2 = .true.
  4009. md_tsp%tr2(1) = data2_t1
  4010. md_tsp%tr2(2) = data2_t2
  4011. end if
  4012. !------------------
  4013. ! time interpolation
  4014. !------------------
  4015. call TimeInterpolation( md_mfu, tr, status )
  4016. IF_NOTOK_RETURN(status=1)
  4017. call TimeInterpolation( md_mfv, tr, status )
  4018. IF_NOTOK_RETURN(status=1)
  4019. call TimeInterpolation( md_mfw, tr, status )
  4020. IF_NOTOK_RETURN(status=1)
  4021. call TimeInterpolation( md_tsp, tr, status )
  4022. IF_NOTOK_RETURN(status=1)
  4023. !------------------
  4024. ! done
  4025. !------------------
  4026. status = 0
  4027. call goLabel()
  4028. end subroutine SETUP_UVW
  4029. ! **************************************************************
  4030. ! ***
  4031. ! *** temperature and humidity
  4032. ! ***
  4033. ! **************************************************************
  4034. subroutine Setup_TQ( region, md_T, md_Q, tr, lli, levi, status)
  4035. use GO, only : TDate, wrtgol, operator(/=)
  4036. use Grid, only : TllGridInfo, TLevelInfo
  4037. use TMM, only : TMeteoInfo, Read_TQ, WriteField
  4038. use meteodata, only : TMeteoData, TimeInterpolation
  4039. use dims, only : im, jm
  4040. ! --- in/out ----------------------------------
  4041. integer, intent(in) :: region ! region number
  4042. type(TMeteoData), intent(inout) :: md_T
  4043. type(TMeteoData), intent(inout) :: md_Q
  4044. type(TDate), intent(in) :: tr(2)
  4045. type(TllGridInfo), intent(in) :: lli
  4046. type(TLevelInfo), intent(in) :: levi
  4047. integer, intent(out) :: status
  4048. ! --- const --------------------------------------
  4049. character(len=*), parameter :: rname = mname//'/Setup_TQ'
  4050. ! --- local ----------------------------------
  4051. logical :: data1_read, data1_copy
  4052. type(TDate) :: data1_tref, data1_t1, data1_t2
  4053. logical :: data2_read, data2_copy
  4054. type(TDate) :: data2_tref, data2_t1, data2_t2
  4055. real, allocatable :: tmp_sp(:,:)
  4056. real, pointer :: T(:,:,:), Q(:,:,:) ! work array
  4057. integer :: is(2), js(2) ! work arrays (bounds)
  4058. ! --- begin -----------------------------
  4059. call goLabel(rname)
  4060. ! leave if not in use:
  4061. if ( md_T%used .neqv. md_Q%used ) then
  4062. write (gol,'("either none or both T and Q should be in use")'); call goErr
  4063. call goErr; status=1; return
  4064. end if
  4065. if ( .not. md_T%used ) then
  4066. call goLabel()
  4067. status=0; return
  4068. end if
  4069. ! not changed by default
  4070. md_T%changed = .false.
  4071. md_Q%changed = .false.
  4072. !------------------
  4073. ! time stuff
  4074. !------------------
  4075. ! get time interval of met field and check if data from start and/or end
  4076. ! of interval must be read (sufficient to setup from T only)
  4077. call SetupSetup( md_T, tr, &
  4078. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  4079. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  4080. status )
  4081. IF_NOTOK_RETURN(status=1)
  4082. !--------------------------
  4083. ! read/write primary field
  4084. !--------------------------
  4085. if ( data1_read ) then
  4086. ! Need whole region for I/O on root. Dummy else.
  4087. is = (/1,im(region)/)
  4088. js = (/1,jm(region)/)
  4089. IF (isRoot) THEN
  4090. ALLOCATE( T(is(1):is(2), js(1):js(2), md_T%ls(1):md_T%ls(2) ))
  4091. ALLOCATE( Q(is(1):is(2), js(1):js(2), md_Q%ls(1):md_Q%ls(2) ))
  4092. ELSE
  4093. ALLOCATE( T(1,1,1), Q(1,1,1) )
  4094. END IF
  4095. if (isRoot) then ! only root does IO
  4096. ! safety check ...
  4097. if ( data1_t2 /= data1_t1 ) then
  4098. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  4099. call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
  4100. call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
  4101. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  4102. call goErr; status=1; return
  4103. end if
  4104. ! surface pressure field:
  4105. allocate( tmp_sp( is(1):is(2), js(1):js(2) ) )
  4106. ! fill data:
  4107. call Read_TQ( tmmd, md_T%sourcekey, md_Q%sourcekey, &
  4108. data1_tref, data1_t1, data1_t2, lli, levi, &
  4109. tmp_sp, &
  4110. T, md_T%tmi1, &
  4111. Q, md_Q%tmi1, status )
  4112. IF_NOTOK_RETURN(status=1)
  4113. ! write meteofiles ?
  4114. if ( md_T%putout ) then
  4115. call WriteField( tmmd, md_T%destkey, &
  4116. md_T%tmi1, 'sp', trim(md_T%name), trim(md_T%unit), &
  4117. data1_tref, data1_t1, data1_t2, &
  4118. lli, 'n', levi, 'n', &
  4119. tmp_sp, T, status )
  4120. IF_NOTOK_RETURN(status=1)
  4121. end if
  4122. if ( md_Q%putout ) then
  4123. call WriteField( tmmd, md_Q%destkey, &
  4124. md_Q%tmi1, 'sp', trim(md_Q%name), trim(md_Q%unit), &
  4125. data1_tref, data1_t1, data1_t2, &
  4126. lli, 'n', levi, 'n', &
  4127. tmp_sp, Q, status )
  4128. IF_NOTOK_RETURN(status=1)
  4129. end if
  4130. ! clear
  4131. deallocate( tmp_sp )
  4132. end if ! root ?
  4133. ! Distribute
  4134. CALL SCATTER( dgrid(region), md_T%data1, T, md_T%halo, status)
  4135. IF_NOTOK_RETURN(status=1)
  4136. CALL SCATTER( dgrid(region), md_Q%data1, Q, md_Q%halo, status)
  4137. IF_NOTOK_RETURN(status=1)
  4138. DEALLOCATE(T, Q)
  4139. ! data array is filled now:
  4140. md_T%filled1 = .true.
  4141. md_T%tr1(1) = data1_t1
  4142. md_T%tr1(2) = data1_t2
  4143. md_T%changed = .true.
  4144. md_Q%filled1 = .true.
  4145. md_Q%tr1(1) = data1_t1
  4146. md_Q%tr1(2) = data1_t2
  4147. md_Q%changed = .true.
  4148. else if ( data1_copy ) then
  4149. ! copy data from secondary array:
  4150. md_T%data1 = md_T%data2
  4151. md_Q%data1 = md_Q%data2
  4152. ! data array is filled now:
  4153. md_T%filled1 = .true.
  4154. md_T%tr1(1) = data1_t1
  4155. md_T%tr1(2) = data1_t2
  4156. md_T%changed = .true.
  4157. md_Q%filled1 = .true.
  4158. md_Q%tr1(1) = data1_t1
  4159. md_Q%tr1(2) = data1_t2
  4160. md_Q%changed = .true.
  4161. end if
  4162. !--------------------------
  4163. ! read/write secondary field
  4164. !--------------------------
  4165. if ( data2_read ) then
  4166. ! Need whole region for I/O on root. Dummy else.
  4167. is = (/1,im(region)/)
  4168. js = (/1,jm(region)/)
  4169. IF (isRoot) THEN
  4170. allocate( T(is(1):is(2), js(1):js(2), md_T%ls(1):md_T%ls(2) ))
  4171. allocate( Q(is(1):is(2), js(1):js(2), md_Q%ls(1):md_Q%ls(2) ))
  4172. ELSE
  4173. allocate( T(1,1,1), Q(1,1,1) )
  4174. END IF
  4175. if (isRoot) then ! only root does IO
  4176. ! safety check ...
  4177. if ( data2_t2 /= data2_t1 ) then
  4178. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  4179. call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
  4180. call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
  4181. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  4182. call goErr; status=1; return
  4183. end if
  4184. ! surface pressure field:
  4185. allocate( tmp_sp( is(1):is(2), js(1):js(2)) )
  4186. ! fill data:
  4187. call Read_TQ( tmmd, md_T%sourcekey, md_Q%sourcekey, &
  4188. data2_tref, data2_t1, data2_t2, lli, levi, &
  4189. tmp_sp, &
  4190. T, md_T%tmi2, &
  4191. Q, md_Q%tmi2, status )
  4192. IF_NOTOK_RETURN(status=1)
  4193. ! write meteofiles ?
  4194. if ( md_T%putout ) then
  4195. call WriteField( tmmd, md_T%destkey, &
  4196. md_T%tmi2, 'sp', trim(md_T%name), trim(md_T%unit), &
  4197. data2_tref, data2_t1, data2_t2, &
  4198. lli, 'n', levi, 'n', &
  4199. tmp_sp, T, status )
  4200. IF_NOTOK_RETURN(status=1)
  4201. endif
  4202. if ( md_Q%putout ) then
  4203. call WriteField( tmmd, md_Q%destkey, &
  4204. md_Q%tmi2, 'sp', trim(md_Q%name), trim(md_Q%unit), &
  4205. data2_tref, data2_t1, data2_t2, &
  4206. lli, 'n', levi, 'n', &
  4207. tmp_sp, Q, status )
  4208. IF_NOTOK_RETURN(status=1)
  4209. end if
  4210. ! clear
  4211. deallocate( tmp_sp )
  4212. end if ! root
  4213. CALL SCATTER( dgrid(region), md_T%data2, T, md_T%halo, status)
  4214. IF_NOTOK_RETURN(status=1)
  4215. CALL SCATTER( dgrid(region), md_Q%data2, Q, md_Q%halo, status)
  4216. IF_NOTOK_RETURN(status=1)
  4217. DEALLOCATE(T, Q)
  4218. ! data array is filled now:
  4219. md_T%filled2 = .true.
  4220. md_T%tr2(1) = data2_t1
  4221. md_T%tr2(2) = data2_t2
  4222. md_Q%filled2 = .true.
  4223. md_Q%tr2(1) = data2_t1
  4224. md_Q%tr2(2) = data2_t2
  4225. else if ( data2_copy ) then
  4226. ! copy data from primary array:
  4227. md_T%data2 = md_T%data1
  4228. md_Q%data2 = md_Q%data1
  4229. ! data array is filled now:
  4230. md_T%filled2 = .true.
  4231. md_T%tr2(1) = data2_t1
  4232. md_T%tr2(2) = data2_t2
  4233. md_Q%filled2 = .true.
  4234. md_Q%tr2(1) = data2_t1
  4235. md_Q%tr2(2) = data2_t2
  4236. end if
  4237. !------------------
  4238. ! time interpolation
  4239. !------------------
  4240. call TimeInterpolation( md_T, tr, status )
  4241. IF_NOTOK_RETURN(status=1)
  4242. call TimeInterpolation( md_Q, tr, status )
  4243. IF_NOTOK_RETURN(status=1)
  4244. !------------------
  4245. ! done
  4246. !------------------
  4247. status = 0
  4248. call goLabel()
  4249. end subroutine Setup_TQ
  4250. !--------------------------------------------------------------------------
  4251. ! TM5 !
  4252. !--------------------------------------------------------------------------
  4253. !BOP
  4254. !
  4255. ! !IROUTINE: METEO_CHECKPRESSURE
  4256. !
  4257. ! !DESCRIPTION: Compute difference b/w sp1_dat (read) and sp_dat (advected),
  4258. ! and compare to threshold.
  4259. !\\
  4260. !\\
  4261. ! !INTERFACE:
  4262. !
  4263. SUBROUTINE METEO_CHECKPRESSURE( n, status )
  4264. !
  4265. ! !USES:
  4266. !
  4267. use ParTools, only : Par_Reduce
  4268. use dims, only : idate, newsrun
  4269. use dims, only : xcyc, im, jm
  4270. use redgridZoom, only : calc_pdiff
  4271. use io_hdf, only : io_write2d_32d, DFACC_CREATE
  4272. !
  4273. ! !INPUT PARAMETERS:
  4274. !
  4275. integer, intent(in) :: n ! region
  4276. !
  4277. ! !OUTPUT PARAMETERS:
  4278. !
  4279. integer, intent(out) :: status
  4280. !
  4281. ! !REVISION HISTORY:
  4282. ! 7 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  4283. !
  4284. ! !REMARKS:
  4285. !
  4286. !EOP
  4287. !------------------------------------------------------------------------
  4288. !BOC
  4289. character(len=*), parameter :: rname = mname//'/Meteo_CheckPressure'
  4290. ! maximum accepted pressure difference:
  4291. real, parameter :: pdiffmax_treshold = 1.0e2 ! Pa
  4292. ! --- external -------------------------
  4293. integer(4), external :: sfStart, sfEnd
  4294. ! --- local -----------------------------
  4295. real :: pdiffmax, pdiffmax_l
  4296. integer(4) :: io
  4297. ! --- begin ------------------------------
  4298. call goLabel(rname)
  4299. ! compare 'advected' pressure with read pressure
  4300. if ( .not. newsrun ) then
  4301. ! compute difference between 'advected' pressure sp and read pressure
  4302. ! sp1, accounting for reduce grid if any
  4303. call calc_pdiff( n, pdiffmax_l )
  4304. ! compute maximum over all pe's
  4305. call Par_Reduce( pdiffmax_l, 'max', pdiffmax, status, all=.true. )
  4306. IF_NOTOK_RETURN(status=1)
  4307. ! check ...
  4308. if ( pdiffmax > pdiffmax_treshold ) then
  4309. write (gol,'("difference between advected and read-in pressure exceeds treshold :")'); call goErr
  4310. write (gol,'(" max diff. : ",es9.2," [Pa]")') pdiffmax; call goErr
  4311. write (gol,'(" treshold : ",es9.2," [Pa]")') pdiffmax_treshold; call goErr
  4312. write (gol,'("pressure arrays saved to local `pressure.hdf`")'); call goErr
  4313. if (isRoot) then
  4314. io = sfStart( 'pressure.hdf', DFACC_CREATE )
  4315. if ( io > 0 ) then
  4316. call io_write2d_32d( io, im(n)+4, 'LON', jm(n)+4, 'LAT', sp1_dat(n)%data(:,:,1), 'p' , idate )
  4317. call io_write2d_32d( io, im(n)+4, 'LON', jm(n)+4, 'LAT', sp_dat(n)%data(:,:,1), 'pold', idate )
  4318. status = sfend(io)
  4319. else
  4320. write (gol,'("writing pressures")'); call goErr
  4321. end if
  4322. end if ! root
  4323. call goErr; status=1; return
  4324. end if ! max diff
  4325. end if ! no newsrun
  4326. ! ok
  4327. status = 0
  4328. call goLabel()
  4329. END SUBROUTINE METEO_CHECKPRESSURE
  4330. !EOC
  4331. ! **************************************************************
  4332. ! ***
  4333. ! *** vertical velocity
  4334. ! ***
  4335. ! **************************************************************
  4336. subroutine Compute_Omega( omega, lli, mfw, status )
  4337. use binas , only : grav
  4338. use grid, only : TllGridInfo, AreaOper
  4339. use meteodata, only : TMeteoData
  4340. use tmm, only : SetHistory, AddHistory
  4341. ! --- in/out ----------------------------------
  4342. type(TMeteoData), intent(inout) :: omega ! Pa/s downward
  4343. type(TllGridInfo), intent(in) :: lli
  4344. type(TMeteoData), intent(in) :: mfw ! kg/s upward
  4345. integer, intent(out) :: status
  4346. ! --- const -----------------------------------
  4347. character(len=*), parameter :: rname = mname//'/Compute_Omega'
  4348. ! --- local ----------------------------------
  4349. integer :: l
  4350. ! --- begin ----------------------------------
  4351. ! not in use ?
  4352. if ( .not. omega%used ) return
  4353. ! leave if not in use:
  4354. if ( .not. mfw%used ) then
  4355. write (gol,'("omega (Pa/s) requires mfw (kg/s)")'); call goErr
  4356. call goErr; status=1; return
  4357. end if
  4358. call goLabel(rname)
  4359. ! Pa/s = kg/s / m2 * g
  4360. ! init with mass flux; revert sign from upward to downard, divide by
  4361. ! gravity accelaration
  4362. omega%data = - mfw%data * grav ! Pa/s m2
  4363. ! loop over levels and divide by cell area (m2)
  4364. do l = 1, size(omega%data,3)
  4365. call AreaOper( lli, omega%data(:,:,l), '/', 'm2', status )
  4366. IF_NOTOK_RETURN(status=1)
  4367. end do
  4368. ! info ..
  4369. !call SetHistory( omega%tmi, mfw%tmi, status )
  4370. !call AddHistory( omega%tmi, 'convert to Pa/s', status )
  4371. ! ok
  4372. status = 0
  4373. call goLabel()
  4374. end subroutine Compute_Omega
  4375. ! **************************************************************
  4376. ! ***
  4377. ! *** Specific SETUP routine for CONVECTIVE FLUXES
  4378. ! ***
  4379. ! **************************************************************
  4380. subroutine Setup_Convec_SERIAL( region, entu, entd, detu, detd, omega, gph, &
  4381. tr, lli, levi, status )
  4382. use GO, only : TDate, wrtgol, operator(/=)
  4383. use Grid, only : TllGridInfo, TLevelInfo
  4384. use TMM, only : TMeteoInfo, Read_Convec, WriteField
  4385. use meteodata, only : TMeteoData, TimeInterpolation
  4386. use dims, only : im, jm
  4387. ! --- in/out ----------------------------------
  4388. integer, intent(in) :: region ! region number
  4389. type(TMeteoData), intent(inout) :: entu, entd, detu, detd
  4390. type(TMeteoData), intent(in) :: omega, gph
  4391. type(TDate), intent(in) :: tr(2)
  4392. type(TllGridInfo), intent(in) :: lli
  4393. type(TLevelInfo), intent(in) :: levi
  4394. integer, intent(out) :: status
  4395. ! --- const --------------------------------------
  4396. character(len=*), parameter :: rname = mname//'/SETUP_CONVEC_SERIAL'
  4397. ! --- local ----------------------------------
  4398. logical :: data1_read, data1_copy
  4399. type(TDate) :: data1_tref, data1_t1, data1_t2
  4400. logical :: data2_read, data2_copy
  4401. type(TDate) :: data2_tref, data2_t1, data2_t2
  4402. real, allocatable :: tmp_sp(:,:)
  4403. ! to differentiate b/w local and global data set
  4404. real, pointer, dimension(:,:,:) :: L_entu, L_entd, L_detu, L_detd
  4405. real, pointer :: L_omega(:,:,:), L_gph(:,:,:)
  4406. integer, dimension(2) :: is, js, ls, auxls
  4407. integer :: halo
  4408. ! --- begin -----------------------------
  4409. call goLabel(rname)
  4410. ! leave if not in use:
  4411. if ( (.not. all((/entu%used,entd%used,detu%used,detd%used/)) ) &
  4412. .and. any((/entu%used,entd%used,detu%used,detd%used/)) ) then
  4413. write (gol,'("either none or all of entu/entd/detu/detd should be in use")'); call goErr
  4414. call goErr; status=1; return
  4415. end if
  4416. if ( .not. entu%used ) then
  4417. call goLabel()
  4418. status=0; return
  4419. end if
  4420. if (okdebug) then
  4421. write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(entu%name),trim(lli%name); call goPr
  4422. endif
  4423. ! gph is required as input:
  4424. if ( .not. gph%used ) then
  4425. write (gol,'("gph should be in use to compute convective stuff from EC convective fluxes")'); call goErr
  4426. call goErr; status=1; return
  4427. end if
  4428. ! NOT NEEDED in EC-Earth, since we are using the ec-ll method (read_convec)
  4429. ! ! omega is required as input:
  4430. ! if ( .not. omega%used ) then
  4431. ! write (gol,'("omega should be in use to compute convective stuff")'); call goErr
  4432. ! call goErr; status=1; return
  4433. ! end if
  4434. ! not changed by default
  4435. entu%changed = .false.
  4436. entd%changed = .false.
  4437. detu%changed = .false.
  4438. detd%changed = .false.
  4439. !------------------
  4440. ! time stuff
  4441. !------------------
  4442. ! get time interval of met field and check if data from start and/or end
  4443. ! of interval must be read (sufficient to setup from entu only)
  4444. call SetupSetup( entu, tr, &
  4445. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  4446. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  4447. status )
  4448. IF_NOTOK_RETURN(status=1)
  4449. !--------------------------
  4450. ! read/write primary field
  4451. !--------------------------
  4452. if ( data1_read ) then
  4453. ! Need whole region for I/O on root. Dummy else.
  4454. is = (/1,im(region)/)
  4455. js = (/1,jm(region)/)
  4456. ls = entu%ls
  4457. auxls = gph%ls
  4458. IF (isRoot) THEN
  4459. ! Use the fact that entu, entd, detu, and detd have been allocated with the same bounds and halo=0
  4460. allocate( L_entu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4461. allocate( L_entd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4462. allocate( L_detu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4463. allocate( L_detd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4464. allocate(L_gph (im(region), jm(region), auxls(1):auxls(2)) )
  4465. allocate(L_omega(im(region), jm(region), auxls(1):auxls(2)) )
  4466. ELSE
  4467. allocate( L_entu(1,1,1), L_entd(1,1,1), L_detu(1,1,1), L_detd(1,1,1))
  4468. allocate(L_gph (1,1,1))
  4469. allocate(L_omega(1,1,1))
  4470. END IF
  4471. CALL GATHER( dgrid(region), gph%data, L_gph, gph%halo, status)
  4472. IF_NOTOK_RETURN(status=1)
  4473. ! NOT NEEDED in EC-Earth, since we are using the ec-ll method (read_convec)
  4474. ! CALL GATHER( dgrid(region), omega%data, L_omega, omega%halo, status)
  4475. ! IF_NOTOK_RETURN(status=1)
  4476. ! Read/write on root
  4477. IOroot : if (isRoot) then
  4478. ! safety check ...
  4479. ! if ( data1_t2 /= data1_t1 ) then
  4480. !write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  4481. !call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
  4482. !call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
  4483. !write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  4484. !call goErr; status=1; return
  4485. ! write (gol,'("WARNING - convec for interval, but pressure/gph/etc instant ...")'); call goPr
  4486. ! end if
  4487. ! surface pressure field:
  4488. allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
  4489. ! fill data
  4490. call Read_Convec( tmmd, entu%sourcekey, &
  4491. data1_tref, data1_t1, data1_t2, lli, levi, &
  4492. L_omega, omega%tmi, &
  4493. L_gph, gph%tmi, &
  4494. tmp_sp, &
  4495. L_entu, entu%tmi1, L_entd, entd%tmi1, &
  4496. L_detu, detu%tmi1, L_detd, detd%tmi1, &
  4497. status )
  4498. IF_NOTOK_RETURN(status=1)
  4499. ! write meteofiles
  4500. if ( entu%putout ) then
  4501. call WriteField( tmmd, entu%destkey, &
  4502. entu%tmi1, 'sp', trim(entu%name), trim(entu%unit), &
  4503. data1_tref, data1_t1, data1_t2, &
  4504. lli, 'n', levi, '*', &
  4505. tmp_sp, L_entu, status )
  4506. IF_NOTOK_RETURN(status=1)
  4507. end if
  4508. if ( entd%putout ) then
  4509. call WriteField( tmmd, entd%destkey, &
  4510. entd%tmi1, 'sp', trim(entd%name), trim(entd%unit), &
  4511. data1_tref, data1_t1, data1_t2, &
  4512. lli, 'n', levi, '*', &
  4513. tmp_sp, L_entd, status )
  4514. IF_NOTOK_RETURN(status=1)
  4515. end if
  4516. if ( detu%putout ) then
  4517. call WriteField( tmmd, detu%destkey, &
  4518. detu%tmi1, 'sp', trim(detu%name), trim(detu%unit), &
  4519. data1_tref, data1_t1, data1_t2, &
  4520. lli, 'n', levi, '*', &
  4521. tmp_sp, L_detu, status )
  4522. IF_NOTOK_RETURN(status=1)
  4523. end if
  4524. if ( detd%putout ) then
  4525. call WriteField( tmmd, detd%destkey, &
  4526. detd%tmi1, 'sp', trim(detd%name), trim(detd%unit), &
  4527. data1_tref, data1_t1, data1_t2, &
  4528. lli, 'n', levi, '*', &
  4529. tmp_sp, L_detd, status )
  4530. IF_NOTOK_RETURN(status=1)
  4531. end if
  4532. ! clear
  4533. deallocate( tmp_sp )
  4534. end if IOroot
  4535. ! Scatter & clean up
  4536. CALL SCATTER( dgrid(region), entu%data1, L_entu, entu%halo, status)
  4537. IF_NOTOK_RETURN(status=1)
  4538. CALL SCATTER( dgrid(region), entd%data1, L_entd, entd%halo, status)
  4539. IF_NOTOK_RETURN(status=1)
  4540. CALL SCATTER( dgrid(region), detu%data1, L_detu, detu%halo, status)
  4541. IF_NOTOK_RETURN(status=1)
  4542. CALL SCATTER( dgrid(region), detd%data1, L_detd, detd%halo, status)
  4543. IF_NOTOK_RETURN(status=1)
  4544. deallocate(L_entu, L_entd, L_detu, L_detd, L_gph, L_omega)
  4545. ! data array is filled now:
  4546. entu%filled1 = .true.
  4547. entu%tr1(1) = data1_t1
  4548. entu%tr1(2) = data1_t2
  4549. entu%changed = .true.
  4550. entd%filled1 = .true.
  4551. entd%tr1(1) = data1_t1
  4552. entd%tr1(2) = data1_t2
  4553. entd%changed = .true.
  4554. detu%filled1 = .true.
  4555. detu%tr1(1) = data1_t1
  4556. detu%tr1(2) = data1_t2
  4557. detu%changed = .true.
  4558. detd%filled1 = .true.
  4559. detd%tr1(1) = data1_t1
  4560. detd%tr1(2) = data1_t2
  4561. detd%changed = .true.
  4562. else if ( data1_copy ) then
  4563. ! copy data from secondary array:
  4564. entu%data1 = entu%data2
  4565. entd%data1 = entd%data2
  4566. detu%data1 = detu%data2
  4567. detd%data1 = detd%data2
  4568. ! data array is filled now:
  4569. entu%filled1 = .true.
  4570. entu%tr1(1) = data1_t1
  4571. entu%tr1(2) = data1_t2
  4572. entu%changed = .true.
  4573. entd%filled1 = .true.
  4574. entd%tr1(1) = data1_t1
  4575. entd%tr1(2) = data1_t2
  4576. entd%changed = .true.
  4577. detu%filled1 = .true.
  4578. detu%tr1(1) = data1_t1
  4579. detu%tr1(2) = data1_t2
  4580. detu%changed = .true.
  4581. detd%filled1 = .true.
  4582. detd%tr1(1) = data1_t1
  4583. detd%tr1(2) = data1_t2
  4584. detd%changed = .true.
  4585. end if
  4586. !--------------------------
  4587. ! read/write secondary field
  4588. !--------------------------
  4589. if ( data2_read ) then
  4590. ! Need whole region for I/O on root. Dummy else
  4591. is = (/1,im(1)/)
  4592. js = (/1,jm(1)/)
  4593. ls = entu%ls
  4594. auxls = gph%ls
  4595. IF (isRoot) THEN
  4596. ! Use the fact that entu, entd, detu, and detd have been allocated with the same bounds and halo
  4597. ALLOCATE( L_entu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4598. ALLOCATE( L_entd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4599. ALLOCATE( L_detu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4600. ALLOCATE( L_detd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4601. ALLOCATE(L_gph (im(region),jm(region),auxls(1):auxls(2)))
  4602. ALLOCATE(L_omega (im(region),jm(region),auxls(1):auxls(2)))
  4603. ELSE
  4604. ALLOCATE( L_entu(1,1,1), L_entd(1,1,1), L_detu(1,1,1), L_detd(1,1,1))
  4605. ALLOCATE( L_gph(1,1,1), L_omega(1,1,1) )
  4606. END IF
  4607. CALL GATHER( dgrid(region), gph%data, L_gph, gph%halo, status)
  4608. IF_NOTOK_RETURN(status=1)
  4609. ! NOT NEEDED in EC-Earth, since we are using the ec-ll method (read_convec)
  4610. ! CALL GATHER( dgrid(region), omega%data, L_omega, omega%halo, status)
  4611. ! IF_NOTOK_RETURN(status=1)
  4612. ! Read/write on root
  4613. IOroot2 : if (isRoot) then
  4614. ! safety check ...
  4615. ! if ( data2_t2 /= data2_t1 ) then
  4616. !write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  4617. !call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
  4618. !call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
  4619. !write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  4620. !call goErr; status=1; return
  4621. ! write (gol,'("WARNING - convec for interval, but pressure/gph/etc instant ...")'); call goPr
  4622. ! end if
  4623. ! surface pressure field:
  4624. allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
  4625. ! fill data2
  4626. call Read_Convec( tmmd, entu%sourcekey, &
  4627. data2_tref, data2_t1, data2_t2, lli, levi, &
  4628. L_omega, omega%tmi, &
  4629. L_gph, gph%tmi, &
  4630. tmp_sp, &
  4631. L_entu, entu%tmi2, L_entd, entd%tmi2, &
  4632. L_detu, detu%tmi2, L_detd, detd%tmi2, &
  4633. status )
  4634. IF_NOTOK_RETURN(status=1)
  4635. ! write meteofiles ?
  4636. if ( entu%putout ) then
  4637. call WriteField( tmmd, entu%destkey, &
  4638. entu%tmi2, 'sp', trim(entu%name), trim(entu%unit), &
  4639. data2_tref, data2_t1, data2_t2, &
  4640. lli, 'n', levi, '*', &
  4641. tmp_sp, L_entu, status )
  4642. IF_NOTOK_RETURN(status=1)
  4643. end if
  4644. if ( entd%putout ) then
  4645. call WriteField( tmmd, entd%destkey, &
  4646. entd%tmi2, 'sp', trim(entd%name), trim(entd%unit), &
  4647. data2_tref, data2_t1, data2_t2, &
  4648. lli, 'n', levi, '*', &
  4649. tmp_sp, L_entd, status )
  4650. IF_NOTOK_RETURN(status=1)
  4651. end if
  4652. if ( detu%putout ) then
  4653. call WriteField( tmmd, detu%destkey, &
  4654. detu%tmi2, 'sp', trim(detu%name), trim(detu%unit), &
  4655. data2_tref, data2_t1, data2_t2, &
  4656. lli, 'n', levi, '*', &
  4657. tmp_sp, L_detu, status )
  4658. IF_NOTOK_RETURN(status=1)
  4659. end if
  4660. if ( detd%putout ) then
  4661. call WriteField( tmmd, detd%destkey, &
  4662. detd%tmi2, 'sp', trim(detd%name), trim(detd%unit), &
  4663. data2_tref, data2_t1, data2_t2, &
  4664. lli, 'n', levi, '*', &
  4665. tmp_sp, L_detd, status )
  4666. IF_NOTOK_RETURN(status=1)
  4667. end if
  4668. ! clear
  4669. deallocate( tmp_sp )
  4670. end if IOroot2
  4671. CALL SCATTER( dgrid(region), entu%data2, L_entu, entu%halo, status)
  4672. IF_NOTOK_RETURN(status=1)
  4673. CALL SCATTER( dgrid(region), entd%data2, L_entd, entd%halo, status)
  4674. IF_NOTOK_RETURN(status=1)
  4675. CALL SCATTER( dgrid(region), detu%data2, L_detu, detu%halo, status)
  4676. IF_NOTOK_RETURN(status=1)
  4677. CALL SCATTER( dgrid(region), detd%data2, L_detd, detd%halo, status)
  4678. IF_NOTOK_RETURN(status=1)
  4679. DEALLOCATE( L_entu, L_entd, L_detu, L_detd, L_gph, L_omega )
  4680. ! data2 array is filled now:
  4681. entu%filled2 = .true.
  4682. entu%tr2(1) = data2_t1
  4683. entu%tr2(2) = data2_t2
  4684. entd%filled2 = .true.
  4685. entd%tr2(1) = data2_t1
  4686. entd%tr2(2) = data2_t2
  4687. detu%filled2 = .true.
  4688. detu%tr2(1) = data2_t1
  4689. detu%tr2(2) = data2_t2
  4690. detd%filled2 = .true.
  4691. detd%tr2(1) = data2_t1
  4692. detd%tr2(2) = data2_t2
  4693. else if ( data2_copy ) then
  4694. ! copy data2 from primary array:
  4695. entu%data2 = entu%data1
  4696. entd%data2 = entd%data1
  4697. detu%data2 = detu%data1
  4698. detd%data2 = detd%data1
  4699. ! data2 array is filled now:
  4700. entu%filled2 = .true.
  4701. entu%tr2(1) = data2_t1
  4702. entu%tr2(2) = data2_t2
  4703. entd%filled2 = .true.
  4704. entd%tr2(1) = data2_t1
  4705. entd%tr2(2) = data2_t2
  4706. detu%filled2 = .true.
  4707. detu%tr2(1) = data2_t1
  4708. detu%tr2(2) = data2_t2
  4709. detd%filled2 = .true.
  4710. detd%tr2(1) = data2_t1
  4711. detd%tr2(2) = data2_t2
  4712. end if
  4713. !------------------
  4714. ! time interpolation
  4715. !------------------
  4716. call TimeInterpolation( entu, tr, status )
  4717. IF_NOTOK_RETURN(status=1)
  4718. call TimeInterpolation( entd, tr, status )
  4719. IF_NOTOK_RETURN(status=1)
  4720. call TimeInterpolation( detu, tr, status )
  4721. IF_NOTOK_RETURN(status=1)
  4722. call TimeInterpolation( detd, tr, status )
  4723. IF_NOTOK_RETURN(status=1)
  4724. !------------------
  4725. ! done
  4726. !------------------
  4727. status = 0
  4728. call goLabel()
  4729. END SUBROUTINE SETUP_CONVEC_SERIAL
  4730. !--------------------------------------------------------------------------
  4731. ! TM5 !
  4732. !--------------------------------------------------------------------------
  4733. !BOP
  4734. !
  4735. ! !IROUTINE: SETUP_CONVEC_PARA
  4736. !
  4737. ! !DESCRIPTION: same as setup_convec_serial_io but with parallel i/o
  4738. !\\
  4739. !\\
  4740. ! !INTERFACE:
  4741. !
  4742. SUBROUTINE SETUP_CONVEC_PARA( region, entu, entd, detu, detd, omega, gph, &
  4743. tr, levi, status )
  4744. !
  4745. ! !USES:
  4746. !
  4747. use GO, only : TDate, wrtgol, operator(/=)
  4748. use Grid, only : TllGridInfo, TLevelInfo
  4749. use TMM, only : TMeteoInfo, Read_Convec, WriteField
  4750. !
  4751. ! !INPUT PARAMETERS:
  4752. !
  4753. integer, intent(in) :: region ! region number
  4754. !
  4755. ! !INPUT/OUTPUT PARAMETERS:
  4756. !
  4757. type(TMeteoData), intent(inout) :: entu, entd, detu, detd
  4758. type(TMeteoData), intent(in) :: omega, gph
  4759. type(TDate), intent(in) :: tr(2)
  4760. type(TLevelInfo), intent(in) :: levi
  4761. !
  4762. ! !OUTPUT PARAMETERS:
  4763. !
  4764. integer, intent(out) :: status
  4765. !
  4766. ! !REVISION HISTORY:
  4767. ! 24 Oct 2013 - Ph. Le Sager - v0
  4768. !
  4769. ! !REMARKS:
  4770. !
  4771. !EOP
  4772. !------------------------------------------------------------------------
  4773. !BOC
  4774. character(len=*), parameter :: rname = mname//'/SETUP_CONVEC_PARA'
  4775. logical :: data1_read, data1_copy
  4776. type(TDate) :: data1_tref, data1_t1, data1_t2
  4777. logical :: data2_read, data2_copy
  4778. type(TDate) :: data2_tref, data2_t1, data2_t2
  4779. real, allocatable :: tmp_sp(:,:)
  4780. ! to differentiate b/w local and global data set
  4781. real, pointer, dimension(:,:,:) :: L_entu, L_entd, L_detu, L_detd
  4782. real, pointer :: L_omega(:,:,:), L_gph(:,:,:)
  4783. integer, dimension(2) :: is, js, ls, auxls
  4784. integer :: halo
  4785. integer :: i1, i2, j1, j2
  4786. ! --- begin -----------------------------
  4787. call goLabel(rname)
  4788. ! leave if not in use:
  4789. if ( (.not. all((/entu%used,entd%used,detu%used,detd%used/)) ) &
  4790. .and. any((/entu%used,entd%used,detu%used,detd%used/)) ) then
  4791. write (gol,'("either none or all of entu/entd/detu/detd should be in use")'); call goErr
  4792. call goErr; status=1; return
  4793. end if
  4794. if ( .not. entu%used ) then
  4795. call goLabel()
  4796. status=0; return
  4797. end if
  4798. ! gph is required as input:
  4799. if ( .not. gph%used ) then
  4800. write (gol,'("gph should be in use to compute convective stuff from EC convective fluxes")'); call goErr
  4801. call goErr; status=1; return
  4802. end if
  4803. ! omega is required as input:
  4804. if ( .not. omega%used ) then
  4805. write (gol,'("omega should be in use to compute convective stuff")'); call goErr
  4806. call goErr; status=1; return
  4807. end if
  4808. ! not changed by default
  4809. entu%changed = .false.
  4810. entd%changed = .false.
  4811. detu%changed = .false.
  4812. detd%changed = .false.
  4813. !------------------
  4814. ! time stuff
  4815. !------------------
  4816. ! get time interval of met field and check if data from start and/or end
  4817. ! of interval must be read (sufficient to setup from entu only)
  4818. call SetupSetup( entu, tr, &
  4819. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  4820. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  4821. status )
  4822. IF_NOTOK_RETURN(status=1)
  4823. ! work arrays
  4824. if (data1_read .or. data2_read) then
  4825. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  4826. is = (/i1,i2/)
  4827. js = (/j1,j2/)
  4828. ls = entu%ls
  4829. auxls = gph%ls
  4830. ! Use the fact that entu, entd, detu, and detd have been allocated with the same bounds and halo=0
  4831. allocate( L_entu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4832. allocate( L_entd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4833. allocate( L_detu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4834. allocate( L_detd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  4835. allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
  4836. L_gph => gph%data
  4837. L_omega => omega%data
  4838. end if
  4839. !--------------------------
  4840. ! read/write primary field
  4841. !--------------------------
  4842. if ( data1_read ) then
  4843. !AJS if ( data1_t2 /= data1_t1 ) then
  4844. !AJS write (gol,'("WARNING - convec for interval, but pressure/gph/etc instant ...")'); call goPr
  4845. !AJS end if
  4846. call Read_Convec( tmmd, entu%sourcekey, &
  4847. data1_tref, data1_t1, data1_t2, lli(region), levi, &
  4848. L_omega, omega%tmi, &
  4849. L_gph, gph%tmi, &
  4850. tmp_sp, &
  4851. L_entu, entu%tmi1, L_entd, entd%tmi1, &
  4852. L_detu, detu%tmi1, L_detd, detd%tmi1, &
  4853. status )
  4854. IF_NOTOK_RETURN(status=1)
  4855. entu%data1(i1:i2,j1:j2,:) = L_entu
  4856. entd%data1(i1:i2,j1:j2,:) = L_entd
  4857. detu%data1(i1:i2,j1:j2,:) = L_detu
  4858. detd%data1(i1:i2,j1:j2,:) = L_detd
  4859. ! data array is filled now:
  4860. entu%filled1 = .true.
  4861. entu%tr1(1) = data1_t1
  4862. entu%tr1(2) = data1_t2
  4863. entu%changed = .true.
  4864. entd%filled1 = .true.
  4865. entd%tr1(1) = data1_t1
  4866. entd%tr1(2) = data1_t2
  4867. entd%changed = .true.
  4868. detu%filled1 = .true.
  4869. detu%tr1(1) = data1_t1
  4870. detu%tr1(2) = data1_t2
  4871. detu%changed = .true.
  4872. detd%filled1 = .true.
  4873. detd%tr1(1) = data1_t1
  4874. detd%tr1(2) = data1_t2
  4875. detd%changed = .true.
  4876. else if ( data1_copy ) then
  4877. ! copy data from secondary array:
  4878. entu%data1 = entu%data2
  4879. entd%data1 = entd%data2
  4880. detu%data1 = detu%data2
  4881. detd%data1 = detd%data2
  4882. ! data array is filled now:
  4883. entu%filled1 = .true.
  4884. entu%tr1(1) = data1_t1
  4885. entu%tr1(2) = data1_t2
  4886. entu%changed = .true.
  4887. entd%filled1 = .true.
  4888. entd%tr1(1) = data1_t1
  4889. entd%tr1(2) = data1_t2
  4890. entd%changed = .true.
  4891. detu%filled1 = .true.
  4892. detu%tr1(1) = data1_t1
  4893. detu%tr1(2) = data1_t2
  4894. detu%changed = .true.
  4895. detd%filled1 = .true.
  4896. detd%tr1(1) = data1_t1
  4897. detd%tr1(2) = data1_t2
  4898. detd%changed = .true.
  4899. end if
  4900. !--------------------------
  4901. ! read/write secondary field
  4902. !--------------------------
  4903. if ( data2_read ) then
  4904. !AJS if ( data2_t2 /= data2_t1 ) then
  4905. !AJS write (gol,'("WARNING - convec for interval, but pressure/gph/etc instant ...")'); call goPr
  4906. !AJS end if
  4907. call Read_Convec( tmmd, entu%sourcekey, &
  4908. data2_tref, data2_t1, data2_t2, lli(region), levi, &
  4909. L_omega, omega%tmi, &
  4910. L_gph, gph%tmi, &
  4911. tmp_sp, &
  4912. L_entu, entu%tmi2, L_entd, entd%tmi2, &
  4913. L_detu, detu%tmi2, L_detd, detd%tmi2, &
  4914. status )
  4915. IF_NOTOK_RETURN(status=1)
  4916. ! write meteofiles ?
  4917. ! if ( entu%putout ) then
  4918. ! end if
  4919. entu%data2(i1:i2,j1:j2,:) = L_entu
  4920. entd%data2(i1:i2,j1:j2,:) = L_entd
  4921. detu%data2(i1:i2,j1:j2,:) = L_detu
  4922. detd%data2(i1:i2,j1:j2,:) = L_detd
  4923. ! data2 array is filled now:
  4924. entu%filled2 = .true.
  4925. entu%tr2(1) = data2_t1
  4926. entu%tr2(2) = data2_t2
  4927. entd%filled2 = .true.
  4928. entd%tr2(1) = data2_t1
  4929. entd%tr2(2) = data2_t2
  4930. detu%filled2 = .true.
  4931. detu%tr2(1) = data2_t1
  4932. detu%tr2(2) = data2_t2
  4933. detd%filled2 = .true.
  4934. detd%tr2(1) = data2_t1
  4935. detd%tr2(2) = data2_t2
  4936. else if ( data2_copy ) then
  4937. ! copy data2 from primary array:
  4938. entu%data2 = entu%data1
  4939. entd%data2 = entd%data1
  4940. detu%data2 = detu%data1
  4941. detd%data2 = detd%data1
  4942. ! data2 array is filled now:
  4943. entu%filled2 = .true.
  4944. entu%tr2(1) = data2_t1
  4945. entu%tr2(2) = data2_t2
  4946. entd%filled2 = .true.
  4947. entd%tr2(1) = data2_t1
  4948. entd%tr2(2) = data2_t2
  4949. detu%filled2 = .true.
  4950. detu%tr2(1) = data2_t1
  4951. detu%tr2(2) = data2_t2
  4952. detd%filled2 = .true.
  4953. detd%tr2(1) = data2_t1
  4954. detd%tr2(2) = data2_t2
  4955. end if
  4956. !------------------
  4957. ! time interpolation
  4958. !------------------
  4959. call TimeInterpolation( entu, tr, status )
  4960. IF_NOTOK_RETURN(status=1)
  4961. call TimeInterpolation( entd, tr, status )
  4962. IF_NOTOK_RETURN(status=1)
  4963. call TimeInterpolation( detu, tr, status )
  4964. IF_NOTOK_RETURN(status=1)
  4965. call TimeInterpolation( detd, tr, status )
  4966. IF_NOTOK_RETURN(status=1)
  4967. !------------------
  4968. ! done
  4969. !------------------
  4970. if (data1_read .or. data2_read) then
  4971. deallocate(L_entu, L_entd, L_detu, L_detd)
  4972. deallocate( tmp_sp )
  4973. nullify(L_gph, L_omega)
  4974. end if
  4975. status = 0
  4976. call goLabel()
  4977. END SUBROUTINE SETUP_CONVEC_PARA
  4978. !EOC
  4979. ! **************************************************************
  4980. ! ***
  4981. ! *** Specific SETUP routine for CLOUD COVER
  4982. ! ***
  4983. ! **************************************************************
  4984. SUBROUTINE SETUP_CLOUDCOVERS_SERIAL( region, cc, cco, ccu, tr, lli, levi, status )
  4985. use GO, only : TDate, wrtgol, operator(/=)
  4986. use Grid, only : TllGridInfo, TLevelInfo
  4987. use TMM, only : TMeteoInfo, Read_CloudCovers, WriteField
  4988. use meteodata, only : TMeteoData, TimeInterpolation
  4989. use dims, only : im, jm
  4990. ! --- in/out ----------------------------------
  4991. integer, intent(in) :: region ! region number
  4992. type(TMeteoData), intent(inout) :: cc, cco, ccu
  4993. type(TDate), intent(in) :: tr(2)
  4994. type(TllGridInfo), intent(in) :: lli
  4995. type(TLevelInfo), intent(in) :: levi
  4996. integer, intent(out) :: status
  4997. ! --- const --------------------------------------
  4998. character(len=*), parameter :: rname = mname//'/Setup_CloudCovers_Serial'
  4999. ! --- local ----------------------------------
  5000. logical :: data1_read, data1_copy
  5001. type(TDate) :: data1_tref, data1_t1, data1_t2
  5002. logical :: data2_read, data2_copy
  5003. type(TDate) :: data2_tref, data2_t1, data2_t2
  5004. real, allocatable :: tmp_sp(:,:) ! surface pressure
  5005. real, pointer, dimension(:,:,:) :: L_cc, L_cco, L_ccu ! work arrays (data)
  5006. integer :: is(2), js(2), ls(2) ! work arrays (bounds)
  5007. ! --- begin -----------------------------
  5008. call goLabel(rname)
  5009. ! leave if not in use:
  5010. if ( (.not. all((/cc%used,cco%used,ccu%used/)) ) .and. any((/cc%used,cco%used,ccu%used/)) ) then
  5011. write (gol,'("either none or all of cc/cco/ccu should be in use")'); call goErr
  5012. call goErr; status=1; return
  5013. end if
  5014. if ( .not. cc%used ) then
  5015. call goLabel()
  5016. status=0; return
  5017. end if
  5018. if (okdebug) then
  5019. write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(cc%name),trim(lli%name); call goPr
  5020. endif
  5021. ! not changed by default
  5022. cc%changed = .false.
  5023. cco%changed = .false.
  5024. ccu%changed = .false.
  5025. !------------------
  5026. ! time stuff
  5027. !------------------
  5028. ! get time interval of met field and check if data from start and/or end
  5029. ! of interval must be read (sufficient to setup from cc only)
  5030. call SetupSetup( cc, tr, &
  5031. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  5032. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  5033. status )
  5034. IF_NOTOK_RETURN(status=1)
  5035. !--------------------------
  5036. ! read/write primary field
  5037. !--------------------------
  5038. if ( data1_read ) then
  5039. ! Allocate global arrays for I/O
  5040. is = (/1,im(region)/)
  5041. js = (/1,jm(region)/)
  5042. ls = cc%ls
  5043. IF (isRoot) THEN
  5044. ALLOCATE( L_cc( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5045. ALLOCATE( L_cco( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5046. ALLOCATE( L_ccu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5047. ELSE
  5048. ALLOCATE( L_cc(1,1,1), L_cco(1,1,1), L_ccu(1,1,1) )
  5049. END IF
  5050. ! Read/write on root
  5051. IOroot : if (isRoot) then
  5052. ! safety check ...
  5053. if ( data1_t2 /= data1_t1 ) then
  5054. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  5055. call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
  5056. call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
  5057. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  5058. call goErr; status=1; return
  5059. end if
  5060. ! surface pressure field:
  5061. allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
  5062. ! fill data:
  5063. call Read_CloudCovers( tmmd, cc%sourcekey, &
  5064. data1_tref, data1_t1, data1_t2, lli, levi, &
  5065. tmp_sp, &
  5066. L_cc, cc%tmi1, &
  5067. L_cco, cco%tmi1, &
  5068. L_ccu, ccu%tmi1, &
  5069. status )
  5070. IF_NOTOK_RETURN(status=1)
  5071. ! write meteofiles
  5072. if ( cc%putout ) then
  5073. call WriteField( tmmd, cc%destkey, &
  5074. cc%tmi1, 'sp', trim(cc%name), trim(cc%unit), &
  5075. data1_tref, data1_t1, data1_t2, &
  5076. lli, 'n', levi, 'n', &
  5077. tmp_sp, L_cc, status )
  5078. IF_NOTOK_RETURN(status=1)
  5079. end if
  5080. if ( cco%putout ) then
  5081. call WriteField( tmmd, cco%destkey, &
  5082. cco%tmi1, 'sp', trim(cco%name), trim(cco%unit), &
  5083. data1_tref, data1_t1, data1_t2, &
  5084. lli, 'n', levi, 'n', &
  5085. tmp_sp, L_cco, status )
  5086. IF_NOTOK_RETURN(status=1)
  5087. end if
  5088. if ( ccu%putout ) then
  5089. call WriteField( tmmd, ccu%destkey, &
  5090. ccu%tmi1, 'sp', trim(ccu%name), trim(ccu%unit), &
  5091. data1_tref, data1_t1, data1_t2, &
  5092. lli, 'n', levi, 'n', &
  5093. tmp_sp, L_ccu, status )
  5094. IF_NOTOK_RETURN(status=1)
  5095. end if
  5096. ! clear
  5097. deallocate( tmp_sp )
  5098. end if IOroot
  5099. ! Wrap up
  5100. CALL SCATTER( dgrid(region), cc%data1, L_cc, cc%halo, status)
  5101. IF_NOTOK_RETURN(status=1)
  5102. CALL SCATTER( dgrid(region), cco%data1, L_cco, cco%halo, status)
  5103. IF_NOTOK_RETURN(status=1)
  5104. CALL SCATTER( dgrid(region), ccu%data1, L_ccu, ccu%halo, status)
  5105. IF_NOTOK_RETURN(status=1)
  5106. DEALLOCATE(L_cc, L_cco, L_ccu)
  5107. ! data array is filled now:
  5108. cc%filled1 = .true.
  5109. cc%tr1(1) = data1_t1
  5110. cc%tr1(2) = data1_t2
  5111. cc%changed = .true.
  5112. cco%filled1 = .true.
  5113. cco%tr1(1) = data1_t1
  5114. cco%tr1(2) = data1_t2
  5115. cco%changed = .true.
  5116. ccu%filled1 = .true.
  5117. ccu%tr1(1) = data1_t1
  5118. ccu%tr1(2) = data1_t2
  5119. ccu%changed = .true.
  5120. else if ( data1_copy ) then
  5121. ! copy data from secondary array:
  5122. cc%data1 = cc%data2
  5123. cco%data1 = cco%data2
  5124. ccu%data1 = ccu%data2
  5125. ! data array is filled now:
  5126. cc%filled1 = .true.
  5127. cc%tr1(1) = data1_t1
  5128. cc%tr1(2) = data1_t2
  5129. cc%changed = .true.
  5130. cco%filled1 = .true.
  5131. cco%tr1(1) = data1_t1
  5132. cco%tr1(2) = data1_t2
  5133. cco%changed = .true.
  5134. ccu%filled1 = .true.
  5135. ccu%tr1(1) = data1_t1
  5136. ccu%tr1(2) = data1_t2
  5137. ccu%changed = .true.
  5138. end if
  5139. !--------------------------
  5140. ! read/write secondary field
  5141. !--------------------------
  5142. if ( data2_read ) then
  5143. ! Allocate global arrays for I/O
  5144. is = (/1,im(region)/)
  5145. js = (/1,jm(region)/)
  5146. ls = cc%ls
  5147. IF (isRoot) THEN
  5148. ! Use the fact that entu, entd, detu, and detd have been allocated with the same bounds and halo
  5149. ALLOCATE( L_cc( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5150. ALLOCATE( L_cco( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5151. ALLOCATE( L_ccu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5152. ELSE
  5153. ALLOCATE( L_cc(1,1,1), L_cco(1,1,1), L_ccu(1,1,1) )
  5154. END IF
  5155. ! Read/write
  5156. IOroot2 : IF (isRoot) THEN
  5157. ! safety check ...
  5158. if ( data2_t2 /= data2_t1 ) then
  5159. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  5160. call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
  5161. call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
  5162. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  5163. call goErr; status=1; return
  5164. end if
  5165. ! surface pressure field:
  5166. allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
  5167. ! fill data2:
  5168. call Read_CloudCovers( tmmd, cc%sourcekey, data2_tref, &
  5169. data2_t1, data2_t2, lli, levi, &
  5170. tmp_sp, &
  5171. L_cc, cc%tmi2, &
  5172. L_cco, cco%tmi2, &
  5173. L_ccu, ccu%tmi2, &
  5174. status )
  5175. IF_NOTOK_RETURN(status=1)
  5176. ! write meteofiles ?
  5177. if ( cc%putout ) then
  5178. call WriteField( tmmd, cc%destkey, &
  5179. cc%tmi2, 'sp', trim( cc%name), trim( cc%unit), &
  5180. data2_tref, data2_t1, data2_t2, &
  5181. lli, 'n', levi, 'n', &
  5182. tmp_sp, L_cc, status )
  5183. IF_NOTOK_RETURN(status=1)
  5184. end if
  5185. if ( cco%putout ) then
  5186. call WriteField( tmmd, cco%destkey, &
  5187. cco%tmi2, 'sp', trim(cco%name), trim(cco%unit), &
  5188. data2_tref, data2_t1, data2_t2, &
  5189. lli, 'n', levi, 'n', &
  5190. tmp_sp, L_cco, status )
  5191. IF_NOTOK_RETURN(status=1)
  5192. end if
  5193. if ( ccu%putout ) then
  5194. call WriteField( tmmd, ccu%destkey, &
  5195. ccu%tmi2, 'sp', trim(ccu%name), trim(ccu%unit), &
  5196. data2_tref, data2_t1, data2_t2, &
  5197. lli, 'n', levi, 'n', &
  5198. tmp_sp, L_ccu, status )
  5199. IF_NOTOK_RETURN(status=1)
  5200. end if
  5201. ! clear
  5202. deallocate( tmp_sp )
  5203. end if IOroot2
  5204. ! Wrap up
  5205. CALL SCATTER( dgrid(region), cc%data2, L_cc, cc%halo, status)
  5206. IF_NOTOK_RETURN(status=1)
  5207. CALL SCATTER( dgrid(region), cco%data2, L_cco, cco%halo, status)
  5208. IF_NOTOK_RETURN(status=1)
  5209. CALL SCATTER( dgrid(region), ccu%data2, L_ccu, ccu%halo, status)
  5210. IF_NOTOK_RETURN(status=1)
  5211. DEALLOCATE(L_cc, L_cco, L_ccu)
  5212. ! data2 array is filled now:
  5213. cc%filled2 = .true.
  5214. cc%tr2(1) = data2_t1
  5215. cc%tr2(2) = data2_t2
  5216. cco%filled2 = .true.
  5217. cco%tr2(1) = data2_t1
  5218. cco%tr2(2) = data2_t2
  5219. ccu%filled2 = .true.
  5220. ccu%tr2(1) = data2_t1
  5221. ccu%tr2(2) = data2_t2
  5222. else if ( data2_copy ) then
  5223. ! copy data2 from primary array:
  5224. cc%data2 = cc%data1
  5225. cco%data2 = cco%data1
  5226. ccu%data2 = ccu%data1
  5227. ! data2 array is filled now:
  5228. cc%filled2 = .true.
  5229. cc%tr2(1) = data2_t1
  5230. cc%tr2(2) = data2_t2
  5231. cco%filled2 = .true.
  5232. cco%tr2(1) = data2_t1
  5233. cco%tr2(2) = data2_t2
  5234. ccu%filled2 = .true.
  5235. ccu%tr2(1) = data2_t1
  5236. ccu%tr2(2) = data2_t2
  5237. end if
  5238. !------------------
  5239. ! time interpolation
  5240. !------------------
  5241. call TimeInterpolation( cc, tr, status )
  5242. IF_NOTOK_RETURN(status=1)
  5243. call TimeInterpolation( cco, tr, status )
  5244. IF_NOTOK_RETURN(status=1)
  5245. call TimeInterpolation( ccu, tr, status )
  5246. IF_NOTOK_RETURN(status=1)
  5247. !------------------
  5248. ! done
  5249. !------------------
  5250. status = 0
  5251. call goLabel()
  5252. END SUBROUTINE SETUP_CLOUDCOVERS_SERIAL
  5253. !--------------------------------------------------------------------------
  5254. ! TM5 !
  5255. !--------------------------------------------------------------------------
  5256. !BOP
  5257. !
  5258. ! !IROUTINE: SETUP_CLOUDCOVERS_PARA
  5259. !
  5260. ! !DESCRIPTION:
  5261. !\\
  5262. !\\
  5263. ! !INTERFACE:
  5264. !
  5265. SUBROUTINE SETUP_CLOUDCOVERS_PARA( region, cc, cco, ccu, tr, levi, status )
  5266. !
  5267. ! !USES:
  5268. !
  5269. use GO, only : TDate, wrtgol, operator(/=)
  5270. use Grid, only : TllGridInfo, TLevelInfo
  5271. use TMM, only : TMeteoInfo, Read_CloudCovers, WriteField
  5272. use dims, only : im, jm
  5273. !
  5274. ! !INPUT PARAMETERS:
  5275. !
  5276. integer, intent(in) :: region ! region number
  5277. !
  5278. ! !INPUT/OUTPUT PARAMETERS:
  5279. !
  5280. type(TMeteoData), intent(inout) :: cc, cco, ccu
  5281. type(TDate), intent(in) :: tr(2)
  5282. type(TLevelInfo), intent(in) :: levi
  5283. !
  5284. ! !OUTPUT PARAMETERS:
  5285. !
  5286. integer, intent(out) :: status
  5287. !
  5288. ! !REVISION HISTORY:
  5289. ! 24 Oct 2013 - Ph. Le Sager - v0
  5290. !
  5291. ! !REMARKS:
  5292. !
  5293. !EOP
  5294. !------------------------------------------------------------------------
  5295. !BOC
  5296. character(len=*), parameter :: rname = mname//'/SETUP_CLOUDCOVERS_PARA'
  5297. logical :: data1_read, data1_copy
  5298. type(TDate) :: data1_tref, data1_t1, data1_t2
  5299. logical :: data2_read, data2_copy
  5300. type(TDate) :: data2_tref, data2_t1, data2_t2
  5301. real, allocatable :: tmp_sp(:,:) ! surface pressure
  5302. real, pointer, dimension(:,:,:) :: L_cc, L_cco, L_ccu ! work arrays (data)
  5303. integer :: is(2), js(2), ls(2) ! work arrays (bounds)
  5304. integer :: i1, i2, j1, j2
  5305. ! --- begin -----------------------------
  5306. call goLabel(rname)
  5307. ! leave if not in use:
  5308. if ( (.not. all((/cc%used,cco%used,ccu%used/)) ) .and. any((/cc%used,cco%used,ccu%used/)) ) then
  5309. write (gol,'("either none or all of cc/cco/ccu should be in use")'); call goErr
  5310. call goErr; status=1; return
  5311. end if
  5312. if ( .not. cc%used ) then
  5313. call goLabel()
  5314. status=0; return
  5315. end if
  5316. ! not changed by default
  5317. cc%changed = .false.
  5318. cco%changed = .false.
  5319. ccu%changed = .false.
  5320. !------------------
  5321. ! time stuff
  5322. !------------------
  5323. ! get time interval of met field and check if data from start and/or end
  5324. ! of interval must be read (sufficient to setup from cc only)
  5325. call SetupSetup( cc, tr, &
  5326. data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
  5327. data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
  5328. status )
  5329. IF_NOTOK_RETURN(status=1)
  5330. ! work arrays
  5331. IF (data1_read .OR. data2_read) THEN
  5332. CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  5333. is = (/i1,i2/)
  5334. js = (/j1,j2/)
  5335. ls = cc%ls
  5336. ALLOCATE( L_cc( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5337. ALLOCATE( L_cco( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5338. ALLOCATE( L_ccu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
  5339. ALLOCATE( tmp_sp(is(1):is(2),js(1):js(2)) )
  5340. ENDIF
  5341. !--------------------------
  5342. ! read/write primary field
  5343. !--------------------------
  5344. if ( data1_read ) then
  5345. ! safety check
  5346. if ( data1_t2 /= data1_t1 ) then
  5347. write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
  5348. call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
  5349. call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
  5350. write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
  5351. TRACEBACK; status=1; return
  5352. end if
  5353. call Read_CloudCovers( tmmd, cc%sourcekey, &
  5354. data1_tref, data1_t1, data1_t2, lli(region), levi, &
  5355. tmp_sp, &
  5356. L_cc, cc%tmi1, &
  5357. L_cco, cco%tmi1, &
  5358. L_ccu, ccu%tmi1, &
  5359. status )
  5360. IF_NOTOK_RETURN(status=1)
  5361. cc%data1(i1:i2,j1:j2,:) = L_cc
  5362. cco%data1(i1:i2,j1:j2,:) = L_cco
  5363. ccu%data1(i1:i2,j1:j2,:) = L_ccu
  5364. ! data array is filled now:
  5365. cc%filled1 = .true.
  5366. cc%tr1(1) = data1_t1
  5367. cc%tr1(2) = data1_t2
  5368. cc%changed = .true.
  5369. cco%filled1 = .true.
  5370. cco%tr1(1) = data1_t1
  5371. cco%tr1(2) = data1_t2
  5372. cco%changed = .true.
  5373. ccu%filled1 = .true.
  5374. ccu%tr1(1) = data1_t1
  5375. ccu%tr1(2) = data1_t2
  5376. ccu%changed = .true.
  5377. else if ( data1_copy ) then
  5378. ! copy data from secondary array:
  5379. cc%data1 = cc%data2
  5380. cco%data1 = cco%data2
  5381. ccu%data1 = ccu%data2
  5382. ! data array is filled now:
  5383. cc%filled1 = .true.
  5384. cc%tr1(1) = data1_t1
  5385. cc%tr1(2) = data1_t2
  5386. cc%changed = .true.
  5387. cco%filled1 = .true.
  5388. cco%tr1(1) = data1_t1
  5389. cco%tr1(2) = data1_t2
  5390. cco%changed = .true.
  5391. ccu%filled1 = .true.
  5392. ccu%tr1(1) = data1_t1
  5393. ccu%tr1(2) = data1_t2
  5394. ccu%changed = .true.
  5395. end if
  5396. !--------------------------
  5397. ! read/write secondary field
  5398. !--------------------------
  5399. if ( data2_read ) then
  5400. ! safety check ...
  5401. if ( data2_t2 /= data2_t1 ) then
  5402. write (gol,'("not sure that this routine is correct for time intervals:")') ; call goErr
  5403. call wrtgol( ' data2_t1 : ', data2_t1 ) ; call goErr
  5404. call wrtgol( ' data2_t2 : ', data2_t2 ) ; call goErr
  5405. write (gol,'("please deceide what to do with surface pressures ... ")') ; call goErr
  5406. call goErr; status=1; return
  5407. end if
  5408. call Read_CloudCovers( tmmd, cc%sourcekey, data2_tref, &
  5409. data2_t1, data2_t2, lli(region), levi, &
  5410. tmp_sp, &
  5411. L_cc, cc%tmi2, &
  5412. L_cco, cco%tmi2, &
  5413. L_ccu, ccu%tmi2, &
  5414. status )
  5415. IF_NOTOK_RETURN(status=1)
  5416. cc%data2(i1:i2,j1:j2,:) = L_cc
  5417. cco%data2(i1:i2,j1:j2,:) = L_cco
  5418. ccu%data2(i1:i2,j1:j2,:) = L_ccu
  5419. ! data2 array is filled now:
  5420. cc%filled2 = .true.
  5421. cc%tr2(1) = data2_t1
  5422. cc%tr2(2) = data2_t2
  5423. cco%filled2 = .true.
  5424. cco%tr2(1) = data2_t1
  5425. cco%tr2(2) = data2_t2
  5426. ccu%filled2 = .true.
  5427. ccu%tr2(1) = data2_t1
  5428. ccu%tr2(2) = data2_t2
  5429. else if ( data2_copy ) then
  5430. ! copy data2 from primary array:
  5431. cc%data2 = cc%data1
  5432. cco%data2 = cco%data1
  5433. ccu%data2 = ccu%data1
  5434. ! data2 array is filled now:
  5435. cc%filled2 = .true.
  5436. cc%tr2(1) = data2_t1
  5437. cc%tr2(2) = data2_t2
  5438. cco%filled2 = .true.
  5439. cco%tr2(1) = data2_t1
  5440. cco%tr2(2) = data2_t2
  5441. ccu%filled2 = .true.
  5442. ccu%tr2(1) = data2_t1
  5443. ccu%tr2(2) = data2_t2
  5444. end if
  5445. !------------------
  5446. ! time interpolation
  5447. !------------------
  5448. call TimeInterpolation( cc, tr, status )
  5449. IF_NOTOK_RETURN(status=1)
  5450. call TimeInterpolation( cco, tr, status )
  5451. IF_NOTOK_RETURN(status=1)
  5452. call TimeInterpolation( ccu, tr, status )
  5453. IF_NOTOK_RETURN(status=1)
  5454. !------------------
  5455. ! done
  5456. !------------------
  5457. if (data1_read .or. data2_read) then
  5458. deallocate( tmp_sp )
  5459. deallocate(L_cc, L_cco, L_ccu)
  5460. end if
  5461. status = 0
  5462. call goLabel()
  5463. END SUBROUTINE SETUP_CLOUDCOVERS_PARA
  5464. !EOC
  5465. !--------------------------------------------------------------------------
  5466. ! TM5 !
  5467. !--------------------------------------------------------------------------
  5468. !BOP
  5469. !
  5470. ! !IROUTINE: PRESSURE_TO_MASS
  5471. !
  5472. ! !DESCRIPTION: Get Air Mass: from surface pressure (sp), get pressure at
  5473. ! box boundaries (so-called half-levels, phlb), and then air
  5474. ! mass (m_dat).
  5475. !\\
  5476. !\\
  5477. ! !INTERFACE:
  5478. !
  5479. SUBROUTINE PRESSURE_TO_MASS( region, status )
  5480. !
  5481. ! !USES:
  5482. !
  5483. use Binas, only : grav
  5484. use Grid, only : HPressure
  5485. !use Grid, only : FillMass
  5486. use Grid, only : AreaOper
  5487. use dims, only : im, jm, lm
  5488. use dims, only : xcyc
  5489. !
  5490. ! !INPUT PARAMETERS:
  5491. !
  5492. integer, intent(in) :: region
  5493. !
  5494. ! !OUTPUT PARAMETERS:
  5495. !
  5496. integer, intent(out) :: status
  5497. !
  5498. ! !REVISION HISTORY:
  5499. ! 7 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  5500. !
  5501. ! !REMARKS: (old remark: "assume that halo cells in sp have been filled
  5502. ! correctly..." still valid???)
  5503. !
  5504. !EOP
  5505. !------------------------------------------------------------------------
  5506. !BOC
  5507. character(len=*), parameter :: rname = mname//'/Pressure_to_Mass'
  5508. integer :: l, i0, i1, j0, j1, lmr
  5509. ! --- begin ----------------------------------
  5510. ! Local grid size
  5511. i0 = sp_dat(region)%is(1)
  5512. i1 = sp_dat(region)%is(2)
  5513. j0 = sp_dat(region)%js(1)
  5514. j1 = sp_dat(region)%js(2)
  5515. lmr = lm(region)
  5516. ! Fill pressure boundaries (Pa)
  5517. if ( phlb_dat(region)%used ) then
  5518. call HPressure( levi, sp_dat(region)%data(i0:i1, j0:j1, 1), &
  5519. phlb_dat(region)%data(i0:i1, j0:j1, :), status )
  5520. IF_NOTOK_RETURN(status=0)
  5521. end if
  5522. ! Fill air mass (kg)
  5523. if ( m_dat(region)%used ) then
  5524. !call FillMass( m_dat(region)%data(1:imr,1:jmr,:), lli(region), levi, &
  5525. ! sp_dat(region)%data(1:imr,1:jmr,1), status )
  5526. !IF_NOTOK_RETURN(status=0)
  5527. ! Pressure difference between top and bottom of layer
  5528. do l = 1, lmr
  5529. m_dat(region)%data(:,:,l) = phlb_dat(region)%data(:,:,l) - phlb_dat(region)%data(:,:,l+1) ! Pa
  5530. end do
  5531. ! Convert to kg/m2
  5532. m_dat(region)%data = m_dat(region)%data / grav ! Pa/g = kg/m2
  5533. ! Convert to kg
  5534. call AreaOper( lli(region), m_dat(region)%data(i0:i1, j0:j1, :), '*', 'm2', status ) ! kg
  5535. IF_NOTOK_RETURN(status=0)
  5536. end if
  5537. ! ok
  5538. status = 0
  5539. END SUBROUTINE PRESSURE_TO_MASS
  5540. !EOC
  5541. !--------------------------------------------------------------------------
  5542. ! TM5 !
  5543. !--------------------------------------------------------------------------
  5544. !BOP
  5545. !
  5546. ! !IROUTINE: MASS_TO_PRESSURE
  5547. !
  5548. ! !DESCRIPTION: get 3D and surface (spm) pressures from 3D Air Mass.
  5549. !\\
  5550. !\\
  5551. ! !INTERFACE:
  5552. !
  5553. SUBROUTINE MASS_TO_PRESSURE( region, status )
  5554. !
  5555. ! !USES:
  5556. !
  5557. use Binas, only : grav
  5558. use Grid, only : AreaOper
  5559. use dims, only : lm
  5560. !
  5561. ! !INPUT PARAMETERS:
  5562. !
  5563. integer, intent(in) :: region
  5564. !
  5565. ! !OUTPUT PARAMETERS:
  5566. !
  5567. integer, intent(out) :: status
  5568. !
  5569. ! !REVISION HISTORY:
  5570. ! 7 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  5571. !
  5572. !EOP
  5573. !------------------------------------------------------------------------
  5574. !BOC
  5575. character(len=*), parameter :: rname = mname//'/Mass_to_Pressure'
  5576. integer :: l, i0, i1, j0, j1, lmr
  5577. ! --- begin ----------------------------------
  5578. ! Local grid size
  5579. i0 = sp_dat(region)%is(1)
  5580. i1 = sp_dat(region)%is(2)
  5581. j0 = sp_dat(region)%js(1)
  5582. j1 = sp_dat(region)%js(2)
  5583. lmr = lm(region)
  5584. ! Fill pressure at half level boundaries:
  5585. ! o zero in space:
  5586. phlb_dat(region)%data(:,:,lmr+1) = 0.0 ! kg m/s2 = Pa m2
  5587. ! o add for each level pressure gradient:
  5588. do l = lmr, 1, -1
  5589. phlb_dat(region)%data(i0:i1, j0:j1, l) = phlb_dat(region)%data(i0:i1, j0:j1, l+1) &
  5590. + m_dat(region)%data(i0:i1, j0:j1, l ) * grav ! kg m/s2 = Pa m2
  5591. end do
  5592. ! Divide by grid cell area
  5593. call AreaOper( lli(region), phlb_dat(region)%data(i0:i1, j0:j1, :), '/', 'm2', status ) ! Pa
  5594. IF_NOTOK_RETURN(status=0)
  5595. ! copy surface pressure
  5596. spm_dat(region)%data(i0:i1, j0:j1, 1) = phlb_dat(region)%data(i0:i1, j0:j1, 1) ! Pa
  5597. ! ok
  5598. status = 0
  5599. END SUBROUTINE MASS_TO_PRESSURE
  5600. !EOC
  5601. !--------------------------------------------------------------------------
  5602. ! TM5 !
  5603. !--------------------------------------------------------------------------
  5604. !BOP
  5605. !
  5606. ! !IROUTINE: COMPUTE_GPH
  5607. !
  5608. ! !DESCRIPTION: compute geopotential height
  5609. !\\
  5610. !\\
  5611. ! !INTERFACE:
  5612. !
  5613. SUBROUTINE COMPUTE_GPH( region, status )
  5614. !
  5615. ! !USES:
  5616. !
  5617. use Dims, only : itau, lm
  5618. use Dims, only : at, bt
  5619. use binas, only : grav
  5620. use datetime, only : tstamp
  5621. !
  5622. ! !INPUT PARAMETERS:
  5623. !
  5624. integer, intent(in) :: region
  5625. !
  5626. ! !OUTPUT PARAMETERS:
  5627. !
  5628. integer, intent(out) :: status
  5629. !
  5630. ! !REVISION HISTORY:
  5631. ! 10 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  5632. !
  5633. !EOP
  5634. !------------------------------------------------------------------------
  5635. !BOC
  5636. character(len=*), parameter :: rname = mname//'/compute_gph'
  5637. ! --- local ----------------------------------
  5638. real,dimension(:,:,:),pointer :: gph, t, q
  5639. real,dimension(:,:,:),pointer :: ps
  5640. integer :: i,j,l,i0,i1,j0,j1
  5641. real :: tv,pdown,pup
  5642. ! --- begin -----------------------------
  5643. ! leave if not in use:
  5644. if ( .not. gph_dat(region)%used ) then
  5645. if (okdebug) then
  5646. write (gol,'(a," not used on : ",i2)') trim(gph_dat(region)%name),region; call goPr
  5647. endif
  5648. status=0; return
  5649. end if
  5650. ! other meteo required:
  5651. if ( (.not. temper_dat(region)%used) .or. (.not. humid_dat(region)%used) &
  5652. .or. (.not. sp_dat(region)%used) .or. (.not. oro_dat(region)%used)) then
  5653. write (gol,'("computation of gph requires temper, humid, sp, and oro")'); call goErr
  5654. TRACEBACK; status=1; return
  5655. end if
  5656. ! leave if input did not change:
  5657. if ( (.not. sp_dat(region)%changed) .and. &
  5658. (.not. temper_dat(region)%changed) .and. &
  5659. (.not. humid_dat(region)%changed) ) then
  5660. if (okdebug) then
  5661. write (gol,'(a,": not changed for region ",i2)') rname, region; call goPr
  5662. endif
  5663. status=0
  5664. return
  5665. end if
  5666. ! field will be changed ...
  5667. gph_dat(region)%changed = .true.
  5668. ! pointers to meteo field
  5669. ps => sp_dat(region)%data
  5670. t => temper_dat(region)%data
  5671. q => humid_dat(region)%data
  5672. gph => gph_dat(region)%data
  5673. ! bounds w/o halo (same as: call Get_DistGrid( dgrid(region), I_STRT=i01, I_STOP=i02, J_STRT=j01, J_STOP=j02 )
  5674. i0 = gph_dat(region)%is(1)
  5675. i1 = gph_dat(region)%is(2)
  5676. j0 = gph_dat(region)%js(1)
  5677. j1 = gph_dat(region)%js(2)
  5678. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5679. ! compute geo potential height
  5680. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5681. gph(i0:i1,j0:j1,1) = oro_dat(region)%data(i0:i1,j0:j1,1)/grav ! oro is stored in g*m
  5682. do l=1,lm(region)-1
  5683. do j=j0,j1
  5684. do i=i0,i1
  5685. tv = t(i,j,l)*(1. + 0.608*q(i,j,l))
  5686. pdown = at(l) + bt(l)*ps(i,j,1)
  5687. pup = at(l+1) + bt(l+1)*ps(i,j,1)
  5688. ! rgas in different units!
  5689. gph(i,j,l+1) = gph(i,j,l) + tv*287.05*alog(pdown/pup)/grav
  5690. ! note dec 2002 (MK) gph now from 1--->lm+1
  5691. end do
  5692. end do
  5693. end do
  5694. !set top of atmosphere at 200 km
  5695. gph(:,:,lm(region)+1) = 200000.0
  5696. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5697. ! done
  5698. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5699. nullify( ps )
  5700. nullify( t )
  5701. nullify( q )
  5702. nullify( gph )
  5703. status = 0
  5704. END SUBROUTINE COMPUTE_GPH
  5705. !EOC
  5706. END MODULE METEO