1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063 |
- !### macro's #####################################################
- !
- #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
- #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
- #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
- !
- #include "tm5.inc"
- #include "tmm.inc"
- !
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !MODULE: METEO
- !
- ! !DESCRIPTION: Routines to initialize/finalize meteo grids and data, allocate
- ! datasets, and fill them. Include wrappers around read/write
- ! meteo files.
- ! Perform some meteo dependend calculations (omega, gph,
- ! mass <=> pressure, ...)
- !
- !
- ! !REVISION HISTORY:
- !
- ! 09 Jun 2010 - P. Le Sager
- ! - Fix in METEO_SETUP_MASS when reading restart files.
- ! - Added some (protex) doc.
- ! - Merge updates from EC-Earth project.
- !
- ! 10 Aug 2010 - Arjo Segers
- ! - Reset previous fix since it gives differences after a restart.
- ! - Use 'pw_dat' instead of 'mfw_dat' for massflux balancing;
- ! otherwise 'mfw_dat' is changed by matching its values in a zoom
- ! region with the parent, and this would give tiny differences
- ! between a long run and two smaller runs with a restart in between.
- ! - Reformatted protex comments.
- !
- ! 10 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- !
- ! (1) Several surface pressure fields are used:
- !
- ! sp1,sp2 : Surface pressures at begin and end of dynamic time step.
- ! Their values are interpolated between surface pressures
- ! read from the meteorological archive (in real(4) !)
- ! or received from the meteorological model.
- ! Fields from the meteorological archive are stored into
- ! the 'sp2' structure, and copied from there into 'sp1'.
- !
- ! sp : Actual surface pressure due to advection.
- ! In theory this field is equal to 'sp1' at the begin of a timestep,
- ! but due to numerical inacuracies ( real(4) vs real(8) )
- ! tiny differeces occur.
- ! Therefore, this field is stored and restored in case of restart.
- !
- ! spm Surface pressure for the mid of the time interval,
- ! thus in between 'sp1' and 'sp2' .
- !
- ! !INTERFACE:
- !
- MODULE METEO
- !
- ! !USES:
- !
- use GO, only : gol, goErr, goPr, goLabel
- use GO, only : TDate
- use partools, only : isRoot
- use grid, only : TllGridInfo, TLevelInfo
- use tmm, only : TtmMeteo
- !
- use dims, only : nregions, nregions_all, okdebug
- use tm5_distgrid, only : dgrid, Get_DistGrid, GATHER, SCATTER, UPDATE_HALO
- use tm5_distgrid, only : SCATTER_J_BAND, SCATTER_I_BAND
- USE METEODATA
- IMPLICIT NONE
- PRIVATE
- !
- ! !PUBLIC MEMBER FUNCTIONS:
- !
- public :: Meteo_Init_Grids, Meteo_Done_Grids
- public :: Meteo_Init, Meteo_Done, Meteo_Alloc
- public :: Meteo_Setup_Mass, Meteo_Setup_Other
- public :: Set, Check
- public :: TimeInterpolation
- !
- ! !PRIVATE TYPES:
- !
- type TMeteoField ! storage for a single meteo field:
- logical :: used
- character(len=16) :: name
- character(len=16) :: unit
- integer :: is(2), js(2), ls(2) ! shapes
- real, pointer :: data(:,:,:)
- end type TMeteoField
- !
- ! !INTERFACE:
- !
- ! diff b/w para & serial: serial has LLI argument
- ! diff b/w 2d and 2d_n : size of 1st argument (TMeteoData)
- ! diff b/w 2d and 3d : two extra arguments for levels info
- interface Setup
- module procedure Setup_2d_para
- module procedure Setup_2d_n_para
- module procedure Setup_3d_para
- module procedure Setup_2d_serial
- module procedure Setup_2d_n_serial
- module procedure Setup_3d_serial
- end interface
-
- interface Setup_CONVEC
- module procedure Setup_CONVEC_para
- module procedure Setup_CONVEC_serial
- end interface
- interface Setup_CLOUDCOVERS
- module procedure Setup_CLOUDCOVERS_para
- module procedure Setup_CLOUDCOVERS_serial
- end interface
- !
- ! !PRIVATE DATA MEMBERS:
- !
- character(len=*), parameter :: mname = 'Meteo'
- type(TtmMeteo), save :: tmmd ! interface to TM meteo data
- real :: sp_region0(1,1) ! single cell global surface pressure (region 0)
- #ifdef with_tmm_tm5
- logical, save :: use_tiedtke
- #endif
- !
- !EOP
- !------------------------------------------------------------------------
- CONTAINS
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: METEO_INIT_GRIDS
- !
- ! !DESCRIPTION: initialize grids and levels for each region. Grids on the
- ! local domain are simply copied from the DistGrid object.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE METEO_INIT_GRIDS( status )
- !
- ! !USES:
- !
- use Grid, only : Init
- use dims, only : region_name
- use dims, only : xbeg, xend, dx, xref, im
- use dims, only : ybeg, yend, dy, yref, jm
- use dims, only : echlevs, lme, a_ec, b_ec
- use geometry, only : geomtryv
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 19 Oct 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Meteo_Init_Grids'
- integer :: n
- real :: dlon, dlat
- ! --- begin ----------------------------
- call goLabel(rname)
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! setup horizontal grids for the 0th one-cell grid
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- ! grid spacing:
- dlon = real(xend(0)-xbeg(0))/im(0)
- dlat = real(yend(0)-ybeg(0))/jm(0)
- ! define grid:
- call Init( lli(0), xbeg(0)+dlon/2.0, dlon, im(0), &
- ybeg(0)+dlat/2.0, dlat, jm(0), status, &
- name=trim(region_name(0)) )
- IF_NOTOK_RETURN(status=1)
- ! zonal grids
- dlat = real(yend(0)-ybeg(0))/jm(0)
- call Init( lli_z(0), 0.0, 360.0, 1, &
- ybeg(0)+dlat/2.0, dlat, jm(0), status, &
- name=trim(region_name(0))//'_z' )
- IF_NOTOK_RETURN(status=1)
- global_lli(0) = lli(0)
-
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! local horizontal grid : get info from Distributed Grid
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- do n=1, nregions_all
- call Get_DistGrid( dgrid(n), lli=lli(n), lli_z=lli_z(n), global_lli=global_lli(n) )
- ! correct name (it defines file to read data)
- lli(n)%name = trim(region_name(n))
- lli_z(n)%name = trim(region_name(n))//'_z'
- global_lli(n)%name = trim(region_name(n))
-
- end do
-
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! level definition
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! setup parent level definition:
- call Init( levi_ec, lme, a_ec, b_ec, status ) ! ecmwf levels
- IF_NOTOK_RETURN(status=1)
- ! setup level definition:
- call Init( levi, levi_ec, echlevs, status ) ! tm half level selection
- IF_NOTOK_RETURN(status=1)
- ! determine "old" at, bt of dims module
- call geomtryv( )
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! done
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- status = 0
- call goLabel()
- END SUBROUTINE METEO_INIT_GRIDS
- !EOC
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: METEO_DONE_GRIDS
- !
- ! !DESCRIPTION: finalize all grids and levels used for met fields.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE METEO_DONE_GRIDS( status )
- !
- ! !USES:
- !
- use Grid, only : Done
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 19 Oct 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Meteo_Done_Grids'
- integer :: n
- ! --- begin --------------------------------
- call goLabel(rname)
-
- ! horizontal (local) and zonal grids
- do n = 0, nregions_all
- call Done( lli(n), status )
- IF_NOTOK_RETURN(status=1)
-
- call Done( lli_z(n), status )
- IF_NOTOK_RETURN(status=1)
- end do
- ! horizontal (global) grids
- do n = 1, nregions_all
- call Done( global_lli(n), status )
- IF_NOTOK_RETURN(status=1)
-
- end do
-
- ! done parent level definition:
- call Done( levi_ec, status )
- IF_NOTOK_RETURN(status=1)
- ! level definition:
- call Done( levi, status )
- IF_NOTOK_RETURN(status=1)
- ! done
- status = 0
- call goLabel()
- END SUBROUTINE METEO_DONE_GRIDS
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: METEO_INIT
- !
- ! !DESCRIPTION: Init met fields, i.e. nullify pointers, store shape, and set
- ! if needed (ie used) according to meteo.rc.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE METEO_INIT( status )
- !
- ! !USES:
- !
- use GO, only : TrcFile, Init, Done, ReadRc
- use Binas, only : p_global
- use TMM, only : Init
- use dims, only : im, jm, lm, lmax_conv
- use meteodata, only : Init
- use global_data, only : rcfile
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 9 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Meteo_Init'
- ! --- local -----------------------------
- integer :: region, n
- integer :: imr, jmr, lmr
- integer :: halo
- type(TrcFile) :: rcF
- integer :: iveg
- character(len=4) :: sveg
- integer :: i01, i02, j01, j02
- ! --- begin ----------------------------
- call goLabel(rname)
- ! open rcfile:
- call Init( rcF, rcfile, status )
- IF_NOTOK_RETURN(status=1)
- #ifdef with_tmm_tm5
- ! are convection fluxes derived (Tiedtke, sub files) or from IFS (convec files)?
- call ReadRc( rcF, 'tiedtke', use_tiedtke, status )
- IF_NOTOK_RETURN(status=1)
- #endif
-
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! meteo database
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! setup interface to TM meteo:
- call Init( tmmd, rcF, status )
- IF_NOTOK_RETURN(status=1)
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! define meteo data
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! global mean surface pressure
- sp_region0 = p_global
- ! setup meteo fields: not in use, not allocated:
- do region = 1, nregions_all
- call Get_DistGrid( dgrid(region), I_STRT=i01, I_STOP=i02, J_STRT=j01, J_STOP=j02 )
- lmr = lm(region)
- !
- ! ** surface pressure *************************************
- !
- ! two extra horizontal cells
- halo = 2
- ! end of interval; also reads for sp1 and spm :
- call Init_MeteoData( sp2_dat(region), 'sp', 'Pa', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','ml','sp'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! check time interpolation:
- if ( sp2_dat(region)%tinterp(1:6) /= 'interp' ) then
- write (gol,'("surface pressure should be interpolated:")'); call goErr
- write (gol,'(" requested tinterp : ",a)') trim(sp2_dat(region)%tinterp); call goErr
- call goErr; status=1; return
- end if
- ! start of interval (copied from sp2_dat):
- call Init( sp1_dat(region), 'sp', 'Pa', 'computed', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- ! current pressure:
- call Init( sp_dat(region), 'sp', 'Pa', 'computed', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- ! surface pressure at mid of dynamic time interval:
- call Init( spm_dat(region), 'sp', 'Pa', 'computed', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- !
- ! ** 3D pressure and mass **************************
- !
- ! two extra horizontal cells (same as surface pressures)
- halo = 2
- ! pressure at half levels (lm+1):
- call Init( phlb_dat(region), 'phlb', 'Pa', 'computed', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr+1/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- ! air mass:
- call Init( m_dat(region), 'm', 'kg', 'computed', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- !
- ! ** massfluxes *************************************
- !
- ! ~~ vertical
- ! no extra cells
- halo = 0
- ! vertical flux (kg/s)
- call Init_MeteoData( mfw_dat(region), 'mfw', 'kg/s', &
- (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
- rcF, (/'* ','ml ','mflux_w'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! vertical flux (kg/s) : BALANCED
- ! NOTE: data is copied from mfw, thus use same tinterp
- ! for correct allocation of data arrays
- call Init( pw_dat(region), 'pw', 'kg/s', mfw_dat(region)%tinterp, &
- (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- ! tendency of surface pressure:
- call Init_MeteoData( tsp_dat(region), 'tsp', 'Pa/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','ml ','mflux_w'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! ~~ horizontal
- ! NOTE: strange old indexing:
- ! pu_tmpp --> pu(0:imr,1:jmr ,1:lmr) in pu_t(0:imr+1,0:jmr+1,0:lmr)
- ! ^ ^ ^ ^ too large !
- ! pv_tmpp --> pv(1:imr,1:jmr+1,1:lmr) in pv_t(0:imr+1,0:jmr+1,0:lmr)
- ! ^ ^ ^ ^ too large !
- ! The extra cells are implemented below as halo cells.
- ! one extra cell
- halo = 1
- !! east/west flux (kg/s)
- !call Init( mfu_dat(region), 'mfu', 'kg/s', tinterp_curr, &
- ! (/0,imr/), (/1,jmr/), halo, (/1,lmr/), &
- ! sourcekey_curr, write_meteo, status, default=destkey_curr )
- !IF_NOTOK_RETURN(status=1)
- !! south/north flux (kg/s)
- !call Init( mfv_dat(region), 'mfv', 'kg/s', tinterp_curr, &
- ! (/1,imr/), (/0,jmr/), halo, (/1,lmr/), &
- ! sourcekey_curr, write_meteo, status, default=destkey_curr )
- !IF_NOTOK_RETURN(status=1)
- ! east/west flux (kg/s)
- call Init_MeteoData( mfu_dat(region), 'mfu', 'kg/s', &
- (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
- rcF, (/'* ','ml ','mflux_uv'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! south/north flux (kg/s)
- call Init_MeteoData( mfv_dat(region), 'mfv', 'kg/s', &
- (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
- rcF, (/'* ','ml ','mflux_uv'/), region, status )
- IF_NOTOK_RETURN(status=1)
- !! east/west flux (kg/s) : BALANCED
- !call Init( pu_dat(region), 'pu', 'kg/s', 'computed', &
- ! (/0,imr/), (/1,jmr/), halo, (/1,lmr/), &
- ! 'no-sourcekey', .false., 'no-destkey', status )
- !IF_NOTOK_RETURN(status=1)
- !
- !! south/north flux (kg/s) : BALANCED
- !call Init( pv_dat(region), 'pv', 'kg/s', 'computed', &
- ! (/1,imr/), (/0,jmr/), halo, (/1,lmr/), &
- ! 'no-sourcekey', .false., 'no-destkey', status )
- !IF_NOTOK_RETURN(status=1)
- halo = 1
- ! east/west flux (kg/s) : BALANCED
- ! NOTE: data is copied from mfu, thus use same tinterp
- ! for correct allocation of data arrays
- call Init( pu_dat(region), 'pu', 'kg/s', mfu_dat(region)%tinterp, &
- (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- ! south/north flux (kg/s) : BALANCED
- ! NOTE: data is copied from mfv, thus use same tinterp
- ! for correct allocation of data arrays
- call Init( pv_dat(region), 'pv', 'kg/s', mfv_dat(region)%tinterp, &
- (/i01,i02/), (/j01,j02/), halo, (/0,lmr/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- !
- ! ** temperature *************************************
- !
- ! no extra cells
- halo = 0
- ! temperature (K) (halo=0)
- call Init_MeteoData( temper_dat(region), 'T', 'K', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
- rcF, (/'* ','ml ','temper'/), region, status )
- IF_NOTOK_RETURN(status=1)
- !
- ! ** humidity *************************************
- !
- ! no extra cells
- halo = 0
- ! humidity (kg/kg) (halo = 0)
- call Init_MeteoData( humid_dat(region), 'Q', 'kg/kg', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
- rcF, (/'* ','ml ','humid'/), region, status )
- IF_NOTOK_RETURN(status=1)
- !
- ! ** computed *************************************
- !
- halo = 1 ! halo needed for station output in USER_OUTPUT_AEROCOM
- ! geopotential height(m) (lm+1, halo=0)
- call Init( gph_dat(region), 'gph', 'm', 'computed', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr+1/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
-
- ! no extra cells
- halo = 0
- ! vertical velocity (Pa/s) (lm+1, halo=0)
- call Init( omega_dat(region), 'omega', 'Pa/s', 'computed', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr+1/), &
- 'no-sourcekey', .false., 'no-destkey', status )
- IF_NOTOK_RETURN(status=1)
- !
- ! ** clouds *************************************
- !
- ! no extra cells
- halo = 0
- ! lwc liquid water content (kg/kg) (halo=0)
- call Init_MeteoData( lwc_dat(region), 'CLWC', 'kg/kg', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
- rcF, (/'* ','ml ','cloud'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! iwc ice water content (kg/kg) (halo=0)
- call Init_MeteoData( iwc_dat(region), 'CIWC', 'kg/kg', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
- rcF, (/'* ','ml ','cloud'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! cc cloud cover (fraction) (halo=0)
- call Init_MeteoData( cc_dat(region), 'CC', '1', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
- rcF, (/'* ','ml ','cloud'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! cco cloud cover overhead = above bottom of box (fraction) (halo=0)
- call Init_MeteoData( cco_dat(region), 'CCO', '1', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
- rcF, (/'* ','ml ','cloud'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! ccu cloud cover underfeet = below top of box (fraction) (halo=0)
- call Init_MeteoData( ccu_dat(region), 'CCU', '1', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmr/), &
- rcF, (/'* ','ml ','cloud'/), region, status )
- IF_NOTOK_RETURN(status=1)
- !
- ! ** convection *************************************
- !
- ! no extra cells
- halo = 0
- ! entu entrainement updraft
- call Init_MeteoData( entu_dat(region), 'eu', 'kg/m2/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmax_conv/), &
- rcF, (/'* ','ml ','convec'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! entd entrainement downdraft (im,jm,lmax_conv)
- call Init_MeteoData( entd_dat(region), 'ed', 'kg/m2/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmax_conv/), &
- rcF, (/'* ','ml ','convec'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! detu detrainement updraft
- call Init_MeteoData( detu_dat(region), 'du', 'kg/m2/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmax_conv/), &
- rcF, (/'* ','ml ','convec'/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! detd detrainement downdraft
- call Init_MeteoData( detd_dat(region), 'dd', 'kg/m2/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,lmax_conv/), &
- rcF, (/'* ','ml ','convec'/), region, status )
- IF_NOTOK_RETURN(status=1)
- !
- ! *** surface fields
- !
- ! no extra cells
- halo = 0
- ! orography (m*[g])
- call Init_MeteoData( oro_dat(region), 'oro', 'm m/s2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.const','sfc.an ','oro '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! land/sea mask (%)
- call Init_MeteoData( lsmask_dat(region), 'lsm', '%', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.const','sfc.an ','lsm '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! ~~~ instantaneous fields
- ! sea surface temperatue:
- call Init_MeteoData( sst_dat(region), 'sst', 'K', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','sst '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! 10m u wind (m/s)
- call Init_MeteoData( u10m_dat(region), 'u10m', 'm/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','u10m '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! 10m v wind (m/s)
- call Init_MeteoData( v10m_dat(region), 'v10m', 'm/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','v10m '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! 10m wind speed (m/s)
- call Init_MeteoData( wspd_dat(region), 'wspd', 'm/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','wspd '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! skin reservoir content (m water) ; instant
- call Init_MeteoData( src_dat(region), 'src', 'm', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','src '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! 2 meter dewpoint temperature (K) ; instant
- call Init_MeteoData( d2m_dat(region), 'd2m', 'K', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','d2m '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! 2 meter temperature (K) ; instant
- call Init_MeteoData( t2m_dat(region), 't2m', 'K', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','t2m '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! skin temperature (K) ; instant
- call Init_MeteoData( skt_dat(region), 'skt', 'K', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','skt '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! boundary layer height (m) ; instant
- call Init_MeteoData( blh_dat(region), 'blh', 'm', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.fc ','blh '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! ~~~ average field (accumulated)
- ! surface sensible heat flux (W/m2) ; time aver
- call Init_MeteoData( sshf_dat(region), 'sshf', 'W/m2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','sshf '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! surface latent heat flux (W/m2) ; time aver
- call Init_MeteoData( slhf_dat(region), 'slhf', 'W/m2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','slhf '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! east-west surface stress (N/m2); time aver
- call Init_MeteoData( ewss_dat(region), 'ewss', 'N/m2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','ewss '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! north-south surface stress (N/m2) ; time aver
- call Init_MeteoData( nsss_dat(region), 'nsss', 'N/m2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','nsss '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! convective precipitation (m/s) ; time aver
- call Init_MeteoData( cp_dat(region), 'cp', 'm/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','cp '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! large scale stratiform precipitation (m/s) ; time aver
- call Init_MeteoData( lsp_dat(region), 'lsp', 'm/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','lsp '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! surface solar radiation ( W/m2 ) ; time aver
- call Init_MeteoData( ssr_dat(region), 'ssr', 'W/m2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','ssr '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! surface solar radiation downwards ( W/m2 ) ; time aver
- call Init_MeteoData( ssrd_dat(region), 'ssrd', 'W/m2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','ssrd '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! surface thermal radiation ( W/m2 ) ; time aver
- call Init_MeteoData( str_dat(region), 'str', 'W/m2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','str '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! surface thermal radiation downwards ( W/m2 ) ; time aver
- call Init_MeteoData( strd_dat(region), 'strd', 'W/m2', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','strd '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! snow fall (m water eqv); time aver
- call Init_MeteoData( sf_dat(region), 'sf', 'm', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','sf '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! ~~~ time averages in grib files tfc+[12,15] etc
- ! 10m wind gust (m/s)
- call Init_MeteoData( g10m_dat(region), 'g10m', 'm/s', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.aver','sfc.fc ','g10m '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! ~~~ in tmpp daily averages
- ! sea ice:
- call Init_MeteoData( ci_dat(region), 'ci', '1', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.fc ','ci '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! snow depth (m water eqv); day aver ?
- call Init_MeteoData( sd_dat(region), 'sd', 'm', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.fc ','sd '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! volumetric soil water layer 1 ( m3 water / m3 soil) ; day aver ?
- call Init_MeteoData( swvl1_dat(region), 'swvl1', '1', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.fc ','swvl1 '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! soil temperature layer 1 (K)
- call Init_MeteoData( stl1_dat(region), 'stl1', 'K', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.fc ','stl1 '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! vegetation type (%) ; day aver
- do iveg = 1, nveg
- write (sveg,'("tv",i2.2)') iveg
- call Init_MeteoData( tv_dat(region,iveg), sveg, '%', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','veg '/), region, status )
- IF_NOTOK_RETURN(status=1)
- end do
- ! low vegetation cover (0-1) ; day aver
- call Init_MeteoData( cvl_dat(region), 'cvl', '1', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','veg '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! high vegetation cover (0-1) ; day aver
- call Init_MeteoData( cvh_dat(region), 'cvh', '1', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','veg '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! albedo ; daily average
- call Init_MeteoData( albedo_dat(region), 'albedo', '1', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','albedo '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! surface roughness (ecmwf,ncep)
- call Init_MeteoData( sr_ecm_dat(region), 'sr', 'm', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','sr '/), region, status )
- IF_NOTOK_RETURN(status=1)
- ! ~~~ monthly data
- ! surface roughness (olsson) ; monthly
- call Init_MeteoData( sr_ols_dat(region), 'srols', 'm', &
- (/i01,i02/), (/j01,j02/), halo, (/1,1/), &
- rcF, (/'* ','sfc ','sfc.inst','sfc.day ','sfc.an ','srols '/), region, status )
- IF_NOTOK_RETURN(status=1)
- end do ! regions
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! done
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! close rcfile:
- call Done( rcF, status )
- IF_NOTOK_RETURN(status=1)
- ! ok
- status = 0
- call goLabel()
- END SUBROUTINE METEO_INIT
- !EOC
- !
- ! Read multiple keys in rcfile to setup meteodata structure.
- ! The following keys are read:
- !
- ! meteo.tinterp.<param> <-- time interpolation
- ! tmm.sourcekey.<grid>.<param> <-- input file name description
- ! tmm.output.<grid>.<param> <-- write meteo ?
- ! tmm.destkey.<grid>.<param> <-- output file name description
- !
- ! where <grid> is first '*' and then set to the grid name,
- ! and <param> is set to each of the provided keys.
- !
- ! Called for region=1..nregions_all
-
- SUBROUTINE INIT_METEODATA( md, name, unit, is, js, halo, ls, &
- rcF, rcs, region, status )
-
- use GO, only : TRcFile, ReadRc
- use Dims, only : nregions, nregions_max
- use MeteoData, only : TMeteoData, Init, Set
-
- ! --- in/out -------------------------------------
-
- type(TMeteoData), intent(out) :: md
- character(len=*), intent(in) :: name, unit
- integer, intent(in) :: is(2), js(2)
- integer, intent(in) :: halo
- integer, intent(in) :: ls(2)
- type(TRcFile), intent(inout) :: rcF
- character(len=*), intent(in) :: rcs(:)
- integer, intent(in) :: region
- integer, intent(out) :: status
-
- ! --- const --------------------------------------
-
- character(len=*), parameter :: rname = mname//'/Init_MeteoData'
-
- ! --- local -------------------------------------
-
- character(len=10) :: tinterp
- character(len=256) :: sourcekey
- logical :: write_meteo
- character(len=256) :: destkey
- logical :: used
- ! --- begin -------------------------------------
- ! time interpolation :
- call ReadRc( rcF, 'meteo.tinterp', rcs, tinterp, status )
- IF_NOTOK_RETURN(status=1)
- ! source filenames:
- call ReadRc( rcF, 'tmm.sourcekey.*', rcs, sourcekey, status, default='no-sourcekey' )
- IF_ERROR_RETURN(status=1)
- call ReadRc( rcF, 'tmm.sourcekey.'//trim(lli(region)%name), rcs, sourcekey, status, default=sourcekey )
- IF_ERROR_RETURN(status=1)
- ! write flag:
- call ReadRc( rcF, 'tmm.output.*', rcs, write_meteo, status, default=.false. )
- IF_ERROR_RETURN(status=1)
- call ReadRc( rcF, 'tmm.output.'//trim(lli(region)%name), rcs, write_meteo, status, default=write_meteo )
- IF_ERROR_RETURN(status=1)
- ! destination filenames:
- if ( write_meteo ) then
- call ReadRc( rcF, 'tmm.destkey.*', rcs, destkey, status, default='no-destkey' )
- IF_ERROR_RETURN(status=1)
- call ReadRc( rcF, 'tmm.destkey.'//trim(lli(region)%name), rcs, destkey, status, default=destkey )
- IF_ERROR_RETURN(status=1)
- else
- destkey = 'no-destkey'
- end if
- ! define meteo data,
- ! but should be marked as 'used' to be allocated and filled:
- call Init( md, name, unit, tinterp, is, js, halo, ls, &
- sourcekey, write_meteo, destkey, status )
- IF_NOTOK_RETURN(status=1)
-
- ! read this type of meteo ?
- ! only regions 1..nregions or the extra fiels above nregions_max
- ! could be in use:
- ! [all regions, but do "if test", because nregions may be different from nregions_max]
- if ( (region <= nregions) .or. (region > nregions_max) ) then
- call ReadRc( rcF, 'meteo.read.*', rcs, used, status, default=.false. )
- IF_ERROR_RETURN(status=1)
- call ReadRc( rcF, 'meteo.read.'//trim(lli(region)%name), rcs, used, status, default=used )
- IF_ERROR_RETURN(status=1)
- else
- used = .false.
- end if
-
- ! in use ?
- call Set( md, status, used=used )
- IF_NOTOK_RETURN(status=1)
- ! ok
- status = 0
-
- END SUBROUTINE INIT_METEODATA
-
- ! ***
- SUBROUTINE METEO_DONE( status )
- use TMM, only : Done
- use Dims, only : nregions_all
- use meteodata, only : Done
- ! --- in/out -------------------------------
-
- integer, intent(out) :: status
-
- ! --- const --------------------------------------
-
- character(len=*), parameter :: rname = mname//'/Meteo_Done'
-
- ! --- local -----------------------------
-
- integer :: n
- integer :: iveg
- ! --- begin --------------------------------
- call goLabel(rname)
-
- ! interface to TM meteo:
- call Done( tmmd, status )
- IF_NOTOK_RETURN(status=1)
-
- !
- ! done meteo data
- !
- ! destroy meteo fields:
- do n = 1, nregions_all
- ! ***
-
- call Done( sp1_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( sp2_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( sp_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( spm_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
- call Done( phlb_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( m_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
- call Done( mfu_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( mfv_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( mfw_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( tsp_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( pu_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( pv_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( pw_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- call Done( temper_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( humid_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( gph_dat(n), status )
- IF_NOTOK_RETURN(status=1)
-
- call Done( omega_dat(n), status )
- IF_NOTOK_RETURN(status=1)
-
- ! ***
-
- call Done( lwc_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( iwc_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( cc_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( cco_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( ccu_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- call Done( entu_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( entd_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( detu_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( detd_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
- call Done( oro_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( lsmask_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( albedo_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( sr_ecm_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( sr_ols_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( ci_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( sst_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( u10m_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( v10m_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( wspd_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( g10m_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( src_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( d2m_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( t2m_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( blh_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( sshf_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( slhf_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( ewss_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( nsss_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( cp_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( lsp_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( ssr_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( ssrd_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( str_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( strd_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( skt_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( sd_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( sf_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( swvl1_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( stl1_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- do iveg = 1, nveg
- call Done( tv_dat(n,iveg), status )
- IF_NOTOK_RETURN(status=1)
- end do
- call Done( cvl_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- call Done( cvh_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- end do ! regions
- ! ok
- status = 0
- call goLabel()
- END SUBROUTINE METEO_DONE
-
- ! ***
- SUBROUTINE METEO_ALLOC( status )
-
- use dims, only : nregions_all
- use meteodata, only : Alloc
- ! --- in/out -------------------------------
-
- integer, intent(out) :: status
-
- ! --- const --------------------------------------
-
- character(len=*), parameter :: rname = mname//'/Meteo_Alloc'
-
- ! --- local -----------------------------
-
- integer :: region
- integer :: iveg
- ! --- begin --------------------------------
-
- call goLabel(rname)
-
- ! allocate meteo fields if in use:
- do region = 1, nregions_all
- ! ***
-
- call Alloc( sp1_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( sp2_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( sp_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( spm_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- call Alloc( phlb_dat(region), status )
- IF_NOTOK_RETURN(status=1)
-
- call Alloc( m_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- call Alloc( mfu_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( mfv_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( mfw_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( tsp_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( pu_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( pv_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( pw_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- call Alloc( temper_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( humid_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( gph_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( omega_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- call Alloc( lwc_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( iwc_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( cc_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( cco_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( ccu_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- call Alloc( entu_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( entd_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( detu_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( detd_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
- call Alloc( oro_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( lsmask_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( albedo_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( sr_ecm_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( sr_ols_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( ci_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( sst_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( u10m_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( v10m_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( wspd_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( src_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( d2m_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( t2m_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( skt_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( blh_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( sshf_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( slhf_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( ewss_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( nsss_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( cp_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( lsp_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( ssr_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( ssrd_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( str_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( strd_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( sd_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( sf_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( g10m_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( swvl1_dat(region), status )
- IF_NOTOK_RETURN(status=1)
-
- call Alloc( stl1_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- do iveg = 1, nveg
- call Alloc( tv_dat(region,iveg), status )
- IF_NOTOK_RETURN(status=1)
- end do
- call Alloc( cvl_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- call Alloc( cvh_dat(region), status )
- IF_NOTOK_RETURN(status=1)
- ! ***
-
- end do ! regions
- ! ok
- status = 0
- call goLabel()
- END SUBROUTINE METEO_ALLOC
-
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: METEO_SETUP_MASS
- !
- ! !DESCRIPTION: Set up Mass FLuxes and Surface Pressures
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE METEO_SETUP_MASS( tr1, tr2, status, isfirst, check_pressure )
- !
- ! !USES:
- !
- use go, only : TDate, rTotal, operator(-), wrtgol
- use go, only : IncrDate, operator(+), Get
- use grid, only : Match, TllGridInfo, assignment(=), Done
- use Grid, only : FillMassChange, BalanceMassFluxes, CheckMassBalance
- use dims, only : nregions, im, jm, lm, parent
- use dims, only : xcyc
- use meteodata, only : SetData ! to copy %data and %tr from one MD to another
- #ifdef with_prism
- use meteodata, only : TimeInterpolation
- #endif
- use restart, only : Restart_Read
- !
- ! !INPUT PARAMETERS:
- !
- type(TDate), intent(in) :: tr1, tr2
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- logical, intent(in), optional :: check_pressure
- logical, intent(in), optional :: isfirst
- !
- ! !REVISION HISTORY:
- !
- ! 12 Mar 2010 - P. Le Sager - Fix when reading restart files. Added
- ! protex doc. Added comments.
- ! 9 Jun 2010 - P. Le Sager - Merged with updates for EC-Earth project.
- !
- ! 10 Aug 2010, Arjo Segers
- ! Reset previous fix since it makes a restart different from a long run.
- ! Use 'pw_dat' instead of 'mfw_dat' since otherwise the later changed
- ! while matching a zoom region with its parent, and this would give
- ! tiny differences during a restart of a zoomed run.
- !
- ! 9 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- !
- ! push of Surf Press is done with sp2 (the only one on which we call
- ! setup -ie the only one for which %data1 and %data2 matter). Only %data
- ! of SP and SP1 are updated and used, and not their %data1 and %data2.
- !
- !------------------------------------------------------------------------------
- !EOP
- character(len=*), parameter :: rname = mname//'/Meteo_Setup_Mass'
- logical :: do_check_pressure, WestBorder, NorthBorder
- logical :: do_isfirst
- integer :: n, p
- integer :: idater(6)
- real, allocatable :: dm_dt(:,:,:)
- real :: dt_sec
- integer :: l, i0, i1, j0, j1, is, js, ie, je
- real :: tol_rms, tol_diff
- type(TllGridInfo) :: L_lli
- real, pointer :: field(:,:), field_parent(:,:) ! work arrays
- real, allocatable :: islice(:,:), jslice(:,:), bigIslice(:,:), bigJslice(:,:)
- real, allocatable :: full_pu(:,:,:), full_pv(:,:,:), full_pw(:,:,:), full_dm_dt(:,:,:)
- #ifdef with_prism
- integer :: hour1, dhour
- #endif
-
- ! --- begin --------------------------------
-
- call goLabel(rname)
-
- ! check pressure ?
- if ( present(check_pressure) ) then
- do_check_pressure = check_pressure
- else
- do_check_pressure = .false.
- end if
- ! EC-EARTH do not check pressure since we would compare pressure from
- ! restart file at 00 ( as written by previous chunk) with the one received
- ! at 06 (or whatever the coupling period is) from IFS
- do_check_pressure = .false.
-
- ! initial call ?
- if ( present(isfirst) ) then
- do_isfirst = isfirst
- else
- do_isfirst = .false.
- end if
- !
- ! ** MASS FLUXES *************************************
- !
- do n = 1, nregions_all
- L_lli = global_lli(n)
-
- call Setup_UVW( n, mfu_dat(n), mfv_dat(n), mfw_dat(n), tsp_dat(n),&
- (/tr1,tr2/), L_lli, 'n', levi, 'w', status)
- IF_NOTOK_RETURN(status=1)
- end do
- !
- ! ** SURFACE PRESSURES : SP1, SP *****************************
- !
- REG: do n = 1, nregions_all
-
- if ( .not. sp1_dat(n)%used ) cycle
-
- L_lli = global_lli(n)
- ! Advance 'next' surface pressure (a/k/a sp2%data) to start of
- ! new interval tr1. If start of a new meteo interval, then data
- ! is automatically read from file, or recieved from coupler
- ! with OASIS/prism
- call Setup( n, sp2_dat(n), (/tr1,tr1/), L_lli, 'n', status )
- IF_NOTOK_RETURN(status=1)
- ! copy SP2 into SP1 (%data and %tr)
- call SetData( sp1_dat(n), sp2_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- ! GATHER sp1 array (dummy if not root)
- !-----------------
- ! ...of parent region, if any:
- if ( n /= 1 ) then
-
- p = parent(n)
- if (isRoot) then
- allocate( field_parent(im(p), jm(p)) )
- else
- allocate( field_parent(1,1) )
- end if
- call GATHER( dgrid(p), sp1_dat(p)%data(:,:,1), field_parent, sp1_dat(p)%halo, status )
- IF_NOTOK_RETURN(status=1)
-
- end if
- ! ...of current region:
- if (isRoot) then
- allocate( field(im(n), jm(n)) )
- else
- allocate( field(1,1) )
- end if
-
- call GATHER( dgrid(n), sp1_dat(n)%data(:,:,1), field, sp1_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- ! MATCH surface pressures to ensure mass balance
- !-----------------
- if (isRoot) then
- ! IF global field (i.e first region) : match global region with one-cell
- ! world value (average global surface pressure), ELSE match with parent
- if ( n == 1 ) then
- call Match( 'area-aver', 'n', lli(0), sp_region0, &
- global_lli(n), field, status )
- IF_NOTOK_RETURN(status=1)
- else
- call Match( 'area-aver', 'n', global_lli(p), field_parent, &
- global_lli(n), field, status )
- IF_NOTOK_RETURN(status=1)
- endif
- end if
- ! SCATTER sp1 array, and clean
- !-----------------
- call SCATTER( dgrid(n), sp1_dat(n)%data(:,:,1), field, sp1_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
-
- deallocate(field)
- if ( n /= 1 ) then
- if (associated(field_parent)) deallocate(field_parent)
- endif
- ! Set SP
- !-----------------
- ! If initial call *OR* beginning of new meteo interval in case of coupled runs,
- ! then set current surface pressure to just read/advanced sp1. Otherwise, sp
- ! remains filled with the advected pressure.
- #ifdef with_prism
- if ( sp2_dat(n)%sourcekey(1:6) == 'prism:' ) then
- select case ( sp2_dat(n)%tinterp )
- case ( 'interp6' ) ; dhour = 6
- case ( 'interp3' ) ; dhour = 3
- case ( 'interp2' ) ; dhour = 2
- case ( 'interp1' ) ; dhour = 1
- case default
- write (gol,'("unsupported time interpolation:")'); call goErr
- write (gol,'(" md%tinterp : ",a)') trim(sp2_dat(n)%tinterp); call goErr
- TRACEBACK; status=1; return
- end select
- call Get( tr1, hour=hour1 )
-
- !else partial coupling - not handled here
- endif
-
- ! at begin of dhour interval ?
- if ( modulo(hour1,dhour) == 0 ) then
- #else
- if ( do_isfirst ) then
- #endif
- ! write (gol,'(" copy SP1 to SP ...")'); call goPr
- ! copy sp1 into sp :
- call SetData( sp_dat(n), sp1_dat(n), status )
- IF_NOTOK_RETURN(status=1)
- ! fill pressure and mass from sp
- call Pressure_to_Mass( n, status )
- IF_NOTOK_RETURN(status=1)
-
- #ifndef with_prism
- ! Eventually replace with fields from restart file, since meteo from hdf meteo
- ! files is in real(4) while computed pressures and mass are probably in
- ! real(8). But not for coupled runs, since they receive pressures from
- ! IFS. Note that this call will do nothing if istart=32.
- call Restart_Read( status, surface_pressure=.true., pressure=.true., air_mass=.true. )
- IF_NOTOK_RETURN(status=1)
- !AJS>>> don't do this! sp1 contains data interpolated between
- ! fields received from the archive or the coupled model,
- ! while sp contains the actual pressure after advection.
- !! copy sp into sp1 (PLS, 29-3-2010)
- !call SetData( sp1_dat(n), sp_dat(n), status )
- !IF_NOTOK_RETURN(status=1)
- !<<<
- #endif
- end if ! first or new coupling meteo
- !! fill initial pressure and mass arrays,
- !! eventually apply cyclic boundaries to mass
- !call Meteo_SetupMass( n, status )
- !IF_NOTOK_RETURN(status=1)
- ! check 'advected' pressure ?
- if ( do_check_pressure) then
- ! compare 'advected' pressure still in sp with just read
- ! pressure sp1 : diff b/w sp%data and sp1%data
- call Meteo_CheckPressure( n, status )
- IF_NOTOK_RETURN(status=1)
- end if
- END DO REG ! regions
- !
- ! ** SURFACE PRESSURES : SP2 *****************************
- !
- REG2: do n = 1, nregions_all
- if ( .not. sp2_dat(n)%used ) cycle
- ! grid and bounds
- L_lli = global_lli(n)
- i0 = sp2_dat(n)%is(1)
- i1 = sp2_dat(n)%is(2)
- j0 = sp2_dat(n)%js(1)
- j1 = sp2_dat(n)%js(2)
-
- #ifdef with_prism
-
- ! sp2 for prism coupler is computed from : sp(t2) = sp(t1) + tsp*(t2-t1)
- if ( sp2_dat(n)%sourcekey(1:6) == 'prism:' ) then
-
- select case ( sp2_dat(n)%tinterp )
- case ( 'interp6' ) ; dhour = 6
- case ( 'interp3' ) ; dhour = 3
- case ( 'interp2' ) ; dhour = 2
- case ( 'interp1' ) ; dhour = 1
- case default
- write (gol,'("unsupported time interpolation:")'); call goErr
- write (gol,'(" md%tinterp : ",a)') trim(sp2_dat(n)%tinterp); call goErr
- TRACEBACK; status=1; return
- end select
-
- ! current interval [tr1,tr2] at begin of dhour interval ?
- call Get( tr1, hour=hour1 )
- if ( modulo(hour1,dhour) == 0 ) then
- ! reset sp2_dat%data1 and sp2_dat%data2:
- ! Read into sp2%data1 : surface pressure received for tr1
- ! set filled flags to false to force re-reading if necessary;
- ! prism received lnsp fields are stored in cache
- ! thus re-reading is fast and error-free
- sp2_dat(n)%filled1 = .false.
- sp2_dat(n)%filled2 = .false.
- call Setup( n, sp2_dat(n), (/tr1,tr1/), L_lli, 'n', status )
- IF_NOTOK_RETURN(status=1)
- ! %data2 = %data1 + tsp * dhour*3600.0
- !write (gol,'(" compute sp2%data2 from sp2%data1 and sp tendency ...")'); call goPr
- dt_sec = dhour * 3600.0 ! sec
- sp2_dat(n)%data2(i0:i1,j0:j1,1) = &
- sp2_dat(n)%data1(i0:i1,j0:j1,1) + tsp_dat(n)%data(i0:i1,j0:j1,1) * dt_sec
- sp2_dat(n)%tr2 = tr1 + IncrDate(sec=nint(dt_sec))
- endif
- ! Once SP2_DAT contains data1 and data2 valid for a dhour interval, %data is
- ! simply interpolated between %data1 and %data2:
- !call wrtgol( ' interpolate sp2%data to : ', tr2 ); call goPr
- call TimeInterpolation( sp2_dat(n), (/tr2,tr2/), status )
- IF_NOTOK_RETURN(status=1)
- else
- ! PLS: this one is never used apparently... AJS: it might be used in a partial
- ! coupling with only some fields exchanged and others read; this was often the
- ! case during the first coupling experiments, and might be useful for testing
- ! advance 'next' surface pressure to end of interval:
- call Setup( n, sp2_dat(n), (/tr2,tr2/), L_lli, 'n', status )
- IF_NOTOK_RETURN(status=1)
- end if ! it is prism sourcekey
- #else
- ! advance 'next' surface pressure to end of interval:
- call Setup( n, sp2_dat(n), (/tr2,tr2/), L_lli, 'n', status )
- IF_NOTOK_RETURN(status=1)
- #endif /* WITH_PRISM */
-
- ! GATHER sp2 array (dummy if not root)
- !-----------------
- ! ...of parent region, if any:
- if ( n /= 1 ) then
- p = parent(n)
- if (isRoot) then
- allocate( field_parent(im(p), jm(p)) )
- else
- allocate( field_parent(1,1) )
- end if
- call GATHER( dgrid(p), sp2_dat(p)%data(:,:,1), field_parent, sp2_dat(p)%halo, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! ...of current region:
- if (isRoot) then
- allocate( field(im(n), jm(n)) )
- else
- allocate( field(1,1) )
- end if
- call GATHER( dgrid(n), sp2_dat(n)%data(:,:,1), field, sp2_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- ! MATCH surface pressures to ensure mass balance
- !-----------------
- if (isRoot) then
- ! IF global field (i.e first region) : match global region with one-cell
- ! world value (average global surface pressure), ELSE match with parent
- if ( n == 1 ) then
- call Match( 'area-aver', 'n', lli(0), sp_region0, &
- global_lli(n), field, status )
- IF_NOTOK_RETURN(status=1)
- else
- call Match( 'area-aver', 'n', global_lli(p), field_parent, &
- global_lli(n), field, status )
- IF_NOTOK_RETURN(status=1)
- endif
- end if
- ! SCATTER sp2 array, and clean
- !-----------------
- call SCATTER( dgrid(n), sp2_dat(n)%data(:,:,1), field, sp2_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- deallocate(field)
- if ( n /= 1 ) then
- if (associated(field_parent)) deallocate(field_parent)
- endif
- END DO REG2 ! regions
- #ifndef without_advection
- !
- ! ** MASS BALANCE *****************************
- !
- ! NOTE: since only the surface pressure gradient is used,
- ! it is not necessary to use the data1 and data2 arrays
- do n = 1, nregions_all
- if ( .not. pu_dat(n)%used ) cycle
- if ( .not. pv_dat(n)%used ) cycle
- if ( .not. pw_dat(n)%used ) cycle
- L_lli = global_lli(n)
- i0 = sp2_dat(n)%is(1)
- i1 = sp2_dat(n)%is(2)
- j0 = sp2_dat(n)%js(1)
- j1 = sp2_dat(n)%js(2)
- ! local indices and tile location (is, ie, js, je must be equal to i0, i1, j0, j1 BTW)
- CALL GET_DISTGRID( dgrid(n), &
- I_STRT=is, I_STOP=ie, &
- J_STRT=js, J_STOP=je, &
- hasWestBorder=WestBorder, hasNorthBorder=NorthBorder)
-
- ! length of time step between sp1 and sp2:
- dt_sec = rTotal( sp2_dat(n)%tr(1) - sp1_dat(n)%tr(1), 'sec' )
- ! allocate temporary array:
- allocate(dm_dt(i0:i1,j0:j1,lm(n)))
- ! mass change (kg) :
- call FillMassChange( dm_dt, lli(n), levi, &
- sp1_dat(n)%data(i0:i1,j0:j1,1), &
- sp2_dat(n)%data(i0:i1,j0:j1,1), &
- status )
- IF_NOTOK_RETURN(status=1)
- ! mass tendency (kg/s) :
- dm_dt = dm_dt / dt_sec ! kg/s
- ! >>> data1 >>>
- ! initial guess for balanced fluxes are unbalanced fluxes:
- pu_dat(n)%data1 = mfu_dat(n)%data1
- pu_dat(n)%filled1 = mfu_dat(n)%filled1
- pu_dat(n)%tr1 = mfu_dat(n)%tr1
- pv_dat(n)%data1 = mfv_dat(n)%data1
- pv_dat(n)%filled1 = mfv_dat(n)%filled1
- pv_dat(n)%tr1 = mfv_dat(n)%tr1
- pw_dat(n)%data1 = mfw_dat(n)%data1
- pw_dat(n)%filled1 = mfw_dat(n)%filled1
- pw_dat(n)%tr1 = mfw_dat(n)%tr1
- !#ifdef with_prism
- ! EC-Earth 2.4 discussion - Coupling has changed in EC-Earth 3.
- !
- ! Skip initial mass balance; relative large differences might exist
- ! between pressure imposed by mass fluxes and pressure according to
- ! surface pressure tendencies since the later is based on:
- !
- ! sp(t-1)+tsp(t-1) _ *
- ! _ - o-------* sp(t), sp(t)+tsp(t)
- ! sp(t-1) o
- !
- ! PLS : I do not understand that diagram... tsp is for an
- ! interval, and sp for a point in time. This may be
- ! wrong then.
- !
- ! AJS : This describes what the CTM received before the above
- ! described update. The 'tsp' was *not* for an interval but
- ! an instantaneous field describing the 'direction' of the surface
- ! pressure in time (you might call this 'tendency', but that is a
- ! dangerous word in GEMS IFS-CTM coupling context).
- ! Thus, at time 't-1' the only estimate of 'sp(t)' we could make was:
- ! sp(t-1)+tsp(t-1)
- ! At time 't' we received the actual 'sp(t)' and this was of course
- ! different from the initial guess.
- !
- !#else
- ! CHECK INITIAL MASS BALANCE:
- ! -----------------------------------
- ! NOTE: strange old indexing:
- ! 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))
- ! 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))
- ! tolerance for difference between sp from mass fluxes and sp from tendency:
- tol_rms = 1.0e-4 ! max rms
- tol_diff = 1.0e-3 ! max absolute difference
-
- CALL UPDATE_HALO( dgrid(n), pu_dat(n)%data1, pu_dat(n)%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL UPDATE_HALO( dgrid(n), pv_dat(n)%data1, pv_dat(n)%halo, status)
- IF_NOTOK_RETURN(status=1)
- call CheckMassBalance( lli(n), &
- pu_dat(n)%data1(i0-1:i1, j0:j1 , 1:lm(n) ), &
- pv_dat(n)%data1( i0:i1, j0:j1+1, 1:lm(n) ), &
- sp1_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
- sp2_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
- dt_sec, tol_rms, tol_diff, status )
- if (status/=0) then
- write (gol,'("initial mass imbalance too large for region ",i2)') n; call goErr
- call goErr; status=1; return
- end if
- !#endif
- ! BALANCE HORIZONTAL FLUXES
- ! -----------------------------------
- ! NOTE: strange old indexing:
- ! 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))
- ! 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))
- ! needs to be done globally... so gather data
- if (isRoot) then
- allocate(full_pu( 0:im(n), 1:jm(n), 0:lm(n)) ) ! must have same number of levels as mfu
- allocate(full_pv( 1:im(n), 1:jm(n)+1, 0:lm(n)) )
- allocate(full_pw( 1:im(n), 1:jm(n), 0:lm(n)) ) ! used also as temp arr in comm
- allocate(full_dm_dt(im(n), jm(n), lm(n)) )
- else
- allocate( full_pu(1,1,1) )
- allocate( full_pv(1,1,1) )
- allocate( full_pw(1,1,1) )
- allocate( full_dm_dt(1,1,1))
- end if
-
- !for slice scattering
- allocate(islice(j0:j1,0:lm(n)))
- allocate(jslice(i0:i1,0:lm(n)))
- if (isRoot) then
- allocate(bigIslice(1:jm(n),0:lm(n)))
- allocate(bigJslice(1:im(n),0:lm(n)))
- else
- allocate(bigIslice(1,1))
- allocate(bigJslice(1,1))
- end if
- call GATHER( dgrid(n), pu_dat(n)%data1, full_pw, pu_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- if (isRoot) then
- full_pu(1:im(n),1:jm(n),:) = full_pw
- full_pu(0,:,:) = full_pu(im(n),:,:) ! East-West periodicity
- end if
- call GATHER( dgrid(n), pv_dat(n)%data1, full_pw, pv_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- if (isRoot) then
- full_pv(1:im(n),1:jm(n),:) = full_pw
- full_pv(:,jm(n)+1,:) = full_pv(:,1,:) ! donut periodicity
- end if
- call GATHER( dgrid(n), dm_dt, full_dm_dt, 0, status )
- IF_NOTOK_RETURN(status=1)
-
- call GATHER( dgrid(n), pw_dat(n)%data1, full_pw, pw_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- if (isRoot) then
- call BalanceMassFluxes( global_lli(n), &
- full_pu(0:im(n),1:jm(n) ,1:lm(n)), &
- full_pv(1:im(n),1:jm(n)+1,1:lm(n)), &
- full_pw, full_dm_dt, global_lli(parent(n)), dt_sec, status )
- IF_NOTOK_RETURN(status=1)
- end if
- call SCATTER( dgrid(n), pw_dat(n)%data1, full_pw, pw_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- if(isRoot) full_pw = full_pu(1:im(n),1:jm(n),:)
- call SCATTER( dgrid(n), pu_dat(n)%data1, full_pw, pu_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- ! scatter extra column full_pu(0,:,:) - needed only for noncyclic zoom
- ! region, for others update_halo takes care of it [FIXME: could had a
- ! test around these 3 lines ]
- if(isRoot) bigIslice = full_pu(0,1:jm(n),:)
- CALL SCATTER_I_BAND( dgrid(n), islice, bigIslice, status, iref=1)
- if(WestBorder)pu_dat(n)%data1(0,j0:j1,0:lm(n)) = islice
- if(isRoot) full_pw = full_pv(1:im(n),1:jm(n),:)
- call SCATTER( dgrid(n), pv_dat(n)%data1, full_pw, pv_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
-
- ! Scatter PV(:,jm+1,:)
- if(isroot) bigJslice=full_pv(1:im(n),jm(n)+1,:)
- CALL SCATTER_J_BAND( dgrid(n), jslice, bigJslice, status, jref=jm(n))
- if(NorthBorder)pv_dat(n)%data1(i0:i1,jm(n)+1,0:lm(n))=jslice
-
- ! CHECK FINAL MASS BALANCE:
- ! -----------------------------------
- ! NOTE: strange old indexing:
- ! 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))
- ! 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))
- ! tolerance for difference between sp from mass fluxes and sp from tendency:
- tol_rms = 1.0e-7 ! max rms
- tol_diff = 1.0e-6 ! max absolute difference
-
- CALL UPDATE_HALO( dgrid(n), pu_dat(n)%data1, pu_dat(n)%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL UPDATE_HALO( dgrid(n), pv_dat(n)%data1, pv_dat(n)%halo, status)
- IF_NOTOK_RETURN(status=1)
- call CheckMassBalance( lli(n), &
- pu_dat(n)%data1(i0-1:i1, j0:j1 , 1:lm(n) ), &
- pv_dat(n)%data1( i0:i1, j0:j1+1, 1:lm(n) ), &
- sp1_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
- sp2_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
- dt_sec, tol_rms, tol_diff, status )
- if (status/=0) then
- write (gol,'("final mass imbalance too large for region ",i2)') n; call goErr
- call goErr; status=1; return
- end if
- !done
- deallocate(full_pw, full_pu, full_pv, full_dm_dt, bigJslice, bigIslice,&
- jslice, islice)
-
-
- ! >>> data2 >>>
- if ( any((/mfu_dat%filled2,mfv_dat%filled2,mfw_dat%filled2/)) ) then
- if ( .not. all((/mfu_dat(n)%filled2,mfv_dat(n)%filled2,mfw_dat(n)%filled2/)) ) then
- write (gol,'("either none or all secondary data should be in use:")'); call goErr
- write (gol,'(" mfu_dat%filled2 : ",l1)') mfu_dat(n)%filled2; call goErr
- write (gol,'(" mfv_dat%filled2 : ",l1)') mfv_dat(n)%filled2; call goErr
- write (gol,'(" mfw_dat%filled2 : ",l1)') mfw_dat(n)%filled2; call goErr
- call goErr; status=1; return
- end if
- ! initial guess for balanced fluxes are unbalanced fluxes:
- pu_dat(n)%data2 = mfu_dat(n)%data2
- pu_dat(n)%filled2 = .true.
- pu_dat(n)%tr2 = mfu_dat(n)%tr2
- pv_dat(n)%data2 = mfv_dat(n)%data2
- pv_dat(n)%filled2 = .true.
- pv_dat(n)%tr2 = mfv_dat(n)%tr2
- pw_dat(n)%data2 = mfw_dat(n)%data2
- pw_dat(n)%filled2 = .true.
- pw_dat(n)%tr2 = mfw_dat(n)%tr2
- ! CHECK INITIAL MASS BALANCE:
- ! -----------------------------------
- ! NOTE: strange old indexing:
- ! 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))
- ! 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))
-
- CALL UPDATE_HALO( dgrid(n), pu_dat(n)%data2, pu_dat(n)%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL UPDATE_HALO( dgrid(n), pv_dat(n)%data2, pv_dat(n)%halo, status)
- IF_NOTOK_RETURN(status=1)
- call CheckMassBalance( lli(n), &
- pu_dat(n)%data2(i0-1:i1, j0:j1 , 1:lm(n) ), &
- pv_dat(n)%data2( i0:i1, j0:j1+1, 1:lm(n) ), &
- sp1_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
- sp2_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
- dt_sec, 1.0e-4, 1.0e-3, status )
- if (status/=0) then
- write (gol,'("initial mass imbalance too large for region ",i2)') n; call goErr
- call goErr; status=1; return
- end if
- ! BALANCE HORIZONTAL FLUXES
- ! -----------------------------------
- ! balance horizontal fluxes:
- ! NOTE: strange old indexing:
- ! 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))
- ! 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))
- if (isRoot) then
- allocate(full_pu( 0:im(n), 1:jm(n), 0:lm(n)) ) ! must have same number of levels as mfu
- allocate(full_pv( 1:im(n), 1:jm(n)+1, 0:lm(n)) )
- allocate(full_pw( 1:im(n), 1:jm(n), 0:lm(n)) ) ! used also as temp arr in comm
- allocate(full_dm_dt(im(n), jm(n), lm(n)) )
- else
- allocate( full_pu(1,1,1) )
- allocate( full_pv(1,1,1) )
- allocate( full_pw(1,1,1) )
- allocate( full_dm_dt(1,1,1))
- end if
- !for slice scattering
- allocate(islice(j0:j1,0:lm(n)))
- allocate(jslice(i0:i1,0:lm(n)))
- if (isRoot) then
- allocate(bigIslice(1:jm(n),0:lm(n)))
- allocate(bigJslice(1:im(n),0:lm(n)))
- else
- allocate(bigIslice(1,1))
- allocate(bigJslice(1,1))
- end if
- call GATHER( dgrid(n), pu_dat(n)%data2, full_pw, pu_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- if (isRoot) then
- full_pu(1:im(n),1:jm(n),:) = full_pw
- full_pu(0,:,:) = full_pu(im(n),:,:) ! East-West periodicity
- end if
- call GATHER( dgrid(n), pv_dat(n)%data2, full_pw, pv_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- if (isRoot) then
- full_pv(1:im(n),1:jm(n),:) = full_pw
- full_pv(:,jm(n)+1,:) = full_pv(:,1,:) ! donut periodicity
- end if
- call GATHER( dgrid(n), dm_dt, full_dm_dt, 0, status )
- IF_NOTOK_RETURN(status=1)
- call GATHER( dgrid(n), pw_dat(n)%data2, full_pw, pw_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- if (isRoot) then
- call BalanceMassFluxes( global_lli(n), &
- full_pu(0:im(n),1:jm(n) ,1:lm(n)), &
- full_pv(1:im(n),1:jm(n)+1,1:lm(n)), &
- full_pw, full_dm_dt, global_lli(parent(n)), dt_sec, status )
- IF_NOTOK_RETURN(status=1)
- end if
- call SCATTER( dgrid(n), pw_dat(n)%data2, full_pw, pw_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- if(isRoot) full_pw = full_pu(1:im(n),1:jm(n),:)
- call SCATTER( dgrid(n), pu_dat(n)%data2, full_pw, pu_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- ! scatter extra column full_pu(0,:,:) - needed only for noncyclic zoom
- ! regions, for others update_halo takes care of it [FIXME: could had a
- ! test around these 3 lines ]
- if(isRoot) bigIslice = full_pu(0,1:jm(n),:)
- CALL SCATTER_I_BAND( dgrid(n), islice, bigIslice, status, iref=1)
- if(WestBorder) pu_dat(n)%data2(0,j0:j1,:) = islice
- if(isRoot) full_pw = full_pv(1:im(n),1:jm(n),:)
- call SCATTER( dgrid(n), pv_dat(n)%data2, full_pw, pv_dat(n)%halo, status )
- IF_NOTOK_RETURN(status=1)
- ! Scatter PV(:,jm+1,:)
- if(isroot) bigJslice=full_pv(1:im(n),jm(n)+1,:)
- CALL SCATTER_J_BAND( dgrid(n), jslice, bigJslice, status, jref=jm(n))
- if(NorthBorder)pv_dat(n)%data2(i0:i1,jm(n)+1,:)=jslice
- ! CHECK FINAL MASS BALANCE:
- ! -----------------------------------
- ! NOTE: strange old indexing:
- ! 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))
- ! 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))
- CALL UPDATE_HALO( dgrid(n), pu_dat(n)%data2, pu_dat(n)%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL UPDATE_HALO( dgrid(n), pv_dat(n)%data2, pv_dat(n)%halo, status)
- IF_NOTOK_RETURN(status=1)
- call CheckMassBalance( lli(n), &
- pu_dat(n)%data2(i0-1:i1, j0:j1 , 1:lm(n) ), &
- pv_dat(n)%data2( i0:i1, j0:j1+1, 1:lm(n) ), &
- sp1_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
- sp2_dat(n)%data ( i0:i1, j0:j1 , 1 ), &
- dt_sec, 1.0e-7, 1.0e-6, status )
- if (status/=0) then
- write (gol,'("final mass imbalance too large for region ",i2)') n; call goErr
- call goErr; status=1; return
- end if
- deallocate(full_pw, full_pu, full_pv, full_dm_dt, bigJslice, bigIslice,&
- jslice, islice)
- end if ! filled2
- ! >>>
- ! clear
- deallocate( dm_dt )
- end do ! regions
- #endif /* ADVECTION */
- !------------
- ! Done
- !------------
- call done(l_lli, status)
- IF_NOTOK_RETURN(status=1)
-
- status = 0
- call goLabel()
- END SUBROUTINE METEO_SETUP_MASS
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: METEO_SETUP_OTHER
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE METEO_SETUP_OTHER( tr1, tr2, status, isfirst )
- !
- ! !USES:
- !
- use GO, only : TDate, NewDate, rTotal, wrtgol
- use GO, only : operator(-), operator(+), operator(/)
- use GO, only : InterpolFractions
- use dims, only : nregions, im, jm, lm
- use dims, only : lmax_conv
- use dims, only : xcyc
- use Dims, only : czeta
- use global_data, only : region_dat
- #ifndef without_convection
- use global_data, only : conv_dat
- #endif
- use Phys, only : ConvCloudDim
- !
- ! !INPUT PARAMETERS:
- !
- type(TDate), intent(in) :: tr1, tr2
- logical, intent(in), optional :: isfirst
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 9 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Meteo_Setup_Other'
-
- logical :: do_isfirst
- integer :: n, p
- integer :: i, j, l
- integer :: lsave, i0, i1, j0, j1
- real :: tote, totd, maxe
- real, pointer :: dxyp(:)
- type(TDate) :: tmid
- real :: alfa1, alfa2
- integer :: iveg
- ! --- begin --------------------------------
-
- call goLabel(rname)
-
- ! initial call ?
- if ( present(isfirst) ) then
- do_isfirst = isfirst
- else
- do_isfirst = .false.
- end if
- !
- ! ** orography *****************************
- !
- ! read orographies (if necessary):
- do n = 1, nregions_all
- #ifdef parallel_cplng
- call setup( n, oro_dat(n), (/tr1,tr2/), 'n', status )
- #else
- call setup( n, oro_dat(n), (/tr1,tr2/), global_lli(n), 'n', status )
- #endif
- IF_NOTOK_RETURN(status=1)
- end do
- !
- ! ** spm **************************************
- !
- do n = 1, nregions
-
- ! skip ?
- if ( .not. spm_dat(n)%used ) cycle
-
- ! mid time:
- tmid = tr1 + ( tr2 - tr1 )/2
-
- ! deterimine weights to sp1 and sp2 :
- call InterpolFractions( tmid, sp1_dat(n)%tr(1), sp2_dat(n)%tr(1), alfa1, alfa2, status )
- IF_NOTOK_RETURN(status=1)
- call Get_DistGrid( dgrid(n), I_STRT=i0, I_STOP=i1, J_STRT=j0, J_STOP=j1 )
- ! interpolate:
- spm_dat(n)%data(i0:i1,j0:j1,1) = alfa1 * sp1_dat(n)%data(i0:i1,j0:j1,1) + &
- alfa2 * sp2_dat(n)%data(i0:i1,j0:j1,1)
- ! store time:
- spm_dat(n)%tr = (/tr1,tr2/)
-
- end do ! regions
- !
- ! ** omega **************************************
- !
- do n = 1, nregions_all
-
- ! re-compute omega from vertical mass flux:
- call Compute_Omega( omega_dat(n), lli(n), mfw_dat(n), status )
- IF_NOTOK_RETURN(status=1)
-
- end do ! regions
-
- !
- ! ** temperature and humid **************************************
- !
- do n = 1, nregions_all
-
- ! ncep meteo requires conversion of virtual temperature using humidity ...
- if ( (temper_dat(n)%sourcekey(1:4) == 'ncep') .or. (humid_dat(n)%sourcekey(1:4) == 'ncep') ) then
-
- ! read temperature and humidity (if necessary):
- call setup_TQ( n, temper_dat(n), humid_dat(n), (/tr1,tr2/), global_lli(n), levi, status)
- IF_NOTOK_RETURN(status=1)
-
- else
- ! read temperature (if necessary):
- #ifdef parallel_cplng
- call setup( n, temper_dat(n), (/tr1,tr2/), 'n', levi, 'n', status)
- IF_NOTOK_RETURN(status=1)
-
- ! read humidity (if necessary):
- call setup( n, humid_dat(n), (/tr1,tr2/), 'n', levi, 'n', status)
- IF_NOTOK_RETURN(status=1)
- #else
- call setup( n, temper_dat(n), (/tr1,tr2/), global_lli(n), 'n', levi, 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! read humidity (if necessary):
- call setup( n, humid_dat(n), (/tr1,tr2/), global_lli(n), 'n', levi, 'n', status)
- IF_NOTOK_RETURN(status=1)
- #endif
- end if
-
- end do ! regions
- !
- ! ** gph **************************************
- !
- do n = 1, nregions_all
-
- ! re-compute gph from pressure, temperature, and humidity:
- call compute_gph( n, status )
- IF_NOTOK_RETURN(status=1)
-
- end do
-
- !
- ! ** clouds **************************************
- !
- do n = 1, nregions
- #ifdef parallel_cplng
-
- call setup( n, lwc_dat(n), (/tr1,tr2/), 'n', levi, 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( n, iwc_dat(n), (/tr1,tr2/), 'n', levi, 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup_CloudCovers( n, cc_dat(n), cco_dat(n), ccu_dat(n), (/tr1,tr2/), levi, status)
- IF_NOTOK_RETURN(status=1)
- #else
- call setup( n, lwc_dat(n), (/tr1,tr2/), global_lli(n), 'n', levi, 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( n, iwc_dat(n), (/tr1,tr2/), global_lli(n), 'n', levi, 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup_CloudCovers( n, cc_dat(n), cco_dat(n), ccu_dat(n), (/tr1,tr2/), global_lli(n), levi, status)
- IF_NOTOK_RETURN(status=1)
- #endif
- end do
- !
- ! ** convection **************************************
- !
- do n = 1, nregions
- #ifdef parallel_cplng
- call setup_Convec( n, entu_dat(n), entd_dat(n), detu_dat(n), detd_dat(n), &
- omega_dat(n), gph_dat(n), (/tr1,tr2/), levi, status )
- IF_NOTOK_RETURN(status=1)
- #else
- call setup_Convec( n, entu_dat(n), entd_dat(n), detu_dat(n), detd_dat(n), &
- omega_dat(n), gph_dat(n), (/tr1,tr2/), global_lli(n), levi, status )
- IF_NOTOK_RETURN(status=1)
- #endif
- end do
- #ifndef without_convection
- ! ~~ convective clouds
- do n = 1, nregions
- if ( .not. entu_dat(n)%used ) cycle
- if ( .not. entd_dat(n)%used ) cycle
- ! update necessary ?
- if ( any((/entu_dat(n)%changed,entd_dat(n)%changed/)) ) then
-
- call Get_DistGrid( dgrid(n), I_STRT=i0, I_STOP=i1, J_STRT=j0, J_STOP=j1 )
-
- do j = j0, j1
- do i = i0, i1
- ! compute convective cloud dimensions for this column:
- call ConvCloudDim( 'u', size(detu_dat(n)%data,3), &
- detu_dat(n)%data(i,j,:), entd_dat(n)%data(i,j,:),&
- conv_dat(n)%cloud_base(i,j), &
- conv_dat(n)%cloud_top (i,j), &
- conv_dat(n)%cloud_lfs (i,j), &
- status )
- IF_NOTOK_RETURN(status=1)
- end do
- end do
- end if ! changed
- end do ! regions
- #endif
- ! ~~ unit conversion
-
- do n = 1, nregions
-
- if ( .not. entu_dat(n)%used ) cycle
- if ( .not. entd_dat(n)%used ) cycle
- if ( .not. detu_dat(n)%used ) cycle
- if ( .not. detd_dat(n)%used ) cycle
- ! update necessary ?
- if ( any((/ entu_dat(n)%changed, entd_dat(n)%changed, &
- detu_dat(n)%changed, detd_dat(n)%changed /)) ) then
- call Get_DistGrid( dgrid(n), I_STRT=i0, I_STOP=i1, J_STRT=j0, J_STOP=j1 )
- !cmk calculate the rates in kg/gridbox and scale with czeta
- dxyp => region_dat(n)%dxyp
- do j = j0, j1
- do i = i0, i1
- ! kg/m2/s -> kg/gridbox/s * scale_factor
- entu_dat(n)%data(i,j,:) = entu_dat(n)%data(i,j,:)*dxyp(j)*czeta
- detu_dat(n)%data(i,j,:) = detu_dat(n)%data(i,j,:)*dxyp(j)*czeta
- ! ensure netto zero tracer transport by updraught in column
- ! (add difference between total entrement and detrement
- ! to level where entrement reaches maximum):
- tote = sum( entu_dat(n)%data(i,j,:) )
- totd = sum( detu_dat(n)%data(i,j,:) )
- maxe = entu_dat(n)%data(i,j,1) ! changed: reported by PB feb 2003
- lsave = 1
- do l = 2, lmax_conv
- if ( entu_dat(n)%data(i,j,l) > maxe ) then
- maxe = entu_dat(n)%data(i,j,l)
- lsave = l
- end if
- end do
- entu_dat(n)%data(i,j,lsave) = entu_dat(n)%data(i,j,lsave) - tote + totd
- ! kg/m2/s -> kg/gridbox/s * scale_factor
- entd_dat(n)%data(i,j,:) = entd_dat(n)%data(i,j,:)*dxyp(j)*czeta
- detd_dat(n)%data(i,j,:) = detd_dat(n)%data(i,j,:)*dxyp(j)*czeta
- ! ensure netto zero tracer transport by downdraught in column
- ! (add difference between total entrement and detrement
- ! to level where entrement reaches maximum):
- tote = sum( entd_dat(n)%data(i,j,:) ) ! total entrainement
- totd = sum( detd_dat(n)%data(i,j,:) ) ! total detrainement
- maxe = 0.0
- lsave = lmax_conv
- do l = 1, lmax_conv
- if ( entd_dat(n)%data(i,j,l) > maxe ) then
- maxe = entd_dat(n)%data(i,j,l)
- lsave = l
- end if
- end do
- entd_dat(n)%data(i,j,lsave) = entd_dat(n)%data(i,j,lsave) - tote + totd
- end do
- end do
- end if ! changed ?
-
- end do ! regions
- !
- ! ** surface fields *****************************
- !
- #ifdef parallel_cplng
- ! * lsmask
-
- call setup( lsmask_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * albedo
- call setup( albedo_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * sr_ecm
- call setup( sr_ecm_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #else
- ! * lsmask
-
- call setup( lsmask_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * albedo
- call setup( albedo_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * sr_ecm
- call setup( sr_ecm_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #endif
-
- ! * sr_ols
- call setup( sr_ols_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #ifdef parallel_cplng
- ! * sea ice
-
- call setup( ci_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * sea surface temperature
- call setup( sst_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * u10m
- call setup( u10m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * v10m
- call setup( v10m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * windspeed
-
- call setup( wspd_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * skin reservoir content
- call setup( src_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * 2m dewpoint temperature
- call setup( d2m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * 2m temperature
- call setup( t2m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * slhf
- call setup( slhf_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * sshf
- call setup( sshf_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * surface stress
- call setup( ewss_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( nsss_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * convective precipitation
- call setup( cp_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * large scale stratiform precipitation
- call setup( lsp_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * surface solar radiation
- call setup( ssr_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( ssrd_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * surface thermal radiation
- call setup( str_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( strd_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * skin temperature
- call setup( skt_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * boundary layer height
- #ifndef with_tmm_ecearth
- call setup( blh_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #endif
-
- ! * snow fall and depth
- call setup( sf_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( sd_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * g10m
- #ifndef with_tmm_ecearth
- call setup( g10m_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #endif
-
- ! * soil water level 1
- call setup( swvl1_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * soil temperature level 1
-
- call setup( stl1_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * vegetation types
- do iveg = 1, nveg
- select case ( iveg )
- case ( 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 16, 17, 18, 19 )
- call setup( tv_dat(1:nregions_all,iveg), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- case ( 8, 12, 14, 15, 20 )
- if ( tv_dat(n,iveg)%used ) tv_dat(n,iveg)%data = 0.0
- case default
- write (gol,'("do not know how to setup vegetation type ",i2)') iveg
- call goErr; status=1; return
- end select
- end do
- ! * low vegetation cover
- call setup( cvl_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * high vegetation cover
- call setup( cvh_dat(1:nregions_all), (/tr1,tr2/), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #else
- ! * sea ice
-
- call setup( ci_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * sea surface temperature
- call setup( sst_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * u10m
- call setup( u10m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * v10m
- call setup( v10m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * windspeed
-
- call setup( wspd_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * skin reservoir content
- call setup( src_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * 2m dewpoint temperature
- call setup( d2m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * 2m temperature
- call setup( t2m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * slhf
- call setup( slhf_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * sshf
- call setup( sshf_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * surface stress
- call setup( ewss_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( nsss_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * convective precipitation
- call setup( cp_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * large scale stratiform precipitation
- call setup( lsp_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * surface solar radiation
- call setup( ssr_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( ssrd_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * surface thermal radiation
- call setup( str_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( strd_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * skin temperature
- call setup( skt_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * boundary layer height
- #ifndef with_tmm_ecearth
- call setup( blh_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #endif
- ! * snow fall and depth
- call setup( sf_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- call setup( sd_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * g10m
- #ifndef with_tmm_ecearth
- call setup( g10m_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #endif
- ! * soil water level 1
- call setup( swvl1_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * vegetation types
- do iveg = 1, nveg
- select case ( iveg )
- case ( 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 16, 17, 18, 19 )
- call setup( tv_dat(1:nregions_all,iveg), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- case ( 8, 12, 14, 15, 20 )
- if ( tv_dat(n,iveg)%used ) tv_dat(n,iveg)%data = 0.0
- case default
- write (gol,'("do not know how to setup vegetation type ",i2)') iveg
- call goErr; status=1; return
- end select
- end do
- ! * low vegetation cover
- call setup( cvl_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * high vegetation cover
- call setup( cvh_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- ! * MACC emissions
- call setup( ch4fire_dat(1:nregions_all), (/tr1,tr2/), global_lli(1:nregions_all), 'n', status)
- IF_NOTOK_RETURN(status=1)
- #endif
- !
- ! ** done ********************************************
- !
- status = 0
- call goLabel()
- END SUBROUTINE METEO_SETUP_OTHER
- !EOC
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUPSETUP
- !
- ! !DESCRIPTION: for one met data MD and one time range TR, returns the dates
- ! at begining and end of the met field interval that
- ! encompasses TR, and if the data for these dates (%data1 and
- ! %data2, resp.) must be read or copied.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUPSETUP( md, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- !
- ! !USES:
- !
- use GO, only : TDate, NewDate, IncrDate, AnyDate, IsAnyDate, Get, Set, wrtgol
- use GO, only : rTotal, iTotal
- use GO, only : operator(+), operator(-), operator(/)
- use GO, only : operator(==), operator(/=), operator(<), operator(<=)
- use meteodata, only : TMeteoData
- use global_data, only : fcmode, tfcday0
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: md
- !
- ! !INPUT PARAMETERS:
- !
- type(TDate), intent(in) :: tr(2)
- !
- ! !OUTPUT PARAMETERS:
- !
- logical, intent(out) :: data1_read, data1_copy
- type(TDate), intent(out) :: data1_tref, data1_t1, data1_t2
- logical, intent(out) :: data2_read, data2_copy
- type(TDate), intent(out) :: data2_tref, data2_t1, data2_t2
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 29 Mar 2010 - P. Le Sager -
- !
- !EOP
- !------------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/SetupSetup'
- integer :: dth, baseh
- integer :: year, month, day, hour, minu
- type(TDate) :: tmid
- type(TDate) :: tc(2)
- integer :: dth_int
- type(TDate) :: tprev, tnext
- real :: dhr
- ! --- begin -----------------------------
- call goLabel(rname)
-
- ! default output:
- data1_read = .false.
- data1_copy = .false.
- data2_read = .false.
- data2_copy = .false.
-
- !
- ! trap constant fields ...
- !
-
- ! constant and already filled ? then leave
- if ( (md%tinterp == 'const') .and. md%filled1 ) then
- call goLabel()
- status = 0; return
- end if
-
- !
- ! fc stuff
- !
-
- ! 3 hourly data only available up to 72h, then 6 hourly
- if ( fcmode ) then
- ! number of hours from fcday 00:00 to end of requested interval:
- dhr = rTotal( tr(2) - tfcday0, 'hour' )
- ! lower time resolution after a while ...
- if ( tfcday0 < NewDate(year=2006,month=03,day=14) ) then
- ! after 12+72 hour ?
- if ( dhr > 12.0 + 72.0 ) then
- ! convert time interpolation:
- select case ( md%tinterp )
- case ( 'aver3' )
- write (gol,'("WARNING - convert time interpolation from `aver3` to `aver6`")'); call goPr
- md%tinterp = 'aver6'
- case ( 'interp3' )
- write (gol,'("WARNING - convert time interpolation from `interp3` to `interp6`")'); call goPr
- md%tinterp = 'interp6'
- end select
- end if ! > 72 hour
- else
- ! after 12+96 hour ?
- if ( dhr > 12.0 + 96.0 ) then
- ! convert time interpolation:
- select case ( md%tinterp )
- case ( 'aver3' )
- write (gol,'("WARNING - convert time interpolation from `aver3` to `aver6`")'); call goPr
- md%tinterp = 'aver6'
- case ( 'interp3' )
- write (gol,'("WARNING - convert time interpolation from `interp3` to `interp6`")'); call goPr
- md%tinterp = 'interp6'
- end select
- end if ! > 96 hour
- end if ! change in fc resolution
- end if ! fcmode
-
-
- !
- ! time stuff
- !
-
- ! basic time resolution in hours
- select case ( md%tinterp )
- case ( 'const', 'month' )
- ! nothing to be set here ...
- case ( 'aver24' )
- ! constant fields produced valid for [00,24]
- dth = 24
- baseh = 00
- case ( 'aver24_3' )
- ! constant fields produced by tmpp valid for [21,21] = [09-12,09+12]
- dth = 24
- baseh = -3
- case ( 'const3', 'interp3', 'aver3', 'cpl3' )
- dth = 3
- baseh = 0
- case ( 'interp2', 'cpl2' )
- dth = 2
- baseh = 0
- case ( 'const1', 'interp1', 'aver1', 'cpl1' )
- dth = 1
- baseh = 0
- case ( 'const6', 'interp6', 'aver6', 'cpl6' )
- dth = 6
- baseh = 0
- case ( 'interp6_3' )
- dth = 6
- baseh = 3
- case default
- write (gol,'("unsupported time interpolation : ",a)') md%tinterp; call goErr
- call goErr; status=1; return
- end select
- ! set time parameters for field to be read:
- select case ( md%tinterp )
- !
- ! ** constant fields
- !
- case ( 'const' )
- ! read main field ?
- data1_read = .not. md%filled1
- ! read or leave ?
- if ( data1_read ) then
- data1_tref = tr(1) ! <--- used for file names
- data1_t1 = AnyDate()
- data1_t2 = AnyDate()
- else
- ! field valid around requested interval, thus leave:
- call goLabel()
- status=0; return
- end if
- !
- ! ** constant fields, valid for complete month
- !
- case ( 'month' )
- ! extract time values for begin of current interval:
- call Get( tr(1), year=year, month=month )
- ! interval for this month:
- tc(1) = NewDate( year=year, month=month, day=01, hour=00 )
- month = month + 1
- if ( month > 12 ) then
- month = 1
- year = year + 1
- end if
- tc(2) = NewDate( year=year, month=month, day=01, hour=00 )
- ! check for strange values:
- if ( (tr(1) < tc(1)) .or. (tc(2) < tr(2)) ) then
- write (gol,'("determined invalid constant interval:")'); call goErr
- call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
- call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
- write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
- call goErr; status=1; return
- !write (gol,'(" WARNING - requested interval exceeds meteo interval; should be improved")')
- end if
- ! read main field ?
- if ( md%filled1 ) then
- data1_read = md%tr1(1) /= tc(1)
- else
- data1_read = .true.
- end if
- ! read or leave ?
- if ( data1_read ) then
- data1_tref = tr(1)
- data1_t1 = tc(1)
- data1_t2 = tc(2)
- else
- ! field valid around requested interval, thus leave:
- call goLabel()
- status=0; return
- end if
- !
- ! ** constant fields, valid for 24hr intervals [21:00,21:00]
- ! constant fields, valid for 6hr intervals [21:00,03:00] etc
- ! constant fields, valid for 3hr intervals [22:30,01:30] etc
- !
- case ( 'const6', 'const3' )
- ! extract time values for begin of current interval:
- call Get( tr(1), year, month, day, hour, minu )
- ! round hour to 00/06/12/18 or 00/03/06/09/12/15/18/21 or 09
- hour = dth * nint(real(hour+minu/60.0-baseh)/real(dth)) + baseh
- ! set mid of 3 or 6 hour interval:
- tmid = NewDate( year, month, day, hour )
- ! interval with constant field
- tc(1) = tmid - IncrDate(hour=dth)/2
- tc(2) = tmid + IncrDate(hour=dth)/2
- ! check for strange values:
- if ( (tr(1) < tc(1)) .or. (tc(2) < tr(2)) ) then
- write (gol,'("determined invalid constant interval:")'); call goErr
- call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
- call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
- write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
- call goErr; status=1; return
- end if
- ! read main field ?
- if ( md%filled1 ) then
- data1_read = md%tr1(1) /= tmid
- else
- data1_read = .true.
- end if
- ! read or leave ?
- if ( data1_read ) then
- data1_tref = tmid
- data1_t1 = tmid
- data1_t2 = tmid
- else
- ! field valid around requested interval, thus leave:
- call goLabel()
- status=0; return
- end if
- !
- ! ** couple fields, valid for 3hr intervals [00:00,03:00] etc
- ! input filed valid for BEGIN of interval !
- !
- case ( 'cpl6', 'cpl3', 'cpl2', 'cpl1' )
- ! extract time values for begin of current interval:
- call Get( tr(1), year, month, day, hour, minu )
- ! round hour to previous baseh + 00/03/06/09/12/15/18/21
- hour = dth * floor(real(hour-baseh)/real(dth)) + baseh
- ! interval with constant field
- tc(1) = NewDate( year, month, day, hour )
- tc(2) = tc(1) + IncrDate(hour=dth)
-
- ! check for strange values:
- if ( (tr(1) < tc(1)) .or. (tc(2) < tr(1)) ) then
- write (gol,'("determined invalid first interval:")'); call goErr
- call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
- call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
- write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
- call goErr; status=1; return
- end if
-
- ! read primary field ?
- if ( md%filled1 ) then
- ! read new field if times are different:
- data1_read = (md%tr1(1) /= tc(1)) .or. (md%tr1(2) /= tc(1))
- else
- ! not filled yet, thus must read:
- data1_read = .true.
- end if
- ! read or leave ?
- if ( data1_read ) then
- data1_tref = tc(1) ! begin of time interval
- data1_t1 = tc(1)
- data1_t2 = tc(1)
- end if
- !
- ! ** average fields, valid for 3hr intervals [00:00,03:00] etc
- ! average fields, valid for 3hr intervals [00:00,06:00] etc
- !
- case ( 'aver1', 'aver3', 'aver6', 'aver24', 'aver24_3' )
- ! extract time values for begin of current interval:
- call Get( tr(1), year, month, day, hour, minu )
- ! round hour to previous baseh + 00/03/06/09/12/15/18/21
- hour = dth * floor(real(hour-baseh)/real(dth)) + baseh
- ! interval with constant field
- tc(1) = NewDate( year, month, day, hour )
- tc(2) = tc(1) + IncrDate(hour=dth)
- ! check for strange values:
- if ( (tr(1) < tc(1)) .or. (tc(2) < tr(1)) ) then
- write (gol,'("determined invalid first interval:")'); call goErr
- call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
- call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
- write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
- call goErr; status=1; return
- end if
- ! read primary field ?
- if ( md%filled1 ) then
- ! read new field if times are different:
- data1_read = (md%tr1(1) /= tc(1)) .or. (md%tr1(2) /= tc(2))
- else
- ! not filled yet, thus must read:
- data1_read = .true.
- end if
- if ( data1_read ) then
- data1_tref = tc(1)
- data1_t1 = tc(1)
- data1_t2 = tc(2)
- end if
- ! setup reading of secondary data only if end of requested
- ! interval is later than primary interval:
- if ( tc(2) < tr(2) ) then
- ! extract time values for end of requested interval:
- call Get( tr(2), year, month, day, hour, minu )
- ! round hour to next baseh + 00/03/06/09/12/15/18/21
- hour = dth * floor(real(hour+minu/60.0-baseh)/real(dth)) + baseh
- ! interval with constant field
- tc(1) = NewDate( year, month, day ) + IncrDate(hour=hour)
- tc(2) = tc(1) + IncrDate(hour=dth)
- ! check for strange values:
- if ( (tr(2) < tc(1)) .or. (tc(2) < tr(2)) ) then
- write (gol,'("determined invalid second interval:")'); call goErr
- call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
- call wrtgol( ' guessed : ', tc(1), ' - ', tc(2) ); call goErr
- write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
- call goErr; status=1; return
- end if
- ! read secondary field ?
- if ( md%filled2 ) then
- ! read new field if times are different;
- data2_read = (md%tr2(1) /= tc(1)) .or. (md%tr2(2) /= tc(2))
- else
- ! not filled yet, thus must read:
- data2_read = .true.
- end if
- if ( data2_read ) then
- data2_tref = tc(1)
- data2_t1 = tc(1)
- data2_t2 = tc(2)
- end if
- end if ! tr partly after primary interval
- !
- ! ** interpolated between 6 hourly times 00/06/12/18
- ! interpolated between 6 hourly times 03/09/15/21
- ! interpolated between 3 hourly times 00/03/06/09/12/15/18/21
- !
- case ( 'interp6', 'interp6_3', 'interp3', 'interp2', 'interp1' )
- ! extract time values for begin of current interval:
- call Get( tr(1), year, month, day, hour, minu )
- ! truncate hour to previous 00/06/12/18, 03/09/15/21,
- ! or 00/03/06/09/12/15/18/21
- hour = dth * floor(real(hour+minu/60.0-baseh)/real(dth)) + baseh
- ! set begin of 3 or 6 hour interval:
- tprev = NewDate( year, month, day, hour )
- ! extract time values for end of current interval:
- call Get( tr(2), year, month, day, hour, minu )
- ! truncate hour to previous 00/06/12/18
- hour = dth * ceiling(real(hour+minu/60.0-baseh)/real(dth)) + baseh
- ! set end of 3 or 6 hour interval:
- tnext = NewDate( year, month, day, hour )
- ! checks:
- ! [tprev,tmax] should be dth hours
- ! [tprev,tmax] should contain [tr(1),tr(2)]
- dth_int = iTotal(tnext-tprev,'hour')
- if ( (tr(1) < tprev) .or. (tnext < tr(2)) .or. &
- ( (dth_int /= 0) .and. (dth_int /= dth) ) ) then
- write (gol,'("determined invalid interpolation interval:")'); call goErr
- call wrtgol( ' requested : ', tr(1), ' - ', tr(2) ); call goErr
- call wrtgol( ' guessed : ', tprev, ' - ', tnext ); call goErr
- write (gol,'(" for tinterp : ",a)') md%tinterp; call goErr
- call goErr; status=1; return
- end if
-
- !
- ! . <-- previous field at dth hours
- ! o <-- latest interpolated field
- ! x <-- target
- ! o <-- next field at dth hours
- ! tr1 tr tr2
- ! --+--------------+------
- ! tprev tnext
- !
- ! read main field ?
- if ( md%filled1 ) then
- ! md%data should be defined in [tprev,tr]
- data1_read = (md%tr1(1) < tprev) .or. (tr(2) < md%tr1(1))
- else
- data1_read = .true.
- end if
- if ( data1_read ) then
- data1_tref = tprev
- data1_t1 = tprev
- data1_t2 = tprev
- end if
- ! read second field ?
- if ( md%filled2 ) then
- ! md%data should be defined for tnext
- data2_read = md%tr2(1) /= tnext
- else
- data2_read = .true.
- end if
- if ( data2_read ) then
- data2_tref = tnext
- data2_t1 = tnext
- data2_t2 = tnext
- end if
-
- !
- ! ** error ...
- !
- case default
- write (gol,'("unsupported time interpolation : ",a)') md%tinterp ; call goErr
- call goErr; status=1; return
- end select
-
-
- !
- ! set ref times
- !
-
- if ( fcmode ) then
- ! in forecast mode, tfcday0 is 00:00 at the day the forecast starts;
- data1_tref = tfcday0
- data2_tref = tfcday0
- else
- ! dummy tref's : begin of day in which [data?_t1,data?_t2] starts:
- data1_tref = data1_t1
- if ( IsAnyDate(data1_tref) ) data1_tref = tr(1)
- call Set( data1_tref, hour=0, min=0, sec=0, mili=0 )
-
- data2_tref = data2_t1
- if ( IsAnyDate(data2_tref) ) data2_tref = tr(1)
- call Set( data2_tref, hour=0, min=0, sec=0, mili=0 )
-
- end if
-
- !
- ! trap double reading
- !
-
- ! data already in data2 ?
- if ( data1_read .and. md%filled2 ) then
- if ( (data1_t1 == md%tr2(1)) .and. (data1_t2 == md%tr2(2)) ) then
- data1_read = .false.
- data1_copy = .true.
- end if
- end if
-
- ! data2 just read ?
- if ( data2_read .and. data1_read ) then
- ! data2 is same as data ?
- if ( (data2_tref == data1_tref) .and. &
- (data2_t1 == data1_t1) .and. (data2_t2 == data1_t2) ) then
- data2_read = .false.
- data2_copy = .true.
- end if
- end if
-
- !write (gol,'("SetupSetup:")'); call goPr
- !write (gol,'(" fcmode : ",l1)') fcmode; call goPr
- !call wrtgol( ' tfcday0 : ', tfcday0 ); call goPr
- !write (gol,'(" md%tinterp : ",a)') trim(md%tinterp); call goPr
- !call wrtgol( ' tr(1) : ', tr(1) ); call goPr
- !call wrtgol( ' tr(2) : ', tr(2) ); call goPr
- !write (gol,'(" 1 read,copy : ",2l2)') data1_read, data1_copy; call goPr
- !call wrtgol( ' 1 tref : ', data1_tref ); call goPr
- !call wrtgol( ' 1 t1 : ', data1_t1 ); call goPr
- !call wrtgol( ' 1 t2 : ', data1_t2 ); call goPr
- !write (gol,'(" 2 read,copy : ",2l2)') data2_read, data2_copy; call goPr
- !call wrtgol( ' 2 tref : ', data2_tref ); call goPr
- !call wrtgol( ' 2 t1 : ', data2_t1 ); call goPr
- !call wrtgol( ' 2 t2 : ', data2_t2 ); call goPr
- ! ok
- status = 0
- call goLabel()
-
- end subroutine SetupSetup
- !EOC
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUP_2D_SERIAL
- !
- ! !DESCRIPTION: Fill md%data1 and md%data2 of a 2D met field type (md), with
- ! data for date tr(1) and tr(2) respectively (and if needed)
- ! through reading or copying. Also write to disk the met field
- ! if requested.
- !
- ! Then set md%data according to its type of interpolation (see
- ! TimeInterpolation in meteodata.F90).
- ! For constant type, %data => %data1.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUP_2D_SERIAL( region, md, tr, lli, nuv, status )
- !
- ! !USES:
- !
- use GO, only : TDate, wrtgol
- use Grid, only : TllGridInfo
- use TMM, only : ReadField, Read_SP, Read_SR_OLS, WriteField
- use meteodata, only : TMeteoData, TimeInterpolation
- use dims, only : im, jm
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: md ! met field
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region ! region number
- type(TDate), intent(in) :: tr(2) ! dates
- type(TllGridInfo), intent(in) :: lli ! grid (GLOBAL)
- character(len=1), intent(in) :: nuv ! staggering
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status ! return code
- !
- ! !REVISION HISTORY:
- ! 4 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Setup_2d_serial'
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
-
- real, pointer :: field(:,:) ! work array
- ! --- begin -----------------------------
-
- call goLabel(rname)
-
- ! leave if not in use:
- if ( .not. md%used ) then
- call goLabel()
- status=0; return
- end if
- if (okdebug) then
- write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md%name),trim(lli%name); call goPr
- endif
-
- ! not changed by default
- md%changed = .false.
-
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read or copy
-
- call SetupSetup( md, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! -------------------------
- ! Read/write primary field
- ! -------------------------
- if ( data1_read ) then
- ! Switch to global
- if ( md%ls(1) /= md%ls(2) ) then
- write (gol,'("SETUP_2D called instead of SETUP_3D, field is 3D:")'); call goErr
- write (gol, '(" md%ls(1:2) : ",2i3)') md%ls; call goErr
- status=1; IF_NOTOK_RETURN(status=1)
- end if
- ! Need whole region for I/O on root. Dummy else.
- IF (isRoot) THEN
- ALLOCATE( field( im(region), jm(region)) )
- ELSE
- ALLOCATE( field(1,1) )
- END IF
-
- ! Read/write
- IOroot : IF (isRoot) THEN
- select case ( md%name )
- case ( 'sp', 'sps' )
- ! special routine for surface pressure
- call Read_SP( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, FIELD, md%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- case ( 'srols' )
- ! special routine for Olsson surface roughness:
- call Read_SR_OLS( tmmd, md%sourcekey, &
- data1_tref, data1_t1, data1_t2, &
- lli, FIELD, md%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- case default
- ! general field
- call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data1_tref, data1_t1, data1_t2, lli, &
- nuv, FIELD, md%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- end select
- ! write meteofiles
- if ( md%putout ) then
- call WriteField( tmmd, md%destkey, &
- md%tmi1, trim(md%name), trim(md%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, nuv, FIELD, status )
- IF_NOTOK_RETURN(status=1)
- end if
- END IF IOroot
- CALL SCATTER( dgrid(region), md%data1(:,:,1), FIELD, md%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE( FIELD )
-
- ! data array is filled now:
- md%filled1 = .true.
- md%tr1(1) = data1_t1
- md%tr1(2) = data1_t2
- md%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- md%data1 = md%data2
- ! data array is filled now:
- md%filled1 = .true.
- md%tr1(1) = data1_t1
- md%tr1(2) = data1_t2
- md%changed = .true.
- end if
- ! -------------------------
- ! Read/write (or copy or nothing) secondary field
- ! -------------------------
- if ( data2_read ) then
- ! Need whole region for I/O on root. Dummy else.
- IF (isRoot) THEN
- ALLOCATE( field( im(region), jm(region)) )
- ELSE
- ALLOCATE( field(1,1) )
- END IF
- ! Read/write
- IOroot2: IF (isRoot) THEN
- select case ( md%name )
- case ( 'sp', 'sps' )
-
- ! special routine for surface pressure
-
- call Read_SP( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, FIELD, md%tmi2, status )
- IF_NOTOK_RETURN(status=1)
- case default
-
- ! general field
-
- call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data2_tref, data2_t1, data2_t2, lli, &
- nuv, FIELD, md%tmi2, status )
- IF_NOTOK_RETURN(status=1)
- end select
- ! write meteo files
- if ( md%putout ) then
- call WriteField( tmmd, md%destkey, &
- md%tmi2, trim(md%name), trim(md%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, nuv, FIELD, status )
- IF_NOTOK_RETURN(status=1)
- end if
- END IF IOroot2
- CALL SCATTER( dgrid(region), md%data2(:,:,1), FIELD, md%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE( FIELD )
- ! data array is filled now
- md%filled2 = .true.
- md%tr2(1) = data2_t1
- md%tr2(2) = data2_t2
- else if ( data2_copy ) then
- ! copy data from secondary array
- md%data2 = md%data1
- ! data array is filled now
- md%filled2 = .true.
- md%tr2(1) = data2_t1
- md%tr2(2) = data2_t2
- end if
- ! -------------------------
- ! time interpolation
- ! -------------------------
- call TimeInterpolation( md, tr, status )
- IF_NOTOK_RETURN(status=1)
- ! -------------------------
- ! done
- ! -------------------------
- status = 0
- call goLabel()
- END SUBROUTINE SETUP_2D_SERIAL
- !EOC
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUP_2D_PARA
- !
- ! !DESCRIPTION: Same as SETUP_2D_SERIAL, except all processes get field from IFS
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUP_2D_PARA( region, md, tr, nuv, status )
- !
- ! !USES:
- !
- use GO, only : TDate, wrtgol
- use Grid, only : TllGridInfo
- use TMM, only : ReadField, Read_SP, Read_SR_OLS, WriteField
- ! use meteodata, only : TMeteoData, TimeInterpolation
- use dims, only : im, jm
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: md ! met field
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region ! region number
- type(TDate), intent(in) :: tr(2) ! dates
- character(len=1), intent(in) :: nuv ! staggering
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status ! return code
- !
- ! !REVISION HISTORY:
- ! 18 Oct 2013 - Ph. Le Sager - v0
- !
- !EOP
- !------------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Setup_2d_para'
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
- integer :: i1, i2, j1, j2
- real, pointer :: field(:,:) ! work array
- ! --- begin -----------------------------
- call goLabel(rname)
- ! leave if not in use:
- if ( .not. md%used ) then
- call goLabel()
- status=0; return
- end if
- ! not changed by default
- md%changed = .false.
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read or copy
- call SetupSetup( md, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! -------------------------
- ! Read/write primary field
- ! -------------------------
- if ( data1_read ) then
- ! test
- if ( md%ls(1) /= md%ls(2) ) then
- write (gol,'("SETUP_2D called instead of SETUP_3D, field is 3D:")'); call goErr
- write (gol, '(" md%ls(1:2) : ",2i3)') md%ls; call goErr
- status=1; IF_NOTOK_RETURN(status=1)
- end if
- ! could get those bounds from md% directly
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- allocate( field( i1:i2, j1:j2) ) !! bonds are not strictly required, could as well do (i2-i1+1, ..)
- ! Read/write
- select case ( md%name )
- case ( 'sp', 'sps' )
- ! special routine for surface pressure
- call Read_SP( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli(region), FIELD, md%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- case ( 'srols' )
- ! special routine for Olsson surface roughness:
- call Read_SR_OLS( tmmd, md%sourcekey, &
- data1_tref, data1_t1, data1_t2, &
- lli(region), FIELD, md%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- case default
- ! general field
- call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data1_tref, data1_t1, data1_t2, lli(region), &
- nuv, FIELD, md%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- end select
- md%data1(i1:i2, j1:j2, 1) = field
- deallocate( field )
- ! write meteofiles
- if ( md%putout ) then
- write(gol,*)"writing of remapped met field not tested yet.. SKIPPED." ; call goErr
- TRACEBACK; status=1; return
- end if
- ! data array is filled now:
- md%filled1 = .true.
- md%tr1(1) = data1_t1
- md%tr1(2) = data1_t2
- md%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- md%data1 = md%data2
- ! data array is filled now:
- md%filled1 = .true.
- md%tr1(1) = data1_t1
- md%tr1(2) = data1_t2
- md%changed = .true.
- end if
- ! -------------------------
- ! Read/write (or copy or nothing) secondary field
- ! -------------------------
- if ( data2_read ) then
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- allocate( field( i1:i2, j1:j2) )
- select case ( md%name )
- case ( 'sp', 'sps' )
- ! special routine for surface pressure
- call Read_SP( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli(region), FIELD, md%tmi2, status )
- IF_NOTOK_RETURN(status=1)
- case default
- ! general field
- call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data2_tref, data2_t1, data2_t2, lli(region), &
- nuv, FIELD, md%tmi2, status )
- IF_NOTOK_RETURN(status=1)
- end select
- md%data2(i1:i2, j1:j2, 1) = FIELD
- deallocate( field )
- ! data array is filled now
- md%filled2 = .true.
- md%tr2(1) = data2_t1
- md%tr2(2) = data2_t2
- else if ( data2_copy ) then
- ! copy data from secondary array
- md%data2 = md%data1
- ! data array is filled now
- md%filled2 = .true.
- md%tr2(1) = data2_t1
- md%tr2(2) = data2_t2
- end if
- ! -------------------------
- ! time interpolation
- ! -------------------------
- call TimeInterpolation( md, tr, status )
- IF_NOTOK_RETURN(status=1)
- ! -------------------------
- ! done
- ! -------------------------
- status = 0
- call goLabel()
- END SUBROUTINE SETUP_2D_PARA
- !EOC
-
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUP_2D_N_SERIAL
- !
- ! !DESCRIPTION: wrapper around setup_2d to process several regions for the
- ! same field.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUP_2D_N_SERIAL( md, tr, lli, nuv, status )
- !
- ! !USES:
- !
- use GO , only : TDate
- use Grid , only : TllGridInfo
- use meteodata, only : TMeteoData
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: md(:)
- !
- ! !INPUT PARAMETERS:
- !
- type(TDate), intent(in) :: tr(2)
- type(TllGridInfo), intent(in) :: lli(:)
- character(len=1), intent(in) :: nuv
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 6 Apr 2010 - P. Le Sager -
- !
- ! !REMARKS:
- ! (1) Attention: we assume that the regions list start from #1.
- !
- !EOP
- !------------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Setup_2d_n_serial'
- integer :: n
- ! --- begin -----------------------------
- ! check ...
- if ( size(md) /= size(lli) ) then
- write (gol,'("md and lli arrays should have same size:")' ) ; call goErr
- write (gol,'(" size md : ",i6)' ) size(md) ; call goErr
- write (gol,'(" size lli : ",i6)' ) size(lli) ; call goErr
- TRACEBACK; status=1; return
- end if
- ! loop over regions:
- do n = 1, size(md)
- if (okdebug) then
- write (gol,'(" ",a," ",a)') trim(md(n)%name), trim(lli(n)%name); call goPr
- endif
- call Setup( n, md(n), tr, lli(n), nuv, status )
- IF_NOTOK_RETURN(status=1)
- end do
- status = 0
- END SUBROUTINE SETUP_2D_N_SERIAL
- !EOC
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUP_2D_N_PARA
- !
- ! !DESCRIPTION: wrapper around setup_2d to process several regions for the
- ! same field.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUP_2D_N_PARA( md, tr, nuv, status )
- !
- ! !USES:
- !
- use GO , only : TDate
- use Grid , only : TllGridInfo
- use meteodata, only : TMeteoData
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: md(:)
- !
- ! !INPUT PARAMETERS:
- !
- type(TDate), intent(in) :: tr(2)
- character(len=1), intent(in) :: nuv
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- !EOP
- !------------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Setup_2d_n_para'
- integer :: n
- do n = 1, size(md)
-
- if (okdebug) then
- write (gol,'(" ",a," ",a)') trim(md(n)%name), trim(lli(n)%name); call goPr
- endif
-
- call Setup( n, md(n), tr, nuv, status )
- IF_NOTOK_RETURN(status=1)
- end do
- status = 0
- END SUBROUTINE SETUP_2D_N_PARA
- !EOC
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUP_3D
- !
- ! !DESCRIPTION: same as SETUP_2D, but for 3D fields by accounting for levels
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUP_3D_SERIAL( region, md, tr, lli, nuv, levi, nw, status )
- !
- ! !USES:
- !
- use GO, only : TDate, wrtgol, operator(/=)
- use Grid, only : TllGridInfo, TLevelInfo
- use TMM, only : TMeteoInfo, ReadField, WriteField
- use meteodata, only : TMeteoData, TimeInterpolation
- use dims, only : im, jm
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: md ! met field
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region ! region number
- type(TDate), intent(in) :: tr(2) ! dates
- type(TllGridInfo), intent(in) :: lli ! grid
- character(len=1), intent(in) :: nuv ! horiz. staggering
- type(TLevelInfo), intent(in) :: levi ! levels
- character(len=1), intent(in) :: nw ! vertical staggering
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status ! return code
- !
- ! !REVISION HISTORY:
- ! 4 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Setup_3d_serial'
-
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
-
- real, allocatable :: tmp_sp(:,:)
- real, pointer :: field(:,:,:) ! work array (data)
- integer :: is(2), js(2) ! work arrays (bounds)
- ! --- begin -----------------------------
-
- call goLabel(rname)
-
- ! leave if not in use:
- if ( .not. md%used ) then
- call goLabel()
- status=0; return
- end if
-
- if (okdebug) then
- write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md%name),trim(lli%name); call goPr
- endif
-
- ! not changed by default
- md%changed = .false.
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read or copy
-
- call SetupSetup( md, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! -------------------------
- ! Read/write primary field
- ! -------------------------
- if ( data1_read ) then
- ! Need whole region for I/O on root. Dummy else. Allocate global array for I/O
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
- IF (isRoot) THEN
- ALLOCATE( FIELD( is(1):is(2), js(1):js(2), md%ls(1):md%ls(2) ))
- ELSE
- ALLOCATE( FIELD(1,1,1) )
- END IF
- ! Read/write on root
- IOroot : IF (isRoot) THEN
- ! safety check
- if ( data1_t2 /= data1_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
- call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- call goErr; status=1; return
- end if
- ! surface pressure
- allocate( tmp_sp( is(1):is(2), js(1):js(2) ) )
- ! fill data
- call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, nuv, levi, nw, &
- tmp_sp, FIELD, md%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- ! write meteo file
- if ( md%putout ) then
- call WriteField( tmmd, md%destkey, &
- md%tmi1, 'sp', trim(md%name), trim(md%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, nuv, levi, nw, &
- tmp_sp, FIELD, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! clear
- deallocate( tmp_sp )
- END IF IOroot
- CALL SCATTER( dgrid(region), md%data1, FIELD, md%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE( FIELD )
-
- ! data array is filled now
- md%filled1 = .true.
- md%tr1(1) = data1_t1
- md%tr1(2) = data1_t2
- md%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- md%data1 = md%data2
- ! data array is filled now:
- md%filled1 = .true.
- md%tr1(1) = data1_t1
- md%tr1(2) = data1_t2
- md%changed = .true.
- end if
-
- !--------------------------
- ! read/write secondary field
- !--------------------------
- if ( data2_read ) then
- ! Need whole region for I/O on root. Dummy else.
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
-
- IF (isRoot) THEN
- ALLOCATE(field(im(region), jm(region), md%ls(1):md%ls(2)))
- ELSE
- ALLOCATE(field(1,1,1))
- END IF
- ! Read/write
- IOroot2 : IF (isRoot) THEN
-
- ! safety check ...
- if ( data2_t2 /= data2_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
- call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- call goErr; status=1; return
- end if
- ! surface pressure
- allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
- ! fill data
- call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, nuv, levi, nw, &
- tmp_sp, FIELD, md%tmi2, status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles
- if ( md%putout ) then
- call WriteField( tmmd, md%destkey, &
- md%tmi2, 'sp', trim(md%name), trim(md%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, nuv, levi, nw, &
- tmp_sp, FIELD, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! clear
- deallocate( tmp_sp )
- END IF IOroot2
- CALL SCATTER( dgrid(region), md%data2, FIELD, md%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE( FIELD )
-
- ! data array is filled now
- md%filled2 = .true.
- md%tr2(1) = data2_t1
- md%tr2(2) = data2_t2
- else if ( data2_copy ) then
- ! copy data from secondary array
- md%data2 = md%data1
- ! data array is filled now
- md%filled2 = .true.
- md%tr2(1) = data2_t1
- md%tr2(2) = data2_t2
- end if
- ! -------------------------
- ! time interpolation
- ! -------------------------
- call TimeInterpolation( md, tr, status )
- IF_NOTOK_RETURN(status=1)
- ! -------------------------
- ! done
- ! -------------------------
- status = 0
- call goLabel()
- END SUBROUTINE SETUP_3D_SERIAL
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUP_3D_PARA
- !
- ! !DESCRIPTION: same as SETUP_3D_SERIAL, except reading is done by every processes.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUP_3D_PARA( region, md, tr, nuv, levi, nw, status )
- !
- ! !USES:
- !
- use GO, only : TDate, wrtgol, operator(/=)
- use Grid, only : TllGridInfo, TLevelInfo
- use TMM, only : TMeteoInfo, ReadField, WriteField
- use meteodata, only : TMeteoData, TimeInterpolation
- use dims, only : im, jm
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: md ! met field
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region ! region number
- type(TDate), intent(in) :: tr(2) ! dates
- character(len=1), intent(in) :: nuv ! horiz. staggering
- type(TLevelInfo), intent(in) :: levi ! levels
- character(len=1), intent(in) :: nw ! vertical staggering
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status ! return code
- !
- ! !REVISION HISTORY:
- ! 18 Oct 2013 - Ph. Le Sager - v0
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Setup_3d_para'
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
- integer :: i1, i2, j1, j2
- real, allocatable :: tmp_sp(:,:)
- real, pointer :: field(:,:,:) ! work array
- ! --- begin -----------------------------
- call goLabel(rname)
- ! leave if not in use:
- if ( .not. md%used ) then
- call goLabel()
- status=0; return
- end if
- ! not changed by default
- md%changed = .false.
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read or copy
- call SetupSetup( md, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! -------------------------
- ! Read/write primary field
- ! -------------------------
- if ( data1_read ) then
- ! could get those bounds from md% directly
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- allocate( field( i1:i2, j1:j2, md%ls(1):md%ls(2)))
- ! safety check
- if ( data1_t2 /= data1_t1 ) then
- ! write (gol,'("not sure that this routine is correct for time intervals:")') ; call goErr
- ! call wrtgol( ' data1_t1 : ', data1_t1 ) ; call goErr
- ! call wrtgol( ' data1_t2 : ', data1_t2 ) ; call goErr
- ! write (gol,'("please decide what to do with surface pressures ... ")') ; call goErr
- ! TRACEBACK; status=1; return
- write (gol,'("WARNING - using instant surface pressure for regridding temporal averaged 3D field ...")'); call goPr
- end if
- ! surface pressure
- allocate( tmp_sp( i1:i2, j1:j2 ) )
- ! read data
- call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli(region), nuv, levi, nw, &
- tmp_sp, FIELD, md%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- md%data1(i1:i2, j1:j2, md%ls(1):md%ls(2)) = field
- ! write meteo file
- if ( md%putout ) then
- write(gol,*)"writing of remapped met field not finished yet.. Sorry." ; call goErr
- TRACEBACK; status=1; return
- endif
- DEALLOCATE( TMP_SP )
- DEALLOCATE( FIELD )
- ! data array is filled now
- md%filled1 = .true.
- md%tr1(1) = data1_t1
- md%tr1(2) = data1_t2
- md%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- md%data1 = md%data2
- ! data array is filled now:
- md%filled1 = .true.
- md%tr1(1) = data1_t1
- md%tr1(2) = data1_t2
- md%changed = .true.
- end if
- !--------------------------
- ! read/write secondary field
- !--------------------------
- if ( data2_read ) then
- ! could get those bounds from md% directly
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- allocate( field( i1:i2, j1:j2, md%ls(1):md%ls(2)))
- ! safety check ...
- if ( data2_t2 /= data2_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")') ; call goErr
- call wrtgol( ' data2_t1 : ', data2_t1 ) ; call goErr
- call wrtgol( ' data2_t2 : ', data2_t2 ) ; call goErr
- write (gol,'("please decide what to do with surface pressures ... ")') ; call goErr
- TRACEBACK; status=1; return
- end if
- ! surface pressure
- allocate( tmp_sp( i1:i2, j1:j2 ) )
- ! read data
- call ReadField( tmmd, md%sourcekey, trim(md%name), trim(md%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli(region), nuv, levi, nw, &
- tmp_sp, FIELD, md%tmi2, status )
- IF_NOTOK_RETURN(status=1)
- md%data2(i1:i2, j1:j2, md%ls(1):md%ls(2)) = field
- ! write meteofiles
- if ( md%putout ) then
- write(gol,*)"writing of remapped met field not finished yet.. Sorry. SKIPPED." ; call goErr
- TRACEBACK; status=1; return
- end if
- ! clear
- DEALLOCATE( TMP_SP )
- DEALLOCATE( FIELD )
- ! data array is filled now
- md%filled2 = .true.
- md%tr2(1) = data2_t1
- md%tr2(2) = data2_t2
- else if ( data2_copy ) then
- ! copy data from secondary array
- md%data2 = md%data1
- ! data array is filled now
- md%filled2 = .true.
- md%tr2(1) = data2_t1
- md%tr2(2) = data2_t2
- end if
- ! -------------------------
- ! time interpolation
- ! -------------------------
- call TimeInterpolation( md, tr, status )
- IF_NOTOK_RETURN(status=1)
- ! -------------------------
- ! done
- ! -------------------------
- status = 0
- call goLabel()
- END SUBROUTINE SETUP_3D_PARA
- !EOC
- ! **************************************************************
- ! ***
- ! *** Specific SETUP routines for MASS FLUXES - Only serial case
- ! *** since it reads spectral fields from IFS
- ! ***
- ! **************************************************************
-
- SUBROUTINE SETUP_UVW( region, md_mfu, md_mfv, md_mfw, md_tsp, tr, lli, nuv, levi, nw, status )
- ! Set up MFU and MFV (horizontal fluxes)
- ! Set up MFW (vertical flux) and TSP (tendency surface pressure)
- ! Read or copy %data1 and %data2, and get %data through time interpolation
- use GO, only : TDate, wrtgol, operator(/=)
- use Grid, only : TllGridInfo, TLevelInfo
- use TMM, only : TMeteoInfo, TMM_Read_UVW, WriteField
- use meteodata, only : TMeteoData, TimeInterpolation
- use dims, only : im, jm
- ! --- in/out ----------------------------------
- integer, intent(in) :: region ! region number
- type(TMeteoData), intent(inout) :: md_mfu
- type(TMeteoData), intent(inout) :: md_mfv
- type(TMeteoData), intent(inout) :: md_mfw
- type(TMeteoData), intent(inout) :: md_tsp
- type(TDate), intent(in) :: tr(2) ! time range
- type(TllGridInfo), intent(in) :: lli
- character(len=1), intent(in) :: nuv
- type(TLevelInfo), intent(in) :: levi
- character(len=1), intent(in) :: nw
- integer, intent(out) :: status
- ! --- const --------------------------------------
- character(len=*), parameter :: rname = mname//'/Setup_UVW'
- ! --- local ----------------------------------
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
- logical :: NorthBorder, WestBorder ! tile location
- real, allocatable :: tmp_spu(:,:)
- real, allocatable :: tmp_spv(:,:)
- real, allocatable :: tmp_sp(:,:)
- ! to read the entire region
- real, pointer :: wrld_u(:,:,:), wrld_v(:,:,:), wrkarr(:,:,:)
- real, pointer :: mfw(:,:,:), tsp(:,:) ! work arrays (data)
- integer, dimension(2) :: is, js, ls
- integer :: halo, i1, i2, j1, j2
- real, allocatable :: bigIslice(:,:), bigJslice(:,:), Islice(:,:), Jslice(:,:)
- ! --- begin -----------------------------
- call goLabel(rname)
- ! leave if not in use:
- if ( md_mfu%used .neqv. md_mfv%used ) then
- write (gol,'("either none or both mfu and mfv should be in use")'); call goErr
- call goErr; status=1; return
- end if
- if ( .not. md_mfu%used ) then
- call goLabel()
- status=0; return
- end if
- if (okdebug) then
- write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md_mfu%name),trim(lli%name); call goPr
- write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md_mfv%name),trim(lli%name); call goPr
- write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(md_mfw%name),trim(lli%name); call goPr
- endif
-
- ! not changed by default
- md_mfu%changed = .false.
- md_mfv%changed = .false.
- md_mfw%changed = .false.
- md_tsp%changed = .false.
- ! local indices and tile location
- CALL GET_DISTGRID( dgrid(region), &
- I_STRT=i1, I_STOP=i2, &
- J_STRT=j1, J_STOP=j2, &
- hasWestBorder=WestBorder, hasNorthBorder=NorthBorder)
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read (sufficient to setup from mfu only)
- call SetupSetup( md_mfu, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
- !--------------------------
- ! read/write primary field
- !--------------------------
- if ( data1_read ) then
- ! Use fact that mfu and mfv have been allocated with the same bounds and halo
- ! Need whole region for I/O on root. Dummy else.
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
- ls = md_mfu%ls
- halo = md_mfu%halo
- IF (isRoot) THEN
- ALLOCATE( wrld_u( is(1)-halo:is(2)+halo, js(1)-halo:js(2)+halo, ls(1):ls(2)) )
- ALLOCATE( wrld_v( is(1)-halo:is(2)+halo, js(1)-halo:js(2)+halo, ls(1):ls(2)) )
- ALLOCATE( wrkarr( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- wrld_v = 0.
- wrld_u = 0.
- allocate( bigIslice(jm(region),ls(1):ls(2)))
- allocate( bigJslice(im(region),ls(1):ls(2)))
- allocate( mfw(is(1):is(2), js(1):js(2), ls(1):ls(2) ))
- allocate( tsp(is(1):is(2), js(1):js(2)) )
- ELSE
- ALLOCATE(wrld_u(1,1,1), wrld_v(1,1,1), wrkarr(1,1,1))
- ALLOCATE( bigIslice(1,1), bigJslice(1,1) )
- allocate( mfw(1,1,1), tsp(1,1) )
- END IF
- ALLOCATE( Islice(j1:j2,ls(1):ls(2)) )
- ALLOCATE( Jslice(i1:i2,ls(1):ls(2)) )
- if (isRoot) then ! only root does IO
- ! safety check ...
- if ( data1_t2 /= data1_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
- call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- call goErr; status=1; return
- end if
- ! surface pressure field:
- allocate( tmp_spu(is(1)-1:is(2), js(1):js(2) ) )
- allocate( tmp_spv( is(1):is(2), js(1):js(2)+1) )
- allocate( tmp_sp ( is(1):is(2), js(1):js(2) ) )
- ! NOTE: strange old indexing:
- ! pu_tmpp --> pu(0:imr,1:jmr ,1:lmr) in pu_t(0:imr+1,0:jmr+1,0:lmr)
- ! pv_tmpp --> pv(1:imr,1:jmr+1,1:lmr) in pv_t(0:imr+1,0:jmr+1,0:lmr)
- ! fill data:
- call TMM_READ_UVW( tmmd, md_mfu%sourcekey, &
- data1_tref, data1_t1, data1_t2, lli, levi, &
- tmp_spu, &
- wrld_u( is(1)-1:is(2), js(1):js(2), ls(1)+1:ls(2) ), &
- md_mfu%tmi1, &
- tmp_spv, &
- wrld_v( is(1):is(2), js(1):js(2)+1, ls(1)+1:ls(2) ), &
- md_mfv%tmi1, &
- tmp_sp, mfw, &
- tsp, &
- md_mfw%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles
- if ( md_mfu%putout ) then
- call WriteField( tmmd, md_mfu%destkey, &
- md_mfu%tmi1, 'spu', trim(md_mfu%name), trim(md_mfu%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'u', levi, 'n', &
- tmp_spu, wrld_u(is(1)-1:is(2), js(1):js(2), ls(1)+1:ls(2) ), &
- status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( md_mfv%putout ) then
- call WriteField( tmmd, md_mfv%destkey, &
- md_mfv%tmi1, 'spv', trim(md_mfv%name), trim(md_mfv%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'v', levi, 'n', &
- tmp_spv, wrld_v(is(1):is(2), js(1):js(2)+1, ls(1)+1:ls(2) ), &
- status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( md_mfw%putout ) then
- call WriteField( tmmd, md_mfw%destkey, &
- md_mfw%tmi1, 'sp', trim(md_mfw%name), trim(md_mfw%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, nuv, levi, nw, &
- tmp_sp, mfw, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( md_tsp%putout ) then
- ! use history from mfw ...
- call WriteField( tmmd, md_tsp%destkey, &
- md_mfw%tmi1, trim(md_tsp%name), trim(md_tsp%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, nuv, tsp, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! clear
- deallocate( tmp_spu )
- deallocate( tmp_spv )
- deallocate( tmp_sp )
- end if ! root ?
- ! Scatter U
- if(isRoot) wrkarr = wrld_u(is(1):is(2),js(1):js(2),:)
- CALL SCATTER( dgrid(region), md_mfu%data1, wrkarr, md_mfu%halo, status)
- IF_NOTOK_RETURN(status=1)
- ! manually scatter wrld_u(is(1)-1,:,:). This is needed only with non-cyclic
- ! zoom regions, since any update_halo will overwrite is(1)-1. [FIXME: could had a
- ! test around these 3 lines ]
- !PLS if(isRoot) bigIslice = wrld_u(0,js(1):js(2),:)
- !PLS CALL SCATTER_I_BAND( dgrid(region), islice, bigIslice, status, iref=1)
- !PLS if (WestBorder) md_mfu%data1(0,j1:j2,:) = islice
- ! Scatter V
- if(isRoot) wrkarr = wrld_v(is(1):is(2),js(1):js(2),:)
- CALL SCATTER( dgrid(region), md_mfv%data1, wrkarr, md_mfv%halo, status)
- IF_NOTOK_RETURN(status=1)
- ! manually SCATTER wrld_v( :, js(2)+1 , :) : NORTH POLE HALO
- if(isroot) bigJslice=wrld_v(is(1):is(2),jm(region)+1,:)
- CALL SCATTER_J_BAND( dgrid(region), jslice, bigJslice, status, jref=jm(region))
- if (NorthBorder) md_mfv%data1(i1:i2,jm(region)+1,:)=jslice
- deallocate(wrld_u, wrld_v, wrkarr, bigIslice, bigJslice, Islice, Jslice)
-
- ! Scatter W
- CALL SCATTER( dgrid(region), md_mfw%data1, MFW, md_mfw%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), md_tsp%data1(:,:,1), TSP, md_tsp%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE(MFW, TSP)
- ! data array is filled now
- md_mfu%filled1 = .true.
- md_mfu%tr1(1) = data1_t1
- md_mfu%tr1(2) = data1_t2
- md_mfu%changed = .true.
- md_mfv%filled1 = .true.
- md_mfv%tr1(1) = data1_t1
- md_mfv%tr1(2) = data1_t2
- md_mfv%changed = .true.
- md_mfw%filled1 = .true.
- md_mfw%tr1(1) = data1_t1
- md_mfw%tr1(2) = data1_t2
- md_mfw%changed = .true.
- md_tsp%filled1 = .true.
- md_tsp%tr1(1) = data1_t1
- md_tsp%tr1(2) = data1_t2
- md_tsp%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- md_mfu%data1 = md_mfu%data2
- md_mfv%data1 = md_mfv%data2
- md_mfw%data1 = md_mfw%data2
- ! data array is filled now:
- md_mfu%filled1 = .true.
- md_mfu%tr1(1) = data1_t1
- md_mfu%tr1(2) = data1_t2
- md_mfu%changed = .true.
- md_mfv%filled1 = .true.
- md_mfv%tr1(1) = data1_t1
- md_mfv%tr1(2) = data1_t2
- md_mfv%changed = .true.
- md_mfw%filled1 = .true.
- md_mfw%tr1(1) = data1_t1
- md_mfw%tr1(2) = data1_t2
- md_mfw%changed = .true.
- md_tsp%filled1 = .true.
- md_tsp%tr1(1) = data1_t1
- md_tsp%tr1(2) = data1_t2
- md_tsp%changed = .true.
- end if
- !--------------------------
- ! read/write secondary field
- !--------------------------
- if ( data2_read ) then
- ! Need whole region for I/O on root. Dummy else.
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
- ls = md_mfu%ls
- halo = md_mfu%halo
- IF (isRoot) THEN
- allocate( wrld_u( is(1)-halo:is(2)+halo, js(1)-halo:js(2)+halo, ls(1):ls(2)) )
- allocate( wrld_v( is(1)-halo:is(2)+halo, js(1)-halo:js(2)+halo, ls(1):ls(2)) )
- allocate( wrkarr( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- wrld_v = 0.
- wrld_u = 0.
- allocate( bigIslice(jm(region),ls(1):ls(2)))
- allocate( bigJslice(im(region),ls(1):ls(2)))
- allocate( mfw(is(1):is(2), js(1):js(2), ls(1):ls(2) ))
- allocate( tsp(is(1):is(2), js(1):js(2)) )
- ELSE
- ALLOCATE(wrld_u(1,1,1), wrld_v(1,1,1), wrkarr(1,1,1))
- ALLOCATE( bigIslice(1,1), bigJslice(1,1) )
- allocate( mfw(1,1,1), tsp(1,1) )
- END IF
- ALLOCATE( Islice(j1:j2,ls(1):ls(2)) )
- ALLOCATE( Jslice(i1:i2,ls(1):ls(2)) )
- if (isRoot) then ! only root does IO
- if ( data2_t2 /= data2_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
- call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- call goErr; status=1; return
- end if
- ! surface pressure field:
- allocate( tmp_spu(is(1)-1:is(2), js(1):js(2) ) )
- allocate( tmp_spv( is(1):is(2), js(1):js(2)+1) )
- allocate( tmp_sp ( is(1):is(2), js(1):js(2) ) )
- ! NOTE: strange old indexing:
- ! pu_tmpp --> pu(0:imr,1:jmr ,1:lmr) in pu_t(0:imr+1,0:jmr+1,0:lmr)
- ! pv_tmpp --> pv(1:imr,1:jmr+1,1:lmr) in pv_t(0:imr+1,0:jmr+1,0:lmr)
- ! fill data:
- call TMM_READ_UVW( tmmd, md_mfu%sourcekey, &
- data2_tref, data2_t1, data2_t2, lli, levi, &
- tmp_spu, &
- wrld_u( is(1)-1:is(2), js(1):js(2), ls(1)+1:ls(2) ), &
- md_mfu%tmi2, &
- tmp_spv, &
- wrld_v( is(1):is(2), js(1):js(2)+1, ls(1)+1:ls(2) ), &
- md_mfv%tmi2, &
- tmp_sp, MFW, TSP, md_mfw%tmi2, status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles
- if ( md_mfu%putout ) then
- call WriteField( tmmd, md_mfu%destkey, &
- md_mfu%tmi2, 'spu', trim(md_mfu%name), trim(md_mfu%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'u', levi, 'n', &
- tmp_spu, wrld_u( is(1)-1:is(2), js(1):js(2), ls(1)+1:ls(2) ), &
- status )
- IF_NOTOK_RETURN(status=1)
- endif
- if ( md_mfv%putout ) then
- call WriteField( tmmd, md_mfv%destkey, &
- md_mfv%tmi2, 'spv', trim(md_mfv%name), trim(md_mfv%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'v', levi, 'n', &
- tmp_spv, wrld_v( is(1):is(2), js(1):js(2)+1, ls(1)+1:ls(2) ), &
- status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( md_mfw%putout ) then
- call WriteField( tmmd, md_mfw%destkey, &
- md_mfw%tmi2, 'sp', trim(md_mfw%name), trim(md_mfw%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, nuv, levi, nw, &
- tmp_sp, MFW, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( md_tsp%putout ) then
- ! use history from mfw ...
- call WriteField( tmmd, md_tsp%destkey, &
- md_mfw%tmi2, trim(md_tsp%name), trim(md_tsp%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, nuv, TSP, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! clear
- deallocate( tmp_spu )
- deallocate( tmp_spv )
- deallocate( tmp_sp )
- end if ! root
- ! Scatter U
- if(isRoot) wrkarr = wrld_u(is(1):is(2),js(1):js(2),:)
- CALL SCATTER( dgrid(region), md_mfu%data2, wrkarr, md_mfu%halo, status)
- IF_NOTOK_RETURN(status=1)
- ! important for zoom regions only, since any update_halo will overwrite is(1)-1. [FIXME: could had a
- ! test around these 3 lines ]
- !PLS if(isRoot) bigIslice = wrld_u(0,js(1):js(2),:)
- !PLS CALL SCATTER_I_BAND( dgrid(region), islice, bigIslice, status, iref=1)
- !PLS if (WestBorder) md_mfu%data2(0,j1:j2,:) = islice
- ! Scatter V
- if(isRoot) wrkarr = wrld_v(is(1):is(2),js(1):js(2),:)
- CALL SCATTER( dgrid(region), md_mfv%data2, wrkarr, md_mfv%halo, status)
- IF_NOTOK_RETURN(status=1)
- ! manually SCATTER wrld_v( :, js(2)+1 , :) : NORTH POLE HALO
- if(isroot) bigJslice=wrld_v(is(1):is(2),jm(region)+1,:)
- CALL SCATTER_J_BAND( dgrid(region), jslice, bigJslice, status, jref=jm(region))
- if (NorthBorder) md_mfv%data2(i1:i2,jm(region)+1,:)=jslice
- DEALLOCATE(wrld_u, wrld_v, wrkarr, bigIslice, bigJslice, Islice, Jslice)
- ! Scatter W
- CALL SCATTER( dgrid(region), md_mfw%data2, MFW, md_mfw%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), md_tsp%data2(:,:,1), TSP, md_tsp%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE(MFW, TSP)
-
- ! data array is filled now:
- md_mfu%filled2 = .true.
- md_mfu%tr2(1) = data2_t1
- md_mfu%tr2(2) = data2_t2
- md_mfv%filled2 = .true.
- md_mfv%tr2(1) = data2_t1
- md_mfv%tr2(2) = data2_t2
- md_mfw%filled2 = .true.
- md_mfw%tr2(1) = data2_t1
- md_mfw%tr2(2) = data2_t2
- md_tsp%filled2 = .true.
- md_tsp%tr2(1) = data2_t1
- md_tsp%tr2(2) = data2_t2
- else if ( data2_copy ) then
- ! copy data from primary array:
- md_mfu%data2 = md_mfu%data
- md_mfv%data2 = md_mfv%data
- md_mfw%data2 = md_mfw%data1
- ! data array is filled now:
- md_mfu%filled2 = .true.
- md_mfu%tr2(1) = data2_t1
- md_mfu%tr2(2) = data2_t2
- md_mfv%filled2 = .true.
- md_mfv%tr2(1) = data2_t1
- md_mfv%tr2(2) = data2_t2
- md_mfw%filled2 = .true.
- md_mfw%tr2(1) = data2_t1
- md_mfw%tr2(2) = data2_t2
- md_tsp%filled2 = .true.
- md_tsp%tr2(1) = data2_t1
- md_tsp%tr2(2) = data2_t2
- end if
- !------------------
- ! time interpolation
- !------------------
- call TimeInterpolation( md_mfu, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( md_mfv, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( md_mfw, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( md_tsp, tr, status )
- IF_NOTOK_RETURN(status=1)
- !------------------
- ! done
- !------------------
- status = 0
- call goLabel()
- end subroutine SETUP_UVW
- ! **************************************************************
- ! ***
- ! *** temperature and humidity
- ! ***
- ! **************************************************************
-
- subroutine Setup_TQ( region, md_T, md_Q, tr, lli, levi, status)
- use GO, only : TDate, wrtgol, operator(/=)
- use Grid, only : TllGridInfo, TLevelInfo
- use TMM, only : TMeteoInfo, Read_TQ, WriteField
- use meteodata, only : TMeteoData, TimeInterpolation
- use dims, only : im, jm
-
- ! --- in/out ----------------------------------
- integer, intent(in) :: region ! region number
- type(TMeteoData), intent(inout) :: md_T
- type(TMeteoData), intent(inout) :: md_Q
- type(TDate), intent(in) :: tr(2)
- type(TllGridInfo), intent(in) :: lli
- type(TLevelInfo), intent(in) :: levi
- integer, intent(out) :: status
- ! --- const --------------------------------------
-
- character(len=*), parameter :: rname = mname//'/Setup_TQ'
-
- ! --- local ----------------------------------
-
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
-
- real, allocatable :: tmp_sp(:,:)
-
- real, pointer :: T(:,:,:), Q(:,:,:) ! work array
- integer :: is(2), js(2) ! work arrays (bounds)
- ! --- begin -----------------------------
-
- call goLabel(rname)
-
- ! leave if not in use:
- if ( md_T%used .neqv. md_Q%used ) then
- write (gol,'("either none or both T and Q should be in use")'); call goErr
- call goErr; status=1; return
- end if
- if ( .not. md_T%used ) then
- call goLabel()
- status=0; return
- end if
-
- ! not changed by default
- md_T%changed = .false.
- md_Q%changed = .false.
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read (sufficient to setup from T only)
-
- call SetupSetup( md_T, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
-
- !--------------------------
- ! read/write primary field
- !--------------------------
- if ( data1_read ) then
- ! Need whole region for I/O on root. Dummy else.
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
- IF (isRoot) THEN
- ALLOCATE( T(is(1):is(2), js(1):js(2), md_T%ls(1):md_T%ls(2) ))
- ALLOCATE( Q(is(1):is(2), js(1):js(2), md_Q%ls(1):md_Q%ls(2) ))
- ELSE
- ALLOCATE( T(1,1,1), Q(1,1,1) )
- END IF
- if (isRoot) then ! only root does IO
-
- ! safety check ...
- if ( data1_t2 /= data1_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
- call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- call goErr; status=1; return
- end if
- ! surface pressure field:
- allocate( tmp_sp( is(1):is(2), js(1):js(2) ) )
- ! fill data:
- call Read_TQ( tmmd, md_T%sourcekey, md_Q%sourcekey, &
- data1_tref, data1_t1, data1_t2, lli, levi, &
- tmp_sp, &
- T, md_T%tmi1, &
- Q, md_Q%tmi1, status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles ?
- if ( md_T%putout ) then
- call WriteField( tmmd, md_T%destkey, &
- md_T%tmi1, 'sp', trim(md_T%name), trim(md_T%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, T, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- if ( md_Q%putout ) then
- call WriteField( tmmd, md_Q%destkey, &
- md_Q%tmi1, 'sp', trim(md_Q%name), trim(md_Q%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, Q, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- ! clear
- deallocate( tmp_sp )
- end if ! root ?
- ! Distribute
- CALL SCATTER( dgrid(region), md_T%data1, T, md_T%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), md_Q%data1, Q, md_Q%halo, status)
- IF_NOTOK_RETURN(status=1)
-
- DEALLOCATE(T, Q)
-
-
- ! data array is filled now:
- md_T%filled1 = .true.
- md_T%tr1(1) = data1_t1
- md_T%tr1(2) = data1_t2
- md_T%changed = .true.
- md_Q%filled1 = .true.
- md_Q%tr1(1) = data1_t1
- md_Q%tr1(2) = data1_t2
- md_Q%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- md_T%data1 = md_T%data2
- md_Q%data1 = md_Q%data2
-
- ! data array is filled now:
- md_T%filled1 = .true.
- md_T%tr1(1) = data1_t1
- md_T%tr1(2) = data1_t2
- md_T%changed = .true.
- md_Q%filled1 = .true.
- md_Q%tr1(1) = data1_t1
- md_Q%tr1(2) = data1_t2
- md_Q%changed = .true.
- end if
-
- !--------------------------
- ! read/write secondary field
- !--------------------------
- if ( data2_read ) then
- ! Need whole region for I/O on root. Dummy else.
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
- IF (isRoot) THEN
- allocate( T(is(1):is(2), js(1):js(2), md_T%ls(1):md_T%ls(2) ))
- allocate( Q(is(1):is(2), js(1):js(2), md_Q%ls(1):md_Q%ls(2) ))
- ELSE
- allocate( T(1,1,1), Q(1,1,1) )
- END IF
- if (isRoot) then ! only root does IO
- ! safety check ...
- if ( data2_t2 /= data2_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
- call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- call goErr; status=1; return
- end if
-
- ! surface pressure field:
- allocate( tmp_sp( is(1):is(2), js(1):js(2)) )
- ! fill data:
- call Read_TQ( tmmd, md_T%sourcekey, md_Q%sourcekey, &
- data2_tref, data2_t1, data2_t2, lli, levi, &
- tmp_sp, &
- T, md_T%tmi2, &
- Q, md_Q%tmi2, status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles ?
- if ( md_T%putout ) then
- call WriteField( tmmd, md_T%destkey, &
- md_T%tmi2, 'sp', trim(md_T%name), trim(md_T%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, T, status )
- IF_NOTOK_RETURN(status=1)
- endif
-
- if ( md_Q%putout ) then
- call WriteField( tmmd, md_Q%destkey, &
- md_Q%tmi2, 'sp', trim(md_Q%name), trim(md_Q%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, Q, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! clear
- deallocate( tmp_sp )
- end if ! root
-
- CALL SCATTER( dgrid(region), md_T%data2, T, md_T%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), md_Q%data2, Q, md_Q%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE(T, Q)
- ! data array is filled now:
- md_T%filled2 = .true.
- md_T%tr2(1) = data2_t1
- md_T%tr2(2) = data2_t2
- md_Q%filled2 = .true.
- md_Q%tr2(1) = data2_t1
- md_Q%tr2(2) = data2_t2
- else if ( data2_copy ) then
-
- ! copy data from primary array:
- md_T%data2 = md_T%data1
- md_Q%data2 = md_Q%data1
-
- ! data array is filled now:
- md_T%filled2 = .true.
- md_T%tr2(1) = data2_t1
- md_T%tr2(2) = data2_t2
- md_Q%filled2 = .true.
- md_Q%tr2(1) = data2_t1
- md_Q%tr2(2) = data2_t2
- end if
-
- !------------------
- ! time interpolation
- !------------------
- call TimeInterpolation( md_T, tr, status )
- IF_NOTOK_RETURN(status=1)
-
- call TimeInterpolation( md_Q, tr, status )
- IF_NOTOK_RETURN(status=1)
-
- !------------------
- ! done
- !------------------
- status = 0
- call goLabel()
- end subroutine Setup_TQ
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: METEO_CHECKPRESSURE
- !
- ! !DESCRIPTION: Compute difference b/w sp1_dat (read) and sp_dat (advected),
- ! and compare to threshold.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE METEO_CHECKPRESSURE( n, status )
- !
- ! !USES:
- !
- use ParTools, only : Par_Reduce
- use dims, only : idate, newsrun
- use dims, only : xcyc, im, jm
- use redgridZoom, only : calc_pdiff
- #ifdef with_hdf4
- use io_hdf, only : io_write2d_32d, DFACC_CREATE
- #endif
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: n ! region
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 7 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Meteo_CheckPressure'
-
- ! maximum accepted pressure difference:
- real, parameter :: pdiffmax_treshold = 1.0e2 ! Pa
-
- ! --- external -------------------------
-
- integer(4), external :: sfStart, sfEnd
-
- ! --- local -----------------------------
-
- real :: pdiffmax, pdiffmax_l
- integer(4) :: io
- ! --- begin ------------------------------
-
- call goLabel(rname)
-
- ! compare 'advected' pressure with read pressure
- if ( .not. newsrun ) then
-
- ! compute difference between 'advected' pressure sp and read pressure
- ! sp1, accounting for reduce grid if any
- call calc_pdiff( n, pdiffmax_l )
- ! compute maximum over all pe's
- call Par_Reduce( pdiffmax_l, 'max', pdiffmax, status, all=.true. )
- IF_NOTOK_RETURN(status=1)
- ! check ...
- if ( pdiffmax > pdiffmax_treshold ) then
- write (gol,'("difference between advected and read-in pressure exceeds treshold :")'); call goErr
- write (gol,'(" max diff. : ",es9.2," [Pa]")') pdiffmax; call goErr
- write (gol,'(" treshold : ",es9.2," [Pa]")') pdiffmax_treshold; call goErr
- write (gol,'("pressure arrays saved to local `pressure.hdf`")'); call goErr
- #ifdef with_hdf4
- if (isRoot) then
- io = sfStart( 'pressure.hdf', DFACC_CREATE )
- if ( io > 0 ) then
- call io_write2d_32d( io, im(n)+4, 'LON', jm(n)+4, 'LAT', sp1_dat(n)%data(:,:,1), 'p' , idate )
- call io_write2d_32d( io, im(n)+4, 'LON', jm(n)+4, 'LAT', sp_dat(n)%data(:,:,1), 'pold', idate )
- status = sfend(io)
- else
- write (gol,'("writing pressures")'); call goErr
- end if
- end if ! root
- #endif
- TRACEBACK; status=1; return
- end if ! max diff
- end if ! no newsrun
- ! ok
- status = 0
- call goLabel()
-
- END SUBROUTINE METEO_CHECKPRESSURE
- !EOC
- ! **************************************************************
- ! ***
- ! *** vertical velocity
- ! ***
- ! **************************************************************
-
- subroutine Compute_Omega( omega, lli, mfw, status )
-
- use binas , only : grav
- use grid, only : TllGridInfo, AreaOper
- use meteodata, only : TMeteoData
- use tmm, only : SetHistory, AddHistory
-
- ! --- in/out ----------------------------------
-
- type(TMeteoData), intent(inout) :: omega ! Pa/s downward
- type(TllGridInfo), intent(in) :: lli
- type(TMeteoData), intent(in) :: mfw ! kg/s upward
- integer, intent(out) :: status
-
- ! --- const -----------------------------------
-
- character(len=*), parameter :: rname = mname//'/Compute_Omega'
-
- ! --- local ----------------------------------
-
- integer :: l
-
- ! --- begin ----------------------------------
-
- ! not in use ?
- if ( .not. omega%used ) return
- ! leave if not in use:
- if ( .not. mfw%used ) then
- write (gol,'("omega (Pa/s) requires mfw (kg/s)")'); call goErr
- call goErr; status=1; return
- end if
- call goLabel(rname)
- ! Pa/s = kg/s / m2 * g
-
- ! init with mass flux; revert sign from upward to downard, divide by
- ! gravity accelaration
- omega%data = - mfw%data * grav ! Pa/s m2
- ! loop over levels and divide by cell area (m2)
- do l = 1, size(omega%data,3)
- call AreaOper( lli, omega%data(:,:,l), '/', 'm2', status )
- IF_NOTOK_RETURN(status=1)
- end do
-
- ! info ..
- !call SetHistory( omega%tmi, mfw%tmi, status )
- !call AddHistory( omega%tmi, 'convert to Pa/s', status )
- ! ok
- status = 0
- call goLabel()
-
- end subroutine Compute_Omega
-
- ! **************************************************************
- ! ***
- ! *** Specific SETUP routine for CONVECTIVE FLUXES
- ! ***
- ! **************************************************************
-
- subroutine Setup_Convec_SERIAL( region, entu, entd, detu, detd, omega, gph, &
- tr, lli, levi, status )
- use GO, only : TDate, wrtgol, operator(/=)
- use Grid, only : TllGridInfo, TLevelInfo
- use TMM, only : TMeteoInfo, Read_Convec, WriteField
- use meteodata, only : TMeteoData, TimeInterpolation
- use dims, only : im, jm
- ! --- in/out ----------------------------------
- integer, intent(in) :: region ! region number
- type(TMeteoData), intent(inout) :: entu, entd, detu, detd
- type(TMeteoData), intent(in) :: omega, gph
- type(TDate), intent(in) :: tr(2)
- type(TllGridInfo), intent(in) :: lli
- type(TLevelInfo), intent(in) :: levi
- integer, intent(out) :: status
- ! --- const --------------------------------------
-
- character(len=*), parameter :: rname = mname//'/SETUP_CONVEC_SERIAL'
-
- ! --- local ----------------------------------
-
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
- real, allocatable :: tmp_sp(:,:)
- ! to differentiate b/w local and global data set
- real, pointer, dimension(:,:,:) :: L_entu, L_entd, L_detu, L_detd
- real, pointer :: L_omega(:,:,:), L_gph(:,:,:)
- integer, dimension(2) :: is, js, ls, auxls
- integer :: halo
- ! --- begin -----------------------------
- call goLabel(rname)
-
- ! leave if not in use:
- if ( (.not. all((/entu%used,entd%used,detu%used,detd%used/)) ) &
- .and. any((/entu%used,entd%used,detu%used,detd%used/)) ) then
- write (gol,'("either none or all of entu/entd/detu/detd should be in use")'); call goErr
- call goErr; status=1; return
- end if
-
- if ( .not. entu%used ) then
- call goLabel()
- status=0; return
- end if
- if (okdebug) then
- write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(entu%name),trim(lli%name); call goPr
- endif
-
- ! gph is required as input:
- if ( .not. gph%used ) then
- write (gol,'("gph should be in use to compute convective stuff from EC convective fluxes")'); call goErr
- call goErr; status=1; return
- end if
- ! NOT NEEDED in EC-Earth, since we are using the ec-ll method (read_convec)
- ! ! omega is required as input:
- ! if ( .not. omega%used ) then
- ! write (gol,'("omega should be in use to compute convective stuff")'); call goErr
- ! call goErr; status=1; return
- ! end if
-
- ! not changed by default
- entu%changed = .false.
- entd%changed = .false.
- detu%changed = .false.
- detd%changed = .false.
-
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read (sufficient to setup from entu only)
-
- call SetupSetup( entu, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
-
- !--------------------------
- ! read/write primary field
- !--------------------------
- if ( data1_read ) then
- ! Need whole region for I/O on root. Dummy else.
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
- ls = entu%ls
- auxls = gph%ls
- IF (isRoot) THEN
- ! Use the fact that entu, entd, detu, and detd have been allocated with the same bounds and halo=0
- allocate( L_entu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- allocate( L_entd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- allocate( L_detu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- allocate( L_detd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- allocate(L_gph (im(region), jm(region), auxls(1):auxls(2)) )
- allocate(L_omega(im(region), jm(region), auxls(1):auxls(2)) )
- ELSE
- allocate( L_entu(1,1,1), L_entd(1,1,1), L_detu(1,1,1), L_detd(1,1,1))
- allocate(L_gph (1,1,1))
- allocate(L_omega(1,1,1))
- END IF
-
- CALL GATHER( dgrid(region), gph%data, L_gph, gph%halo, status)
- IF_NOTOK_RETURN(status=1)
-
- ! NOT NEEDED in EC-Earth, since we are using the ec-ll method (read_convec)
- ! CALL GATHER( dgrid(region), omega%data, L_omega, omega%halo, status)
- ! IF_NOTOK_RETURN(status=1)
- ! Read/write on root
- IOroot : if (isRoot) then
-
- ! safety check ...
- ! if ( data1_t2 /= data1_t1 ) then
- !write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- !call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
- !call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
- !write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- !call goErr; status=1; return
- ! write (gol,'("WARNING - convec for interval, but pressure/gph/etc instant ...")'); call goPr
- ! end if
- ! surface pressure field:
- allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
- ! fill data
- call Read_Convec( tmmd, entu%sourcekey, &
- data1_tref, data1_t1, data1_t2, lli, levi, &
- L_omega, omega%tmi, &
- L_gph, gph%tmi, &
- tmp_sp, &
- L_entu, entu%tmi1, L_entd, entd%tmi1, &
- L_detu, detu%tmi1, L_detd, detd%tmi1, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles
- if ( entu%putout ) then
- call WriteField( tmmd, entu%destkey, &
- entu%tmi1, 'sp', trim(entu%name), trim(entu%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, '*', &
- tmp_sp, L_entu, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( entd%putout ) then
- call WriteField( tmmd, entd%destkey, &
- entd%tmi1, 'sp', trim(entd%name), trim(entd%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, '*', &
- tmp_sp, L_entd, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( detu%putout ) then
- call WriteField( tmmd, detu%destkey, &
- detu%tmi1, 'sp', trim(detu%name), trim(detu%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, '*', &
- tmp_sp, L_detu, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( detd%putout ) then
- call WriteField( tmmd, detd%destkey, &
- detd%tmi1, 'sp', trim(detd%name), trim(detd%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, '*', &
- tmp_sp, L_detd, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! clear
- deallocate( tmp_sp )
- end if IOroot
- ! Scatter & clean up
- CALL SCATTER( dgrid(region), entu%data1, L_entu, entu%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), entd%data1, L_entd, entd%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), detu%data1, L_detu, detu%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), detd%data1, L_detd, detd%halo, status)
- IF_NOTOK_RETURN(status=1)
- deallocate(L_entu, L_entd, L_detu, L_detd, L_gph, L_omega)
-
- ! data array is filled now:
- entu%filled1 = .true.
- entu%tr1(1) = data1_t1
- entu%tr1(2) = data1_t2
- entu%changed = .true.
- entd%filled1 = .true.
- entd%tr1(1) = data1_t1
- entd%tr1(2) = data1_t2
- entd%changed = .true.
- detu%filled1 = .true.
- detu%tr1(1) = data1_t1
- detu%tr1(2) = data1_t2
- detu%changed = .true.
- detd%filled1 = .true.
- detd%tr1(1) = data1_t1
- detd%tr1(2) = data1_t2
- detd%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- entu%data1 = entu%data2
- entd%data1 = entd%data2
- detu%data1 = detu%data2
- detd%data1 = detd%data2
- ! data array is filled now:
- entu%filled1 = .true.
- entu%tr1(1) = data1_t1
- entu%tr1(2) = data1_t2
- entu%changed = .true.
- entd%filled1 = .true.
- entd%tr1(1) = data1_t1
- entd%tr1(2) = data1_t2
- entd%changed = .true.
- detu%filled1 = .true.
- detu%tr1(1) = data1_t1
- detu%tr1(2) = data1_t2
- detu%changed = .true.
- detd%filled1 = .true.
- detd%tr1(1) = data1_t1
- detd%tr1(2) = data1_t2
- detd%changed = .true.
- end if
-
- !--------------------------
- ! read/write secondary field
- !--------------------------
- if ( data2_read ) then
- ! Need whole region for I/O on root. Dummy else
- is = (/1,im(1)/)
- js = (/1,jm(1)/)
- ls = entu%ls
- auxls = gph%ls
- IF (isRoot) THEN
- ! Use the fact that entu, entd, detu, and detd have been allocated with the same bounds and halo
- ALLOCATE( L_entu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_entd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_detu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_detd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE(L_gph (im(region),jm(region),auxls(1):auxls(2)))
- ALLOCATE(L_omega (im(region),jm(region),auxls(1):auxls(2)))
- ELSE
- ALLOCATE( L_entu(1,1,1), L_entd(1,1,1), L_detu(1,1,1), L_detd(1,1,1))
- ALLOCATE( L_gph(1,1,1), L_omega(1,1,1) )
- END IF
-
- CALL GATHER( dgrid(region), gph%data, L_gph, gph%halo, status)
- IF_NOTOK_RETURN(status=1)
-
- ! NOT NEEDED in EC-Earth, since we are using the ec-ll method (read_convec)
- ! CALL GATHER( dgrid(region), omega%data, L_omega, omega%halo, status)
- ! IF_NOTOK_RETURN(status=1)
- ! Read/write on root
- IOroot2 : if (isRoot) then
-
- ! safety check ...
- ! if ( data2_t2 /= data2_t1 ) then
- !write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- !call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
- !call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
- !write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- !call goErr; status=1; return
- ! write (gol,'("WARNING - convec for interval, but pressure/gph/etc instant ...")'); call goPr
- ! end if
-
- ! surface pressure field:
- allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
- ! fill data2
- call Read_Convec( tmmd, entu%sourcekey, &
- data2_tref, data2_t1, data2_t2, lli, levi, &
- L_omega, omega%tmi, &
- L_gph, gph%tmi, &
- tmp_sp, &
- L_entu, entu%tmi2, L_entd, entd%tmi2, &
- L_detu, detu%tmi2, L_detd, detd%tmi2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles ?
- if ( entu%putout ) then
- call WriteField( tmmd, entu%destkey, &
- entu%tmi2, 'sp', trim(entu%name), trim(entu%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, '*', &
- tmp_sp, L_entu, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- if ( entd%putout ) then
- call WriteField( tmmd, entd%destkey, &
- entd%tmi2, 'sp', trim(entd%name), trim(entd%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, '*', &
- tmp_sp, L_entd, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- if ( detu%putout ) then
- call WriteField( tmmd, detu%destkey, &
- detu%tmi2, 'sp', trim(detu%name), trim(detu%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, '*', &
- tmp_sp, L_detu, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- if ( detd%putout ) then
- call WriteField( tmmd, detd%destkey, &
- detd%tmi2, 'sp', trim(detd%name), trim(detd%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, '*', &
- tmp_sp, L_detd, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- ! clear
- deallocate( tmp_sp )
-
- end if IOroot2
- CALL SCATTER( dgrid(region), entu%data2, L_entu, entu%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), entd%data2, L_entd, entd%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), detu%data2, L_detu, detu%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), detd%data2, L_detd, detd%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE( L_entu, L_entd, L_detu, L_detd, L_gph, L_omega )
-
- ! data2 array is filled now:
- entu%filled2 = .true.
- entu%tr2(1) = data2_t1
- entu%tr2(2) = data2_t2
- entd%filled2 = .true.
- entd%tr2(1) = data2_t1
- entd%tr2(2) = data2_t2
- detu%filled2 = .true.
- detu%tr2(1) = data2_t1
- detu%tr2(2) = data2_t2
- detd%filled2 = .true.
- detd%tr2(1) = data2_t1
- detd%tr2(2) = data2_t2
- else if ( data2_copy ) then
-
- ! copy data2 from primary array:
- entu%data2 = entu%data1
- entd%data2 = entd%data1
- detu%data2 = detu%data1
- detd%data2 = detd%data1
-
- ! data2 array is filled now:
- entu%filled2 = .true.
- entu%tr2(1) = data2_t1
- entu%tr2(2) = data2_t2
- entd%filled2 = .true.
- entd%tr2(1) = data2_t1
- entd%tr2(2) = data2_t2
- detu%filled2 = .true.
- detu%tr2(1) = data2_t1
- detu%tr2(2) = data2_t2
- detd%filled2 = .true.
- detd%tr2(1) = data2_t1
- detd%tr2(2) = data2_t2
- end if
-
- !------------------
- ! time interpolation
- !------------------
- call TimeInterpolation( entu, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( entd, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( detu, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( detd, tr, status )
- IF_NOTOK_RETURN(status=1)
-
- !------------------
- ! done
- !------------------
- status = 0
- call goLabel()
- END SUBROUTINE SETUP_CONVEC_SERIAL
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUP_CONVEC_PARA
- !
- ! !DESCRIPTION: same as setup_convec_serial_io but with parallel i/o
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUP_CONVEC_PARA( region, entu, entd, detu, detd, omega, gph, &
- tr, levi, status )
- !
- ! !USES:
- !
- use GO, only : TDate, wrtgol, operator(/=)
- use Grid, only : TllGridInfo, TLevelInfo
- use TMM, only : TMeteoInfo, Read_Convec, WriteField
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region ! region number
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: entu, entd, detu, detd
- type(TMeteoData), intent(in) :: omega, gph
- type(TDate), intent(in) :: tr(2)
- type(TLevelInfo), intent(in) :: levi
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 24 Oct 2013 - Ph. Le Sager - v0
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/SETUP_CONVEC_PARA'
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
- real, allocatable :: tmp_sp(:,:)
- ! to differentiate b/w local and global data set
- real, pointer, dimension(:,:,:) :: L_entu, L_entd, L_detu, L_detd
- real, pointer :: L_omega(:,:,:), L_gph(:,:,:)
- integer, dimension(2) :: is, js, ls, auxls
- integer :: halo
- integer :: i1, i2, j1, j2
- ! --- begin -----------------------------
- call goLabel(rname)
- ! leave if not in use:
- if ( (.not. all((/entu%used,entd%used,detu%used,detd%used/)) ) &
- .and. any((/entu%used,entd%used,detu%used,detd%used/)) ) then
- write (gol,'("either none or all of entu/entd/detu/detd should be in use")'); call goErr
- call goErr; status=1; return
- end if
- if ( .not. entu%used ) then
- call goLabel()
- status=0; return
- end if
- ! gph is required as input:
- if ( .not. gph%used ) then
- write (gol,'("gph should be in use to compute convective stuff from EC convective fluxes")'); call goErr
- call goErr; status=1; return
- end if
- ! omega is required as input:
- if ( .not. omega%used ) then
- write (gol,'("omega should be in use to compute convective stuff")'); call goErr
- call goErr; status=1; return
- end if
- ! not changed by default
- entu%changed = .false.
- entd%changed = .false.
- detu%changed = .false.
- detd%changed = .false.
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read (sufficient to setup from entu only)
- call SetupSetup( entu, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! work arrays
- if (data1_read .or. data2_read) then
- CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- is = (/i1,i2/)
- js = (/j1,j2/)
- ls = entu%ls
- auxls = gph%ls
- ! Use the fact that entu, entd, detu, and detd have been allocated with the same bounds and halo=0
- allocate( L_entu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- allocate( L_entd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- allocate( L_detu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- allocate( L_detd( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
- L_gph => gph%data
- L_omega => omega%data
- end if
- !--------------------------
- ! read/write primary field
- !--------------------------
- if ( data1_read ) then
- !AJS if ( data1_t2 /= data1_t1 ) then
- !AJS write (gol,'("WARNING - convec for interval, but pressure/gph/etc instant ...")'); call goPr
- !AJS end if
- call Read_Convec( tmmd, entu%sourcekey, &
- data1_tref, data1_t1, data1_t2, lli(region), levi, &
- L_omega, omega%tmi, &
- L_gph, gph%tmi, &
- tmp_sp, &
- L_entu, entu%tmi1, L_entd, entd%tmi1, &
- L_detu, detu%tmi1, L_detd, detd%tmi1, &
- status )
- IF_NOTOK_RETURN(status=1)
- entu%data1(i1:i2,j1:j2,:) = L_entu
- entd%data1(i1:i2,j1:j2,:) = L_entd
- detu%data1(i1:i2,j1:j2,:) = L_detu
- detd%data1(i1:i2,j1:j2,:) = L_detd
- ! data array is filled now:
- entu%filled1 = .true.
- entu%tr1(1) = data1_t1
- entu%tr1(2) = data1_t2
- entu%changed = .true.
- entd%filled1 = .true.
- entd%tr1(1) = data1_t1
- entd%tr1(2) = data1_t2
- entd%changed = .true.
- detu%filled1 = .true.
- detu%tr1(1) = data1_t1
- detu%tr1(2) = data1_t2
- detu%changed = .true.
- detd%filled1 = .true.
- detd%tr1(1) = data1_t1
- detd%tr1(2) = data1_t2
- detd%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- entu%data1 = entu%data2
- entd%data1 = entd%data2
- detu%data1 = detu%data2
- detd%data1 = detd%data2
- ! data array is filled now:
- entu%filled1 = .true.
- entu%tr1(1) = data1_t1
- entu%tr1(2) = data1_t2
- entu%changed = .true.
- entd%filled1 = .true.
- entd%tr1(1) = data1_t1
- entd%tr1(2) = data1_t2
- entd%changed = .true.
- detu%filled1 = .true.
- detu%tr1(1) = data1_t1
- detu%tr1(2) = data1_t2
- detu%changed = .true.
- detd%filled1 = .true.
- detd%tr1(1) = data1_t1
- detd%tr1(2) = data1_t2
- detd%changed = .true.
- end if
- !--------------------------
- ! read/write secondary field
- !--------------------------
- if ( data2_read ) then
- !AJS if ( data2_t2 /= data2_t1 ) then
- !AJS write (gol,'("WARNING - convec for interval, but pressure/gph/etc instant ...")'); call goPr
- !AJS end if
- call Read_Convec( tmmd, entu%sourcekey, &
- data2_tref, data2_t1, data2_t2, lli(region), levi, &
- L_omega, omega%tmi, &
- L_gph, gph%tmi, &
- tmp_sp, &
- L_entu, entu%tmi2, L_entd, entd%tmi2, &
- L_detu, detu%tmi2, L_detd, detd%tmi2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles ?
- ! if ( entu%putout ) then
- ! end if
- entu%data2(i1:i2,j1:j2,:) = L_entu
- entd%data2(i1:i2,j1:j2,:) = L_entd
- detu%data2(i1:i2,j1:j2,:) = L_detu
- detd%data2(i1:i2,j1:j2,:) = L_detd
- ! data2 array is filled now:
- entu%filled2 = .true.
- entu%tr2(1) = data2_t1
- entu%tr2(2) = data2_t2
- entd%filled2 = .true.
- entd%tr2(1) = data2_t1
- entd%tr2(2) = data2_t2
- detu%filled2 = .true.
- detu%tr2(1) = data2_t1
- detu%tr2(2) = data2_t2
- detd%filled2 = .true.
- detd%tr2(1) = data2_t1
- detd%tr2(2) = data2_t2
- else if ( data2_copy ) then
- ! copy data2 from primary array:
- entu%data2 = entu%data1
- entd%data2 = entd%data1
- detu%data2 = detu%data1
- detd%data2 = detd%data1
- ! data2 array is filled now:
- entu%filled2 = .true.
- entu%tr2(1) = data2_t1
- entu%tr2(2) = data2_t2
- entd%filled2 = .true.
- entd%tr2(1) = data2_t1
- entd%tr2(2) = data2_t2
- detu%filled2 = .true.
- detu%tr2(1) = data2_t1
- detu%tr2(2) = data2_t2
- detd%filled2 = .true.
- detd%tr2(1) = data2_t1
- detd%tr2(2) = data2_t2
- end if
- !------------------
- ! time interpolation
- !------------------
- call TimeInterpolation( entu, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( entd, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( detu, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( detd, tr, status )
- IF_NOTOK_RETURN(status=1)
- !------------------
- ! done
- !------------------
- if (data1_read .or. data2_read) then
- deallocate(L_entu, L_entd, L_detu, L_detd)
- deallocate( tmp_sp )
- nullify(L_gph, L_omega)
- end if
- status = 0
- call goLabel()
- END SUBROUTINE SETUP_CONVEC_PARA
- !EOC
- ! **************************************************************
- ! ***
- ! *** Specific SETUP routine for CLOUD COVER
- ! ***
- ! **************************************************************
-
- SUBROUTINE SETUP_CLOUDCOVERS_SERIAL( region, cc, cco, ccu, tr, lli, levi, status )
- use GO, only : TDate, wrtgol, operator(/=)
- use Grid, only : TllGridInfo, TLevelInfo
- use TMM, only : TMeteoInfo, Read_CloudCovers, WriteField
- use meteodata, only : TMeteoData, TimeInterpolation
- use dims, only : im, jm
- ! --- in/out ----------------------------------
-
- integer, intent(in) :: region ! region number
- type(TMeteoData), intent(inout) :: cc, cco, ccu
- type(TDate), intent(in) :: tr(2)
- type(TllGridInfo), intent(in) :: lli
- type(TLevelInfo), intent(in) :: levi
- integer, intent(out) :: status
- ! --- const --------------------------------------
-
- character(len=*), parameter :: rname = mname//'/Setup_CloudCovers_Serial'
-
- ! --- local ----------------------------------
-
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
-
- real, allocatable :: tmp_sp(:,:) ! surface pressure
-
- real, pointer, dimension(:,:,:) :: L_cc, L_cco, L_ccu ! work arrays (data)
- integer :: is(2), js(2), ls(2) ! work arrays (bounds)
- ! --- begin -----------------------------
-
- call goLabel(rname)
-
- ! leave if not in use:
- if ( (.not. all((/cc%used,cco%used,ccu%used/)) ) .and. any((/cc%used,cco%used,ccu%used/)) ) then
- write (gol,'("either none or all of cc/cco/ccu should be in use")'); call goErr
- call goErr; status=1; return
- end if
- if ( .not. cc%used ) then
- call goLabel()
- status=0; return
- end if
- if (okdebug) then
- write (gol,'(" ",a,": ",a," @ ",a)') rname, trim(cc%name),trim(lli%name); call goPr
- endif
-
- ! not changed by default
- cc%changed = .false.
- cco%changed = .false.
- ccu%changed = .false.
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read (sufficient to setup from cc only)
-
- call SetupSetup( cc, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
-
-
- !--------------------------
- ! read/write primary field
- !--------------------------
- if ( data1_read ) then
- ! Allocate global arrays for I/O
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
- ls = cc%ls
- IF (isRoot) THEN
- ALLOCATE( L_cc( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_cco( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_ccu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ELSE
- ALLOCATE( L_cc(1,1,1), L_cco(1,1,1), L_ccu(1,1,1) )
- END IF
- ! Read/write on root
- IOroot : if (isRoot) then
- ! safety check ...
- if ( data1_t2 /= data1_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
- call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- call goErr; status=1; return
- end if
- ! surface pressure field:
- allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
- ! fill data:
- call Read_CloudCovers( tmmd, cc%sourcekey, &
- data1_tref, data1_t1, data1_t2, lli, levi, &
- tmp_sp, &
- L_cc, cc%tmi1, &
- L_cco, cco%tmi1, &
- L_ccu, ccu%tmi1, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles
- if ( cc%putout ) then
- call WriteField( tmmd, cc%destkey, &
- cc%tmi1, 'sp', trim(cc%name), trim(cc%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, L_cc, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- if ( cco%putout ) then
- call WriteField( tmmd, cco%destkey, &
- cco%tmi1, 'sp', trim(cco%name), trim(cco%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, L_cco, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- if ( ccu%putout ) then
- call WriteField( tmmd, ccu%destkey, &
- ccu%tmi1, 'sp', trim(ccu%name), trim(ccu%unit), &
- data1_tref, data1_t1, data1_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, L_ccu, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! clear
- deallocate( tmp_sp )
- end if IOroot
- ! Wrap up
- CALL SCATTER( dgrid(region), cc%data1, L_cc, cc%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), cco%data1, L_cco, cco%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), ccu%data1, L_ccu, ccu%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE(L_cc, L_cco, L_ccu)
- ! data array is filled now:
- cc%filled1 = .true.
- cc%tr1(1) = data1_t1
- cc%tr1(2) = data1_t2
- cc%changed = .true.
- cco%filled1 = .true.
- cco%tr1(1) = data1_t1
- cco%tr1(2) = data1_t2
- cco%changed = .true.
- ccu%filled1 = .true.
- ccu%tr1(1) = data1_t1
- ccu%tr1(2) = data1_t2
- ccu%changed = .true.
- else if ( data1_copy ) then
-
- ! copy data from secondary array:
- cc%data1 = cc%data2
- cco%data1 = cco%data2
- ccu%data1 = ccu%data2
-
- ! data array is filled now:
- cc%filled1 = .true.
- cc%tr1(1) = data1_t1
- cc%tr1(2) = data1_t2
- cc%changed = .true.
- cco%filled1 = .true.
- cco%tr1(1) = data1_t1
- cco%tr1(2) = data1_t2
- cco%changed = .true.
- ccu%filled1 = .true.
- ccu%tr1(1) = data1_t1
- ccu%tr1(2) = data1_t2
- ccu%changed = .true.
- end if
- !--------------------------
- ! read/write secondary field
- !--------------------------
- if ( data2_read ) then
- ! Allocate global arrays for I/O
- is = (/1,im(region)/)
- js = (/1,jm(region)/)
- ls = cc%ls
- IF (isRoot) THEN
- ! Use the fact that entu, entd, detu, and detd have been allocated with the same bounds and halo
- ALLOCATE( L_cc( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_cco( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_ccu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ELSE
- ALLOCATE( L_cc(1,1,1), L_cco(1,1,1), L_ccu(1,1,1) )
- END IF
-
- ! Read/write
- IOroot2 : IF (isRoot) THEN
-
- ! safety check ...
- if ( data2_t2 /= data2_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data2_t1 : ', data2_t1 ); call goErr
- call wrtgol( ' data2_t2 : ', data2_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- call goErr; status=1; return
- end if
- ! surface pressure field:
- allocate( tmp_sp(is(1):is(2),js(1):js(2)) )
- ! fill data2:
- call Read_CloudCovers( tmmd, cc%sourcekey, data2_tref, &
- data2_t1, data2_t2, lli, levi, &
- tmp_sp, &
- L_cc, cc%tmi2, &
- L_cco, cco%tmi2, &
- L_ccu, ccu%tmi2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! write meteofiles ?
- if ( cc%putout ) then
- call WriteField( tmmd, cc%destkey, &
- cc%tmi2, 'sp', trim( cc%name), trim( cc%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, L_cc, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- if ( cco%putout ) then
- call WriteField( tmmd, cco%destkey, &
- cco%tmi2, 'sp', trim(cco%name), trim(cco%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, L_cco, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( ccu%putout ) then
- call WriteField( tmmd, ccu%destkey, &
- ccu%tmi2, 'sp', trim(ccu%name), trim(ccu%unit), &
- data2_tref, data2_t1, data2_t2, &
- lli, 'n', levi, 'n', &
- tmp_sp, L_ccu, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! clear
- deallocate( tmp_sp )
- end if IOroot2
- ! Wrap up
- CALL SCATTER( dgrid(region), cc%data2, L_cc, cc%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), cco%data2, L_cco, cco%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL SCATTER( dgrid(region), ccu%data2, L_ccu, ccu%halo, status)
- IF_NOTOK_RETURN(status=1)
- DEALLOCATE(L_cc, L_cco, L_ccu)
-
- ! data2 array is filled now:
- cc%filled2 = .true.
- cc%tr2(1) = data2_t1
- cc%tr2(2) = data2_t2
- cco%filled2 = .true.
- cco%tr2(1) = data2_t1
- cco%tr2(2) = data2_t2
- ccu%filled2 = .true.
- ccu%tr2(1) = data2_t1
- ccu%tr2(2) = data2_t2
- else if ( data2_copy ) then
-
- ! copy data2 from primary array:
- cc%data2 = cc%data1
- cco%data2 = cco%data1
- ccu%data2 = ccu%data1
-
- ! data2 array is filled now:
- cc%filled2 = .true.
- cc%tr2(1) = data2_t1
- cc%tr2(2) = data2_t2
- cco%filled2 = .true.
- cco%tr2(1) = data2_t1
- cco%tr2(2) = data2_t2
- ccu%filled2 = .true.
- ccu%tr2(1) = data2_t1
- ccu%tr2(2) = data2_t2
- end if
-
- !------------------
- ! time interpolation
- !------------------
- call TimeInterpolation( cc, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( cco, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( ccu, tr, status )
- IF_NOTOK_RETURN(status=1)
- !------------------
- ! done
- !------------------
- status = 0
- call goLabel()
- END SUBROUTINE SETUP_CLOUDCOVERS_SERIAL
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SETUP_CLOUDCOVERS_PARA
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SETUP_CLOUDCOVERS_PARA( region, cc, cco, ccu, tr, levi, status )
- !
- ! !USES:
- !
- use GO, only : TDate, wrtgol, operator(/=)
- use Grid, only : TllGridInfo, TLevelInfo
- use TMM, only : TMeteoInfo, Read_CloudCovers, WriteField
- use dims, only : im, jm
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region ! region number
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TMeteoData), intent(inout) :: cc, cco, ccu
- type(TDate), intent(in) :: tr(2)
- type(TLevelInfo), intent(in) :: levi
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 24 Oct 2013 - Ph. Le Sager - v0
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/SETUP_CLOUDCOVERS_PARA'
- logical :: data1_read, data1_copy
- type(TDate) :: data1_tref, data1_t1, data1_t2
- logical :: data2_read, data2_copy
- type(TDate) :: data2_tref, data2_t1, data2_t2
- real, allocatable :: tmp_sp(:,:) ! surface pressure
- real, pointer, dimension(:,:,:) :: L_cc, L_cco, L_ccu ! work arrays (data)
- integer :: is(2), js(2), ls(2) ! work arrays (bounds)
- integer :: i1, i2, j1, j2
- ! --- begin -----------------------------
- call goLabel(rname)
- ! leave if not in use:
- if ( (.not. all((/cc%used,cco%used,ccu%used/)) ) .and. any((/cc%used,cco%used,ccu%used/)) ) then
- write (gol,'("either none or all of cc/cco/ccu should be in use")'); call goErr
- call goErr; status=1; return
- end if
- if ( .not. cc%used ) then
- call goLabel()
- status=0; return
- end if
- ! not changed by default
- cc%changed = .false.
- cco%changed = .false.
- ccu%changed = .false.
- !------------------
- ! time stuff
- !------------------
- ! get time interval of met field and check if data from start and/or end
- ! of interval must be read (sufficient to setup from cc only)
- call SetupSetup( cc, tr, &
- data1_read, data1_copy, data1_tref, data1_t1, data1_t2, &
- data2_read, data2_copy, data2_tref, data2_t1, data2_t2, &
- status )
- IF_NOTOK_RETURN(status=1)
- ! work arrays
- IF (data1_read .OR. data2_read) THEN
- CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- is = (/i1,i2/)
- js = (/j1,j2/)
- ls = cc%ls
- ALLOCATE( L_cc( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_cco( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( L_ccu( is(1):is(2), js(1):js(2), ls(1):ls(2)) )
- ALLOCATE( tmp_sp(is(1):is(2),js(1):js(2)) )
- ENDIF
- !--------------------------
- ! read/write primary field
- !--------------------------
- if ( data1_read ) then
- ! safety check
- if ( data1_t2 /= data1_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")'); call goErr
- call wrtgol( ' data1_t1 : ', data1_t1 ); call goErr
- call wrtgol( ' data1_t2 : ', data1_t2 ); call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")'); call goErr
- TRACEBACK; status=1; return
- end if
- call Read_CloudCovers( tmmd, cc%sourcekey, &
- data1_tref, data1_t1, data1_t2, lli(region), levi, &
- tmp_sp, &
- L_cc, cc%tmi1, &
- L_cco, cco%tmi1, &
- L_ccu, ccu%tmi1, &
- status )
- IF_NOTOK_RETURN(status=1)
- cc%data1(i1:i2,j1:j2,:) = L_cc
- cco%data1(i1:i2,j1:j2,:) = L_cco
- ccu%data1(i1:i2,j1:j2,:) = L_ccu
- ! data array is filled now:
- cc%filled1 = .true.
- cc%tr1(1) = data1_t1
- cc%tr1(2) = data1_t2
- cc%changed = .true.
- cco%filled1 = .true.
- cco%tr1(1) = data1_t1
- cco%tr1(2) = data1_t2
- cco%changed = .true.
- ccu%filled1 = .true.
- ccu%tr1(1) = data1_t1
- ccu%tr1(2) = data1_t2
- ccu%changed = .true.
- else if ( data1_copy ) then
- ! copy data from secondary array:
- cc%data1 = cc%data2
- cco%data1 = cco%data2
- ccu%data1 = ccu%data2
- ! data array is filled now:
- cc%filled1 = .true.
- cc%tr1(1) = data1_t1
- cc%tr1(2) = data1_t2
- cc%changed = .true.
- cco%filled1 = .true.
- cco%tr1(1) = data1_t1
- cco%tr1(2) = data1_t2
- cco%changed = .true.
- ccu%filled1 = .true.
- ccu%tr1(1) = data1_t1
- ccu%tr1(2) = data1_t2
- ccu%changed = .true.
- end if
- !--------------------------
- ! read/write secondary field
- !--------------------------
- if ( data2_read ) then
- ! safety check ...
- if ( data2_t2 /= data2_t1 ) then
- write (gol,'("not sure that this routine is correct for time intervals:")') ; call goErr
- call wrtgol( ' data2_t1 : ', data2_t1 ) ; call goErr
- call wrtgol( ' data2_t2 : ', data2_t2 ) ; call goErr
- write (gol,'("please deceide what to do with surface pressures ... ")') ; call goErr
- call goErr; status=1; return
- end if
- call Read_CloudCovers( tmmd, cc%sourcekey, data2_tref, &
- data2_t1, data2_t2, lli(region), levi, &
- tmp_sp, &
- L_cc, cc%tmi2, &
- L_cco, cco%tmi2, &
- L_ccu, ccu%tmi2, &
- status )
- IF_NOTOK_RETURN(status=1)
- cc%data2(i1:i2,j1:j2,:) = L_cc
- cco%data2(i1:i2,j1:j2,:) = L_cco
- ccu%data2(i1:i2,j1:j2,:) = L_ccu
- ! data2 array is filled now:
- cc%filled2 = .true.
- cc%tr2(1) = data2_t1
- cc%tr2(2) = data2_t2
- cco%filled2 = .true.
- cco%tr2(1) = data2_t1
- cco%tr2(2) = data2_t2
- ccu%filled2 = .true.
- ccu%tr2(1) = data2_t1
- ccu%tr2(2) = data2_t2
- else if ( data2_copy ) then
- ! copy data2 from primary array:
- cc%data2 = cc%data1
- cco%data2 = cco%data1
- ccu%data2 = ccu%data1
- ! data2 array is filled now:
- cc%filled2 = .true.
- cc%tr2(1) = data2_t1
- cc%tr2(2) = data2_t2
- cco%filled2 = .true.
- cco%tr2(1) = data2_t1
- cco%tr2(2) = data2_t2
- ccu%filled2 = .true.
- ccu%tr2(1) = data2_t1
- ccu%tr2(2) = data2_t2
- end if
- !------------------
- ! time interpolation
- !------------------
- call TimeInterpolation( cc, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( cco, tr, status )
- IF_NOTOK_RETURN(status=1)
- call TimeInterpolation( ccu, tr, status )
- IF_NOTOK_RETURN(status=1)
- !------------------
- ! done
- !------------------
- if (data1_read .or. data2_read) then
- deallocate( tmp_sp )
- deallocate(L_cc, L_cco, L_ccu)
- end if
- status = 0
- call goLabel()
- END SUBROUTINE SETUP_CLOUDCOVERS_PARA
- !EOC
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PRESSURE_TO_MASS
- !
- ! !DESCRIPTION: Get Air Mass: from surface pressure (sp), get pressure at
- ! box boundaries (so-called half-levels, phlb), and then air
- ! mass (m_dat).
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PRESSURE_TO_MASS( region, status )
- !
- ! !USES:
- !
- use Binas, only : grav
- use Grid, only : HPressure
- !use Grid, only : FillMass
- use Grid, only : AreaOper
- use dims, only : im, jm, lm
- use dims, only : xcyc
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 7 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS: (old remark: "assume that halo cells in sp have been filled
- ! correctly..." still valid???)
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Pressure_to_Mass'
- integer :: l, i0, i1, j0, j1, lmr
- ! --- begin ----------------------------------
- ! Local grid size
- i0 = sp_dat(region)%is(1)
- i1 = sp_dat(region)%is(2)
- j0 = sp_dat(region)%js(1)
- j1 = sp_dat(region)%js(2)
- lmr = lm(region)
- ! Fill pressure boundaries (Pa)
- if ( phlb_dat(region)%used ) then
- call HPressure( levi, sp_dat(region)%data(i0:i1, j0:j1, 1), &
- phlb_dat(region)%data(i0:i1, j0:j1, :), status )
- IF_NOTOK_RETURN(status=0)
- end if
- ! Fill air mass (kg)
- if ( m_dat(region)%used ) then
- !call FillMass( m_dat(region)%data(1:imr,1:jmr,:), lli(region), levi, &
- ! sp_dat(region)%data(1:imr,1:jmr,1), status )
- !IF_NOTOK_RETURN(status=0)
- ! Pressure difference between top and bottom of layer
- do l = 1, lmr
- m_dat(region)%data(:,:,l) = phlb_dat(region)%data(:,:,l) - phlb_dat(region)%data(:,:,l+1) ! Pa
- end do
- ! Convert to kg/m2
- m_dat(region)%data = m_dat(region)%data / grav ! Pa/g = kg/m2
- ! Convert to kg
- call AreaOper( lli(region), m_dat(region)%data(i0:i1, j0:j1, :), '*', 'm2', status ) ! kg
- IF_NOTOK_RETURN(status=0)
- end if
- ! ok
- status = 0
- END SUBROUTINE PRESSURE_TO_MASS
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: MASS_TO_PRESSURE
- !
- ! !DESCRIPTION: get 3D and surface (spm) pressures from 3D Air Mass.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE MASS_TO_PRESSURE( region, status )
- !
- ! !USES:
- !
- use Binas, only : grav
- use Grid, only : AreaOper
- use dims, only : lm
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 7 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Mass_to_Pressure'
- integer :: l, i0, i1, j0, j1, lmr
- ! --- begin ----------------------------------
- ! Local grid size
- i0 = sp_dat(region)%is(1)
- i1 = sp_dat(region)%is(2)
- j0 = sp_dat(region)%js(1)
- j1 = sp_dat(region)%js(2)
- lmr = lm(region)
-
- ! Fill pressure at half level boundaries:
- ! o zero in space:
- phlb_dat(region)%data(:,:,lmr+1) = 0.0 ! kg m/s2 = Pa m2
- ! o add for each level pressure gradient:
- do l = lmr, 1, -1
- phlb_dat(region)%data(i0:i1, j0:j1, l) = phlb_dat(region)%data(i0:i1, j0:j1, l+1) &
- + m_dat(region)%data(i0:i1, j0:j1, l ) * grav ! kg m/s2 = Pa m2
- end do
- ! Divide by grid cell area
- call AreaOper( lli(region), phlb_dat(region)%data(i0:i1, j0:j1, :), '/', 'm2', status ) ! Pa
- IF_NOTOK_RETURN(status=0)
- ! copy surface pressure
- spm_dat(region)%data(i0:i1, j0:j1, 1) = phlb_dat(region)%data(i0:i1, j0:j1, 1) ! Pa
- ! ok
- status = 0
- END SUBROUTINE MASS_TO_PRESSURE
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: COMPUTE_GPH
- !
- ! !DESCRIPTION: compute geopotential height
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE COMPUTE_GPH( region, status )
- !
- ! !USES:
- !
- use Dims, only : itau, lm
- use Dims, only : at, bt
- use binas, only : grav
- use datetime, only : tstamp
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 10 Nov 2011 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/compute_gph'
- ! --- local ----------------------------------
-
- real,dimension(:,:,:),pointer :: gph, t, q
- real,dimension(:,:,:),pointer :: ps
- integer :: i,j,l,i0,i1,j0,j1
- real :: tv,pdown,pup
- ! --- begin -----------------------------
- ! leave if not in use:
- if ( .not. gph_dat(region)%used ) then
- if (okdebug) then
- write (gol,'(a," not used on : ",i2)') trim(gph_dat(region)%name),region; call goPr
- endif
- status=0; return
- end if
-
- ! other meteo required:
- if ( (.not. temper_dat(region)%used) .or. (.not. humid_dat(region)%used) &
- .or. (.not. sp_dat(region)%used) .or. (.not. oro_dat(region)%used)) then
- write (gol,'("computation of gph requires temper, humid, sp, and oro")'); call goErr
- TRACEBACK; status=1; return
- end if
-
- ! leave if input did not change:
- if ( (.not. sp_dat(region)%changed) .and. &
- (.not. temper_dat(region)%changed) .and. &
- (.not. humid_dat(region)%changed) ) then
- if (okdebug) then
- write (gol,'(a,": not changed for region ",i2)') rname, region; call goPr
- endif
- status=0
- return
- end if
-
- ! field will be changed ...
- gph_dat(region)%changed = .true.
- ! pointers to meteo field
- ps => sp_dat(region)%data
- t => temper_dat(region)%data
- q => humid_dat(region)%data
- gph => gph_dat(region)%data
- ! bounds w/o halo (same as: call Get_DistGrid( dgrid(region), I_STRT=i01, I_STOP=i02, J_STRT=j01, J_STOP=j02 )
- i0 = gph_dat(region)%is(1)
- i1 = gph_dat(region)%is(2)
- j0 = gph_dat(region)%js(1)
- j1 = gph_dat(region)%js(2)
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! compute geo potential height
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- gph(i0:i1,j0:j1,1) = oro_dat(region)%data(i0:i1,j0:j1,1)/grav ! oro is stored in g*m
-
- do l=1,lm(region)-1
- do j=j0,j1
- do i=i0,i1
- tv = t(i,j,l)*(1. + 0.608*q(i,j,l))
- pdown = at(l) + bt(l)*ps(i,j,1)
- pup = at(l+1) + bt(l+1)*ps(i,j,1)
- ! rgas in different units!
- gph(i,j,l+1) = gph(i,j,l) + tv*287.05*alog(pdown/pup)/grav
- ! note dec 2002 (MK) gph now from 1--->lm+1
- end do
- end do
- end do
- !set top of atmosphere at 200 km
- gph(:,:,lm(region)+1) = 200000.0
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! done
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- nullify( ps )
- nullify( t )
- nullify( q )
- nullify( gph )
-
- status = 0
- END SUBROUTINE COMPUTE_GPH
- !EOC
- END MODULE METEO
|