meteo.F90 231 KB

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