meteo.F90 287 KB

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