user_output_pdump.F90 233 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631
  1. #define TRACEBACK write (gol,'("in ",a," (",a,i6,")")') rname, __FILE__, __LINE__ ; call goErr
  2. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  3. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  4. #define IF_NOTOK_MDF(action) if (status/=0) then; TRACEBACK; action; call MDF_CLose(fid,status); status=1; return; end if
  5. !
  6. #include "tm5.inc"
  7. !-----------------------------------------------------------------------------
  8. ! TM5 !
  9. !-----------------------------------------------------------------------------
  10. !BOP
  11. !
  12. ! !MODULE: USER_OUTPUT_PDUMP
  13. !
  14. ! !DESCRIPTION:
  15. !
  16. ! Module to deal with time-series output. Output are in NetCDF-4 and use CF
  17. ! conventions. The following output are available:
  18. !
  19. ! - one file with grid definition
  20. ! - one file with time series of some met fields (pressure, temperature, winds, ...)
  21. ! - one or more files with time series of some tracers
  22. ! - one or two files with Local Time output for some tracers
  23. ! - one file with time series of wet and dry depositions
  24. ! - one file with time series of deposition velocity
  25. !
  26. ! If the macro (cpp) "tropomi" is used, then the temperature and extra attributes added to the vmr (tracers) datasets.
  27. !
  28. ! Activation, tracers to account for, time step of the series, are set in the
  29. ! rcfile, following this template :
  30. !
  31. !
  32. ! SAMPLE RCFILE
  33. !
  34. ! output.pdump : T
  35. ! output.pdump.dataset.author : John Doe
  36. ! output.pdump.dataset.institution : MyFirm, Anytown, USA
  37. ! output.pdump.dataset.version : GEMS GRG; era2003 simulation
  38. ! tropomi only:
  39. ! output.pdump.tropomi.tm5version : v4
  40. ! output.pdump.tropomi.institution : KNMI
  41. ! output.pdump.tropomi.tm5reference : Huijnen et al., ACP
  42. ! output.pdump.tropomi.authoremail : Doe@john.com
  43. ! output.pdump.tropomi.datasetname : "S5P_AUX_CTMFCT" or "S5P_AUX_CTMANA"
  44. !
  45. ! output.pdump.fname.model : TM5
  46. ! output.pdump.fname.expid : V2
  47. ! output.pdump.fname.grid.300x200 : 3x2 ! short name, required if there is zoom regions
  48. ! output.pdump.fname.grid.100x100 : 1x1
  49. !
  50. ! output.pdump.griddef.apply : T
  51. !
  52. ! output.pdump.tp.apply : T
  53. ! output.pdump.tp.dhour : 1
  54. !
  55. ! output.pdump.vmr.n : 3
  56. !
  57. ! output.pdump.vmr.001.apply : T
  58. ! output.pdump.vmr.001.fname : vmr3
  59. ! output.pdump.vmr.001.dhour : 3
  60. ! output.pdump.vmr.001.tracers : SO2 NOy CH4 OH HNO3 PAN H2O2 Radon Lead
  61. !
  62. ! output.pdump.vmr.002.apply : T
  63. ! output.pdump.vmr.002.fname : vmr1
  64. ! output.pdump.vmr.002.dhour : 1
  65. ! output.pdump.vmr.002.tracers : O3 O3s CO NO2 NO CH2O
  66. !
  67. ! output.pdump.vmr.003.apply : F
  68. ! output.pdump.vmr.003.fname : vmra
  69. ! output.pdump.vmr.003.dhour : 3
  70. ! output.pdump.vmr.003.tracers : SO4 NO3_A BC BCS POM SS1_N SS1_M SS2_N SS2_M SS3_N SS3_M DUST2_N DUST2_M DUST3_N DUST3_M
  71. !
  72. ! output.pdump.lt.apply : T
  73. ! output.pdump.lt.tracers : O3
  74. ! output.pdump.lt.localtime : 2
  75. !
  76. ! output.pdump.lt2.apply : F
  77. ! output.pdump.lt2.tracers :
  78. ! output.pdump.lt2.localtime :
  79. !
  80. ! output.pdump.depositions.apply : F
  81. ! output.pdump.depositions.dhour : 3
  82. ! output.pdump.depositions.tracers : O3 HNO3 NO NO2 H2O2 CH2O PAN CO NH3 NH4 SO2 NOy
  83. !
  84. ! output.pdump.depvels.apply : F
  85. ! output.pdump.depvels.dhour : 3
  86. ! output.pdump.depvels.tracers : O3 HNO3 NO NO2 H2O2 CH2O PAN CO NH3 NH4 SO2
  87. !
  88. !\\
  89. !\\
  90. ! !INTERFACE:
  91. !
  92. MODULE USER_OUTPUT_PDUMP
  93. !
  94. ! !USES:
  95. !
  96. use partools, only : isRoot
  97. use GO, only : gol, goPr, goErr, goLabel
  98. use GO, only : TDate, IncrDate, NewDate
  99. use GO, only : operator(+), SystemDate, Get
  100. use dims, only : nregions, idatee, idatei, okdebug, nread
  101. use chem_param, only : ntrace
  102. use chem_param, only : iNOx, iHNO3, iPAN, iOrgNtr
  103. #ifdef with_m7
  104. use chem_param, only : iNO3_a
  105. use chem_param, only : iSO4nus, iSO4ais, iSO4acs, iSO4cos
  106. use chem_param, only : iBCais, iBCacs, iBCcos, iBCaii
  107. use chem_param, only : iPOMais, iPOMacs, iPOMcos, iPOMaii
  108. use chem_param, only : iDUacs, iDUcos, iDUaci, iDUcoi
  109. use chem_param, only : iSScos, iSSacs
  110. #endif
  111. USE MDF
  112. USE TM5_DISTGRID, only : dgrid, Get_DistGrid, update_halo
  113. IMPLICIT NONE
  114. PRIVATE
  115. !
  116. ! !PUBLIC MEMBER FUNCTIONS:
  117. !
  118. public :: Output_PDUMP_Init
  119. public :: Output_PDUMP_Step
  120. public :: Output_PDUMP_Done
  121. !
  122. ! !PRIVATE DATA MEMBERS:
  123. !
  124. character(len=*), parameter :: mname = 'user_output_pdump'
  125. character(len=*), parameter :: outfileversnr = '0.1'
  126. integer, parameter :: time_reftime6(6) = (/1950,01,01,00,00,00/) ! reference time
  127. character(len=*), parameter :: time_units = 'days since 1950-01-01 00:00:00'
  128. !
  129. ! NOy is not a standard tracer field, but sum of some transported tracers:
  130. ! NOx HNO3 PAN orgntr NO3_a
  131. ! where NOx is the sum of short lived tracers:
  132. ! NOx = NO + NO2 + NO3 + HNO4 + 2*N2O5
  133. !
  134. #ifdef with_m7
  135. integer, parameter :: iNOy = ntrace + 1
  136. integer, parameter :: nNOyt = 5
  137. integer, parameter :: iNOyt(nNOyt) = (/ iNOx, iHNO3, iNO3_a, iPAN, iOrgNtr /)
  138. integer, parameter :: iSO4 = ntrace + 2
  139. integer, parameter :: nSO4t = 4
  140. integer, parameter :: iSO4t(nSO4t) = (/ iSO4nus, iSO4ais, iSO4acs, iSO4cos /)
  141. integer, parameter :: iBC = ntrace + 3
  142. integer, parameter :: nBCt = 4
  143. integer, parameter :: iBCt(nBCt) = (/ iBCais, iBCacs, iBCcos, iBCaii /)
  144. integer, parameter :: iPOM = ntrace + 4
  145. integer, parameter :: nPOMt = 4
  146. integer, parameter :: iPOMt(nPOMt) = (/ iPOMais, iPOMacs, iPOMcos, iPOMaii /)
  147. integer, parameter :: iSS = ntrace + 5
  148. integer, parameter :: nSSt = 2
  149. integer, parameter :: iSSt(nSSt) = (/ iSSacs, iSScos /)
  150. integer, parameter :: iDU = ntrace + 6
  151. integer, parameter :: nDUt = 4
  152. integer, parameter :: iDUt(nDUt) = (/ iDUacs, iDUcos, iDUaci, iDUcoi /)
  153. #else
  154. integer, parameter :: iNOy = ntrace + 1
  155. integer, parameter :: nNOyt = 4
  156. integer, parameter :: iNOyt(nNOyt) = (/ iNOx, iHNO3, iPAN, iOrgNtr /)
  157. #endif
  158. !
  159. ! !PRIVATE TYPES:
  160. !
  161. type TPdumpFile_GridDef
  162. integer :: trec
  163. integer :: ncid
  164. integer :: dimid_scalar, dimid_lon, dimid_lat, dimid_lev, dimid_levi
  165. integer :: varid_lon, varid_lat, varid_time, varid_date
  166. integer :: varid_gridbox_area
  167. integer :: varid_a, varid_b
  168. integer :: varid_a_bnds, varid_b_bnds
  169. integer :: varid_p0
  170. !integer :: varid_ps
  171. !integer :: varid_geo_height
  172. end type TPdumpFile_GridDef
  173. type TPdumpFile_TP
  174. integer :: trec
  175. integer :: dhour
  176. integer :: ncid
  177. integer :: dimid_lon, dimid_lat, dimid_lev, dimid_time, dimid_datelen
  178. integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
  179. integer :: varid_ps
  180. integer :: varid_surface_temp
  181. integer :: varid_orog
  182. integer :: varid_geop
  183. integer :: varid_pressure
  184. integer :: varid_temp
  185. integer :: varid_humid
  186. integer :: varid_u, varid_v, varid_w
  187. real, allocatable :: data3d(:,:,:,:,:)
  188. real, allocatable :: data2d(:,:,:,:)
  189. real, allocatable :: time(:)
  190. real, allocatable :: date(:,:)
  191. end type TPdumpFile_TP
  192. type TPdumpFile_VMR
  193. integer :: trec, n_rec
  194. logical :: apply
  195. real :: dhour
  196. integer :: dsec
  197. character(len=256) :: tracer_names
  198. integer :: ncid
  199. integer :: dimid_lon, dimid_lat, dimid_lev, dimid_levi, dimid_time, dimid_datelen
  200. integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
  201. integer :: varid_ps
  202. integer :: varid_a_bnds, varid_b_bnds
  203. integer :: ntr
  204. integer :: itr(ntrace)
  205. character(len=8) :: name_tr(ntrace)
  206. #ifdef with_m7
  207. logical :: lpmx(ntrace)
  208. real :: sizepmx(ntrace)
  209. #endif
  210. integer :: varid_tr(ntrace)
  211. character(len=4) :: varid_type(ntrace)
  212. real, allocatable :: data3d(:,:,:,:,:)
  213. real, allocatable :: sp(:,:,:)
  214. real, allocatable :: time(:)
  215. real, allocatable :: date(:,:)
  216. real, allocatable :: data3d_t(:,:,:,:)
  217. integer :: varid_temp
  218. #ifdef tropomi
  219. integer :: varid_hyai, varid_hybi, varid_hyam, varid_hybm
  220. integer :: varid_hgt
  221. integer :: varid_ltropo
  222. real, allocatable :: data2d_hgt(:,:)
  223. integer, allocatable:: data2d_ltropo(:,:,:)
  224. #endif
  225. end type TPdumpFile_VMR
  226. type TPdumpFile_LT
  227. integer :: trec
  228. character(len=256) :: tracer_names
  229. integer :: ncid
  230. integer :: local_time
  231. integer :: dimid_lon, dimid_lat, dimid_lev, dimid_time, dimid_datelen
  232. integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
  233. integer :: varid_ps
  234. integer :: ntr
  235. integer :: itr(ntrace)
  236. character(len=8) :: name_tr(ntrace)
  237. integer :: varid_tr(ntrace)
  238. real,allocatable :: accu(:,:,:,:)
  239. real,allocatable :: naccu(:,:)
  240. real,allocatable :: p_accu(:,:)
  241. real,allocatable :: np_accu(:)
  242. #ifdef with_m7
  243. logical :: laod(ntrace)
  244. real :: wavel(ntrace)
  245. #endif
  246. end type TPdumpFile_LT
  247. type TPdumpFile_DEPS
  248. integer :: trec
  249. integer :: dhour
  250. character(len=256) :: tracer_names
  251. integer :: ncid
  252. integer :: dimid_lon, dimid_lat, dimid_time, dimid_datelen
  253. integer :: varid_lon, varid_lat, varid_time, varid_date, varid_accum
  254. integer :: ntr
  255. integer :: itr(ntrace)
  256. character(len=8) :: name_tr(ntrace)
  257. integer :: varid_ddep(ntrace)
  258. real, pointer :: ddep_budget(:,:,:)
  259. logical :: with_wdep(ntrace)
  260. integer :: varid_wdep(ntrace)
  261. real, pointer :: wdep_budget(:,:,:)
  262. type(TDate) :: t0_budget
  263. real, allocatable :: data2d_dry(:,:,:,:)
  264. real, allocatable :: data2d_wet(:,:,:,:)
  265. real, allocatable :: time(:), dt(:)
  266. real, allocatable :: date(:,:)
  267. end type TPdumpFile_DEPS
  268. type TPdumpFile_DEPV
  269. integer :: trec
  270. integer :: dhour
  271. character(len=256) :: tracer_names
  272. integer :: ncid
  273. integer :: dimid_lon, dimid_lat, dimid_time, dimid_datelen
  274. integer :: varid_lon, varid_lat, varid_time, varid_date
  275. integer :: ntr
  276. integer :: itr(ntrace)
  277. character(len=8) :: name_tr(ntrace)
  278. integer :: varid_tr(ntrace)
  279. real, allocatable :: data2d(:,:,:,:)
  280. real, allocatable :: time(:)
  281. real, allocatable :: date(:,:)
  282. end type TPdumpFile_DEPV
  283. ! --- var -----------------------------
  284. integer :: fid ! file id for IF_NOTOK_MDF macro
  285. integer :: access_mode ! netcdf-4 access mode
  286. integer :: curr_day(nregions,3)
  287. logical :: firstday
  288. logical :: lastday ! it is last day and not a full day (ie day does not end at 00 of next day)
  289. character(len=32) :: fname_model
  290. character(len=8) :: fname_expid, meteo_class
  291. character(len=32) :: fname_grid(nregions)
  292. character(len=256) :: dataset_author, institution, dataset_version
  293. #ifdef tropomi
  294. character(len=256) :: tropomi_authoremail, tropomi_tm5_reference, tropomi_institution
  295. character(len=256) :: tropomi_tm5_version, tropomi_dataset_name
  296. character(len=15) :: tropomi_date_start, tropomi_date_stop, tropomi_date_create
  297. #endif
  298. logical, save :: griddef_apply
  299. type(TPdumpFile_GridDef), save :: RF_GridDef(nregions)
  300. logical, save :: tp_apply
  301. integer :: tp_dhour, n_tp_rec
  302. type(TPdumpFile_TP), save :: RF_TP(nregions)
  303. integer, save :: nvmr
  304. logical, allocatable :: vmr_apply(:)
  305. real, allocatable :: vmr_sregbord(:,:)
  306. character(len=16), allocatable :: vmr_fname(:)
  307. real, allocatable :: vmr_dhour(:)
  308. character(len=256), allocatable :: vmr_tracer_names(:)
  309. type(TPdumpFile_VMR), allocatable, save :: RF_VMR(:,:)
  310. logical, save :: lt_apply
  311. character(len=16) :: lt_fname
  312. character(len=256) :: lt_tracer_names
  313. integer :: lt_localtime
  314. type(TPdumpFile_LT), save :: RF_LT(nregions)
  315. logical, save :: lt2_apply
  316. character(len=16) :: lt2_fname
  317. character(len=256) :: lt2_tracer_names
  318. integer :: lt2_localtime
  319. type(TPdumpFile_LT), save :: RF_LT2(nregions)
  320. logical, save :: deps_apply
  321. character(len=16) :: deps_fname
  322. integer :: deps_dhour, n_deps_rec
  323. character(len=256) :: deps_tracer_names
  324. type(TPdumpFile_DEPS), save :: RF_DEPS(nregions)
  325. logical, save :: depv_apply
  326. character(len=16) :: depv_fname
  327. integer :: depv_dhour, n_depv_rec
  328. character(len=256) :: depv_tracer_names
  329. type(TPdumpFile_DEPV), save :: RF_DEPV(nregions)
  330. !
  331. ! !REVISION HISTORY:
  332. ! 1 Oct 2010 - Achim Strunk - revised older RETRO ouptut :
  333. ! add 2nd local time, regional output,
  334. ! handle aerosol tracers and M7
  335. ! 10 Jul 2012 - Ph. Le Sager - switch from pnetcdf to netcdf4_par (through
  336. ! MDF); get rid of the with_tendencies code.
  337. ! 12 Nov 2012 - Ph. Le Sager - adapted for lon-lat MPI decomposition.
  338. ! - get rid of unlimited dimensions so we can
  339. ! write in collective mode.
  340. ! - store series to write them only at end-of-day
  341. ! to speed-up code
  342. ! 10 Oct 2013 - Ph. Le Sager - fixed GET_N_TIME_RECORDS and several 'init'
  343. ! and write' routines.
  344. ! 14 Apr 2014 - Ph. Le Sager + JEW - tropomi add-ons in VMR: Temperature,
  345. ! As, Bs, better CF
  346. ! 8 October 2014 - H. Eskes - changes in tropomi output (based on the "tropomi" macro)
  347. !
  348. ! !REMARKS:
  349. !
  350. ! (1) Initially called RETRO output for GEMS GRG, the module has been adapted
  351. ! for CLIMAQS project and renamed PDUMP.
  352. ! (2) Previous remarks "as is":
  353. ! - longitudes from [0,360] ?
  354. ! this is imposible for zoom area's such as for the heatwave
  355. ! - levels from surface to top
  356. ! - time from 1950-01-01 00:00
  357. ! (3) This is supposed to work with netcdf4_parallel. You cannot use
  358. ! MPI with a non-parallel version of netcdf4 here.
  359. ! (4) The parallel writing is done in COLLECTIVE mode, but remain
  360. ! expensive on some system. Possible optimization : output one file
  361. ! per month (chunk/leg), and/or per field, and/or per processor.
  362. ! (5) Switch in nstep for DEPS data should work for full days. Not tested
  363. ! for partial days.
  364. !
  365. ! !TODO:
  366. ! - test with M7 tracers. Which ones?
  367. ! - in LT_WRITE : AOD if m7 needs to be coded
  368. ! - in RF_VMR_INIT : match tracer with CF standard names for some aerosols
  369. ! (dust,...)
  370. !
  371. !EOP
  372. !------------------------------------------------------------------------
  373. CONTAINS
  374. !--------------------------------------------------------------------------
  375. ! TM5 !
  376. !--------------------------------------------------------------------------
  377. !BOP
  378. !
  379. ! !FUNCTION: GET_N_TIME_RECORDS
  380. !
  381. ! !DESCRIPTION: return number of time steps for a daily timeseries file
  382. !\\
  383. !\\
  384. ! !INTERFACE:
  385. !
  386. FUNCTION GET_N_TIME_RECORDS( date, dsec, isDEPS, mess )
  387. !
  388. ! !USES:
  389. !
  390. USE GO , only : TDate, NewDate, rTotal, operator(-)
  391. !
  392. ! !RETURN VALUE:
  393. !
  394. integer :: get_n_time_records
  395. !
  396. ! !INPUT PARAMETERS:
  397. !
  398. integer, intent(in) :: date(6) ! 1st time step of the day (timestart basically)
  399. integer, intent(in) :: dsec ! time step for timeseries in sec (should divide 24*3600, be divided by ndyn/2)
  400. logical, optional, intent(in) :: isDEPS ! to differentiate b/w DEPS and others
  401. character(len=*), optional, intent(in) :: mess ! message (if okdebug)
  402. !
  403. ! !REVISION HISTORY:
  404. ! 9 Nov 2012 - Ph. Le Sager - v0
  405. ! 9 Oct 2013 - Ph. Le Sager - fix to work with default "output.after.step: v"
  406. ! 15 Jul 2014 - Ph. Le Sager - works with seconds instead of hours
  407. !
  408. ! !REMARKS:
  409. ! - dynamic timestep cannot be LARGER than timestep of timeseries, with notable exception
  410. ! of dynamic timestep = 2*timeseries_timestep.
  411. !
  412. ! !TODO:
  413. ! - check if anything changes with other possible values of "output.after.step"
  414. !
  415. !EOP
  416. !------------------------------------------------------------------------
  417. !BOC
  418. integer :: is, ie, delta, dynstep
  419. logical :: deps
  420. type(TDate) :: t, t0
  421. real :: time
  422. ! Type of record (standard=vmr, tp, depv) or special (deps)
  423. deps=.false.
  424. if (present(isDEPS)) deps=isDEPS
  425. ! Start index
  426. delta=date(4)*3600+date(5)*60+date(6) ! 0, unless start of the run is not at 00:00:00
  427. if (deps) delta=delta + nread ! one DYNAMIC time step done to output something
  428. if (modulo(delta,dsec)==0) then
  429. is=delta/dsec
  430. else
  431. is=(delta+dsec)/dsec
  432. end if
  433. ! End index for daily file (nread=dynamic time step read from rc)
  434. ie = (24*3600 - nread/2) / dsec
  435. if (deps) then ! there will be an extra step if run goes further than midnight
  436. t0 = NewDate( time6=date )
  437. t = NewDate( time6=idatee )
  438. time = rTotal( t - t0, 'day' )
  439. if (time > 1) ie=24*3600/dsec
  440. end if
  441. ! Case of "last day stopping before midnite". (Need testing for DEPS)
  442. if (lastday) ie=(idatee(4)*3600+idatee(5)*60+idatee(6)-nread/2)/dsec
  443. ! length
  444. get_n_time_records = ie-is+1
  445. if(okdebug)then
  446. if (present(mess))then
  447. write(gol,*) 'GET_N_TIME_RECORDS -'//trim(mess); call goPr
  448. end if
  449. write(gol,*) "GET_N_TIME_RECORDS - is, ie, deps, firstday, lastday, get_n_time_records:" ; call goPr
  450. write(gol,*) "GET_N_TIME_RECORDS - ", is, ie, deps, firstday, lastday, get_n_time_records ; call goPr
  451. write(gol,*) "GET_N_TIME_RECORDS - date, dsec, nread ", date, dsec, nread ; call goPr
  452. write(gol,*) "GET_N_TIME_RECORDS - idateE ", idatee ; call goPr
  453. end if
  454. return
  455. END FUNCTION GET_N_TIME_RECORDS
  456. !EOC
  457. !--------------------------------------------------------------------------
  458. ! TM5 !
  459. !--------------------------------------------------------------------------
  460. !BOP
  461. !
  462. ! !IROUTINE: OUTPUT_PDUMP_INIT
  463. !
  464. ! !DESCRIPTION: reads rc file keys relevant for pdump
  465. !\\
  466. !\\
  467. ! !INTERFACE:
  468. !
  469. SUBROUTINE OUTPUT_PDUMP_INIT( rcF, dsec_min, status )
  470. !
  471. ! !USES:
  472. !
  473. use GO, only : TrcFile, ReadRc
  474. use MeteoData, only : lli, set
  475. use MeteoData, only : sp_dat, oro_dat, temper_dat, humid_dat, pu_dat, pv_dat
  476. use MeteoData, only : mfw_dat, gph_dat, t2m_dat
  477. !
  478. ! !INPUT/OUTPUT PARAMETERS:
  479. !
  480. type(TrcFile), intent(inout) :: rcF
  481. !
  482. ! !OUTPUT PARAMETERS:
  483. !
  484. integer, intent(out) :: dsec_min ! smallest timeseries period in sec
  485. integer, intent(out) :: status
  486. !
  487. ! !REVISION HISTORY:
  488. ! 1 Oct 2010 - Achim Strunk - upgrade from RETRO to PDUMP
  489. ! 8 Nov 2012 - Ph. Le Sager - added access mode switch
  490. !
  491. !EOP
  492. !------------------------------------------------------------------------
  493. !BOC
  494. character(len=*), parameter :: rname = mname//'/Output_PDUMP_Init'
  495. ! --- local ------------------------------
  496. integer :: region
  497. character(len=64) :: key
  498. character(len=3) :: nr
  499. integer :: ivmr
  500. ! --- begin -------------------------------
  501. call goLabel(rname)
  502. #ifdef MPI
  503. #ifdef with_netcdf4_par
  504. access_mode = MDF_COLLECTIVE
  505. #else
  506. write(gol,'("Time Series output (PDUMP) requires netcdf4 with parallel access enabled")') ; call goErr
  507. TRACEBACK
  508. status=1; return
  509. #endif
  510. #else
  511. access_mode = MDF_INDEPENDENT
  512. #endif
  513. ! which day
  514. firstday = .true.
  515. lastday = .true.
  516. ! lowest time frequency in sec
  517. dsec_min = 999999
  518. if (any(idatei(1:3)/=idatee(1:3))) lastday=.false. ! i.e. at least one full day
  519. ! dataset keys:
  520. call ReadRc( rcF, 'output.pdump.dataset.author' , dataset_author , status )
  521. IF_NOTOK_RETURN(status=1)
  522. call ReadRc( rcF, 'output.pdump.dataset.institution', institution , status )
  523. IF_NOTOK_RETURN(status=1)
  524. call ReadRc( rcF, 'output.pdump.dataset.version' , dataset_version , status )
  525. IF_NOTOK_RETURN(status=1)
  526. #ifdef tropomi
  527. call ReadRc( rcF, 'output.pdump.tropomi.tm5version', tropomi_tm5_version , status )
  528. IF_NOTOK_RETURN(status=1)
  529. call ReadRc( rcF, 'output.pdump.tropomi.institution', tropomi_institution , status )
  530. IF_NOTOK_RETURN(status=1)
  531. call ReadRc( rcF, 'output.pdump.tropomi.tm5reference', tropomi_tm5_reference , status )
  532. IF_NOTOK_RETURN(status=1)
  533. call ReadRc( rcF, 'output.pdump.tropomi.authoremail', tropomi_authoremail , status )
  534. IF_NOTOK_RETURN(status=1)
  535. call ReadRc( rcF, 'output.pdump.tropomi.datasetname', tropomi_dataset_name , status )
  536. IF_NOTOK_RETURN(status=1)
  537. #endif
  538. ! filename keys:
  539. call ReadRc( rcF, 'output.pdump.fname.model', fname_model, status )
  540. IF_NOTOK_RETURN(status=1)
  541. call ReadRc( rcF, 'output.pdump.fname.expid', fname_expid, status )
  542. IF_NOTOK_RETURN(status=1)
  543. ! prefix grid name in case of zooming regions:
  544. if ( nregions > 1 ) then
  545. ! loop over regions:
  546. do region = 1, nregions
  547. ! short grid name from rcfile:
  548. call ReadRc( rcF, 'output.pdump.fname.grid.'//trim(lli(region)%name), key, status )
  549. IF_NOTOK_RETURN(status=1)
  550. ! fill grid extenstion to file names:
  551. fname_grid(region) = '-'//trim(key)
  552. end do
  553. else
  554. ! empty
  555. fname_grid = ''
  556. end if
  557. ! griddef file ?
  558. call ReadRc( rcF, 'output.pdump.griddef.apply', griddef_apply, status )
  559. IF_NOTOK_RETURN(status=1)
  560. ! temperature, pressure, etc file ?
  561. call ReadRc( rcF, 'output.pdump.tp.apply', tp_apply, status )
  562. IF_NOTOK_RETURN(status=1)
  563. if (tp_apply) then
  564. ! ensure that required meteo is loaded
  565. do region=1,nregions
  566. call Set( sp_dat(region), status, used=.true. )
  567. call Set( oro_dat(region), status, used=.true. )
  568. call Set( temper_dat(region), status, used=.true. )
  569. call Set( t2m_dat(region), status, used=.true. )
  570. call Set( humid_dat(region), status, used=.true. )
  571. call Set( pu_dat(region), status, used=.true. )
  572. call Set( pv_dat(region), status, used=.true. )
  573. call Set( mfw_dat(region), status, used=.true. )
  574. call Set( gph_dat(region), status, used=.true. ) ! used to compute vertical wind
  575. end do
  576. ! time resolution (1 hour by default)
  577. call ReadRc( rcF, 'output.pdump.tp.dhour', tp_dhour, status, default=1 )
  578. IF_ERROR_RETURN(status=1)
  579. dsec_min = tp_dhour*3600
  580. end if
  581. ! VMR files
  582. call ReadRc( rcF, 'output.pdump.vmr.n', nvmr, status ) ! number of vmr files to be written
  583. IF_NOTOK_RETURN(status=1)
  584. if ( nvmr < 0 ) then
  585. write (gol,'("strange specification of number of vmr files : ",i6)') nvmr; call goErr
  586. TRACEBACK; status=1; return
  587. end if
  588. ! meteo
  589. call ReadRc( rcF, 'my.meteo.class', meteo_class, status, default='unknown' )
  590. IF_ERROR_RETURN(status=1)
  591. ! write any vmr files ?
  592. if ( nvmr > 0 ) then
  593. ! storage:
  594. allocate( vmr_apply(nvmr) ) ; vmr_apply = .false.
  595. allocate( vmr_fname(nvmr) ) ; vmr_fname = ''
  596. allocate( vmr_dhour(nvmr) ) ; vmr_dhour = -1.
  597. allocate( vmr_tracer_names(nvmr) ) ; vmr_tracer_names = ''
  598. allocate( vmr_sregbord(nvmr,4) ) ; vmr_sregbord = -999.9
  599. allocate( RF_VMR(nregions,nvmr) )
  600. #ifdef tropomi
  601. do region=1,nregions
  602. call Set( temper_dat(region), status, used=.true. )
  603. call Set( gph_dat(region), status, used=.true. ) ! used to compute surface altitude
  604. end do
  605. #endif
  606. ! loop over vmr files:
  607. do ivmr = 1, nvmr
  608. ! number in rc keys:
  609. write (nr,'(i3.3)') ivmr
  610. ! apply ?
  611. call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.apply', vmr_apply(ivmr), status )
  612. IF_NOTOK_RETURN(status=1)
  613. rf_vmr(:,ivmr)%apply = vmr_apply(ivmr)
  614. ! proceed ?
  615. if ( vmr_apply(ivmr) ) then
  616. ! first part of filename:
  617. call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.fname', vmr_fname(ivmr), status )
  618. IF_NOTOK_RETURN(status=1)
  619. ! time resolution:
  620. call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.dhour', vmr_dhour(ivmr), status )
  621. IF_NOTOK_RETURN(status=1)
  622. ! here is the catch: fractional hour for step should divide 3600
  623. dsec_min = min( dsec_min, int(vmr_dhour(ivmr)*3600) )
  624. ! tracers to be written:
  625. call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.tracers', vmr_tracer_names(ivmr), status )
  626. IF_NOTOK_RETURN(status=1)
  627. end if ! apply ?
  628. end do ! vmr numbers
  629. ! required meteo
  630. if (any(vmr_apply)) then
  631. do region=1,nregions
  632. call Set( sp_dat(region), status, used=.true. )
  633. end do
  634. end if
  635. end if ! nvmr > 0
  636. ! ---------------------
  637. ! local time:
  638. ! ---------------------
  639. ! file 1
  640. lt_fname = 'lt'
  641. call ReadRc( rcF, 'output.pdump.lt.apply', lt_apply, status )
  642. IF_NOTOK_RETURN(status=1)
  643. if ( lt_apply ) then
  644. call ReadRc( rcF, 'output.pdump.lt.tracers', lt_tracer_names, status )
  645. IF_NOTOK_RETURN(status=1)
  646. call ReadRc( rcF, 'output.pdump.lt.localtime', lt_localtime, status )
  647. IF_NOTOK_RETURN(status=1)
  648. end if
  649. ! file 2
  650. lt2_fname = 'lt2'
  651. call ReadRc( rcF, 'output.pdump.lt2.apply', lt2_apply, status )
  652. IF_NOTOK_RETURN(status=1)
  653. if ( lt2_apply ) then
  654. call ReadRc( rcF, 'output.pdump.lt2.tracers', lt2_tracer_names, status )
  655. IF_NOTOK_RETURN(status=1)
  656. call ReadRc( rcF, 'output.pdump.lt2.localtime', lt2_localtime, status )
  657. IF_NOTOK_RETURN(status=1)
  658. end if
  659. if (lt_apply .or. lt2_apply) then
  660. do region=1,nregions
  661. call Set( sp_dat(region), status, used=.true. )
  662. end do
  663. end if
  664. ! ---------------------
  665. ! deposition fluxes:
  666. ! ---------------------
  667. deps_fname = 'depositions'
  668. call ReadRc( rcF, 'output.pdump.depositions.apply', deps_apply, status )
  669. IF_NOTOK_RETURN(status=1)
  670. if ( deps_apply ) then
  671. #ifdef with_budgets
  672. call ReadRc( rcF, 'output.pdump.depositions.dhour', deps_dhour, status )
  673. IF_NOTOK_RETURN(status=1)
  674. call ReadRc( rcF, 'output.pdump.depositions.tracers', deps_tracer_names, status )
  675. IF_NOTOK_RETURN(status=1)
  676. dsec_min = min( dsec_min, deps_dhour*3600)
  677. #else
  678. write(gol,*) "timeseries of deposition fluxes requires using 'with_budget' macro" ; call goErr
  679. status=1 ; TRACEBACK ; return
  680. #endif
  681. end if
  682. ! ---------------------
  683. ! deposition velocities:
  684. ! ---------------------
  685. depv_fname = 'depvels'
  686. call ReadRc( rcF, 'output.pdump.depvels.apply', depv_apply, status )
  687. IF_NOTOK_RETURN(status=1)
  688. if ( depv_apply ) then
  689. #ifdef with_budgets
  690. call ReadRc( rcF, 'output.pdump.depvels.dhour', depv_dhour, status )
  691. IF_NOTOK_RETURN(status=1)
  692. call ReadRc( rcF, 'output.pdump.depvels.tracers', depv_tracer_names, status )
  693. IF_NOTOK_RETURN(status=1)
  694. dsec_min = min( dsec_min, depv_dhour*3600)
  695. #else
  696. write(gol,*) "timeseries of deposition velocities requires using 'with_budget' macro" ; call goErr
  697. status=1 ; TRACEBACK ; return
  698. #endif
  699. end if
  700. ! no files open yet
  701. curr_day = -1
  702. call goLabel()
  703. ! ok
  704. status = 0
  705. END SUBROUTINE OUTPUT_PDUMP_INIT
  706. !EOC
  707. !--------------------------------------------------------------------------
  708. ! TM5 !
  709. !--------------------------------------------------------------------------
  710. !BOP
  711. !
  712. ! !IROUTINE: OUTPUT_PDUMP_STEP
  713. !
  714. ! !DESCRIPTION:
  715. !\\
  716. !\\
  717. ! !INTERFACE:
  718. !
  719. SUBROUTINE OUTPUT_PDUMP_STEP( region, idate_f, status )
  720. !
  721. ! !INPUT PARAMETERS:
  722. !
  723. integer, intent(in) :: region
  724. integer, intent(in) :: idate_f(6)
  725. !
  726. ! !OUTPUT PARAMETERS:
  727. !
  728. integer, intent(out) :: status
  729. !
  730. ! !REVISION HISTORY:
  731. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  732. !
  733. ! !REMARKS:
  734. ! (1) called every hour.
  735. !
  736. !EOP
  737. !------------------------------------------------------------------------
  738. !BOC
  739. character(len=*), parameter :: rname = mname//'/Output_PDUMP_Step'
  740. ! --- begin -------------------------------
  741. call goLabel(rname)
  742. !----------------------
  743. ! close if necessary
  744. !----------------------
  745. ! if a file is open, and it is a new day
  746. if ( all(curr_day(region,:) > 0) .and. any(idate_f(1:3) /= curr_day(region,:)) ) then
  747. ! write in previous day file end-of-interval data
  748. call PDUMP_Files_Write2( region, idate_f, status )
  749. IF_NOTOK_RETURN(status=1)
  750. ! close all
  751. call PDUMP_Files_Close( region, status )
  752. IF_NOTOK_RETURN(status=1)
  753. ! no files open ...
  754. curr_day(region,:) = -1
  755. firstday = .false.
  756. end if
  757. !----------------------
  758. ! open if necessary
  759. !----------------------
  760. if ( any(curr_day(region,:) < 0) ) then
  761. if (all(idate_f(1:3)==idatee(1:3))) lastday=.true. ! means last day is not a full day
  762. write(gol,*) "U_O_Pdump open [idate_f, last day] = ", idate_f, lastday; call goPr
  763. call PDUMP_Files_Open( region, idate_f, status )
  764. IF_NOTOK_RETURN(status=1)
  765. ! store date of current day
  766. curr_day(region,:) = idate_f(1:3)
  767. end if
  768. !----------------------
  769. ! write
  770. !----------------------
  771. call PDUMP_Files_Write( region, idate_f, status )
  772. IF_NOTOK_RETURN(status=1)
  773. ! if not midnight, write end-of-interval data
  774. if ( any(idate_f(4:6) > 0) ) then
  775. call PDUMP_Files_Write2( region, idate_f, status )
  776. IF_NOTOK_RETURN(status=1)
  777. end if
  778. !----------------------
  779. ! done
  780. !----------------------
  781. call goLabel()
  782. status = 0
  783. END SUBROUTINE OUTPUT_PDUMP_STEP
  784. !EOC
  785. !--------------------------------------------------------------------------
  786. ! TM5 !
  787. !--------------------------------------------------------------------------
  788. !BOP
  789. !
  790. ! !IROUTINE: OUTPUT_PDUMP_DONE
  791. !
  792. ! !DESCRIPTION:
  793. !\\
  794. !\\
  795. ! !INTERFACE:
  796. !
  797. SUBROUTINE OUTPUT_PDUMP_DONE( status )
  798. !
  799. ! !USES:
  800. !
  801. use dims, only : itaur
  802. use datetime, only : tau2date
  803. !
  804. ! !OUTPUT PARAMETERS:
  805. !
  806. integer, intent(out) :: status
  807. !
  808. ! !REVISION HISTORY:
  809. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  810. ! 31 Aug 2012 - P. Le Sager - reverse order in which regions are dealt with (MDF issue)
  811. !
  812. !EOP
  813. !------------------------------------------------------------------------
  814. !BOC
  815. character(len=*), parameter :: rname = mname//'/Output_PDUMP_Done'
  816. integer :: region
  817. integer,dimension(6) :: idate_f
  818. ! --- begin -------------------------------
  819. ! close files:
  820. do region = nregions, 1, -1
  821. ! write end of interval DEPS data (requires that DEPS nstep is calculated with .false. -see RF_DEPS_Init-)
  822. call tau2date(itaur(region),idate_f)
  823. call PDUMP_Files_Write2( region, idate_f, status )
  824. IF_NOTOK_RETURN(status=1)
  825. call PDUMP_Files_Close( region, status )
  826. IF_NOTOK_RETURN(status=1)
  827. end do
  828. ! clear:
  829. if ( nvmr > 0 ) then
  830. deallocate( vmr_apply )
  831. deallocate( vmr_fname )
  832. deallocate( vmr_dhour )
  833. deallocate( vmr_tracer_names )
  834. deallocate( vmr_sregbord )
  835. deallocate( RF_VMR )
  836. end if
  837. ! ok
  838. status = 0
  839. END SUBROUTINE OUTPUT_PDUMP_DONE
  840. !EOC
  841. ! ********************************************************************
  842. ! ***
  843. ! *** open/write/close pdump files
  844. ! ***
  845. ! ********************************************************************
  846. !--------------------------------------------------------------------------
  847. ! TM5 !
  848. !--------------------------------------------------------------------------
  849. !BOP
  850. !
  851. ! !IROUTINE: PDUMP_FILES_OPEN
  852. !
  853. ! !DESCRIPTION: call init method of each output file.
  854. !\\
  855. !\\
  856. ! !INTERFACE:
  857. !
  858. subroutine PDUMP_Files_Open( region, idate_f, status )
  859. !
  860. ! !USES:
  861. !
  862. use global_data, only : outdir
  863. !
  864. ! !INPUT PARAMETERS:
  865. !
  866. integer, intent(in) :: region
  867. integer, intent(in) :: idate_f(6)
  868. !
  869. ! !OUTPUT PARAMETERS:
  870. !
  871. integer, intent(out) :: status
  872. !
  873. ! !REVISION HISTORY:
  874. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  875. !
  876. !EOP
  877. !------------------------------------------------------------------------
  878. !BOC
  879. character(len=*), parameter :: rname = mname//'/PDUMP_Files_Open'
  880. ! --- local -------------------------------
  881. integer :: ivmr
  882. ! --- begin -------------------------------
  883. ! grid definition:
  884. if ( griddef_apply ) then
  885. call RF_GridDef_Init( RF_GridDef(region), outdir, fname_model, fname_expid, region, status )
  886. IF_NOTOK_RETURN(status=1)
  887. end if
  888. ! dynamics:
  889. if ( tp_apply ) then
  890. call RF_TP_Init ( RF_TP(region) , outdir, fname_model, fname_expid, &
  891. region, idate_f, tp_dhour, status )
  892. IF_NOTOK_RETURN(status=1)
  893. end if
  894. ! tracer concentrations:
  895. do ivmr = 1, nvmr
  896. if ( .not. vmr_apply(ivmr) ) cycle
  897. call RF_VMR_Init( RF_VMR(region,ivmr), outdir, fname_model, fname_expid, &
  898. vmr_fname(ivmr), region, idate_f, &
  899. vmr_dhour(ivmr), vmr_tracer_names(ivmr), status )
  900. IF_NOTOK_RETURN(status=1)
  901. vmr_apply(ivmr) = rf_vmr(region,ivmr)%apply
  902. end do
  903. ! lt output:
  904. if ( lt_apply ) then
  905. call RF_LT_Init( RF_LT(region), outdir, fname_model, fname_expid, &
  906. lt_fname, region, idate_f, &
  907. lt_localtime, lt_tracer_names, status )
  908. IF_NOTOK_RETURN(status=1)
  909. end if
  910. if ( lt2_apply ) then
  911. call RF_LT_Init( RF_LT2(region), outdir, fname_model, fname_expid, &
  912. lt2_fname, region, idate_f, &
  913. lt2_localtime, lt2_tracer_names, status )
  914. IF_NOTOK_RETURN(status=1)
  915. end if
  916. #ifdef with_budgets
  917. ! deposition fluxes:
  918. if ( deps_apply ) then
  919. call RF_DEPS_Init( RF_DEPS(region), outdir, fname_model, fname_expid, &
  920. deps_fname, region, idate_f, &
  921. deps_dhour, deps_tracer_names, status )
  922. IF_NOTOK_RETURN(status=1)
  923. end if
  924. ! deposition velocities:
  925. if ( depv_apply ) then
  926. call RF_DEPV_Init( RF_DEPV(region), outdir, fname_model, fname_expid, &
  927. depv_fname, region, idate_f, &
  928. depv_dhour, depv_tracer_names, status )
  929. IF_NOTOK_RETURN(status=1)
  930. end if
  931. #endif
  932. ! ok
  933. status = 0
  934. END SUBROUTINE PDUMP_FILES_OPEN
  935. !EOC
  936. !--------------------------------------------------------------------------
  937. ! TM5 !
  938. !--------------------------------------------------------------------------
  939. !BOP
  940. !
  941. ! !IROUTINE: PDUMP_FILES_WRITE
  942. !
  943. ! !DESCRIPTION: call write method for each output file.
  944. !\\
  945. !\\
  946. ! !INTERFACE:
  947. !
  948. SUBROUTINE PDUMP_FILES_WRITE( region, idate_f, status )
  949. !
  950. ! !INPUT PARAMETERS:
  951. !
  952. integer, intent(in) :: region
  953. integer, intent(in) :: idate_f(6)
  954. !
  955. ! !OUTPUT PARAMETERS:
  956. !
  957. integer, intent(out) :: status
  958. !
  959. ! !REVISION HISTORY:
  960. ! 1 Oct 2010 - Achim Strunk -
  961. !
  962. !EOP
  963. !------------------------------------------------------------------------
  964. !BOC
  965. character(len=*), parameter :: rname = mname//'/PDUMP_Files_Write'
  966. integer :: ivmr
  967. ! --- begin -------------------------------
  968. ! grid definition:
  969. if ( griddef_apply ) then
  970. call RF_GridDef_Write( RF_GridDef(region), region, status )
  971. IF_NOTOK_RETURN(status=1)
  972. end if
  973. ! dynamics:
  974. if ( tp_apply ) then
  975. call RF_TP_Write( RF_TP(region), region, idate_f, status )
  976. IF_NOTOK_RETURN(status=1)
  977. end if
  978. ! tracer fields:
  979. do ivmr = 1, nvmr
  980. if ( .not. vmr_apply(ivmr) ) cycle
  981. call RF_VMR_Write( RF_VMR(region,ivmr), region, idate_f, status )
  982. IF_NOTOK_RETURN(status=1)
  983. end do
  984. ! lt output:
  985. if ( lt_apply ) then
  986. call RF_LT_Write( RF_LT(region), region, idate_f, status )
  987. IF_NOTOK_RETURN(status=1)
  988. end if
  989. if ( lt2_apply ) then
  990. call RF_LT_Write( RF_LT2(region), region, idate_f, status )
  991. IF_NOTOK_RETURN(status=1)
  992. end if
  993. #ifdef with_budgets
  994. ! deposition velocities:
  995. if ( depv_apply ) then
  996. call RF_DEPV_Write( RF_DEPV(region), region, idate_f, status )
  997. IF_NOTOK_RETURN(status=1)
  998. end if
  999. #endif
  1000. status = 0
  1001. END SUBROUTINE PDUMP_FILES_WRITE
  1002. !EOC
  1003. !--------------------------------------------------------------------------
  1004. ! TM5 !
  1005. !--------------------------------------------------------------------------
  1006. !BOP
  1007. !
  1008. ! !IROUTINE: PDUMP_FILES_WRITE2
  1009. !
  1010. ! !DESCRIPTION: write at end of time interval
  1011. !
  1012. !\\
  1013. !\\
  1014. ! !INTERFACE:
  1015. !
  1016. SUBROUTINE PDUMP_FILES_WRITE2( region, idate_f, status )
  1017. !
  1018. ! !INPUT PARAMETERS:
  1019. !
  1020. integer, intent(in) :: region
  1021. integer, intent(in) :: idate_f(6)
  1022. !
  1023. ! !OUTPUT PARAMETERS:
  1024. !
  1025. integer, intent(out) :: status
  1026. !
  1027. ! !REVISION HISTORY:
  1028. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  1029. !
  1030. !EOP
  1031. !------------------------------------------------------------------------
  1032. !BOC
  1033. character(len=*), parameter :: rname = mname//'/PDUMP_Files_Write2'
  1034. ! --- begin -------------------------------
  1035. #ifdef with_budgets
  1036. ! deposition fluxes:
  1037. if ( deps_apply ) then
  1038. call RF_DEPS_Write( RF_DEPS(region), region, idate_f, status )
  1039. IF_NOTOK_RETURN(status=1)
  1040. end if
  1041. #endif
  1042. ! lt output:
  1043. if ( lt_apply ) then
  1044. call RF_LT_Write( RF_LT(region), region, idate_f, status )
  1045. IF_NOTOK_RETURN(status=1)
  1046. end if
  1047. if ( lt2_apply ) then
  1048. call RF_LT_Write( RF_LT2(region), region, idate_f, status )
  1049. IF_NOTOK_RETURN(status=1)
  1050. end if
  1051. ! ok
  1052. status = 0
  1053. END SUBROUTINE PDUMP_FILES_WRITE2
  1054. !EOC
  1055. !--------------------------------------------------------------------------
  1056. ! TM5 !
  1057. !--------------------------------------------------------------------------
  1058. !BOP
  1059. !
  1060. ! !IROUTINE: PDUMP_FILES_CLOSE
  1061. !
  1062. ! !DESCRIPTION: call done method of each output file.
  1063. !\\
  1064. !\\
  1065. ! !INTERFACE:
  1066. !
  1067. SUBROUTINE PDUMP_FILES_CLOSE( region, status )
  1068. !
  1069. ! !INPUT PARAMETERS:
  1070. !
  1071. integer, intent(in) :: region
  1072. !
  1073. ! !OUTPUT PARAMETERS:
  1074. !
  1075. integer, intent(out) :: status
  1076. !
  1077. ! !REVISION HISTORY:
  1078. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  1079. ! 31 Aug 2012 - Ph. Le Sager - switch closing order, since it was giving issues on some machine.
  1080. !
  1081. !EOP
  1082. !------------------------------------------------------------------------
  1083. !BOC
  1084. character(len=*), parameter :: rname = mname//'/PDUMP_Files_Close'
  1085. ! --- local -------------------------------
  1086. integer :: ivmr
  1087. ! --- begin -------------------------------
  1088. #ifdef with_budgets
  1089. if ( depv_apply ) then
  1090. call RF_DEPV_Done( RF_DEPV(region), status )
  1091. IF_NOTOK_RETURN(status=1)
  1092. end if
  1093. if ( deps_apply ) then
  1094. call RF_DEPS_Done( RF_DEPS(region), status )
  1095. IF_NOTOK_RETURN(status=1)
  1096. end if
  1097. #endif
  1098. if ( lt2_apply ) then
  1099. call RF_LT_Done( RF_LT2(region), region, status )
  1100. IF_NOTOK_RETURN(status=1)
  1101. end if
  1102. if ( lt_apply ) then
  1103. call RF_LT_Done( RF_LT(region), region, status )
  1104. IF_NOTOK_RETURN(status=1)
  1105. end if
  1106. do ivmr = nvmr, 1, -1
  1107. if ( .not. vmr_apply(ivmr) ) cycle
  1108. call RF_VMR_Done( RF_VMR(region,ivmr), status )
  1109. IF_NOTOK_RETURN(status=1)
  1110. end do
  1111. if ( tp_apply ) then
  1112. call RF_TP_Done ( RF_TP(region) , status )
  1113. IF_NOTOK_RETURN(status=1)
  1114. end if
  1115. if ( griddef_apply ) then
  1116. call RF_GridDef_Done( RF_GridDef(region), status )
  1117. IF_NOTOK_RETURN(status=1)
  1118. end if
  1119. status = 0
  1120. end subroutine PDUMP_Files_Close
  1121. !EOC
  1122. !--------------------------------------------------------------------------
  1123. ! TM5 !
  1124. !--------------------------------------------------------------------------
  1125. !BOP
  1126. !
  1127. ! !IROUTINE: RF_GRIDDEF_INIT
  1128. !
  1129. ! !DESCRIPTION:
  1130. !
  1131. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1132. ! FILE 1: Model horizontal grid definition
  1133. ! (longitude, latitude, size of gridbox [m2] ).
  1134. ! For documentation purposes, please also include the native vertical
  1135. ! grid definition from your model (hybrid level coefficients) and the
  1136. ! formula used to calculate pressure.
  1137. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1138. !
  1139. !\\
  1140. !\\
  1141. ! !INTERFACE:
  1142. !
  1143. subroutine RF_GridDef_Init( RF, fdir, model, expid, region, status )
  1144. !
  1145. ! !USES:
  1146. !
  1147. use partools, only : MPI_INFO_NULL, localComm
  1148. use MeteoData, only : global_lli, levi
  1149. !
  1150. ! !OUTPUT PARAMETERS:
  1151. !
  1152. type(TPdumpFile_GridDef), intent(out) :: RF
  1153. !
  1154. ! !INPUT PARAMETERS:
  1155. !
  1156. character(len=*), intent(in) :: fdir
  1157. character(len=*), intent(in) :: model
  1158. character(len=*), intent(in) :: expid
  1159. integer, intent(in) :: region
  1160. integer, intent(out) :: status
  1161. !
  1162. ! !REVISION HISTORY:
  1163. ! 1 Oct 2010 - Achim Strunk -
  1164. ! 10 Jul 2012 - Ph. Le Sager - switch to MDF_NETCDF4
  1165. !
  1166. !EOP
  1167. !------------------------------------------------------------------------
  1168. !BOC
  1169. character(len=*), parameter :: rname = mname//'/RF_GridDef_Init'
  1170. character(len=256) :: fname
  1171. integer :: varid
  1172. integer :: rtype
  1173. ! --- begin -------------------------------------
  1174. call goLabel(rname)
  1175. ! o open file
  1176. ! write filename
  1177. write (fname,'(a,"/",a,a,"_",a,"_",a,".nc")') &
  1178. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), 'griddef'
  1179. #ifdef MPI
  1180. ! overwrite existing files (clobber), provide MPI stuff:
  1181. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  1182. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  1183. if (status/=0) then
  1184. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  1185. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  1186. TRACEBACK; status=1; return
  1187. end if
  1188. #else
  1189. ! overwrite existing files (clobber)
  1190. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  1191. IF_NOTOK_RETURN(status=1)
  1192. #endif
  1193. ! o global attributes
  1194. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title', 'model horizontal definition' , status)
  1195. IF_NOTOK_MDF(fid=RF%ncid)
  1196. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
  1197. IF_NOTOK_MDF(fid=RF%ncid)
  1198. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
  1199. IF_NOTOK_MDF(fid=RF%ncid)
  1200. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status)
  1201. IF_NOTOK_MDF(fid=RF%ncid)
  1202. ! o define dimensions
  1203. call MDF_Def_Dim( RF%ncid, 'scalar', 1, RF%dimid_scalar , status)
  1204. IF_NOTOK_MDF(fid=RF%ncid)
  1205. call MDF_Def_Dim( RF%ncid, 'lon', global_lli(region)%nlon, RF%dimid_lon , status)
  1206. IF_NOTOK_MDF(fid=RF%ncid)
  1207. call MDF_Def_Dim( RF%ncid, 'lat', global_lli(region)%nlat, RF%dimid_lat , status)
  1208. IF_NOTOK_MDF(fid=RF%ncid)
  1209. call MDF_Def_Dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
  1210. IF_NOTOK_MDF(fid=RF%ncid)
  1211. call MDF_Def_Dim( RF%ncid, 'levi', levi%nlev+1, RF%dimid_levi , status)
  1212. IF_NOTOK_MDF(fid=RF%ncid)
  1213. !call MDF_Def_Dim( RF%ncid, 'time', NTS, RF%dimid_time , status)
  1214. !IF_NOTOK_MDF(fid=RF%ncid)
  1215. !call MDF_Def_Dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
  1216. !IF_NOTOK_MDF(fid=RF%ncid)
  1217. ! o define variables
  1218. rtype = MDF_FLOAT
  1219. call MDF_Def_Var( RF%ncid, 'lon', rtype, (/RF%dimid_lon/), varid , status)
  1220. IF_NOTOK_MDF(fid=RF%ncid)
  1221. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1222. IF_NOTOK_MDF(fid=RF%ncid)
  1223. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  1224. IF_NOTOK_MDF(fid=RF%ncid)
  1225. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'longitude' , status)
  1226. IF_NOTOK_MDF(fid=RF%ncid)
  1227. call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_east' , status)
  1228. IF_NOTOK_MDF(fid=RF%ncid)
  1229. RF%varid_lon = varid
  1230. call MDF_Def_Var( RF%ncid, 'lat', MDF_FLOAT, (/RF%dimid_lat/), varid , status)
  1231. IF_NOTOK_MDF(fid=RF%ncid)
  1232. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1233. IF_NOTOK_MDF(fid=RF%ncid)
  1234. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  1235. IF_NOTOK_MDF(fid=RF%ncid)
  1236. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'latitude' , status)
  1237. IF_NOTOK_MDF(fid=RF%ncid)
  1238. call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_north' , status)
  1239. IF_NOTOK_MDF(fid=RF%ncid)
  1240. RF%varid_lat = varid
  1241. !call MDF_Def_Var( RF%ncid, 'time', MDF_FLOAT, RF%dimid_time, varid , status)
  1242. !IF_NOTOK_MDF(fid=RF%ncid)
  1243. !call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1244. !IF_NOTOK_MDF(fid=RF%ncid)
  1245. !call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
  1246. !IF_NOTOK_MDF(fid=RF%ncid)
  1247. !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'time' , status)
  1248. !IF_NOTOK_MDF(fid=RF%ncid)
  1249. !call MDF_Put_Att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
  1250. !IF_NOTOK_MDF(fid=RF%ncid)
  1251. !call MDF_Put_Att( RF%ncid, varid, 'calender', 'gregorian' , status)
  1252. !IF_NOTOK_MDF(fid=RF%ncid)
  1253. !RF%varid_time = varid
  1254. !call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  1255. !IF_NOTOK_MDF(fid=RF%ncid)
  1256. !call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1257. !IF_NOTOK_MDF(fid=RF%ncid)
  1258. !call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'date' , status)
  1259. !IF_NOTOK_MDF(fid=RF%ncid)
  1260. !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
  1261. !IF_NOTOK_MDF(fid=RF%ncid)
  1262. !call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
  1263. !IF_NOTOK_MDF(fid=RF%ncid)
  1264. !RF%varid_date = varid
  1265. call MDF_Def_Var( RF%ncid, 'area', MDF_FLOAT, (/RF%dimid_lon,RF%dimid_lat/), varid , status)
  1266. IF_NOTOK_MDF(fid=RF%ncid)
  1267. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1268. IF_NOTOK_MDF(fid=RF%ncid)
  1269. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'grid_cell_area' , status)
  1270. IF_NOTOK_MDF(fid=RF%ncid)
  1271. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'grid-cell area' , status)
  1272. IF_NOTOK_MDF(fid=RF%ncid)
  1273. call MDF_Put_Att( RF%ncid, varid, 'units', 'm2' , status)
  1274. IF_NOTOK_MDF(fid=RF%ncid)
  1275. RF%varid_gridbox_area = varid
  1276. call MDF_Def_Var( RF%ncid, 'a', MDF_FLOAT, (/RF%dimid_lev/), varid , status)
  1277. IF_NOTOK_MDF(fid=RF%ncid)
  1278. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1279. IF_NOTOK_MDF(fid=RF%ncid)
  1280. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  1281. IF_NOTOK_MDF(fid=RF%ncid)
  1282. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient' , status)
  1283. IF_NOTOK_MDF(fid=RF%ncid)
  1284. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  1285. IF_NOTOK_MDF(fid=RF%ncid)
  1286. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a(k)*p0 + b(k)*ps(n,j,i)' , status)
  1287. IF_NOTOK_MDF(fid=RF%ncid)
  1288. call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up' , status)
  1289. IF_NOTOK_MDF(fid=RF%ncid)
  1290. RF%varid_a = varid
  1291. call MDF_Def_Var( RF%ncid, 'b', mdf_float, (/RF%dimid_lev/), varid , status)
  1292. IF_NOTOK_MDF(fid=RF%ncid)
  1293. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1294. IF_NOTOK_MDF(fid=RF%ncid)
  1295. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  1296. IF_NOTOK_MDF(fid=RF%ncid)
  1297. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient' , status)
  1298. IF_NOTOK_MDF(fid=RF%ncid)
  1299. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  1300. IF_NOTOK_MDF(fid=RF%ncid)
  1301. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a(k)*p0 + b(k)*ps(n,j,i)' , status)
  1302. IF_NOTOK_MDF(fid=RF%ncid)
  1303. call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up' , status)
  1304. IF_NOTOK_MDF(fid=RF%ncid)
  1305. RF%varid_b = varid
  1306. call MDF_Def_Var( RF%ncid, 'a_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
  1307. IF_NOTOK_MDF(fid=RF%ncid)
  1308. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1309. IF_NOTOK_MDF(fid=RF%ncid)
  1310. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  1311. IF_NOTOK_MDF(fid=RF%ncid)
  1312. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
  1313. IF_NOTOK_MDF(fid=RF%ncid)
  1314. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  1315. IF_NOTOK_MDF(fid=RF%ncid)
  1316. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a_bnds(k)*p0 + b_bnds(k)*ps(n,j,i)' , status)
  1317. IF_NOTOK_MDF(fid=RF%ncid)
  1318. RF%varid_a_bnds = varid
  1319. call MDF_Def_Var( RF%ncid, 'b_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
  1320. IF_NOTOK_MDF(fid=RF%ncid)
  1321. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1322. IF_NOTOK_MDF(fid=RF%ncid)
  1323. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  1324. IF_NOTOK_MDF(fid=RF%ncid)
  1325. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
  1326. IF_NOTOK_MDF(fid=RF%ncid)
  1327. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  1328. IF_NOTOK_MDF(fid=RF%ncid)
  1329. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a_bnds(k)*p0 + b_bnds(k)*ps(n,j,i)' , status)
  1330. IF_NOTOK_MDF(fid=RF%ncid)
  1331. RF%varid_b_bnds = varid
  1332. call MDF_Def_Var( RF%ncid, 'p0', mdf_float, (/RF%dimid_scalar/), varid , status)
  1333. IF_NOTOK_MDF(fid=RF%ncid)
  1334. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1335. IF_NOTOK_MDF(fid=RF%ncid)
  1336. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'reference pressure value' , status)
  1337. IF_NOTOK_MDF(fid=RF%ncid)
  1338. call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
  1339. IF_NOTOK_MDF(fid=RF%ncid)
  1340. RF%varid_p0 = varid
  1341. !status = pnf90_def_var( RF%ncid, 'ps', MDF_FLOAT, &
  1342. ! (/RF%dimid_lon,RF%dimid_lat,RF%dimid_time/), varid )
  1343. !IF_NOTOK_MDF(fid=RF%ncid)
  1344. !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
  1345. !IF_NOTOK_MDF(fid=RF%ncid)
  1346. !call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
  1347. !IF_NOTOK_MDF(fid=RF%ncid)
  1348. !RF%varid_ps = varid
  1349. !status = pnf90_def_var( RF%ncid, 'geo_height', MDF_FLOAT, &
  1350. ! (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid )
  1351. !IF_NOTOK_MDF(fid=RF%ncid)
  1352. !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'geopotential height' , status)
  1353. !IF_NOTOK_MDF(fid=RF%ncid)
  1354. !call MDF_Put_Att( RF%ncid, varid, 'units', 'm' , status)
  1355. !IF_NOTOK_MDF(fid=RF%ncid)
  1356. !call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up; lower half level; top value implicit infinity' , status)
  1357. !IF_NOTOK_MDF(fid=RF%ncid)
  1358. !RF%varid_geo_height = varid
  1359. ! o end defintion mode
  1360. call MDF_EndDef( RF%ncid , status)
  1361. IF_NOTOK_MDF(fid=RF%ncid)
  1362. ! no records written yet
  1363. RF%trec = 0
  1364. call goLabel() ; status = 0
  1365. END SUBROUTINE RF_GRIDDEF_INIT
  1366. !EOC
  1367. !--------------------------------------------------------------------------
  1368. ! TM5 !
  1369. !--------------------------------------------------------------------------
  1370. !BOP
  1371. !
  1372. ! !IROUTINE: RF_GridDef_Write
  1373. !
  1374. ! !DESCRIPTION:
  1375. !\\
  1376. !\\
  1377. ! !INTERFACE:
  1378. !
  1379. SUBROUTINE RF_GRIDDEF_WRITE( RF, region, status )
  1380. !
  1381. ! !USES:
  1382. !
  1383. use GO, only : TDate, NewDate, rTotal, operator(-)
  1384. use Grid, only : AreaOper
  1385. use MeteoData, only : global_lli, levi, sp_dat
  1386. !
  1387. ! !INPUT/OUTPUT PARAMETERS:
  1388. !
  1389. type(TPdumpFile_GridDef), intent(inout) :: RF
  1390. !
  1391. ! !INPUT PARAMETERS:
  1392. !
  1393. integer, intent(in) :: region
  1394. !
  1395. ! !OUTPUT PARAMETERS:
  1396. !
  1397. integer, intent(out) :: status
  1398. !
  1399. ! !REVISION HISTORY:
  1400. ! 1 Oct 2010 - Achim Strunk -
  1401. ! 10 Jul 2012 - Ph. Le Sager - switch to MDF_NETCDF4
  1402. !
  1403. !EOP
  1404. !------------------------------------------------------------------------
  1405. !BOC
  1406. character(len=*), parameter :: rname = mname//'/RF_GridDef_Write'
  1407. integer :: imr, jmr, lmr
  1408. real, allocatable :: ll(:,:)
  1409. real :: time
  1410. ! --- begin -------------------------------------
  1411. call goLabel(rname)
  1412. ! grid size
  1413. imr = global_lli(region)%nlon
  1414. jmr = global_lli(region)%nlat
  1415. lmr = levi%nlev
  1416. ! next time record:
  1417. RF%trec = RF%trec + 1
  1418. ! o write data
  1419. if ( RF%trec == 1 ) then
  1420. ! lat/lon field:
  1421. allocate( ll(imr,jmr) )
  1422. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg, status)
  1423. IF_NOTOK_MDF(fid=RF%ncid)
  1424. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg, status)
  1425. IF_NOTOK_MDF(fid=RF%ncid)
  1426. ll = 1.0
  1427. call AreaOper( global_lli(region), ll, '*', 'm2', status )
  1428. IF_NOTOK_RETURN(status=1)
  1429. call MDF_Put_Var( RF%ncid, RF%varid_gridbox_area, ll , status)
  1430. IF_NOTOK_MDF(fid=RF%ncid)
  1431. call MDF_Put_Var( RF%ncid, RF%varid_a, levi%fa , status)
  1432. IF_NOTOK_MDF(fid=RF%ncid)
  1433. call MDF_Put_Var( RF%ncid, RF%varid_b, levi%fb , status)
  1434. IF_NOTOK_MDF(fid=RF%ncid)
  1435. call MDF_Put_Var( RF%ncid, RF%varid_a_bnds, levi%a(0:levi%nlev) , status)
  1436. IF_NOTOK_MDF(fid=RF%ncid)
  1437. call MDF_Put_Var( RF%ncid, RF%varid_b_bnds, levi%b(0:levi%nlev) , status)
  1438. IF_NOTOK_MDF(fid=RF%ncid)
  1439. call MDF_Put_Var( RF%ncid, RF%varid_p0, (/1.0/) , status)
  1440. IF_NOTOK_MDF(fid=RF%ncid)
  1441. deallocate( ll )
  1442. end if
  1443. !call MDF_Put_Var( RF%ncid, RF%varid_time, time, index=RF%trec , status)
  1444. !IF_NOTOK_MDF(fid=RF%ncid)
  1445. !call MDF_Put_Var( RF%ncid, RF%varid_date, reshape(real(idate_f),(/6,1/), status), &
  1446. ! start=(/1,RF%trec/), count=(/6,1/) )
  1447. !IF_NOTOK_MDF(fid=RF%ncid)
  1448. !status = pnf90_put_var( RF%ncid, RF%varid_ps, &
  1449. ! reshape(sp_dat(region)%data(1:imr,1:jmr,1:1),(/imr,jmr,1/)), &
  1450. ! start=(/1,1,RF%trec/), count=(/imr,jmr,1/) )
  1451. !IF_NOTOK_MDF(fid=RF%ncid)
  1452. !status = pnf90_put_var( RF%ncid, RF%varid_geo_height, &
  1453. ! reshape(gph_dat(region)%data(1:imr,1:jmr,1:lmr),(/imr,jmr,lmr,1/)), &
  1454. ! start=(/1,1,1,RF%trec/), count=(/imr,jmr,lmr,1/) )
  1455. !IF_NOTOK_MDF(fid=RF%ncid)
  1456. call goLabel()
  1457. status = 0
  1458. END SUBROUTINE RF_GridDef_Write
  1459. !EOC
  1460. !--------------------------------------------------------------------------
  1461. ! TM5 !
  1462. !--------------------------------------------------------------------------
  1463. !BOP
  1464. !
  1465. ! !IROUTINE: RF_GRIDDEF_DONE
  1466. !
  1467. ! !DESCRIPTION: close file-1
  1468. !\\
  1469. !\\
  1470. ! !INTERFACE:
  1471. !
  1472. SUBROUTINE RF_GridDef_Done( RF, status )
  1473. !
  1474. ! !INPUT/OUTPUT PARAMETERS:
  1475. !
  1476. type(TPdumpFile_GridDef), intent(inout) :: RF
  1477. !
  1478. ! !OUTPUT PARAMETERS:
  1479. !
  1480. integer, intent(out) :: status
  1481. !
  1482. ! !REVISION HISTORY:
  1483. ! 1 Oct 2010 - Achim Strunk -
  1484. !
  1485. !EOP
  1486. !------------------------------------------------------------------------
  1487. !BOC
  1488. character(len=*), parameter :: rname = mname//'/RF_GridDef_Done'
  1489. ! --- begin -------------------------------------
  1490. call goLabel(rname)
  1491. call MDF_Close( RF%ncid , status)
  1492. IF_NOTOK_RETURN(status=1)
  1493. call goLabel()
  1494. status = 0
  1495. END SUBROUTINE RF_GRIDDEF_DONE
  1496. !EOC
  1497. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1498. ! FILE2: 3D field of monthly Model pressure [Pa] and temperature [K].
  1499. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1500. !--------------------------------------------------------------------------
  1501. ! TM5 !
  1502. !--------------------------------------------------------------------------
  1503. !BOP
  1504. !
  1505. ! !IROUTINE: RF_TP_INIT
  1506. !
  1507. ! !DESCRIPTION: file-2 : open and define var/att
  1508. !
  1509. !\\
  1510. !\\
  1511. ! !INTERFACE:
  1512. !
  1513. SUBROUTINE RF_TP_Init( RF, fdir, model, expid, region, idate_f, dhour, status )
  1514. !
  1515. ! !USES:
  1516. !
  1517. use partools, only : MPI_INFO_NULL, localComm
  1518. use MeteoData, only : global_lli, levi
  1519. !
  1520. ! !OUTPUT PARAMETERS:
  1521. !
  1522. type(TPdumpFile_TP), intent(out) :: RF
  1523. integer, intent(out) :: status
  1524. !
  1525. ! !INPUT PARAMETERS:
  1526. !
  1527. character(len=*), intent(in) :: fdir
  1528. character(len=*), intent(in) :: model
  1529. character(len=*), intent(in) :: expid
  1530. integer, intent(in) :: region
  1531. integer, intent(in) :: idate_f(6)
  1532. integer, intent(in) :: dhour
  1533. !
  1534. ! !REVISION HISTORY:
  1535. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  1536. ! 7 Aug 2012 - Ph. Le Sager - switch to netcdf-4 thru MDF
  1537. !
  1538. !EOP
  1539. !------------------------------------------------------------------------
  1540. !BOC
  1541. character(len=*), parameter :: rname = mname//'/RF_TP_Init'
  1542. ! --- local ------------------------------------
  1543. character(len=256) :: fname
  1544. integer :: varid, i1, i2, j1, j2
  1545. ! --- begin -------------------------------------
  1546. call goLabel(rname)
  1547. ! store arguments
  1548. RF%dhour = dhour
  1549. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1550. n_tp_rec = GET_N_TIME_RECORDS( idate_f, dhour*3600, mess='TP_Init' )
  1551. if ( n_tp_rec == 0 ) then
  1552. tp_apply = .false.
  1553. status=0
  1554. return
  1555. end if
  1556. ! o open file
  1557. ! write filename
  1558. write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
  1559. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), 'TP', idate_f(1:3)
  1560. ! open, overwrite existing files (clobber)
  1561. #ifdef MPI
  1562. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  1563. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  1564. if (status/=0) then
  1565. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  1566. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  1567. TRACEBACK; status=1; return
  1568. end if
  1569. #else
  1570. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  1571. IF_NOTOK_RETURN(status=1)
  1572. #endif
  1573. ! o global attributes
  1574. call mdf_put_att( RF%ncid, MDF_GLOBAL, 'title', 'model pressure and temperature', status)
  1575. IF_NOTOK_MDF(fid=RF%ncid)
  1576. call mdf_put_att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
  1577. IF_NOTOK_MDF(fid=RF%ncid)
  1578. call mdf_put_att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
  1579. IF_NOTOK_MDF(fid=RF%ncid)
  1580. call mdf_put_att( RF%ncid, MDF_GLOBAL, 'dataset_version', trim(dataset_version) , status)
  1581. IF_NOTOK_MDF(fid=RF%ncid)
  1582. ! o define dimensions
  1583. call mdf_def_dim( RF%ncid, 'lon', global_lli(region)%nlon, RF%dimid_lon , status)
  1584. IF_NOTOK_MDF(fid=RF%ncid)
  1585. call mdf_def_dim( RF%ncid, 'lat', global_lli(region)%nlat, RF%dimid_lat , status)
  1586. IF_NOTOK_MDF(fid=RF%ncid)
  1587. call mdf_def_dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
  1588. IF_NOTOK_MDF(fid=RF%ncid)
  1589. call mdf_def_dim( RF%ncid, 'time', n_tp_rec, RF%dimid_time , status)
  1590. IF_NOTOK_MDF(fid=RF%ncid)
  1591. call mdf_def_dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
  1592. IF_NOTOK_MDF(fid=RF%ncid)
  1593. ! o define variables
  1594. call mdf_def_var( RF%ncid, 'lon', MDF_FLOAT, (/RF%dimid_lon/), varid , status)
  1595. IF_NOTOK_MDF(fid=RF%ncid)
  1596. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1597. IF_NOTOK_MDF(fid=RF%ncid)
  1598. call mdf_put_att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  1599. IF_NOTOK_MDF(fid=RF%ncid)
  1600. call mdf_put_att( RF%ncid, varid, 'long_name', 'longitude' , status)
  1601. IF_NOTOK_MDF(fid=RF%ncid)
  1602. call mdf_put_att( RF%ncid, varid, 'units', 'degrees_east' , status)
  1603. IF_NOTOK_MDF(fid=RF%ncid)
  1604. RF%varid_lon = varid
  1605. call mdf_def_var( RF%ncid, 'lat', MDF_FLOAT, (/RF%dimid_lat/), varid , status)
  1606. IF_NOTOK_MDF(fid=RF%ncid)
  1607. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1608. IF_NOTOK_MDF(fid=RF%ncid)
  1609. call mdf_put_att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  1610. IF_NOTOK_MDF(fid=RF%ncid)
  1611. call mdf_put_att( RF%ncid, varid, 'long_name', 'latitude' , status)
  1612. IF_NOTOK_MDF(fid=RF%ncid)
  1613. call mdf_put_att( RF%ncid, varid, 'units', 'degrees_north' , status)
  1614. IF_NOTOK_MDF(fid=RF%ncid)
  1615. RF%varid_lat = varid
  1616. call mdf_def_var( RF%ncid, 'lev', MDF_FLOAT, (/RF%dimid_lev/), varid , status)
  1617. IF_NOTOK_MDF(fid=RF%ncid)
  1618. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1619. IF_NOTOK_MDF(fid=RF%ncid)
  1620. call mdf_put_att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
  1621. IF_NOTOK_MDF(fid=RF%ncid)
  1622. call mdf_put_att( RF%ncid, varid, 'long_name', 'level' , status)
  1623. IF_NOTOK_MDF(fid=RF%ncid)
  1624. call mdf_put_att( RF%ncid, varid, 'units', '1' , status)
  1625. IF_NOTOK_MDF(fid=RF%ncid)
  1626. call mdf_put_att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a_bnds(k)*p0 + b_bnds(k)*ps(n,j,i)' , status)
  1627. IF_NOTOK_MDF(fid=RF%ncid)
  1628. RF%varid_lev = varid
  1629. call mdf_def_var( RF%ncid, 'time', MDF_FLOAT, (/RF%dimid_time/), varid , status)
  1630. IF_NOTOK_MDF(fid=RF%ncid)
  1631. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1632. IF_NOTOK_MDF(fid=RF%ncid)
  1633. call mdf_put_att( RF%ncid, varid, 'standard_name', 'time' , status)
  1634. IF_NOTOK_MDF(fid=RF%ncid)
  1635. call mdf_put_att( RF%ncid, varid, 'long_name', 'time' , status)
  1636. IF_NOTOK_MDF(fid=RF%ncid)
  1637. call mdf_put_att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
  1638. IF_NOTOK_MDF(fid=RF%ncid)
  1639. call mdf_put_att( RF%ncid, varid, 'calender', 'gregorian' , status)
  1640. IF_NOTOK_MDF(fid=RF%ncid)
  1641. RF%varid_time = varid
  1642. allocate(RF%time(n_tp_rec))
  1643. call mdf_def_var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  1644. IF_NOTOK_MDF(fid=RF%ncid)
  1645. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1646. IF_NOTOK_MDF(fid=RF%ncid)
  1647. call mdf_put_att( RF%ncid, varid, 'long_name', 'date and time' , status)
  1648. IF_NOTOK_MDF(fid=RF%ncid)
  1649. call mdf_put_att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
  1650. IF_NOTOK_MDF(fid=RF%ncid)
  1651. RF%varid_date = varid
  1652. allocate(RF%date(6,n_tp_rec))
  1653. call mdf_def_var( RF%ncid, 'ps', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  1654. IF_NOTOK_MDF(fid=RF%ncid)
  1655. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1656. IF_NOTOK_MDF(fid=RF%ncid)
  1657. call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_air_pressure' , status)
  1658. IF_NOTOK_MDF(fid=RF%ncid)
  1659. call mdf_put_att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
  1660. IF_NOTOK_MDF(fid=RF%ncid)
  1661. call mdf_put_att( RF%ncid, varid, 'units', 'Pa' , status)
  1662. IF_NOTOK_MDF(fid=RF%ncid)
  1663. RF%varid_ps = varid
  1664. call mdf_def_var( RF%ncid, 'orog', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  1665. IF_NOTOK_MDF(fid=RF%ncid)
  1666. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1667. IF_NOTOK_MDF(fid=RF%ncid)
  1668. call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_altitude' , status)
  1669. IF_NOTOK_MDF(fid=RF%ncid)
  1670. call mdf_put_att( RF%ncid, varid, 'long_name', 'surface altitude' , status)
  1671. IF_NOTOK_MDF(fid=RF%ncid)
  1672. call mdf_put_att( RF%ncid, varid, 'units', 'm' , status)
  1673. IF_NOTOK_MDF(fid=RF%ncid)
  1674. RF%varid_orog = varid
  1675. call mdf_def_var( RF%ncid, 'surface_temp', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status)
  1676. IF_NOTOK_MDF(fid=RF%ncid)
  1677. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1678. IF_NOTOK_MDF(fid=RF%ncid)
  1679. call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_temperature' , status)
  1680. IF_NOTOK_MDF(fid=RF%ncid)
  1681. call mdf_put_att( RF%ncid, varid, 'long_name', 'surface temperature' , status)
  1682. IF_NOTOK_MDF(fid=RF%ncid)
  1683. call mdf_put_att( RF%ncid, varid, 'units', 'K' , status)
  1684. IF_NOTOK_MDF(fid=RF%ncid)
  1685. call mdf_put_att( RF%ncid, varid, 'comment', &
  1686. '2m temperature from MARS archive or IFS model (grib 167, 2T)' , status)
  1687. IF_NOTOK_MDF(fid=RF%ncid)
  1688. RF%varid_surface_temp = varid
  1689. allocate( RF%data2d(i1:i2, j1:j2, n_tp_rec, 3) )
  1690. call mdf_def_var( RF%ncid, 'geopotential', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), &
  1691. varid, status)
  1692. IF_NOTOK_MDF(fid=RF%ncid)
  1693. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1694. IF_NOTOK_MDF(fid=RF%ncid)
  1695. call mdf_put_att( RF%ncid, varid, 'standard_name', 'geopotential' , status)
  1696. IF_NOTOK_MDF(fid=RF%ncid)
  1697. call mdf_put_att( RF%ncid, varid, 'long_name', 'geopotential' , status)
  1698. IF_NOTOK_MDF(fid=RF%ncid)
  1699. call mdf_put_att( RF%ncid, varid, 'units', 'm2 s-2' , status)
  1700. IF_NOTOK_MDF(fid=RF%ncid)
  1701. call mdf_put_att( RF%ncid, varid, 'comment', 'at mid levels' , status)
  1702. IF_NOTOK_MDF(fid=RF%ncid)
  1703. RF%varid_geop = varid
  1704. call mdf_def_var( RF%ncid, 'pressure', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1705. IF_NOTOK_MDF(fid=RF%ncid)
  1706. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1707. IF_NOTOK_MDF(fid=RF%ncid)
  1708. call mdf_put_att( RF%ncid, varid, 'standard_name', 'pressure' , status)
  1709. IF_NOTOK_MDF(fid=RF%ncid)
  1710. call mdf_put_att( RF%ncid, varid, 'long_name', 'pressure' , status)
  1711. IF_NOTOK_MDF(fid=RF%ncid)
  1712. call mdf_put_att( RF%ncid, varid, 'units', 'Pa' , status)
  1713. IF_NOTOK_MDF(fid=RF%ncid)
  1714. call mdf_put_att( RF%ncid, varid, 'comment', 'at mid levels' , status)
  1715. IF_NOTOK_MDF(fid=RF%ncid)
  1716. RF%varid_pressure = varid
  1717. call mdf_def_var( RF%ncid, 'temp', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1718. IF_NOTOK_MDF(fid=RF%ncid)
  1719. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1720. IF_NOTOK_MDF(fid=RF%ncid)
  1721. call mdf_put_att( RF%ncid, varid, 'standard_name', 'air_temperature' , status)
  1722. IF_NOTOK_MDF(fid=RF%ncid)
  1723. call mdf_put_att( RF%ncid, varid, 'long_name', 'temperature' , status)
  1724. IF_NOTOK_MDF(fid=RF%ncid)
  1725. call mdf_put_att( RF%ncid, varid, 'units', 'K' , status)
  1726. IF_NOTOK_MDF(fid=RF%ncid)
  1727. call mdf_put_att( RF%ncid, varid, 'comment', 'bottom-up; full levels' , status)
  1728. IF_NOTOK_MDF(fid=RF%ncid)
  1729. RF%varid_temp = varid
  1730. call mdf_def_var( RF%ncid, 'specific_humidity', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), &
  1731. varid, status)
  1732. IF_NOTOK_MDF(fid=RF%ncid)
  1733. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1734. IF_NOTOK_MDF(fid=RF%ncid)
  1735. call mdf_put_att( RF%ncid, varid, 'standard_name', 'specific_humidity' , status)
  1736. IF_NOTOK_MDF(fid=RF%ncid)
  1737. call mdf_put_att( RF%ncid, varid, 'long_name', 'specific humidity' , status)
  1738. IF_NOTOK_MDF(fid=RF%ncid)
  1739. call mdf_put_att( RF%ncid, varid, 'units', 'kg kg-1' , status)
  1740. IF_NOTOK_MDF(fid=RF%ncid)
  1741. call mdf_put_att( RF%ncid, varid, 'comment', 'mass fraction of water vapor in moist air; (kg water)/(kg air)' , status)
  1742. IF_NOTOK_MDF(fid=RF%ncid)
  1743. RF%varid_humid = varid
  1744. call mdf_def_var( RF%ncid, 'U', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1745. IF_NOTOK_MDF(fid=RF%ncid)
  1746. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1747. IF_NOTOK_MDF(fid=RF%ncid)
  1748. call mdf_put_att( RF%ncid, varid, 'standard_name', 'eastward_wind' , status)
  1749. IF_NOTOK_MDF(fid=RF%ncid)
  1750. call mdf_put_att( RF%ncid, varid, 'long_name', 'zonal wind' , status)
  1751. IF_NOTOK_MDF(fid=RF%ncid)
  1752. call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
  1753. IF_NOTOK_MDF(fid=RF%ncid)
  1754. call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
  1755. IF_NOTOK_MDF(fid=RF%ncid)
  1756. RF%varid_u = varid
  1757. call mdf_def_var( RF%ncid, 'V', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1758. IF_NOTOK_MDF(fid=RF%ncid)
  1759. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1760. IF_NOTOK_MDF(fid=RF%ncid)
  1761. call mdf_put_att( RF%ncid, varid, 'standard_name', 'northward_wind' , status)
  1762. IF_NOTOK_MDF(fid=RF%ncid)
  1763. call mdf_put_att( RF%ncid, varid, 'long_name', 'meridional wind' , status)
  1764. IF_NOTOK_MDF(fid=RF%ncid)
  1765. call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
  1766. IF_NOTOK_MDF(fid=RF%ncid)
  1767. call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
  1768. IF_NOTOK_MDF(fid=RF%ncid)
  1769. RF%varid_v = varid
  1770. call mdf_def_var( RF%ncid, 'W', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1771. IF_NOTOK_MDF(fid=RF%ncid)
  1772. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1773. IF_NOTOK_MDF(fid=RF%ncid)
  1774. call mdf_put_att( RF%ncid, varid, 'long_name', 'vertical wind velocity' , status)
  1775. IF_NOTOK_MDF(fid=RF%ncid)
  1776. call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
  1777. IF_NOTOK_MDF(fid=RF%ncid)
  1778. call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
  1779. IF_NOTOK_MDF(fid=RF%ncid)
  1780. RF%varid_w = varid
  1781. allocate( RF%data3d(i1:i2, j1:j2, levi%nlev, n_tp_rec, 7) )
  1782. ! o end defintion mode
  1783. call mdf_enddef( RF%ncid , status)
  1784. IF_NOTOK_MDF(fid=RF%ncid)
  1785. ! o
  1786. ! no records written yet
  1787. RF%trec = 0
  1788. call goLabel()
  1789. ! ok
  1790. status = 0
  1791. END SUBROUTINE RF_TP_Init
  1792. !EOC
  1793. !--------------------------------------------------------------------------
  1794. ! TM5 !
  1795. !--------------------------------------------------------------------------
  1796. !BOP
  1797. !
  1798. ! !IROUTINE: RF_TP_Write
  1799. !
  1800. ! !DESCRIPTION: store records, and if last time step write data to file
  1801. !\\
  1802. !\\
  1803. ! !INTERFACE:
  1804. !
  1805. SUBROUTINE RF_TP_Write( RF, region, idate_f, status )
  1806. !
  1807. ! !USES:
  1808. !
  1809. use Binas , only : grav
  1810. use Phys , only : GeoPotentialHeight
  1811. use Grid , only : FPressure, HPressure
  1812. use GO , only : TDate, NewDate, rTotal, operator(-)
  1813. use partools , only : myid, root
  1814. use MeteoData , only : global_lli, lli, levi
  1815. use MeteoData , only : sp_dat, temper_dat, humid_dat, pu_dat, pv_dat, mfw_dat, gph_dat, oro_dat, t2m_dat
  1816. use MeteoData , only : m_dat
  1817. use global_data, only : mass_dat
  1818. !
  1819. ! !INPUT/OUTPUT PARAMETERS:
  1820. !
  1821. type(TPdumpFile_TP), intent(inout) :: RF
  1822. !
  1823. ! !INPUT PARAMETERS:
  1824. !
  1825. integer, intent(in) :: region
  1826. integer, intent(in) :: idate_f(6)
  1827. !
  1828. ! !OUTPUT PARAMETERS:
  1829. !
  1830. integer, intent(out) :: status
  1831. !
  1832. ! !REVISION HISTORY:
  1833. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  1834. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  1835. !
  1836. !EOP
  1837. !------------------------------------------------------------------------
  1838. !BOC
  1839. character(len=*), parameter :: rname = mname//'/RF_TP_Write'
  1840. ! --- local ------------------------------------
  1841. integer :: i, j, l, i1, i2, j1, j2
  1842. integer :: imr, jmr, lmr, klm
  1843. real :: lev(levi%nlev)
  1844. type(TDate) :: t, t0
  1845. real :: time
  1846. real, allocatable :: field3d(:,:,:)
  1847. real :: p_hlev(0:levi%nlev)
  1848. ! --- begin -------------------------------------
  1849. ! for multiple of dhour only ...
  1850. if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
  1851. status=0; return
  1852. end if
  1853. call goLabel(rname)
  1854. ! grid size
  1855. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1856. imr=i2-i1+1
  1857. jmr=j2-j1+1
  1858. lmr = levi%nlev
  1859. ! next time record:
  1860. RF%trec = RF%trec + 1
  1861. ! time since reftime:
  1862. t0 = NewDate( time6=time_reftime6 )
  1863. t = NewDate( time6=idate_f )
  1864. time = rTotal( t - t0, 'day' )
  1865. if(okdebug)then
  1866. write(gol,*) "RF_TP_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
  1867. end if
  1868. ! o write data
  1869. if ( RF%trec == 1 ) then
  1870. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
  1871. IF_NOTOK_MDF(fid=RF%ncid)
  1872. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
  1873. IF_NOTOK_MDF(fid=RF%ncid)
  1874. do l = 1, lmr
  1875. lev(l) = real(l)
  1876. end do
  1877. call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
  1878. IF_NOTOK_MDF(fid=RF%ncid)
  1879. end if
  1880. ! temporary storage for 3D fields
  1881. allocate( field3d(i1:i2,j1:j2,1:lmr) ) ; field3d = 0.
  1882. !-------- FILL DIAGNOSTIC ARRAYS
  1883. RF%time(RF%trec) = time
  1884. RF%date(:,RF%trec) = real(idate_f)
  1885. RF%data2d(:,:,RF%trec,1) = sp_dat(region)%data(i1:i2,j1:j2,1)
  1886. RF%data2d(:,:,RF%trec,2) = oro_dat(region)%data(i1:i2,j1:j2,1)
  1887. RF%data2d(:,:,RF%trec,3) = t2m_dat(region)%data(i1:i2,j1:j2,1)
  1888. ! o geopotential
  1889. ! fill mid level geopotential:
  1890. do j = j1, j2
  1891. do i = i1, i2
  1892. ! half level pressures
  1893. call HPressure( levi, sp_dat(region)%data(i,j,1), p_hlev, status )
  1894. IF_NOTOK_RETURN(status=1)
  1895. ! mid level gph (m)
  1896. call GeoPotentialHeight( lmr, p_hlev, temper_dat(region)%data(i,j,:), &
  1897. humid_dat(region)%data(i,j,:), oro_dat(region)%data(i,j,1)/grav, &
  1898. field3d(i,j,:) ) ! m
  1899. end do
  1900. end do
  1901. ! multiply with gravity for correct unit:
  1902. field3d = field3d * grav ! m2/s2
  1903. RF%data3d(:,:,:,RF%trec,1) = field3d
  1904. ! o pressure
  1905. ! fill mid level pressure
  1906. call FPressure( levi, sp_dat(region)%data(i1:i2,j1:j2,1), field3d, status )
  1907. IF_NOTOK_RETURN(status=1)
  1908. RF%data3d(:,:,:,RF%trec,2) = field3d
  1909. ! o temperature
  1910. RF%data3d(:,:,:,RF%trec,3) = temper_dat(region)%data(i1:i2,j1:j2,1:lmr)
  1911. ! o specific humidity
  1912. RF%data3d(:,:,:,RF%trec,4) = humid_dat(region)%data(i1:i2,j1:j2,1:lmr)
  1913. ! o wind fields
  1914. CALL UPDATE_HALO( dgrid(region), pu_dat(region)%data, pu_dat(region)%halo, status)
  1915. IF_NOTOK_RETURN(status=1)
  1916. CALL UPDATE_HALO( dgrid(region), pv_dat(region)%data, pv_dat(region)%halo, status)
  1917. IF_NOTOK_RETURN(status=1)
  1918. ! average U wind
  1919. field3d = 0.5 * ( pu_dat(region)%data(i1-1:i2-1,j1:j2,1:lmr) + pu_dat(region)%data(i1:i2,j1:j2,1:lmr) ) &
  1920. / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
  1921. do j = j1, j2
  1922. field3d(:,j,:) = field3d(:,j,:) * lli(region)%dx(j-j1+1) ! m/s
  1923. end do
  1924. RF%data3d(:,:,:,RF%trec,5) = field3d
  1925. ! average V wind:
  1926. field3d = 0.5 * ( pv_dat(region)%data(i1:i2,j1-1:j2-1,1:lmr) + pv_dat(region)%data(i1:i2,j1:j2,1:lmr) ) &
  1927. / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
  1928. field3d = field3d * lli(region)%dy ! m/s
  1929. RF%data3d(:,:,:,RF%trec,6) = field3d
  1930. ! from downward massflux to upward average W wind:
  1931. field3d = 0.5 * ( mfw_dat(region)%data(i1:i2,j1:j2,0:lmr-1) + mfw_dat(region)%data(i1:i2,j1:j2,1:lmr) ) &
  1932. / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
  1933. do l = 1, lmr
  1934. field3d(:,:,l) = - 1.0 * field3d(:,:,l) * &
  1935. abs( gph_dat(region)%data(i1:i2,j1:j2,l+1) - gph_dat(region)%data(i1:i2,j1:j2,l) ) ! m/s
  1936. end do
  1937. RF%data3d(:,:,:,RF%trec,7) = field3d
  1938. !-------- WRITE ARRAYS
  1939. if ( RF%trec == n_tp_rec ) then
  1940. ! time
  1941. call MDF_Put_Var( RF%ncid, RF%varid_time, RF%time, status)!, start=(/1/), count=(/n_tp_rec/))
  1942. IF_NOTOK_MDF(fid=RF%ncid)
  1943. ! date
  1944. call MDF_Put_Var( RF%ncid, RF%varid_date, RF%date, status )!, &
  1945. ! start=(/1,1/), count=(/6,1/) )
  1946. IF_NOTOK_MDF(fid=RF%ncid)
  1947. ! surface pressure
  1948. call MDF_Put_Var( RF%ncid, RF%varid_ps, RF%data2d(:,:,:,1), status, start=(/i1,j1,1/), count=(/imr,jmr,n_tp_rec/) )
  1949. IF_NOTOK_MDF(fid=RF%ncid)
  1950. ! orography (in m!)
  1951. call MDF_Put_Var( RF%ncid, RF%varid_orog, RF%data2d(:,:,:,2), status, start=(/i1,j1,1/), count=(/imr,jmr,n_tp_rec/) )
  1952. IF_NOTOK_MDF(fid=RF%ncid)
  1953. ! surface temperature = 2m temperature
  1954. call MDF_Put_Var( RF%ncid, RF%varid_surface_temp, RF%data2d(:,:,:,3), status, start=(/i1,j1,1/) ) !, count=(/imr,jmr,1/) )
  1955. IF_NOTOK_MDF(fid=RF%ncid)
  1956. ! geopotential
  1957. call MDF_Put_Var( RF%ncid, RF%varid_geop, RF%data3d(:,:,:,:,1), status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,n_tp_rec/))
  1958. IF_NOTOK_MDF(fid=RF%ncid)
  1959. ! pressure
  1960. call MDF_Put_Var( RF%ncid, RF%varid_pressure, RF%data3d(:,:,:,:,2), status, start=(/i1,j1,1,1/), &
  1961. count=(/imr,jmr,lmr,n_tp_rec/))
  1962. IF_NOTOK_MDF(fid=RF%ncid)
  1963. ! temperature
  1964. call MDF_Put_Var( RF%ncid, RF%varid_temp, RF%data3d(:,:,:,:,3), status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,n_tp_rec/))
  1965. IF_NOTOK_MDF(fid=RF%ncid)
  1966. ! specific humidity
  1967. call MDF_Put_Var( RF%ncid, RF%varid_humid, RF%data3d(:,:,:,:,4), status, start=(/i1,j1,1,1/),count=(/imr,jmr,lmr,n_tp_rec/))
  1968. IF_NOTOK_MDF(fid=RF%ncid)
  1969. ! winds
  1970. call MDF_Put_Var( RF%ncid, RF%varid_u, RF%data3d(:,:,:,:,5), status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,n_tp_rec/) )
  1971. IF_NOTOK_MDF(fid=RF%ncid)
  1972. call MDF_Put_Var( RF%ncid, RF%varid_v, RF%data3d(:,:,:,:,6), status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,n_tp_rec/) )
  1973. IF_NOTOK_MDF(fid=RF%ncid)
  1974. call MDF_Put_Var( RF%ncid, RF%varid_w, RF%data3d(:,:,:,:,7), status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,n_tp_rec/) )
  1975. IF_NOTOK_MDF(fid=RF%ncid)
  1976. end if
  1977. ! Done
  1978. deallocate( field3d )
  1979. call goLabel()
  1980. status = 0
  1981. END SUBROUTINE RF_TP_Write
  1982. !EOC
  1983. !--------------------------------------------------------------------------
  1984. ! TM5 !
  1985. !--------------------------------------------------------------------------
  1986. !BOP
  1987. !
  1988. ! !IROUTINE: RF_TP_Done
  1989. !
  1990. ! !DESCRIPTION: close file #2
  1991. !\\
  1992. !\\
  1993. ! !INTERFACE:
  1994. !
  1995. subroutine RF_TP_Done( RF, status )
  1996. !
  1997. ! !INPUT/OUTPUT PARAMETERS:
  1998. !
  1999. type(TPdumpFile_TP), intent(inout) :: RF
  2000. !
  2001. ! !OUTPUT PARAMETERS:
  2002. !
  2003. integer, intent(out) :: status
  2004. !
  2005. ! !REVISION HISTORY:
  2006. ! 1 Oct 2010 - Achim Strunk -
  2007. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  2008. !
  2009. !EOP
  2010. !------------------------------------------------------------------------
  2011. !BOC
  2012. character(len=*), parameter :: rname = mname//'/RF_TP_Done'
  2013. ! --- begin -------------------------------------
  2014. call goLabel(rname)
  2015. call MDF_Close( RF%ncid , status)
  2016. IF_NOTOK_RETURN(status=1)
  2017. deallocate( rf%time, rf%date, rf%data2d, rf%data3d )
  2018. call goLabel() ; status = 0
  2019. end subroutine RF_TP_Done
  2020. !EOC
  2021. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2022. ! FILE3: 3D fields for O3, CO, CH4, ... Volume Mixing Ratios
  2023. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2024. !--------------------------------------------------------------------------
  2025. ! TM5 !
  2026. !--------------------------------------------------------------------------
  2027. !BOP
  2028. !
  2029. ! !IROUTINE: RF_VMR_Init
  2030. !
  2031. ! !DESCRIPTION: open and define variables/attribute for file #3
  2032. !\\
  2033. !\\
  2034. ! !INTERFACE:
  2035. !
  2036. subroutine RF_VMR_Init( RF, fdir, model, expid, filetype, region, &
  2037. idate_f, dhour, tracer_names, status )
  2038. !
  2039. ! !USES:
  2040. !
  2041. use Binas, only : xmair
  2042. use GO, only : goReadFromLine, goUpCase
  2043. use chem_param, only : ntrace, names, ra
  2044. use partools, only : PAR_BROADCAST, MPI_INFO_NULL, localComm
  2045. use MeteoData, only : global_lli, lli, levi, sp_dat
  2046. use dims, only : xbeg, xend, ybeg, yend, dx, dy, dz, xref, yref, zref
  2047. use dims, only : zbeg, zend
  2048. !
  2049. ! !INPUT/OUTPUT PARAMETERS:
  2050. !
  2051. type(TPdumpFile_VMR), intent(inout) :: RF
  2052. !
  2053. ! !INPUT PARAMETERS:
  2054. !
  2055. character(len=*), intent(in) :: fdir
  2056. character(len=*), intent(in) :: model
  2057. character(len=*), intent(in) :: expid
  2058. character(len=*), intent(in) :: filetype
  2059. integer, intent(in) :: region
  2060. integer, intent(in) :: idate_f(6)
  2061. real, intent(in) :: dhour
  2062. character(len=*), intent(in) :: tracer_names
  2063. !
  2064. ! !OUTPUT PARAMETERS:
  2065. !
  2066. integer, intent(out) :: status
  2067. !
  2068. ! !REVISION HISTORY:
  2069. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  2070. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  2071. ! 15 Apr 2014 - Ph. Le Sager - tropomi add-ons
  2072. ! 8 Oct 2014 - H. Eskes - tropomi add-ons
  2073. !
  2074. !EOP
  2075. !------------------------------------------------------------------------
  2076. !BOC
  2077. character(len=*), parameter :: rname = mname//'/RF_VMR_Init'
  2078. ! --- local ------------------------------------
  2079. character(len=256) :: fname, history, sysdate, model_meteo
  2080. integer :: varid, i1, i2, j1, j2
  2081. integer, dimension(8) :: isysdate
  2082. character(len=256) :: trnames
  2083. character(len=8) :: trname, tmname
  2084. integer :: k, itr, posend, pospoint
  2085. integer :: imr, jmr, lmr, si, ei, ix, jy
  2086. character(len=32) :: varname_spec
  2087. character(len=5) :: zone
  2088. character(len=64) :: cf_medium_stnd, cf_medium_long
  2089. character(len=64) :: cf_enti_stnd, cf_enti_long, cf_enti_unit
  2090. character(len=64) :: cf_spec_stnd, cf_spec_long
  2091. character(len=4) :: cf_enti_type
  2092. character(len=256) :: cf_name_stnd, cf_name_long, cf_name_unit
  2093. character(len=512) :: comment
  2094. character(len=6) :: csize
  2095. integer, dimension(6) :: idate_f_end, idate_create
  2096. type(TDate) :: date_f_end, date_create
  2097. ! --- begin -------------------------------------
  2098. call goLabel(rname)
  2099. ! store arguments
  2100. RF%dhour = dhour
  2101. RF%dsec = int(dhour*3600.)
  2102. RF%tracer_names = tracer_names
  2103. ! Test that dsec is multiple of dynamic-step/2 (nread in sec)
  2104. if (((RF%dsec*2)/nread < 1).or.(modulo(RF%dsec,nread/2)/=0))then
  2105. write(gol,*) "timeseries timestep should be a multiple of (dynamic_timestep)/2"; call goErr
  2106. TRACEBACK; status=1; return
  2107. end if
  2108. ! size
  2109. imr = global_lli(region)%nlon
  2110. jmr = global_lli(region)%nlat
  2111. lmr = levi%nlev
  2112. ! number of time steps
  2113. rf%n_rec = GET_N_TIME_RECORDS( idate_f, rf%dsec, mess='VMR_Init' )
  2114. ! degenerated cases (eg, very short runs)
  2115. if ( rf%n_rec == 0 ) then
  2116. rf%apply = .false.
  2117. status=0
  2118. return
  2119. end if
  2120. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  2121. ! set tracer index for requested tracers:
  2122. write (gol,'("selected tracers for VMR output:")'); call goPr
  2123. ! initialise RF
  2124. RF%ntr = 0
  2125. #ifdef with_m7
  2126. RF%lpmx = .false.
  2127. RF%sizepmx = -1.0
  2128. #endif
  2129. RF%itr = -1
  2130. trnames = tracer_names
  2131. do
  2132. ! empty ?
  2133. if ( len_trim(trnames) == 0 ) exit
  2134. ! next number:
  2135. if ( RF%ntr == ntrace ) then
  2136. write (gol,'("number of elements in tracer names list exceeds ntrace=",i6)') ntrace; call goErr
  2137. TRACEBACK; status=1; return
  2138. end if
  2139. RF%ntr = RF%ntr + 1
  2140. ! extract leading name:
  2141. call goReadFromLine( trnames, trname, status, sep=' ' )
  2142. IF_NOTOK_RETURN(status=1)
  2143. #ifdef with_m7
  2144. ! ---------------------------
  2145. ! check for PMx
  2146. ! ---------------------------
  2147. if( strlowercase(trname(1:2)) == 'pm' ) then
  2148. RF%lpmx(RF%ntr) = .true.
  2149. RF%itr (RF%ntr) = -1
  2150. ! paste size to real
  2151. read(trname(3:len_trim(trname)), * ) RF%sizepmx(RF%ntr)
  2152. else
  2153. #endif
  2154. ! convert to tm5 name:
  2155. select case ( trim(strlowercase(trname)) )
  2156. case ( 'hcho' ) ; tmname = 'CH2O'
  2157. case ( 'rn', 'radon' ) ; tmname = 'Rn222'
  2158. case ( 'pb', 'lead' ) ; tmname = 'Pb210'
  2159. case default ; tmname = trname
  2160. end select
  2161. ! --------------------------------
  2162. ! NOy and M7 are special cases ...
  2163. ! --------------------------------
  2164. select case ( trim(strlowercase(tmname)) )
  2165. case( 'noy' )
  2166. ! defined as ntrace+1
  2167. RF%itr(RF%ntr) = iNOy
  2168. write (gol,'(" * ",a10)') trim(trname); call goPr
  2169. #ifdef with_m7
  2170. case( 'tso4' )
  2171. ! defined as ntrace+2
  2172. RF%itr(RF%ntr) = iSO4
  2173. write (gol,'(" * ",a10)') trim(trname); call goPr
  2174. case( 'tbc' )
  2175. ! defined as ntrace+3
  2176. RF%itr(RF%ntr) = iBC
  2177. write (gol,'(" * ",a10)') trim(trname); call goPr
  2178. case( 'tpom' )
  2179. ! defined as ntrace+4
  2180. RF%itr(RF%ntr) = iPOM
  2181. write (gol,'(" * ",a10)') trim(trname); call goPr
  2182. case( 'tss' )
  2183. ! defined as ntrace+5
  2184. RF%itr(RF%ntr) = iSS
  2185. write (gol,'(" * ",a10)') trim(trname); call goPr
  2186. case( 'tdu' )
  2187. ! defined as ntrace+6
  2188. RF%itr(RF%ntr) = iDU
  2189. write (gol,'(" * ",a10)') trim(trname); call goPr
  2190. #endif
  2191. case default
  2192. ! --------------------------------
  2193. ! `regular` constituents
  2194. ! --------------------------------
  2195. ! loop over all names:
  2196. RF%itr(RF%ntr) = -1
  2197. do itr = 1, ntrace
  2198. ! case indendent match ?
  2199. if ( goUpCase(trim(tmname)) == goUpCase(trim(names(itr))) ) then
  2200. write (gol,'(" ",i3," ",a10," (",a10,") ",f12.4)') itr, trim(trname), trim(names(itr)), ra(itr); call goPr
  2201. RF%itr(RF%ntr) = itr
  2202. exit
  2203. end if
  2204. end do
  2205. end select
  2206. ! not found ?
  2207. if ( RF%itr(RF%ntr) < 0 ) then
  2208. write (gol,'("tracer name not supported:")'); call goPr
  2209. write (gol,'(" list all : ",a)') trim(tracer_names); call goPr
  2210. write (gol,'(" list element : ",i3)') RF%ntr; call goPr
  2211. write (gol,'(" pdump name : ",a)') trim(trname); call goPr
  2212. write (gol,'(" tm5 name : ",a)') trim(tmname); call goPr
  2213. write (gol,'(" tm5 tracers : ")'); call goPr
  2214. do itr = 1, ntrace
  2215. write (gol,'(" ",i3," ",a)') itr, trim(names(itr)); call goPr
  2216. end do
  2217. TRACEBACK; status=1; return
  2218. end if ! RF%itr
  2219. #ifdef with_m7
  2220. end if ! pmx
  2221. #endif
  2222. ! store pdump name:
  2223. RF%name_tr(RF%ntr) = tmname
  2224. end do
  2225. ! empty file ?
  2226. if ( RF%ntr < 1 ) then
  2227. write (gol,'("no tracers extracted from list :",a)') tracer_names; call goErr
  2228. TRACEBACK; status=1; return
  2229. end if
  2230. ! o open file
  2231. ! write filename
  2232. #ifdef tropomi
  2233. ! define start/stop of output, and run date
  2234. date_f_end = NewDate( time6=idate_f ) + IncrDate(hour=24)
  2235. call Get( date_f_end, time6=idate_f_end )
  2236. if ( isRoot ) then
  2237. date_create = SystemDate()
  2238. call Get( date_create, time6=idate_create )
  2239. endif
  2240. call PAR_BROADCAST(idate_create, status)
  2241. IF_NOTOK_RETURN(status=1)
  2242. date_create = SystemDate()
  2243. call Get( date_create, time6=idate_create )
  2244. write (tropomi_date_start, '(i4.4,i2.2,i2.2,"T",i2.2,i2.2,i2.2)') idate_f
  2245. write (tropomi_date_stop, '(i4.4,i2.2,i2.2,"T",i2.2,i2.2,i2.2)') idate_f_end
  2246. write (tropomi_date_create,'(i4.4,i2.2,i2.2,"T",i2.2,i2.2,i2.2)') idate_create
  2247. ! write filename according to tropomi convention
  2248. write (fname,'(a,"/",a,"_",a,"_",a,".nc")') &
  2249. trim(fdir), trim(tropomi_dataset_name), tropomi_date_start, tropomi_date_stop
  2250. #else
  2251. write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
  2252. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), trim(filetype), idate_f(1:3)
  2253. #endif
  2254. ! open:
  2255. #ifdef MPI
  2256. ! overwrite existing files (clobber), provide MPI stuff:
  2257. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  2258. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  2259. if (status/=0) then
  2260. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  2261. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  2262. TRACEBACK; status=1; return
  2263. end if
  2264. #else
  2265. ! overwrite existing files (clobber)
  2266. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  2267. IF_NOTOK_RETURN(status=1)
  2268. #endif
  2269. ! o global attributes
  2270. #ifdef tropomi
  2271. ! H. Eskes: Extra attributes for TROPOMI
  2272. ! Conventions = "CF-1.6"
  2273. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'Conventions', 'CF-1.6' , status)
  2274. IF_NOTOK_MDF(fid=RF%ncid)
  2275. ! validity_start = "20132305T120000" (zoals in filenaam)
  2276. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'validity_start', tropomi_date_start , status)
  2277. IF_NOTOK_MDF(fid=RF%ncid)
  2278. ! validity_stop = "20132405T000000"
  2279. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'validity_stop', tropomi_date_stop , status)
  2280. IF_NOTOK_MDF(fid=RF%ncid)
  2281. ! creation_date = "20142909T124905"
  2282. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'creation_date', tropomi_date_create , status)
  2283. IF_NOTOK_MDF(fid=RF%ncid)
  2284. ! version = TM5 version string.
  2285. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'version', trim(tropomi_tm5_version) , status)
  2286. IF_NOTOK_MDF(fid=RF%ncid)
  2287. ! institution = "KNMI"
  2288. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution', trim(tropomi_institution) , status)
  2289. IF_NOTOK_MDF(fid=RF%ncid)
  2290. ! reference = TM5 reference (journal article or so)
  2291. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'reference', trim(tropomi_tm5_reference) , status)
  2292. IF_NOTOK_MDF(fid=RF%ncid)
  2293. ! contact = email address of volunteer.
  2294. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'contact', trim(tropomi_authoremail) , status)
  2295. IF_NOTOK_MDF(fid=RF%ncid)
  2296. ! dataset_name = "S5P_NRTI_AUX_CTMFCT" of "S5P_OFFL_AUX_CTMANA"
  2297. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_name', trim(tropomi_dataset_name) , status)
  2298. IF_NOTOK_MDF(fid=RF%ncid)
  2299. #endif
  2300. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title' , 'mixing ratios & concentrations' , status )
  2301. IF_NOTOK_MDF(fid=RF%ncid)
  2302. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status )
  2303. IF_NOTOK_MDF(fid=RF%ncid)
  2304. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status )
  2305. IF_NOTOK_MDF(fid=RF%ncid)
  2306. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'file_version_number', trim(outfileversnr) , status )
  2307. IF_NOTOK_MDF(fid=RF%ncid)
  2308. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'im' , imr , status )
  2309. IF_NOTOK_MDF(fid=RF%ncid)
  2310. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'jm' , jmr , status )
  2311. IF_NOTOK_MDF(fid=RF%ncid)
  2312. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'lm' , lmr , status )
  2313. IF_NOTOK_MDF(fid=RF%ncid)
  2314. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dx' , dx/xref(region) , status )
  2315. IF_NOTOK_MDF(fid=RF%ncid)
  2316. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dy' , dy/yref(region) , status )
  2317. IF_NOTOK_MDF(fid=RF%ncid)
  2318. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dz' , dz/zref(region) , status )
  2319. IF_NOTOK_MDF(fid=RF%ncid)
  2320. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'xbeg' , xbeg(region) , status )
  2321. IF_NOTOK_MDF(fid=RF%ncid)
  2322. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'xend' , xend(region) , status )
  2323. IF_NOTOK_MDF(fid=RF%ncid)
  2324. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'ybeg' , ybeg(region) , status )
  2325. IF_NOTOK_MDF(fid=RF%ncid)
  2326. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'yend' , yend(region) , status )
  2327. IF_NOTOK_MDF(fid=RF%ncid)
  2328. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'zbeg' , zbeg(region) , status )
  2329. IF_NOTOK_MDF(fid=RF%ncid)
  2330. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'zend' , zend(region) , status )
  2331. IF_NOTOK_MDF(fid=RF%ncid)
  2332. ! Meteo attribute
  2333. if (trim(meteo_class)=='ei') then
  2334. model_meteo='analysis (ERA-Interim)'
  2335. elseif (trim(meteo_class)=='ea') then
  2336. model_meteo='reanalysis (ERA5)'
  2337. elseif (trim(meteo_class)=='od') then
  2338. model_meteo='forecast (IFS)'
  2339. elseif (trim(meteo_class)=='ifs10') then
  2340. model_meteo='EC-Earth (ifs 10L)'
  2341. elseif (trim(meteo_class)=='ifs34') then
  2342. model_meteo='EC-Earth (ifs 34L)'
  2343. elseif (trim(meteo_class)=='ifs62') then
  2344. model_meteo='EC-Earth (ifs 62L)'
  2345. elseif (trim(meteo_class)=='ifs91') then
  2346. model_meteo='EC-Earth (ifs 91L)'
  2347. else
  2348. write (gol,'("Meteo Model not known !")'); call goErr
  2349. TRACEBACK; status=1; return
  2350. endif
  2351. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'meteo_model', trim(model_meteo), status )
  2352. IF_NOTOK_MDF(fid=RF%ncid)
  2353. ! History attribute for audit trail: date, time of day, user name, program name
  2354. call date_and_time(values=isysdate, zone=zone)
  2355. write (sysdate, '(i4.4,"-",i2.2,"-",i2.2," ",i2.2,":",i2.2,":",i2.2," ",a)') &
  2356. isysdate(1), isysdate(2), isysdate(3), isysdate(5), isysdate(6), isysdate(7), zone
  2357. write(history,'("Created ",a," by ",a," with TM5.")') trim(sysdate),trim(dataset_author)
  2358. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'history', trim(history), status )
  2359. IF_NOTOK_MDF(fid=RF%ncid)
  2360. ! o define dimensions
  2361. call MDF_Def_Dim( RF%ncid, 'lon', imr, RF%dimid_lon , status)
  2362. IF_NOTOK_MDF(fid=RF%ncid)
  2363. call MDF_Def_Dim( RF%ncid, 'lat', jmr, RF%dimid_lat , status)
  2364. IF_NOTOK_MDF(fid=RF%ncid)
  2365. call MDF_Def_Dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
  2366. IF_NOTOK_MDF(fid=RF%ncid)
  2367. call MDF_Def_Dim( RF%ncid, 'levi', levi%nlev+1, RF%dimid_levi , status)
  2368. IF_NOTOK_MDF(fid=RF%ncid)
  2369. call MDF_Def_Dim( RF%ncid, 'time', rf%n_rec, RF%dimid_time , status)
  2370. IF_NOTOK_MDF(fid=RF%ncid)
  2371. call MDF_Def_Dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
  2372. IF_NOTOK_MDF(fid=RF%ncid)
  2373. ! o define variables
  2374. call MDF_Def_Var( RF%ncid, 'lon', mdf_float, (/RF%dimid_lon/), varid , status)
  2375. IF_NOTOK_MDF(fid=RF%ncid)
  2376. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2377. IF_NOTOK_MDF(fid=RF%ncid)
  2378. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  2379. IF_NOTOK_MDF(fid=RF%ncid)
  2380. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'longitude' , status)
  2381. IF_NOTOK_MDF(fid=RF%ncid)
  2382. call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_east' , status)
  2383. IF_NOTOK_MDF(fid=RF%ncid)
  2384. RF%varid_lon = varid
  2385. call MDF_Def_Var( RF%ncid, 'lat', mdf_float, (/RF%dimid_lat/), varid , status)
  2386. IF_NOTOK_MDF(fid=RF%ncid)
  2387. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2388. IF_NOTOK_MDF(fid=RF%ncid)
  2389. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  2390. IF_NOTOK_MDF(fid=RF%ncid)
  2391. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'latitude' , status)
  2392. IF_NOTOK_MDF(fid=RF%ncid)
  2393. call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_north' , status)
  2394. IF_NOTOK_MDF(fid=RF%ncid)
  2395. RF%varid_lat = varid
  2396. #ifdef tropomi
  2397. call MDF_Def_Var( RF%ncid, 'hyai', mdf_float, (/RF%dimid_levi/), varid , status)
  2398. IF_NOTOK_MDF(fid=RF%ncid)
  2399. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2400. IF_NOTOK_MDF(fid=RF%ncid)
  2401. call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
  2402. IF_NOTOK_MDF(fid=RF%ncid)
  2403. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid A coefficient at layer interfaces' , status)
  2404. IF_NOTOK_MDF(fid=RF%ncid)
  2405. RF%varid_hyai = varid
  2406. #else
  2407. call MDF_Def_Var( RF%ncid, 'a_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
  2408. IF_NOTOK_MDF(fid=RF%ncid)
  2409. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2410. IF_NOTOK_MDF(fid=RF%ncid)
  2411. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  2412. IF_NOTOK_MDF(fid=RF%ncid)
  2413. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
  2414. IF_NOTOK_MDF(fid=RF%ncid)
  2415. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  2416. IF_NOTOK_MDF(fid=RF%ncid)
  2417. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a_bnds(k)*p0 + b_bnds(k)*ps(n,j,i)' , status)
  2418. IF_NOTOK_MDF(fid=RF%ncid)
  2419. RF%varid_a_bnds = varid
  2420. #endif
  2421. #ifdef tropomi
  2422. call MDF_Def_Var( RF%ncid, 'hybi', mdf_float, (/RF%dimid_levi/), varid , status)
  2423. IF_NOTOK_MDF(fid=RF%ncid)
  2424. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2425. IF_NOTOK_MDF(fid=RF%ncid)
  2426. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  2427. IF_NOTOK_MDF(fid=RF%ncid)
  2428. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid B coefficient at layer interfaces' , status)
  2429. IF_NOTOK_MDF(fid=RF%ncid)
  2430. RF%varid_hybi = varid
  2431. #else
  2432. call MDF_Def_Var( RF%ncid, 'b_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
  2433. IF_NOTOK_MDF(fid=RF%ncid)
  2434. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2435. IF_NOTOK_MDF(fid=RF%ncid)
  2436. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  2437. IF_NOTOK_MDF(fid=RF%ncid)
  2438. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
  2439. IF_NOTOK_MDF(fid=RF%ncid)
  2440. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  2441. IF_NOTOK_MDF(fid=RF%ncid)
  2442. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a_bnds(k)*p0 + b_bnds(k)*ps(n,j,i)' , status)
  2443. IF_NOTOK_MDF(fid=RF%ncid)
  2444. RF%varid_b_bnds = varid
  2445. #endif
  2446. #ifdef tropomi
  2447. call MDF_Def_Var( RF%ncid, 'hyam', mdf_float, (/RF%dimid_lev/), varid , status)
  2448. IF_NOTOK_MDF(fid=RF%ncid)
  2449. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2450. IF_NOTOK_MDF(fid=RF%ncid)
  2451. call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
  2452. IF_NOTOK_MDF(fid=RF%ncid)
  2453. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid A coefficient at layer midpoints' , status)
  2454. IF_NOTOK_MDF(fid=RF%ncid)
  2455. RF%varid_hyam = varid
  2456. call MDF_Def_Var( RF%ncid, 'hybm', mdf_float, (/RF%dimid_lev/), varid , status)
  2457. IF_NOTOK_MDF(fid=RF%ncid)
  2458. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2459. IF_NOTOK_MDF(fid=RF%ncid)
  2460. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  2461. IF_NOTOK_MDF(fid=RF%ncid)
  2462. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid B coefficient at layer midpoints' , status)
  2463. IF_NOTOK_MDF(fid=RF%ncid)
  2464. RF%varid_hybm = varid
  2465. #endif
  2466. call MDF_Def_Var( RF%ncid, 'lev', mdf_float, (/RF%dimid_lev/), varid , status)
  2467. IF_NOTOK_MDF(fid=RF%ncid)
  2468. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2469. IF_NOTOK_MDF(fid=RF%ncid)
  2470. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
  2471. IF_NOTOK_MDF(fid=RF%ncid)
  2472. #ifdef tropomi
  2473. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid level at layer midpoints' , status)
  2474. IF_NOTOK_MDF(fid=RF%ncid)
  2475. call MDF_Put_Att( RF%ncid, varid, 'units', 'level' , status)
  2476. IF_NOTOK_MDF(fid=RF%ncid)
  2477. call mdf_put_att( RF%ncid, varid, 'positive', 'down' , status)
  2478. IF_NOTOK_MDF(fid=RF%ncid)
  2479. call MDF_Put_Att( RF%ncid, varid, 'formula', 'hyam hybm (mlev=hyam+hybm*ps)' , status)
  2480. IF_NOTOK_MDF(fid=RF%ncid)
  2481. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'ap: hyam b: hybm ps: ps' , status)
  2482. IF_NOTOK_MDF(fid=RF%ncid)
  2483. #else
  2484. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'level' , status)
  2485. IF_NOTOK_MDF(fid=RF%ncid)
  2486. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  2487. IF_NOTOK_MDF(fid=RF%ncid)
  2488. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a_bnds(k)*p0 + b_bnds(k)*ps(n,j,i)' , status)
  2489. IF_NOTOK_MDF(fid=RF%ncid)
  2490. #endif
  2491. RF%varid_lev = varid
  2492. call MDF_Def_Var( RF%ncid, 'time', mdf_double, (/RF%dimid_time/), varid , status)
  2493. IF_NOTOK_MDF(fid=RF%ncid)
  2494. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2495. IF_NOTOK_MDF(fid=RF%ncid)
  2496. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
  2497. IF_NOTOK_MDF(fid=RF%ncid)
  2498. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'time' , status)
  2499. IF_NOTOK_MDF(fid=RF%ncid)
  2500. call MDF_Put_Att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
  2501. IF_NOTOK_MDF(fid=RF%ncid)
  2502. call MDF_Put_Att( RF%ncid, varid, 'calender', 'gregorian' , status)
  2503. IF_NOTOK_MDF(fid=RF%ncid)
  2504. RF%varid_time = varid
  2505. allocate(RF%time(rf%n_rec))
  2506. call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  2507. IF_NOTOK_MDF(fid=RF%ncid)
  2508. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2509. IF_NOTOK_MDF(fid=RF%ncid)
  2510. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
  2511. IF_NOTOK_MDF(fid=RF%ncid)
  2512. call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
  2513. IF_NOTOK_MDF(fid=RF%ncid)
  2514. RF%varid_date = varid
  2515. allocate(RF%date(6,rf%n_rec))
  2516. call MDF_Def_Var( RF%ncid, 'ps', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  2517. IF_NOTOK_MDF(fid=RF%ncid)
  2518. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2519. IF_NOTOK_MDF(fid=RF%ncid)
  2520. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'surface_air_pressure' , status)
  2521. IF_NOTOK_MDF(fid=RF%ncid)
  2522. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
  2523. IF_NOTOK_MDF(fid=RF%ncid)
  2524. call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
  2525. IF_NOTOK_MDF(fid=RF%ncid)
  2526. RF%varid_ps = varid
  2527. allocate( RF%sp(i1:i2, j1:j2, rf%n_rec) )
  2528. #ifndef tropomi
  2529. call MDF_Def_Var( RF%ncid, 't', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status )
  2530. IF_NOTOK_MDF(fid=RF%ncid)
  2531. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2532. IF_NOTOK_MDF(fid=RF%ncid)
  2533. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'air_temperature' , status)
  2534. IF_NOTOK_MDF(fid=RF%ncid)
  2535. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'temperature' , status)
  2536. IF_NOTOK_MDF(fid=RF%ncid)
  2537. call MDF_Put_Att( RF%ncid, varid, 'units', 'K' , status)
  2538. IF_NOTOK_MDF(fid=RF%ncid)
  2539. call MDF_put_att( RF%ncid, varid, 'comment', 'bottom-up; full levels' , status)
  2540. IF_NOTOK_MDF(fid=RF%ncid)
  2541. RF%varid_temp = varid
  2542. allocate( RF%data3d_t(i1:i2, j1:j2, levi%nlev, rf%n_rec) )
  2543. #endif
  2544. #ifdef tropomi
  2545. ! Extra temperature field output
  2546. ! with compression - crash
  2547. !call MDF_Def_Var( RF%ncid, 't', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status, compression=1, deflate_level=4)
  2548. call MDF_Def_Var( RF%ncid, 't', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  2549. IF_NOTOK_MDF(fid=RF%ncid)
  2550. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2551. IF_NOTOK_MDF(fid=RF%ncid)
  2552. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'air_temperature' , status)
  2553. IF_NOTOK_MDF(fid=RF%ncid)
  2554. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'temperature' , status)
  2555. IF_NOTOK_MDF(fid=RF%ncid)
  2556. call MDF_Put_Att( RF%ncid, varid, 'units', 'K' , status)
  2557. IF_NOTOK_MDF(fid=RF%ncid)
  2558. call MDF_put_att( RF%ncid, varid, 'comment', 'bottom-up; full levels' , status)
  2559. IF_NOTOK_MDF(fid=RF%ncid)
  2560. RF%varid_temp = varid
  2561. allocate( RF%data3d_t(i1:i2, j1:j2, levi%nlev, rf%n_rec) )
  2562. ! Extra surface elevation output, retrieved from GPH (meteo.f90) and g0 (binas.f90) following WGS84?
  2563. call MDF_Def_Var( RF%ncid, 'surface_altitude', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat/), varid, status)
  2564. IF_NOTOK_MDF(fid=RF%ncid)
  2565. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2566. IF_NOTOK_MDF(fid=RF%ncid)
  2567. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'surface_altitude' , status)
  2568. IF_NOTOK_MDF(fid=RF%ncid)
  2569. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'surface altitude of TM5 grid' , status)
  2570. IF_NOTOK_MDF(fid=RF%ncid)
  2571. call MDF_Put_Att( RF%ncid, varid, 'units', 'm' , status)
  2572. IF_NOTOK_MDF(fid=RF%ncid)
  2573. call MDF_put_att( RF%ncid, varid, 'comment', 'ECMWF interpolated orography' , status)
  2574. IF_NOTOK_MDF(fid=RF%ncid)
  2575. RF%varid_hgt = varid
  2576. allocate( RF%data2d_hgt(i1:i2, j1:j2) )
  2577. ! Extra tropopause level output, retrieved from GPH and temperature (meteo.f90)
  2578. call MDF_Def_Var( RF%ncid, 'tropopause_layer_index', MDF_INT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status)
  2579. IF_NOTOK_MDF(fid=RF%ncid)
  2580. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2581. IF_NOTOK_MDF(fid=RF%ncid)
  2582. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'tropopause_layer_index' , status)
  2583. IF_NOTOK_MDF(fid=RF%ncid)
  2584. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'index of the highest model layer in the troposphere' , status)
  2585. IF_NOTOK_MDF(fid=RF%ncid)
  2586. call MDF_Put_Att( RF%ncid, varid, 'units', '-' , status)
  2587. IF_NOTOK_MDF(fid=RF%ncid)
  2588. call MDF_put_att( RF%ncid, varid, 'comment', 'Based on WMO temperature gradient method' , status)
  2589. IF_NOTOK_MDF(fid=RF%ncid)
  2590. RF%varid_ltropo = varid
  2591. allocate( RF%data2d_ltropo(i1:i2, j1:j2, rf%n_rec) )
  2592. #endif
  2593. ! loop over tracer to be written:
  2594. do k = 1, RF%ntr
  2595. #ifdef with_m7
  2596. if( RF%lpmx(k) ) then
  2597. ! get diameter
  2598. write(csize,'(F5.1)') RF%sizepmx(k)
  2599. ! remove leading blanks
  2600. csize = adjustl(csize)
  2601. pospoint = index(csize,'.')
  2602. posend = len_trim(csize)
  2603. ! CF standard name for concentration/mixing ratio/column:
  2604. RF%varid_type(k) = 'conc'
  2605. varname_spec = 'pm'//csize(1:pospoint-1)//'p'//csize(pospoint+1:posend)
  2606. cf_spec_stnd = 'particulate_matter_'//trim(csize)
  2607. cf_spec_long = 'particulate matter diameter le '//trim(csize)//' micrometers'
  2608. cf_enti_stnd = 'concentration'
  2609. cf_enti_unit = 'kg m-3 '
  2610. cf_enti_long = 'mass per volume'
  2611. else
  2612. #endif
  2613. ! ----------------------------
  2614. ! setting defaults (gas phase)
  2615. ! ----------------------------
  2616. ! CF standard name for concentration/mixing ratio/column:
  2617. cf_enti_stnd = 'mole_fraction'
  2618. #ifdef tropomi
  2619. cf_enti_unit = '1'
  2620. #else
  2621. cf_enti_unit = 'mole mole-1'
  2622. #endif
  2623. cf_enti_long = 'volume mixing ratio'
  2624. cf_medium_stnd = 'in_air'
  2625. cf_medium_long = 'in humid air'
  2626. RF%varid_type(k) = 'mixr'
  2627. ! global tracer index
  2628. itr = RF%itr(k)
  2629. ! no comment yet
  2630. comment = ''
  2631. ! standard names from CF conventions:
  2632. select case ( strlowercase(RF%name_tr(k)) )
  2633. case ( 'co2' )
  2634. varname_spec = 'co2'
  2635. cf_spec_stnd = 'carbon_dioxide'
  2636. cf_spec_long = 'CO2'
  2637. case ( 'co' )
  2638. varname_spec = 'co'
  2639. cf_spec_stnd = 'carbon_monoxide'
  2640. cf_spec_long = 'CO'
  2641. case ( 'o3' )
  2642. varname_spec = 'o3'
  2643. cf_spec_stnd = 'ozone'
  2644. cf_spec_long = 'O3'
  2645. case ( 'o3s' )
  2646. varname_spec = 'o3s'
  2647. cf_spec_stnd = 'ozone_from_stratosphere'
  2648. cf_spec_long = 'O3s'
  2649. case ( 'no' )
  2650. varname_spec = 'no'
  2651. cf_spec_stnd = 'nitrogen_monoxide'
  2652. cf_spec_long = 'NO'
  2653. case ( 'no2' )
  2654. varname_spec = 'no2'
  2655. cf_spec_stnd = 'nitrogen_dioxide'
  2656. cf_spec_long = 'NO2'
  2657. case ( 'noy' )
  2658. varname_spec = 'noy'
  2659. cf_spec_stnd = 'nitrogen_oxides'
  2660. cf_spec_long = 'NOy'
  2661. comment = 'NOy = NOx + HNO3 + PAN + org.ntr., '// &
  2662. 'with NOx = NO + NO2 + NO3 + HNO4 + N2O5'
  2663. case ( 'ch2o', 'choh' )
  2664. varname_spec = 'ch2o'
  2665. cf_spec_stnd = 'formaldehyde'
  2666. cf_spec_long = 'CH2O'
  2667. case ( 'so2' )
  2668. varname_spec = 'so2'
  2669. cf_spec_stnd = 'sulfur_dioxide'
  2670. cf_spec_long = 'SO2'
  2671. case( 'h2so4' )
  2672. varname_spec = 'h2so4'
  2673. cf_spec_stnd = 'sulfuric_acid_g'
  2674. cf_spec_long = 'H2SO4 (g)'
  2675. !!$ case ( 'so4' )
  2676. !!$ varname_spec = 'so4'
  2677. !!$ cf_spec_stnd = 'sulfate_as_sulfate_dry_aerosol'
  2678. !!$ cf_spec_long = 'SO4'
  2679. case ( 'ch4' )
  2680. varname_spec = 'ch4'
  2681. cf_spec_stnd = 'methane'
  2682. cf_spec_long = 'CH4'
  2683. case ( 'oh' )
  2684. varname_spec = 'oh'
  2685. cf_spec_stnd = 'hydroxyl_radical'
  2686. cf_spec_long = 'OH'
  2687. case ( 'h2o2' )
  2688. varname_spec = 'h2o2'
  2689. cf_spec_stnd = 'hydrogen_peroxide'
  2690. cf_spec_long = 'H2O2'
  2691. case ( 'hno3' )
  2692. varname_spec = 'hno3'
  2693. cf_spec_stnd = 'nitric_acid'
  2694. cf_spec_long = 'HNO3'
  2695. case ( 'hno4' )
  2696. varname_spec = 'hno4'
  2697. cf_spec_stnd = 'peroxonitric_acid'
  2698. cf_spec_long = 'HNO4'
  2699. case ( 'n2o5' )
  2700. varname_spec = 'n2o5'
  2701. cf_spec_stnd = 'nitrogen_pentoxide'
  2702. cf_spec_long = 'N2O5'
  2703. case ( 'par' )
  2704. varname_spec = 'par'
  2705. cf_spec_stnd = 'paraffinic_carbon_atoms'
  2706. cf_spec_long = 'PAR'
  2707. case ( 'eth' )
  2708. varname_spec = 'eth'
  2709. cf_spec_stnd = 'ethylene'
  2710. cf_spec_long = 'ETH'
  2711. case ( 'ole' )
  2712. varname_spec = 'ole'
  2713. cf_spec_stnd = 'olefinic_carbon_bonds'
  2714. cf_spec_long = 'OLE'
  2715. case ( 'ald2' )
  2716. varname_spec = 'ald2'
  2717. cf_spec_stnd = 'acetaldehyde_and_higher_aldehydes'
  2718. cf_spec_long = 'ALD2'
  2719. case ( 'mgly' )
  2720. varname_spec = 'mgly'
  2721. cf_spec_stnd = 'methylglyoxal'
  2722. cf_spec_long = 'MGLY'
  2723. case ( 'isop' )
  2724. varname_spec = 'isop'
  2725. cf_spec_stnd = 'isoprene'
  2726. cf_spec_long = 'ISOP'
  2727. case ( 'nh3' )
  2728. varname_spec = 'nh3'
  2729. cf_spec_stnd = 'ammonia'
  2730. cf_spec_long = 'NH3'
  2731. case ( 'ORGNTR','orgntr' )
  2732. varname_spec = 'orgntr'
  2733. cf_spec_stnd = 'organic_nitrate'
  2734. cf_spec_long = 'ORGNTR'
  2735. case ( 'pan' )
  2736. varname_spec = 'pan'
  2737. cf_spec_stnd = 'peroxyacetyl_nitrate'
  2738. cf_spec_long = 'PAN'
  2739. case ( 'terp' )
  2740. varname_spec = 'terp'
  2741. cf_spec_stnd = 'terpene'
  2742. cf_spec_long = 'TERP'
  2743. case ( 'elvoc' )
  2744. varname_spec = 'elvoc'
  2745. cf_spec_stnd = 'extremely low volatile OC'
  2746. cf_spec_long = 'ELVOC'
  2747. case ( 'svoc' )
  2748. varname_spec = 'svoc'
  2749. cf_spec_stnd = 'semi volatile OC'
  2750. cf_spec_long = 'SVOC'
  2751. case ( 'rn', 'radon', 'rn222' )
  2752. varname_spec = 'rn'
  2753. cf_spec_stnd = 'radon'
  2754. cf_spec_long = 'Rn'
  2755. case ( 'pb', 'lead', 'pb210' )
  2756. varname_spec = 'pb'
  2757. cf_spec_stnd = 'lead'
  2758. cf_spec_long = 'Pb'
  2759. #ifdef with_m7
  2760. ! Sulphate
  2761. case( 'tso4' )
  2762. RF%varid_type(k) = 'conc'
  2763. varname_spec = 'so4'
  2764. cf_spec_stnd = 'total_sulphate_aerosol'
  2765. cf_spec_long = 'SO4'
  2766. cf_enti_stnd = 'concentration'
  2767. cf_enti_unit = 'kg m-3 '
  2768. cf_enti_long = 'mass per volume'
  2769. ! Black Carbon
  2770. case( 'tbc' )
  2771. RF%varid_type(k) = 'conc'
  2772. varname_spec = 'bc'
  2773. cf_spec_stnd = 'total_black_carbon_aerosol'
  2774. cf_spec_long = 'BC'
  2775. cf_enti_stnd = 'concentration'
  2776. cf_enti_unit = 'kg m-3 '
  2777. cf_enti_long = 'mass per volume'
  2778. ! Particulate Organic Matter
  2779. case( 'tpom' )
  2780. RF%varid_type(k) = 'conc'
  2781. varname_spec = 'pom'
  2782. cf_spec_stnd = 'total_particulate_organic_matter_aerosol'
  2783. cf_spec_long = 'POM'
  2784. cf_enti_stnd = 'concentration'
  2785. cf_enti_unit = 'kg m-3 '
  2786. cf_enti_long = 'mass per volume'
  2787. ! Sea Salt
  2788. case( 'tss' )
  2789. RF%varid_type(k) = 'conc'
  2790. varname_spec = 'ss'
  2791. cf_spec_stnd = 'total_sea_salt_aerosol'
  2792. cf_spec_long = 'SS'
  2793. cf_enti_stnd = 'concentration'
  2794. cf_enti_unit = 'kg m-3 '
  2795. cf_enti_long = 'mass per volume'
  2796. ! Dust
  2797. case( 'tdu' )
  2798. RF%varid_type(k) = 'conc'
  2799. varname_spec = 'du'
  2800. cf_spec_stnd = 'total_dust_aerosol'
  2801. cf_spec_long = 'SS'
  2802. cf_enti_stnd = 'concentration'
  2803. cf_enti_unit = 'kg m-3 '
  2804. cf_enti_long = 'mass per volume'
  2805. ! Nucleation Soluble (nus): number, SO4
  2806. case ( 'nus_n' )
  2807. RF%varid_type(k) = 'numb'
  2808. varname_spec = 'nus_n'
  2809. cf_spec_stnd = 'number_wet_nucleation'
  2810. cf_spec_long = 'Number_nus'
  2811. cf_enti_stnd = 'number'
  2812. cf_enti_unit = '1.'
  2813. cf_enti_long = ''
  2814. case ( 'so4nus' )
  2815. RF%varid_type(k) = 'conc'
  2816. varname_spec = 'so4nus'
  2817. cf_spec_stnd = 'sulphate_wet_nucleation'
  2818. cf_spec_long = 'SO4_nus'
  2819. cf_enti_stnd = 'concentration'
  2820. cf_enti_unit = 'kg m-3 '
  2821. cf_enti_long = 'mass per volume'
  2822. case ( 'soanus' )
  2823. RF%varid_type(k) = 'conc'
  2824. varname_spec = 'soanus'
  2825. cf_spec_stnd = 'SOA_wet_nucleation'
  2826. cf_spec_long = 'SOA_nus'
  2827. cf_enti_stnd = 'concentration'
  2828. cf_enti_unit = 'kg m-3 '
  2829. cf_enti_long = 'mass per volume'
  2830. ! Aitken Soluble (ais): number, SO4, BC, POM
  2831. case ( 'ais_n' )
  2832. RF%varid_type(k) = 'numb'
  2833. varname_spec = 'ais_n'
  2834. cf_spec_stnd = 'number_wet_aitken'
  2835. cf_spec_long = 'Number_ais'
  2836. cf_enti_stnd = 'number'
  2837. cf_enti_unit = '1.'
  2838. cf_enti_long = ''
  2839. case ( 'so4ais' )
  2840. RF%varid_type(k) = 'conc'
  2841. varname_spec = 'so4ais'
  2842. cf_spec_stnd = 'sulphate_wet_aitken'
  2843. cf_spec_long = 'SO4_ais'
  2844. cf_enti_stnd = 'concentration'
  2845. cf_enti_unit = 'kg m-3 '
  2846. cf_enti_long = 'mass per volume'
  2847. case ( 'bcais' )
  2848. RF%varid_type(k) = 'conc'
  2849. varname_spec = 'bcais'
  2850. cf_spec_stnd = 'black_carbon_wet_aitken'
  2851. cf_spec_long = 'BC_ais'
  2852. cf_enti_stnd = 'concentration'
  2853. cf_enti_unit = 'kg m-3 '
  2854. cf_enti_long = 'mass per volume'
  2855. case ( 'pomais' )
  2856. RF%varid_type(k) = 'conc'
  2857. varname_spec = 'pomais'
  2858. cf_spec_stnd = 'particulate_organic_matter_wet_aitken'
  2859. cf_spec_long = 'POM_ais'
  2860. cf_enti_stnd = 'concentration'
  2861. cf_enti_unit = 'kg m-3 '
  2862. cf_enti_long = 'mass per volume'
  2863. case ( 'soaais' )
  2864. RF%varid_type(k) = 'conc'
  2865. varname_spec = 'soaais'
  2866. cf_spec_stnd = 'SOA_dry_Aitken'
  2867. cf_spec_long = 'SOA_ais'
  2868. cf_enti_stnd = 'concentration'
  2869. cf_enti_unit = 'kg m-3 '
  2870. cf_enti_long = 'mass per volume'
  2871. ! Accumulation Soluble (acs): number, SO4, BC, POM, SS, DU
  2872. case ( 'acs_n' )
  2873. RF%varid_type(k) = 'numb'
  2874. varname_spec = 'acs_n'
  2875. cf_spec_stnd = 'number_wet_accumulation'
  2876. cf_spec_long = 'Number_acs'
  2877. cf_enti_stnd = 'number'
  2878. cf_enti_unit = '1.'
  2879. cf_enti_long = ''
  2880. case ( 'so4acs' )
  2881. RF%varid_type(k) = 'conc'
  2882. varname_spec = 'so4acs'
  2883. cf_spec_stnd = 'sulphate_wet_accumulation'
  2884. cf_spec_long = 'SO4_acs'
  2885. cf_enti_stnd = 'concentration'
  2886. cf_enti_unit = 'kg m-3 '
  2887. cf_enti_long = 'mass per volume'
  2888. case ( 'bcacs' )
  2889. RF%varid_type(k) = 'conc'
  2890. varname_spec = 'bcacs'
  2891. cf_spec_stnd = 'black_carbon_wet_accumulation'
  2892. cf_spec_long = 'BC_acs'
  2893. cf_enti_stnd = 'concentration'
  2894. cf_enti_unit = 'kg m-3 '
  2895. cf_enti_long = 'mass per volume'
  2896. case ( 'pomacs' )
  2897. RF%varid_type(k) = 'conc'
  2898. varname_spec = 'pomacs'
  2899. cf_spec_stnd = 'particulate_organic_matter_wet_accumulation'
  2900. cf_spec_long = 'POM_acs'
  2901. cf_enti_stnd = 'concentration'
  2902. cf_enti_unit = 'kg m-3 '
  2903. cf_enti_long = 'mass per volume'
  2904. case ( 'ssacs' )
  2905. RF%varid_type(k) = 'conc'
  2906. varname_spec = 'ssacs'
  2907. cf_spec_stnd = 'seasalt_wet_accumulation'
  2908. cf_spec_long = 'SS_acs'
  2909. cf_enti_stnd = 'concentration'
  2910. cf_enti_unit = 'kg m-3 '
  2911. cf_enti_long = 'mass per volume'
  2912. case ( 'duacs' )
  2913. RF%varid_type(k) = 'conc'
  2914. varname_spec = 'duacs'
  2915. cf_spec_stnd = 'dust_wet_accumulation'
  2916. cf_spec_long = 'DU_acs'
  2917. cf_enti_stnd = 'concentration'
  2918. cf_enti_unit = 'kg m-3 '
  2919. cf_enti_long = 'mass per volume'
  2920. case ( 'soaacs' )
  2921. RF%varid_type(k) = 'conc'
  2922. varname_spec = 'soaacs'
  2923. cf_spec_stnd = 'SOA_dry_Accumulation'
  2924. cf_spec_long = 'SOA_acs'
  2925. cf_enti_stnd = 'concentration'
  2926. cf_enti_unit = 'kg m-3 '
  2927. cf_enti_long = 'mass per volume'
  2928. ! Coarse Soluble (cos): number, SO4, BC, POM, SS, DU
  2929. case ( 'cos_n' )
  2930. RF%varid_type(k) = 'numb'
  2931. varname_spec = 'cos_n'
  2932. cf_spec_stnd = 'number_wet_coarse'
  2933. cf_spec_long = 'Number_cos'
  2934. cf_enti_stnd = 'number'
  2935. cf_enti_unit = '1.'
  2936. cf_enti_long = ''
  2937. case ( 'so4cos' )
  2938. RF%varid_type(k) = 'conc'
  2939. varname_spec = 'so4cos'
  2940. cf_spec_stnd = 'sulphate_wet_coarse'
  2941. cf_spec_long = 'SO4_cos'
  2942. cf_enti_stnd = 'concentration'
  2943. cf_enti_unit = 'kg m-3 '
  2944. cf_enti_long = 'mass per volume'
  2945. case ( 'bccos' )
  2946. RF%varid_type(k) = 'conc'
  2947. varname_spec = 'bccos'
  2948. cf_spec_stnd = 'black_carbon_wet_coarse'
  2949. cf_spec_long = 'BC_cos'
  2950. cf_enti_stnd = 'concentration'
  2951. cf_enti_unit = 'kg m-3 '
  2952. cf_enti_long = 'mass per volume'
  2953. case ( 'pomcos' )
  2954. RF%varid_type(k) = 'conc'
  2955. varname_spec = 'pomcos'
  2956. cf_spec_stnd = 'particulate_organic_matter_wet_coarse'
  2957. cf_spec_long = 'POM_cos'
  2958. cf_enti_stnd = 'concentration'
  2959. cf_enti_unit = 'kg m-3 '
  2960. cf_enti_long = 'mass per volume'
  2961. case ( 'sscos' )
  2962. RF%varid_type(k) = 'conc'
  2963. varname_spec = 'sscos'
  2964. cf_spec_stnd = 'seasalt_wet_coarse'
  2965. cf_spec_long = 'SS_cos'
  2966. cf_enti_stnd = 'concentration'
  2967. cf_enti_unit = 'kg m-3 '
  2968. cf_enti_long = 'mass per volume'
  2969. case ( 'ducos' )
  2970. RF%varid_type(k) = 'conc'
  2971. varname_spec = 'ducos'
  2972. cf_spec_stnd = 'dust_wet_coarse'
  2973. cf_spec_long = 'DU_cos'
  2974. cf_enti_stnd = 'concentration'
  2975. cf_enti_unit = 'kg m-3 '
  2976. cf_enti_long = 'mass per volume'
  2977. case ( 'soacos' )
  2978. RF%varid_type(k) = 'conc'
  2979. varname_spec = 'soacos'
  2980. cf_spec_stnd = 'SOA_dry_coarse'
  2981. cf_spec_long = 'SOA_cos'
  2982. cf_enti_stnd = 'concentration'
  2983. cf_enti_unit = 'kg m-3 '
  2984. cf_enti_long = 'mass per volume'
  2985. ! Aitken Insoluble (aii): number, BC, POM
  2986. case ( 'aii_n' )
  2987. RF%varid_type(k) = 'numb'
  2988. varname_spec = 'aii_n'
  2989. cf_spec_stnd = 'number_dry_aitken'
  2990. cf_spec_long = 'Number_aii'
  2991. cf_enti_stnd = 'number'
  2992. cf_enti_unit = '1.'
  2993. cf_enti_long = ''
  2994. case ( 'bcaii' )
  2995. RF%varid_type(k) = 'conc'
  2996. varname_spec = 'bcaii'
  2997. cf_spec_stnd = 'black_carbon_dry_aitken'
  2998. cf_spec_long = 'BC_aii'
  2999. cf_enti_stnd = 'concentration'
  3000. cf_enti_unit = 'kg m-3 '
  3001. cf_enti_long = 'mass per volume'
  3002. case ( 'pomaii' )
  3003. RF%varid_type(k) = 'conc'
  3004. varname_spec = 'pomaii'
  3005. cf_spec_stnd = 'particulate_organic_matter_dry_aitken'
  3006. cf_spec_long = 'POM_aii'
  3007. cf_enti_stnd = 'concentration'
  3008. cf_enti_unit = 'kg m-3 '
  3009. cf_enti_long = 'mass per volume'
  3010. case ( 'soaaii' )
  3011. RF%varid_type(k) = 'conc'
  3012. varname_spec = 'soaaii'
  3013. cf_spec_stnd = 'SOA_dry_Aitken'
  3014. cf_spec_long = 'SOA_aii'
  3015. cf_enti_stnd = 'concentration'
  3016. cf_enti_unit = 'kg m-3 '
  3017. cf_enti_long = 'mass per volume'
  3018. ! Accumulation Insoluble (aci): number, DU
  3019. case ( 'aci_n' )
  3020. RF%varid_type(k) = 'numb'
  3021. varname_spec = 'aci_n'
  3022. cf_spec_stnd = 'number_dry_accumulation'
  3023. cf_spec_long = 'Number_aci'
  3024. cf_enti_stnd = 'number'
  3025. cf_enti_unit = '1.'
  3026. cf_enti_long = ''
  3027. case ( 'duaci' )
  3028. RF%varid_type(k) = 'conc'
  3029. varname_spec = 'duaci'
  3030. cf_spec_stnd = 'dust_dry_accumulation'
  3031. cf_spec_long = 'DU_aci'
  3032. cf_enti_stnd = 'concentration'
  3033. cf_enti_unit = 'kg m-3 '
  3034. cf_enti_long = 'mass per volume'
  3035. ! Coarse Insoluble (coi): number, DU
  3036. case ( 'coi_n' )
  3037. RF%varid_type(k) = 'numb'
  3038. varname_spec = 'coi_n'
  3039. cf_spec_stnd = 'number_dry_coarse'
  3040. cf_spec_long = 'Number_coi'
  3041. cf_enti_stnd = 'number'
  3042. cf_enti_unit = '1.'
  3043. cf_enti_long = ''
  3044. case ( 'ducoi' )
  3045. RF%varid_type(k) = 'conc'
  3046. varname_spec = 'ducoi'
  3047. cf_spec_stnd = 'dust_dry_coarse'
  3048. cf_spec_long = 'DU_coi'
  3049. cf_enti_stnd = 'concentration'
  3050. cf_enti_unit = 'kg m-3 '
  3051. cf_enti_long = 'mass per volume'
  3052. #endif
  3053. case ( 'nh4' )
  3054. RF%varid_type(k) = 'conc'
  3055. varname_spec = 'nh4'
  3056. cf_spec_stnd = 'ammonium_as_ammonium_dry_aerosol'
  3057. cf_spec_long = 'NH4'
  3058. cf_enti_stnd = 'concentration'
  3059. cf_enti_unit = 'kg m-3 '
  3060. cf_enti_long = 'mass per volume'
  3061. case ( 'no3_a' )
  3062. RF%varid_type(k) = 'conc'
  3063. varname_spec = 'no3'
  3064. cf_spec_stnd = 'nitrate_as_nitrate_dry_aerosol'
  3065. cf_spec_long = 'NO3'
  3066. cf_enti_stnd = 'concentration'
  3067. cf_enti_unit = 'kg m-3 '
  3068. cf_enti_long = 'mass per volume'
  3069. !!$ case ( 'bc' )
  3070. !!$ varname_spec = 'bc'
  3071. !!$ cf_spec_stnd = 'black_carbon_dry_aerosol'
  3072. !!$ cf_spec_long = 'BC'
  3073. !!$ case ( 'BCS', 'bcs' )
  3074. !!$ varname_spec = 'bcs'
  3075. !!$ cf_spec_stnd = 'hydrophilic_black_carbon_dry_aerosol'
  3076. !!$ cf_spec_long = 'BC(aq)'
  3077. !!$ case ( 'POM', 'pom' )
  3078. !!$ varname_spec = 'om'
  3079. !!$ cf_spec_stnd = 'organic_carbon_as_particulate_organic_matter_dry_aerosol'
  3080. !!$ cf_spec_long = 'OM'
  3081. !!$ case ( 'SS1_N', 'ss1_n' )
  3082. !!$ varname_spec = 'ss1_n'
  3083. !!$ cf_spec_stnd = 'seasalt_dry_aerosol_mode1_number'
  3084. !!$ cf_spec_long = 'SS1_n'
  3085. !!$ case ( 'SS1_M', 'ss1_m' )
  3086. !!$ varname_spec = 'ss1_m'
  3087. !!$ cf_spec_stnd = 'seasalt_dry_aerosol_mode1_mass'
  3088. !!$ cf_spec_long = 'SS1_m'
  3089. !!$ case ( 'SS2_N', 'ss2_n' )
  3090. !!$ varname_spec = 'ss2_n'
  3091. !!$ cf_spec_stnd = 'seasalt_dry_aerosol_mode2_number'
  3092. !!$ cf_spec_long = 'SS2_n'
  3093. !!$ case ( 'SS2_M', 'ss2_m' )
  3094. !!$ varname_spec = 'ss2_m'
  3095. !!$ cf_spec_stnd = 'seasalt_dry_aerosol_mode2_mass'
  3096. !!$ cf_spec_long = 'SS2_m'
  3097. !!$ case ( 'SS3_N', 'ss3_n' )
  3098. !!$ varname_spec = 'ss3_n'
  3099. !!$ cf_spec_stnd = 'seasalt_dry_aerosol_mode3_number'
  3100. !!$ cf_spec_long = 'SS3_n'
  3101. !!$ case ( 'SS3_M', 'ss3_m' )
  3102. !!$ varname_spec = 'ss3_m'
  3103. !!$ cf_spec_stnd = 'seasalt_dry_aerosol_mode3_mass'
  3104. !!$ cf_spec_long = 'SS3_m'
  3105. !!$ case ( 'DUST2_N', 'dust2_n' )
  3106. !!$ varname_spec = 'dust2_n'
  3107. !!$ cf_spec_stnd = 'dust_dry_aerosol_mode2_number'
  3108. !!$ cf_spec_long = 'DUST2_n'
  3109. !!$ case ( 'DUST2_M', 'dust2_m' )
  3110. !!$ varname_spec = 'dust2_m'
  3111. !!$ cf_spec_stnd = 'dust_dry_aerosol_mode2_madust'
  3112. !!$ cf_spec_long = 'DUST2_m'
  3113. !!$ case ( 'DUST3_N', 'dust3_n' )
  3114. !!$ varname_spec = 'dust3_n'
  3115. !!$ cf_spec_stnd = 'dust_dry_aerosol_mode3_number'
  3116. !!$ cf_spec_long = 'DUST3_n'
  3117. !!$ case ( 'DUST3_M', 'dust3_m' )
  3118. !!$ varname_spec = 'dust3_m'
  3119. !!$ cf_spec_stnd = 'dust_dry_aerosol_mode3_madust'
  3120. !!$ cf_spec_long = 'DUST3_m'
  3121. case default
  3122. write (gol,'("do not know how to match tracer with CF standard names : ",a)') RF%name_tr(k); call goErr
  3123. TRACEBACK; status=1; return
  3124. end select
  3125. #ifdef with_m7
  3126. end if ! RF%lpmx(k)
  3127. #endif
  3128. ! define variable:
  3129. call MDF_Def_Var( RF%ncid, trim(varname_spec), MDF_FLOAT, &
  3130. (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid, status )
  3131. IF_NOTOK_MDF(fid=RF%ncid)
  3132. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  3133. IF_NOTOK_MDF(fid=RF%ncid)
  3134. ! total names:
  3135. cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)//'_'//trim(cf_medium_stnd)
  3136. cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)//' '//trim(cf_medium_long)
  3137. cf_name_unit = trim(cf_enti_unit)
  3138. ! write attributes:
  3139. call MDF_Put_Att( RF%ncid, varid, 'standard_name', trim(cf_name_stnd) , status)
  3140. IF_NOTOK_MDF(fid=RF%ncid)
  3141. call MDF_Put_Att( RF%ncid, varid, 'long_name', trim(cf_name_long) , status)
  3142. IF_NOTOK_MDF(fid=RF%ncid)
  3143. call MDF_Put_Att( RF%ncid, varid, 'units', trim(cf_name_unit) , status)
  3144. IF_NOTOK_MDF(fid=RF%ncid)
  3145. ! moleweights; ra from chem_param is in g/mol .
  3146. if ( itr <= ntrace .and. itr > 0 ) then
  3147. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', ra(itr)*1e3 , status)
  3148. IF_NOTOK_MDF(fid=RF%ncid)
  3149. else
  3150. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', -1.0 , status)
  3151. IF_NOTOK_MDF(fid=RF%ncid)
  3152. end if
  3153. call MDF_Put_Att( RF%ncid , varid, 'moleweight_air' , xmair*1e3 , status)
  3154. IF_NOTOK_MDF(fid=RF%ncid)
  3155. call MDF_Put_Att( RF%ncid , varid, 'moleweight_unit' , 'kg mole-1' , status)
  3156. IF_NOTOK_MDF(fid=RF%ncid)
  3157. if ( len_trim(comment) > 0 ) then
  3158. call MDF_Put_Att( RF%ncid, varid, 'comment' , trim(comment), status)
  3159. IF_NOTOK_MDF(fid=RF%ncid)
  3160. end if
  3161. ! store varid
  3162. RF%varid_tr(k) = varid
  3163. end do
  3164. ! storage
  3165. allocate(rf%data3d(i1:i2,j1:j2,lmr,rf%n_rec,rf%ntr))
  3166. ! o end defintion mode
  3167. call MDF_EndDef( RF%ncid , status)
  3168. IF_NOTOK_MDF(fid=RF%ncid)
  3169. ! o
  3170. ! no records written yet
  3171. RF%trec = 0
  3172. call goLabel()
  3173. status = 0
  3174. END SUBROUTINE RF_VMR_Init
  3175. !EOC
  3176. !--------------------------------------------------------------------------
  3177. ! TM5 !
  3178. !--------------------------------------------------------------------------
  3179. !BOP
  3180. !
  3181. ! !IROUTINE: RF_VMR_Write
  3182. !
  3183. ! !DESCRIPTION:
  3184. !\\
  3185. !\\
  3186. ! !INTERFACE:
  3187. !
  3188. SUBROUTINE RF_VMR_Write( RF, region, idate_f, status )
  3189. !
  3190. ! !USES:
  3191. !
  3192. use Binas, only : xmair
  3193. use GO, only : TDate, NewDate, rTotal, operator(-)
  3194. use binas, only : Rgas
  3195. use chem_param, only : ntrace, ntracet, fscale, ra
  3196. use tracer_data, only : mass_dat, chem_dat
  3197. use Grid, only : FPressure
  3198. use MeteoData, only : global_lli, levi, m_dat, sp_dat, temper_dat
  3199. #ifdef tropomi
  3200. use MeteoData, only : gph_dat
  3201. use toolbox, only : ltropo_ifs, lvlpress
  3202. #endif
  3203. #ifdef with_m7
  3204. use calc_pm, only : PMx_Integrate_3d
  3205. #endif
  3206. !
  3207. ! !INPUT/OUTPUT PARAMETERS:
  3208. !
  3209. type(TPdumpFile_VMR), intent(inout) :: RF
  3210. !
  3211. ! !INPUT PARAMETERS:
  3212. !
  3213. integer, intent(in) :: region
  3214. integer, intent(in) :: idate_f(6)
  3215. !
  3216. ! !OUTPUT PARAMETERS:
  3217. !
  3218. integer, intent(out) :: status
  3219. !
  3220. ! !REVISION HISTORY:
  3221. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  3222. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  3223. ! 2 Oct 2012 - Ph. Le Sager - adapted for lat-lon mpi decomp
  3224. ! - no more sub-regions available
  3225. !
  3226. ! !REMARKS:
  3227. ! (1)
  3228. !
  3229. !EOP
  3230. !------------------------------------------------------------------------
  3231. !BOC
  3232. character(len=*), parameter :: rname = mname//'/RF_VMR_Write'
  3233. ! --- local ------------------------------------
  3234. integer :: imr, jmr, lmr, i1, i2, j1, j2, i, j
  3235. real, allocatable :: lev(:)
  3236. integer :: l
  3237. type(TDate) :: t, t0
  3238. real :: time
  3239. integer :: k, itr, dsec
  3240. integer :: k_comp, itr_comp
  3241. integer :: ims, ime, jms, jme, lms, lme
  3242. integer :: gimr, gjmr, glmr
  3243. real, allocatable :: compo_k(:,:,:)
  3244. real, allocatable :: field_k(:,:,:)
  3245. real, allocatable :: pres3d(:,:,:), pmx(:,:,:)
  3246. integer :: numtrac
  3247. integer :: listtrac(10)
  3248. ! --- begin -------------------------------------
  3249. ! for multiple of timestep only ...
  3250. dsec = idate_f(4)*3600 + idate_f(5)*60 + idate_f(6)
  3251. if ( modulo(dsec,RF%dsec) /= 0 ) then
  3252. status=0; return
  3253. end if
  3254. call goLabel(rname)
  3255. ! grid sizes
  3256. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3257. imr=i2-i1+1
  3258. jmr=j2-j1+1
  3259. lmr = levi%nlev
  3260. gimr = global_lli(region)%nlon
  3261. gjmr = global_lli(region)%nlat
  3262. ! yet to change ??
  3263. lms = 1
  3264. lme = levi%nlev
  3265. lmr = levi%nlev
  3266. glmr = levi%nlev
  3267. #ifdef with_m7
  3268. ! get helping pressure field in 3d
  3269. allocate( pres3d(i1:i2,j1:j2,lmr) )
  3270. ! fill mid level pressure
  3271. call FPressure( levi, sp_dat(region)%data(i1:i2,j1:j2,1), pres3d, status )
  3272. IF_NOTOK_RETURN(status=1)
  3273. #endif
  3274. ! next time record:
  3275. RF%trec = RF%trec + 1
  3276. if(isRoot.and.okdebug)then
  3277. write(gol,*) "RF_VMR_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
  3278. end if
  3279. ! time since 1950-1-1 00:00
  3280. t0 = NewDate( time6=time_reftime6 )
  3281. t = NewDate( time6=idate_f )
  3282. time = rTotal( t - t0, 'day' )
  3283. ! only once ...
  3284. if ( RF%trec == 1 ) then
  3285. ! write longitudes:
  3286. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
  3287. IF_NOTOK_MDF(fid=RF%ncid)
  3288. ! write latitudes:
  3289. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
  3290. IF_NOTOK_MDF(fid=RF%ncid)
  3291. ! write level indices:
  3292. allocate( lev(lmr) )
  3293. do l = lms, lme
  3294. lev(l) = real(l)
  3295. end do
  3296. call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
  3297. IF_NOTOK_MDF(fid=RF%ncid)
  3298. deallocate(lev)
  3299. #ifdef tropomi
  3300. ! As and Bs interfaces
  3301. call MDF_Put_Var( RF%ncid, RF%varid_hyai, levi%a(0:levi%nlev) , status)
  3302. IF_NOTOK_MDF(fid=RF%ncid)
  3303. call MDF_Put_Var( RF%ncid, RF%varid_hybi, levi%b(0:levi%nlev) , status)
  3304. IF_NOTOK_MDF(fid=RF%ncid)
  3305. ! As and Bs mid-level (full level)
  3306. call MDF_Put_Var( RF%ncid, RF%varid_hyam, levi%fa(1:levi%nlev) , status)
  3307. IF_NOTOK_MDF(fid=RF%ncid)
  3308. call MDF_Put_Var( RF%ncid, RF%varid_hybm, levi%fb(1:levi%nlev) , status)
  3309. IF_NOTOK_MDF(fid=RF%ncid)
  3310. #else
  3311. ! As and Bs
  3312. call MDF_Put_Var( RF%ncid, RF%varid_a_bnds, levi%a(0:levi%nlev) , status)
  3313. IF_NOTOK_MDF(fid=RF%ncid)
  3314. call MDF_Put_Var( RF%ncid, RF%varid_b_bnds, levi%b(0:levi%nlev) , status)
  3315. IF_NOTOK_MDF(fid=RF%ncid)
  3316. #endif
  3317. end if ! first record
  3318. RF%time(RF%trec) = time
  3319. RF%date(:,RF%trec) = real(idate_f)
  3320. RF%sp(:,:,RF%trec) = sp_dat(region)%data(i1:i2,j1:j2,1)
  3321. #ifdef tropomi
  3322. ! copy of temperature field
  3323. RF%data3d_t(:,:,:,RF%trec) = temper_dat(region)%data(i1:i2,j1:j2,1:lmr)
  3324. ! orography: copy of lowest interface gph field. gph in the model is in "m", at interfaces, and gph(1)=oro
  3325. ! only once ...
  3326. if ( RF%trec == 1 ) then
  3327. RF%data2d_hgt(:,:) = gph_dat(region)%data(i1:i2,j1:j2,1)
  3328. end if
  3329. ! compute highest tropopause layer index
  3330. do i = i1, i2
  3331. do j = j1, j2
  3332. RF%data2d_ltropo(i,j,RF%trec) = ltropo_ifs(region,i,j,temper_dat(region)%data(i,j,1:lmr),lmr)
  3333. end do
  3334. end do
  3335. #endif
  3336. ! loop over all tracers to be written:
  3337. do k = 1, RF%ntr
  3338. ! global tracer index:
  3339. itr = RF%itr(k)
  3340. #ifdef with_m7
  3341. ! ---------------------
  3342. ! particulate matter
  3343. ! ---------------------
  3344. if( RF%lpmx(k) ) then
  3345. allocate( pmx( i1:i2, j1:j2, 1:lmr ) ) ; pmx = 0.0
  3346. call PMx_Integrate_3d( region, RF%sizepmx(k), pmx, status )
  3347. IF_NOTOK_RETURN(status=1)
  3348. rf%data3d(:,:,:, rf%trec, k) = pmx
  3349. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  3350. ! reshape( pmx(i1:i2,j1:j2,lms:lme), (/imr,jmr,lmr,1/) ), status &
  3351. ! start=(/i1,j1,1,RF%trec/), count=(/imr,jmr,lmr,1/) )
  3352. deallocate( pmx )
  3353. else
  3354. #endif
  3355. ! ---------
  3356. ! transported or chemistry only ?
  3357. ! ---------
  3358. select case( itr )
  3359. case( 1:ntracet )
  3360. ! ----------------------------------------------------
  3361. ! distinguish between mixing ratios and concentrations
  3362. ! ----------------------------------------------------
  3363. select case( RF%varid_type(k) )
  3364. case( 'conc' )
  3365. ! write slab of concentrations
  3366. ! m(trace) pressure xm(trace)
  3367. ! C = -------- * fscale * ----------- * ---------
  3368. ! m(air) temperature Rgas
  3369. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  3370. ! reshape( mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr) / &
  3371. ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  3372. ! pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  3373. ! Rgas, (/imr,jmr,lmr,1/) ), &
  3374. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  3375. #ifdef with_m7
  3376. rf%data3d(:,:,:, rf%trec, k) = mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr) / &
  3377. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  3378. pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  3379. Rgas
  3380. #else
  3381. write(gol,*)"Not using m7 - did not expected to be here."; call goErr
  3382. write(gol,*)" - make pres3d available"; call goErr
  3383. status=1; TRACEBACK; return
  3384. #endif
  3385. case( 'mixr' )
  3386. ! write slab of volume mixing ratios
  3387. ! m(trace)
  3388. ! X = -------- * fscale
  3389. ! m(air)
  3390. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  3391. ! reshape( mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr)/ &
  3392. ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr), &
  3393. ! (/imr,jmr,lmr,1/) ), &
  3394. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  3395. rf%data3d(:,:,:, rf%trec, k) = mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr)/ &
  3396. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr)
  3397. case( 'numb' )
  3398. ! write slab of concentrations
  3399. ! number(trace) pressure #/gridcell Pa*K*mol
  3400. ! C = ------------- * molmass_air * ---------------- = ------------- * kg/mol *-----------
  3401. ! m(air) temperature*Rgas kg/gridcell K*J
  3402. #ifdef with_m7
  3403. rf%data3d(:,:,:, rf%trec, k) = mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr) / &
  3404. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  3405. pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  3406. Rgas
  3407. #else
  3408. write(gol,*)"Not using m7 - did not expected to be here."; call goErr
  3409. write(gol,*)" - make pres3d available"; call goErr
  3410. status=1; TRACEBACK; return
  3411. #endif
  3412. case default
  3413. write (gol,'("no such unit type",a)') RF%varid_type(k); call goErr
  3414. status=1
  3415. end select
  3416. ! IF_NOTOK_MDF(fid=RF%ncid)
  3417. ! ---------
  3418. case( ntracet+1:ntrace )
  3419. ! ---------
  3420. ! ----------------------------------------------------
  3421. ! distinguish between mixing ratios and concentrations
  3422. ! ----------------------------------------------------
  3423. select case( RF%varid_type(k) )
  3424. case( 'conc' )
  3425. ! write slab of concentrations
  3426. ! m(trace) pressure xm(trace)
  3427. ! C = -------- * fscale * ----------- * ---------
  3428. ! m(air) temperature Rgas
  3429. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  3430. ! reshape( chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr) / &
  3431. ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  3432. ! pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  3433. ! Rgas, (/imr,jmr,lmr,1/) ), &
  3434. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  3435. #ifdef with_m7
  3436. rf%data3d(:,:,:, rf%trec, k) = chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr) / &
  3437. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  3438. pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  3439. Rgas
  3440. #else
  3441. write(gol,*)"Not using m7 - did not expected to be here."; call goErr
  3442. write(gol,*)" - make pres3d available"; call goErr
  3443. status=1; TRACEBACK; return
  3444. #endif
  3445. case( 'mixr' )
  3446. ! write slab of volume mixing ratios
  3447. ! m(trace)
  3448. ! X = -------- * fscale
  3449. ! m(air)
  3450. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  3451. ! reshape( chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr)/ &
  3452. ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr), &
  3453. ! (/imr,jmr,lmr,1/) ), &
  3454. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  3455. rf%data3d(:,:,:, rf%trec, k) = chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr)/ &
  3456. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr)
  3457. case default
  3458. write (gol,'("no such unit type",a)') RF%varid_type(k); call goErr
  3459. status=1
  3460. end select
  3461. IF_NOTOK_MDF(fid=RF%ncid)
  3462. ! ---------
  3463. ! NOy and others (M7)
  3464. ! ---------
  3465. #ifdef with_m7
  3466. case( iNOy, iSO4, iBC, iPOM, iSS, iDU )
  3467. #else
  3468. case( iNOy )
  3469. #endif
  3470. listtrac(:) = -999
  3471. select case( itr )
  3472. case( iNOy ); numtrac = nNOyt; listtrac(1:nNOyt) = iNOyt
  3473. #ifdef with_m7
  3474. case( iSO4 ); numtrac = nSO4t; listtrac(1:nSO4t) = iSO4t
  3475. case( iBC ); numtrac = nBCt ; listtrac(1:nBCt ) = iBCt
  3476. case( iPOM ); numtrac = nPOMt; listtrac(1:nPOMt) = iPOMt
  3477. case( iSS ); numtrac = nSSt ; listtrac(1:nSSt ) = iSSt
  3478. case( iDU ); numtrac = nDUt ; listtrac(1:nDUt ) = iDUt
  3479. #endif
  3480. end select
  3481. ! mole fraction = sum of mole fractions of components
  3482. ! storage for sum of components (distributed over levels):
  3483. allocate( Compo_k(i1:i2,j1:j2,lmr) )
  3484. ! 3d fields with all levels or local levels only:
  3485. allocate( field_k(i1:i2,j1:j2,lmr) )
  3486. ! loop over transported components:
  3487. Compo_k = 0.0
  3488. do k_comp = 1, numtrac
  3489. ! no more components??
  3490. if( listtrac(k_comp) < 0 ) exit
  3491. ! global tracer index:
  3492. itr_comp = listtrac(k_comp)
  3493. ! check ...
  3494. if ( itr_comp > ntracet ) then
  3495. write (gol,'("index of NOy component does not represent a transported tracer : ",i3)') itr_comp; call goErr
  3496. TRACEBACK; status=1; return
  3497. end if
  3498. ! ----------------------------------------------------
  3499. ! distinguish between mixing ratios and concentrations
  3500. ! ----------------------------------------------------
  3501. select case( RF%varid_type(k) )
  3502. case( 'conc' )
  3503. ! calculate concentrations
  3504. ! m(trace) pressure xm(trace)
  3505. ! C = -------- * fscale * ----------- * ---------
  3506. ! m(air) temperature Rgas
  3507. #ifdef with_m7
  3508. field_k = mass_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr_comp) / &
  3509. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * &
  3510. xmair * 1.E-03 * pres3d(i1:i2,j1:j2,1:lmr) / &
  3511. temper_dat(region)%data(i1:i2,j1:j2,1:lmr) / Rgas
  3512. #else
  3513. write(gol,*)"Not using m7 - did not expected to be here."; call goErr
  3514. write(gol,*)" - make pres3d available"; call goErr
  3515. status=1; TRACEBACK; return
  3516. #endif
  3517. case( 'mixr' )
  3518. ! m(trace)
  3519. ! X = -------- * fscale
  3520. ! m(air)
  3521. field_k = mass_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr_comp) / &
  3522. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * &
  3523. fscale(itr_comp)
  3524. case default
  3525. write (gol,'("no such unit type",a)') RF%varid_type(k); call goErr
  3526. TRACEBACK; status=1; return
  3527. end select
  3528. ! add contribution of this component:
  3529. Compo_k = Compo_k + field_k
  3530. end do
  3531. ! write slab of volume mixing ratio's:
  3532. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  3533. ! reshape( Compo_k, (/imr,jmr,lmr,1/) ), &
  3534. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  3535. ! IF_NOTOK_MDF(fid=RF%ncid)
  3536. rf%data3d(:,:,:, rf%trec, k) = Compo_k
  3537. ! clear
  3538. deallocate( Compo_k )
  3539. deallocate( field_k )
  3540. ! -------------------
  3541. case default
  3542. ! -------------------
  3543. write (gol,'("strange tracer index requested : ",i6)') itr; call goErr
  3544. TRACEBACK; status=1; return
  3545. end select
  3546. #ifdef with_m7
  3547. endif
  3548. #endif
  3549. end do ! tracer
  3550. !----------------
  3551. ! WRITE
  3552. !----------------
  3553. if ( RF%trec == rf%n_rec ) then
  3554. call MDF_Put_Var( RF%ncid, RF%varid_time, rf%time, status)
  3555. IF_NOTOK_MDF(fid=RF%ncid)
  3556. call MDF_Put_Var( RF%ncid, RF%varid_date, rf%date, status)
  3557. IF_NOTOK_MDF(fid=RF%ncid)
  3558. ! surface presure
  3559. call MDF_Put_Var( RF%ncid, RF%varid_ps, rf%sp, status, start=(/i1,j1,1/) )
  3560. IF_NOTOK_MDF(fid=RF%ncid)
  3561. ! temperature (3d)
  3562. call MDF_Put_Var( RF%ncid, RF%varid_temp, RF%data3d_t(:,:,:,:), status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,RF%n_rec/) )
  3563. IF_NOTOK_MDF(fid=RF%ncid)
  3564. #ifdef tropomi
  3565. if ( isRoot ) then
  3566. write (gol,'(a,2i4)') 'PDUMP - writing fields T, hgt, ltropo, no2, so2, hcho; trec, n_rec ', RF%trec, rf%n_rec
  3567. call goPr
  3568. end if
  3569. ! temperature (3d)
  3570. call MDF_Put_Var( RF%ncid, RF%varid_temp, RF%data3d_t(:,:,:,:), status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,RF%n_rec/) )
  3571. IF_NOTOK_MDF(fid=RF%ncid)
  3572. ! surface altitude (2d)
  3573. call MDF_Put_Var( RF%ncid, RF%varid_hgt, RF%data2d_hgt(:,:), status, start=(/i1,j1/), count=(/imr,jmr/) )
  3574. IF_NOTOK_MDF(fid=RF%ncid)
  3575. ! highest tropopause level (2d)
  3576. call MDF_Put_Var( RF%ncid, RF%varid_ltropo, RF%data2d_ltropo(:,:,:), status, start=(/i1,j1,1/), count=(/imr,jmr,RF%n_rec/) )
  3577. IF_NOTOK_MDF(fid=RF%ncid)
  3578. #endif
  3579. ! vmr
  3580. do k = 1, RF%ntr
  3581. call MDF_Put_Var( RF%ncid, RF%varid_tr(k), RF%data3d(:,:,:,:,k), status, start=(/i1,j1,1,1/) )
  3582. IF_NOTOK_MDF(fid=RF%ncid)
  3583. end do
  3584. end if
  3585. !----------------
  3586. ! DONE
  3587. !----------------
  3588. #ifdef with_m7
  3589. deallocate(pres3d)
  3590. #endif
  3591. call goLabel()
  3592. status = 0
  3593. END SUBROUTINE RF_VMR_Write
  3594. !EOC
  3595. !--------------------------------------------------------------------------
  3596. ! TM5 !
  3597. !--------------------------------------------------------------------------
  3598. !BOP
  3599. !
  3600. ! !IROUTINE: RF_VMR_Done
  3601. !
  3602. ! !DESCRIPTION: close file #3
  3603. !\\
  3604. !\\
  3605. ! !INTERFACE:
  3606. !
  3607. SUBROUTINE RF_VMR_Done( RF, status )
  3608. !
  3609. ! !INPUT/OUTPUT PARAMETERS:
  3610. !
  3611. type(TPdumpFile_VMR), intent(inout) :: RF
  3612. !
  3613. ! !OUTPUT PARAMETERS:
  3614. !
  3615. integer, intent(out) :: status
  3616. !
  3617. ! !REVISION HISTORY:
  3618. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  3619. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  3620. !
  3621. !EOP
  3622. !------------------------------------------------------------------------
  3623. !BOC
  3624. character(len=*), parameter :: rname = mname//'/RF_VMR_Done'
  3625. ! --- begin -------------------------------------
  3626. call goLabel(rname)
  3627. call MDF_Close( RF%ncid, status )
  3628. IF_NOTOK_RETURN(status=1)
  3629. deallocate(rf%date, rf%time, rf%sp, rf%data3d )
  3630. deallocate(rf%data3d_t)
  3631. #ifdef tropomi
  3632. deallocate(rf%data2d_hgt)
  3633. deallocate(rf%data2d_ltropo)
  3634. #endif
  3635. call goLabel() ; status = 0
  3636. END SUBROUTINE RF_VMR_Done
  3637. !EOC
  3638. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3639. ! FILE: 2D LT output
  3640. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3641. !--------------------------------------------------------------------------
  3642. ! TM5 !
  3643. !--------------------------------------------------------------------------
  3644. !BOP
  3645. !
  3646. ! !IROUTINE: RF_LT_Init
  3647. !
  3648. ! !DESCRIPTION:
  3649. !\\
  3650. !\\
  3651. ! !INTERFACE:
  3652. !
  3653. subroutine RF_LT_Init( RF, fdir, model, expid, filetype, region, &
  3654. idate_f, local_time, tracer_names, status )
  3655. !
  3656. ! !USES:
  3657. !
  3658. use Binas, only : xmair
  3659. use GO, only : goReadFromLine, goUpCase
  3660. use GO, only : NewDate
  3661. use dims, only : im, jm
  3662. use chem_param, only : ntrace, names, ra
  3663. use partools, only : MPI_INFO_NULL, localComm
  3664. use MeteoData, only : global_lli, levi, sp_dat, Set
  3665. !
  3666. ! !OUTPUT PARAMETERS:
  3667. !
  3668. type(TPdumpFile_LT), intent(out) :: RF
  3669. !
  3670. ! !INPUT PARAMETERS:
  3671. !
  3672. character(len=*), intent(in) :: fdir
  3673. character(len=*), intent(in) :: model
  3674. character(len=*), intent(in) :: expid
  3675. character(len=*), intent(in) :: filetype
  3676. integer, intent(in) :: region
  3677. integer, intent(in) :: idate_f(6)
  3678. integer, intent(in) :: local_time
  3679. character(len=*), intent(in) :: tracer_names
  3680. integer, intent(out) :: status
  3681. !
  3682. ! !REVISION HISTORY:
  3683. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  3684. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  3685. !
  3686. !EOP
  3687. !------------------------------------------------------------------------
  3688. !BOC
  3689. character(len=*), parameter :: rname = mname//'/RF_LT_Init'
  3690. ! --- local ------------------------------------
  3691. character(len=256) :: fname
  3692. integer :: varid
  3693. integer :: imr, jmr, lmr
  3694. character(len=256) :: trnames
  3695. character(len=8) :: trname, tmname
  3696. character(len=3) :: cwavel
  3697. integer :: k, itr, i1, i2, j1, j2
  3698. character(len=32) :: varname, varname_enti, varname_spec
  3699. character(len=64) :: cf_medium_stnd, cf_medium_long
  3700. character(len=64) :: cf_enti_stnd, cf_enti_long, cf_enti_unit
  3701. character(len=64) :: cf_spec_stnd, cf_spec_long
  3702. character(len=256) :: cf_name_stnd, cf_name_long, cf_name_unit
  3703. character(len=512) :: comment
  3704. ! --- begin -------------------------------------
  3705. call goLabel(rname)
  3706. ! store arguments
  3707. RF%local_time = local_time
  3708. RF%tracer_names = tracer_names
  3709. ! set tracer index for requested tracers:
  3710. write (gol,'("selected tracers for LT output:")'); call goPr
  3711. RF%ntr = 0
  3712. #ifdef with_m7
  3713. RF%laod = .false.
  3714. RF%wavel = -1.0
  3715. #endif
  3716. RF%itr = -1
  3717. trnames = tracer_names
  3718. do
  3719. ! empty ?
  3720. if ( len_trim(trnames) == 0 ) exit
  3721. ! next number:
  3722. if ( RF%ntr == ntrace ) then
  3723. write (gol,'("number of elements in tracer names list exceeds ntrace=",i6)') ntrace; call goErr
  3724. TRACEBACK; status=1; return
  3725. end if
  3726. RF%ntr = RF%ntr + 1
  3727. ! extract leading name:
  3728. call goReadFromLine( trnames, trname, status, sep=' ' )
  3729. IF_NOTOK_RETURN(status=1)
  3730. #ifdef with_m7
  3731. ! ---------------------------
  3732. ! check for AOD
  3733. ! ---------------------------
  3734. if( strlowercase(trname(1:3)) == 'aod' ) then
  3735. RF%laod(RF%ntr) = .true.
  3736. RF%itr (RF%ntr) = -1
  3737. ! paste size to real
  3738. read(trname(5:len_trim(trname)), * ) RF%wavel(RF%ntr)
  3739. else
  3740. #endif
  3741. ! convert to tm5 name:
  3742. select case ( trim(strlowercase(trname)) )
  3743. case ( 'hcho' ) ; tmname = 'CH2O'
  3744. case ( 'rn', 'radon' ) ; tmname = 'Rn222'
  3745. case ( 'pb', 'lead' ) ; tmname = 'Pb210'
  3746. case default ; tmname = trname
  3747. end select
  3748. ! NOy is a special ...
  3749. select case ( trim(strlowercase(tmname)) )
  3750. case ( 'NOy' )
  3751. ! defined as ntrace+1
  3752. RF%itr(RF%ntr) = iNOy
  3753. write (gol,'(" * ",a10)') trim(trname); call goPr
  3754. case default
  3755. ! loop over all names:
  3756. RF%itr(RF%ntr) = -1
  3757. do itr = 1, ntrace
  3758. ! case indendent match ?
  3759. if ( goUpCase(trim(tmname)) == goUpCase(trim(names(itr))) ) then
  3760. write (gol,'(" ",i3," ",a10," (",a10,") ",f12.4)') itr, trim(trname), trim(names(itr)), ra(itr); call goPr
  3761. RF%itr(RF%ntr) = itr
  3762. exit
  3763. end if
  3764. end do
  3765. end select ! not found ?
  3766. if ( RF%itr(RF%ntr) < 0 ) then
  3767. write (gol,'("tracer name not supported:")'); call goPr
  3768. write (gol,'(" list all : ",a)') trim(tracer_names); call goPr
  3769. write (gol,'(" list element : ",i3)') RF%ntr; call goPr
  3770. write (gol,'(" pdump name : ",a)') trim(trname); call goPr
  3771. write (gol,'(" tm5 name : ",a)') trim(tmname); call goPr
  3772. write (gol,'(" tm5 tracers : ")'); call goPr
  3773. do itr = 1, ntrace
  3774. write (gol,'(" ",i3," ",a)') itr, trim(names(itr)); call goPr
  3775. end do
  3776. TRACEBACK; status=1; return
  3777. end if
  3778. #ifdef with_m7
  3779. end if ! aod
  3780. #endif
  3781. ! store pdump name:
  3782. RF%name_tr(RF%ntr) = trname
  3783. end do
  3784. ! empty file ?
  3785. if ( RF%ntr < 1 ) then
  3786. write (gol,'("no tracers extracted from list :",a)') tracer_names; call goErr
  3787. TRACEBACK; status=1; return
  3788. end if
  3789. ! grid size
  3790. imr = global_lli(region)%nlon
  3791. jmr = global_lli(region)%nlat
  3792. lmr = levi%nlev
  3793. ! o open file
  3794. ! write filename
  3795. write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
  3796. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), trim(filetype), idate_f(1:3)
  3797. ! open:
  3798. #ifdef MPI
  3799. ! overwrite existing files (clobber), provide MPI stuff:
  3800. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  3801. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  3802. if (status/=0) then
  3803. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  3804. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  3805. TRACEBACK; status=1; return
  3806. end if
  3807. #else
  3808. ! overwrite existing files (clobber)
  3809. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  3810. IF_NOTOK_RETURN(status=1)
  3811. #endif
  3812. ! o global attributes
  3813. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title' , 'local time output' , status)
  3814. IF_NOTOK_MDF(fid=RF%ncid)
  3815. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
  3816. IF_NOTOK_MDF(fid=RF%ncid)
  3817. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
  3818. IF_NOTOK_MDF(fid=RF%ncid)
  3819. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status)
  3820. IF_NOTOK_MDF(fid=RF%ncid)
  3821. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'file_version_number', trim(outfileversnr) , status)
  3822. IF_NOTOK_MDF(fid=RF%ncid)
  3823. ! o define dimensions
  3824. call MDF_Def_Dim( RF%ncid, 'lon' , global_lli(region)%nlon, RF%dimid_lon , status)
  3825. IF_NOTOK_MDF(fid=RF%ncid)
  3826. call MDF_Def_Dim( RF%ncid, 'lat' , global_lli(region)%nlat, RF%dimid_lat , status)
  3827. IF_NOTOK_MDF(fid=RF%ncid)
  3828. call MDF_Def_Dim( RF%ncid, 'lev' , levi%nlev , RF%dimid_lev , status)
  3829. IF_NOTOK_MDF(fid=RF%ncid)
  3830. call MDF_Def_Dim( RF%ncid, 'time' , 1 , RF%dimid_time , status)
  3831. IF_NOTOK_MDF(fid=RF%ncid)
  3832. call MDF_Def_Dim( RF%ncid, 'datelen', 6 , RF%dimid_datelen, status)
  3833. IF_NOTOK_MDF(fid=RF%ncid)
  3834. ! o define variables
  3835. call MDF_Def_Var( RF%ncid, 'lon', mdf_float, (/RF%dimid_lon/), varid , status)
  3836. IF_NOTOK_MDF(fid=RF%ncid)
  3837. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  3838. IF_NOTOK_MDF(fid=RF%ncid)
  3839. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  3840. IF_NOTOK_MDF(fid=RF%ncid)
  3841. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'longitude' , status)
  3842. IF_NOTOK_MDF(fid=RF%ncid)
  3843. call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_east', status)
  3844. IF_NOTOK_MDF(fid=RF%ncid)
  3845. RF%varid_lon = varid
  3846. call MDF_Def_Var( RF%ncid, 'lat', mdf_float, (/RF%dimid_lat/), varid , status)
  3847. IF_NOTOK_MDF(fid=RF%ncid)
  3848. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  3849. IF_NOTOK_MDF(fid=RF%ncid)
  3850. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  3851. IF_NOTOK_MDF(fid=RF%ncid)
  3852. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'latitude' , status)
  3853. IF_NOTOK_MDF(fid=RF%ncid)
  3854. call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_north', status)
  3855. IF_NOTOK_MDF(fid=RF%ncid)
  3856. RF%varid_lat = varid
  3857. call MDF_Def_Var( RF%ncid, 'lev', mdf_float, (/RF%dimid_lev/), varid , status)
  3858. IF_NOTOK_MDF(fid=RF%ncid)
  3859. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  3860. IF_NOTOK_MDF(fid=RF%ncid)
  3861. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
  3862. IF_NOTOK_MDF(fid=RF%ncid)
  3863. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'level' , status)
  3864. IF_NOTOK_MDF(fid=RF%ncid)
  3865. call MDF_Put_Att( RF%ncid, varid, 'units' , '1' , status)
  3866. IF_NOTOK_MDF(fid=RF%ncid)
  3867. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a_bnds(k)*p0 + b_bnds(k)*ps(n,j,i)' , status)
  3868. IF_NOTOK_MDF(fid=RF%ncid)
  3869. RF%varid_lev = varid
  3870. call MDF_Def_Var( RF%ncid, 'time', mdf_float, (/RF%dimid_time/), varid , status)
  3871. IF_NOTOK_MDF(fid=RF%ncid)
  3872. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  3873. IF_NOTOK_MDF(fid=RF%ncid)
  3874. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
  3875. IF_NOTOK_MDF(fid=RF%ncid)
  3876. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'time' , status)
  3877. IF_NOTOK_MDF(fid=RF%ncid)
  3878. call MDF_Put_Att( RF%ncid, varid, 'units' , 'days since 1950-01-01 00:00:00', status)
  3879. IF_NOTOK_MDF(fid=RF%ncid)
  3880. call MDF_Put_Att( RF%ncid, varid, 'calender' , 'gregorian' , status)
  3881. IF_NOTOK_MDF(fid=RF%ncid)
  3882. RF%varid_time = varid
  3883. call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  3884. IF_NOTOK_MDF(fid=RF%ncid)
  3885. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  3886. IF_NOTOK_MDF(fid=RF%ncid)
  3887. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
  3888. IF_NOTOK_MDF(fid=RF%ncid)
  3889. call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
  3890. IF_NOTOK_MDF(fid=RF%ncid)
  3891. RF%varid_date = varid
  3892. call MDF_Def_Var( RF%ncid, 'ps', MDF_FLOAT, &
  3893. (/RF%dimid_lon,RF%dimid_lat,RF%dimid_time/), varid, status )
  3894. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  3895. IF_NOTOK_MDF(fid=RF%ncid)
  3896. IF_NOTOK_MDF(fid=RF%ncid)
  3897. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'surface_air_pressure', status)
  3898. IF_NOTOK_MDF(fid=RF%ncid)
  3899. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'surface pressure' , status)
  3900. IF_NOTOK_MDF(fid=RF%ncid)
  3901. call MDF_Put_Att( RF%ncid, varid, 'units' , 'Pa' , status)
  3902. IF_NOTOK_MDF(fid=RF%ncid)
  3903. RF%varid_ps = varid
  3904. ! CF standard name for medium:
  3905. cf_medium_stnd = 'in_air' ; cf_medium_long = 'in humid air'
  3906. ! loop over tracer to be written:
  3907. do k = 1, RF%ntr
  3908. #ifdef with_m7
  3909. if( RF%laod(k) ) then
  3910. ! get diameter
  3911. write(cwavel,'(I3)') RF%wavel(k)
  3912. ! Aerosol Optical Depth (AOD):
  3913. varname_spec = 'AOD@'//trim(cwavel)
  3914. cf_spec_stnd = 'AOD at '//trim(cwavel)//'nm'
  3915. cf_spec_long = 'aerosol optical depth at '//trim(cwavel)//' nanometer'
  3916. cf_enti_stnd = 'aerosol_optical_depth'
  3917. cf_enti_unit = '1'
  3918. cf_enti_long = 'aerosol optical depth'
  3919. else
  3920. #endif
  3921. ! global tracer index
  3922. itr = RF%itr(k)
  3923. ! ~~ local time species info
  3924. ! CF standard name for concentration/mixing ratio/column:
  3925. cf_enti_stnd = 'mole_fraction'
  3926. cf_enti_unit = 'mole mole-1'
  3927. cf_enti_long = 'volume mixing ratio'
  3928. ! start of dataset name:
  3929. varname_enti = 'dry'
  3930. ! no comment yet
  3931. comment = ''
  3932. ! standard names from CF conventions:
  3933. select case ( RF%name_tr(k) )
  3934. case ( 'CO', 'co' )
  3935. varname_spec = 'co'
  3936. cf_spec_stnd = 'carbon_monoxide'
  3937. cf_spec_long = 'CO'
  3938. case ( 'O3', 'o3' )
  3939. varname_spec = 'o3'
  3940. cf_spec_stnd = 'ozone'
  3941. cf_spec_long = 'O3'
  3942. case ( 'O3s', 'o3s' )
  3943. varname_spec = 'o3s'
  3944. cf_spec_stnd = 'ozone_from_stratosphere'
  3945. cf_spec_long = 'O3s'
  3946. case ( 'NO', 'no' )
  3947. varname_spec = 'no'
  3948. cf_spec_stnd = 'nitrogen_monoxide'
  3949. cf_spec_long = 'NO'
  3950. case ( 'NO2', 'no2' )
  3951. varname_spec = 'no2'
  3952. cf_spec_stnd = 'nitrogen_dioxide'
  3953. cf_spec_long = 'NO2'
  3954. case ( 'NOy', 'noy' )
  3955. varname_spec = 'noy'
  3956. cf_spec_stnd = 'all_nitrogen_oxides_as_nitrogen'
  3957. cf_spec_long = 'NOy'
  3958. comment = 'NOy = NOx + HNO3 + PAN + org.ntr., '// &
  3959. 'with NOx = NO + NO2 + NO3 + HNO4 + N2O5'
  3960. case ( 'CH2O', 'ch2o', 'CHOH', 'choh' )
  3961. varname_spec = 'ch2o'
  3962. cf_spec_stnd = 'formaldehyde'
  3963. cf_spec_long = 'CH2O'
  3964. case ( 'SO2', 'so2' )
  3965. varname_spec = 'so2'
  3966. cf_spec_stnd = 'sulfur_dioxide'
  3967. cf_spec_long = 'SO2'
  3968. case ( 'CH4', 'ch4' )
  3969. varname_spec = 'ch4'
  3970. cf_spec_stnd = 'methane'
  3971. cf_spec_long = 'CH4'
  3972. case ( 'OH', 'oh' )
  3973. varname_spec = 'oh'
  3974. cf_spec_stnd = 'hydroxyl_radical'
  3975. cf_spec_long = 'OH'
  3976. case ( 'H2O2', 'h2o2' )
  3977. varname_spec = 'h2o2'
  3978. cf_spec_stnd = 'hydrogen_peroxide'
  3979. cf_spec_long = 'H2O2'
  3980. case ( 'HNO3', 'hno3' )
  3981. varname_spec = 'hno3'
  3982. cf_spec_stnd = 'nitric_acid'
  3983. cf_spec_long = 'HNO3'
  3984. case ( 'NH3', 'nh3' )
  3985. varname_spec = 'nh3'
  3986. cf_spec_stnd = 'ammonia'
  3987. cf_spec_long = 'NH3'
  3988. case ( 'NH4', 'nh4' )
  3989. varname_spec = 'nh4'
  3990. cf_spec_stnd = 'ammonium'
  3991. cf_spec_long = 'NH4'
  3992. case ( 'ORGNTR','orgntr' )
  3993. varname_spec = 'orgntr'
  3994. cf_spec_stnd = 'organic_nitrate'
  3995. cf_spec_long = 'ORGNTR'
  3996. case ( 'PAN', 'pan' )
  3997. varname_spec = 'pan'
  3998. cf_spec_stnd = 'peroxyacetyl_nitrate'
  3999. cf_spec_long = 'PAN'
  4000. case ( 'Rn', 'rn', 'Radon', 'radon' )
  4001. varname_spec = 'rn'
  4002. cf_spec_stnd = 'radon'
  4003. cf_spec_long = 'Rn'
  4004. case ( 'Pb', 'pb', 'Lead', 'lead' )
  4005. varname_spec = 'pb'
  4006. cf_spec_stnd = 'lead'
  4007. cf_spec_long = 'Pb'
  4008. case default
  4009. write (gol,'("do not know how to match tracer with CF standard names : ",a)') RF%name_tr(k); call goPr
  4010. TRACEBACK; status=1; return
  4011. end select
  4012. #ifdef with_m7
  4013. end if ! RF%laod(k)
  4014. #endif
  4015. ! define variable:
  4016. call MDF_Def_Var( RF%ncid, trim(varname_spec), MDF_FLOAT, &
  4017. (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid, status )
  4018. IF_NOTOK_MDF(fid=RF%ncid)
  4019. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  4020. IF_NOTOK_MDF(fid=RF%ncid)
  4021. ! total names:
  4022. cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)//'_'//trim(cf_medium_stnd)
  4023. cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)//' '//trim(cf_medium_long)
  4024. cf_name_unit = trim(cf_enti_unit)
  4025. ! write attributes:
  4026. call MDF_Put_Att( RF%ncid, varid, 'standard_name', trim(cf_name_stnd) , status)
  4027. IF_NOTOK_MDF(fid=RF%ncid)
  4028. call MDF_Put_Att( RF%ncid, varid, 'long_name', trim(cf_name_long) , status)
  4029. IF_NOTOK_MDF(fid=RF%ncid)
  4030. call MDF_Put_Att( RF%ncid, varid, 'units', trim(cf_name_unit) , status)
  4031. IF_NOTOK_MDF(fid=RF%ncid)
  4032. if ( itr <= ntrace .and. itr > 0 ) then
  4033. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', ra(itr)*1e3 , status)
  4034. IF_NOTOK_MDF(fid=RF%ncid)
  4035. else
  4036. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', -1.0 , status)
  4037. IF_NOTOK_MDF(fid=RF%ncid)
  4038. end if
  4039. call MDF_Put_Att( RF%ncid, varid, 'moleweight_air', xmair*1e3 , status)
  4040. IF_NOTOK_MDF(fid=RF%ncid)
  4041. call MDF_Put_Att( RF%ncid, varid, 'moleweight_unit', 'kg mole-1' , status)
  4042. IF_NOTOK_MDF(fid=RF%ncid)
  4043. if ( len_trim(comment) > 0 ) then
  4044. call MDF_Put_Att( RF%ncid, varid, 'comment', trim(comment) , status)
  4045. IF_NOTOK_MDF(fid=RF%ncid)
  4046. end if
  4047. ! store varid
  4048. RF%varid_tr(k) = varid
  4049. end do
  4050. ! o end defintion mode
  4051. call MDF_EndDef( RF%ncid , status)
  4052. IF_NOTOK_MDF(fid=RF%ncid)
  4053. ! no records written yet
  4054. RF%trec = 0
  4055. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  4056. allocate(RF%accu (i1:i2, j1:j2, 1:lmr, RF%ntr)) ; RF%accu = 0
  4057. allocate(RF%naccu (i1:i2, RF%ntr )) ; RF%naccu = 0
  4058. allocate(RF%p_accu (i1:i2, j1:j2 )) ; RF%p_accu = 0
  4059. allocate(RF%np_accu(i1:i2 )) ; RF%np_accu = 0
  4060. call goLabel()
  4061. status = 0
  4062. END SUBROUTINE RF_LT_Init
  4063. !EOC
  4064. !--------------------------------------------------------------------------
  4065. ! TM5 !
  4066. !--------------------------------------------------------------------------
  4067. !BOP
  4068. !
  4069. ! !IROUTINE: RF_LT_Write
  4070. !
  4071. ! !DESCRIPTION: does not write anything, just get
  4072. !\\
  4073. !\\
  4074. ! !INTERFACE:
  4075. !
  4076. SUBROUTINE RF_LT_Write( RF, region, idate_f, status )
  4077. !
  4078. ! !USES:
  4079. !
  4080. use GO, only : TDate, NewDate, Set, iTotal, rTotal, operator(-), wrtgol
  4081. use chem_param, only : ntrace, ntracet, fscale
  4082. use tracer_data, only : mass_dat, chem_dat
  4083. use MeteoData, only : global_lli, levi, m_dat, sp_dat
  4084. !
  4085. ! !INPUT/OUTPUT PARAMETERS:
  4086. !
  4087. type(TPdumpFile_LT), intent(inout) :: RF
  4088. !
  4089. ! !INPUT PARAMETERS:
  4090. !
  4091. integer, intent(in) :: region
  4092. integer, intent(in) :: idate_f(6)
  4093. !
  4094. ! !OUTPUT PARAMETERS:
  4095. !
  4096. integer, intent(out) :: status
  4097. !
  4098. ! !REVISION HISTORY:
  4099. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  4100. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  4101. !
  4102. !EOP
  4103. !------------------------------------------------------------------------
  4104. !BOC
  4105. character(len=*), parameter :: rname = mname//'/RF_LT_Write'
  4106. ! --- local ------------------------------------
  4107. integer :: imr, jmr, lmr, gimr, i1, i2, j1, j2
  4108. real, allocatable :: lev(:)
  4109. real, allocatable :: field_out(:,:,:)
  4110. real, allocatable :: field_out_b(:,:)
  4111. integer :: l, ls, le
  4112. type(TDate) :: t, t0
  4113. real :: time
  4114. real :: dt_sec
  4115. integer :: i, j, k, itr
  4116. integer(kind=8) :: itau
  4117. integer :: loctim, gridboxtimestep
  4118. integer :: iloctim,itautoday,ilon
  4119. integer :: icomp, itr_loc, ncells, window
  4120. ! --- begin -------------------------------------
  4121. ! for multiple of dhour only ...
  4122. ! if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
  4123. ! status=0; return
  4124. ! end if
  4125. call goLabel(rname)
  4126. ! grid size
  4127. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  4128. imr=i2-i1+1
  4129. jmr=j2-j1+1
  4130. gimr = global_lli(region)%nlon
  4131. ! gjmr = global_lli(region)%nlat
  4132. lmr = levi%nlev
  4133. ! next time record:
  4134. RF%trec = RF%trec + 1
  4135. if(okdebug)then
  4136. write(gol,*) "RF_LT_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
  4137. end if
  4138. ! grid index offsets for GMT and local time
  4139. loctim=RF%local_time
  4140. if( loctim < 0 ) loctim=loctim+24*3600
  4141. ! time since 1950-1-1 00:00
  4142. t0 = NewDate( time6=time_reftime6 )
  4143. t = NewDate( time6=idate_f )
  4144. call SET( t, hour=0, min=0, sec=0 )
  4145. time = rTotal( t - t0, 'day' ) + loctim / 86400.
  4146. !
  4147. ! ~~ time, grid
  4148. !
  4149. ! only once ...
  4150. if ( RF%trec == 1 ) then
  4151. ! write longitudes:
  4152. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
  4153. IF_NOTOK_MDF(fid=RF%ncid)
  4154. ! write latitudes:
  4155. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
  4156. IF_NOTOK_MDF(fid=RF%ncid)
  4157. ! write level indices:
  4158. allocate( lev(lmr) )
  4159. do l = 1, lmr
  4160. lev(l) = real(l)
  4161. end do
  4162. call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
  4163. IF_NOTOK_MDF(fid=RF%ncid)
  4164. deallocate(lev)
  4165. ! time:
  4166. call MDF_Put_Var( RF%ncid, RF%varid_time, (/time/) , status, start=(/RF%trec/))
  4167. IF_NOTOK_MDF(fid=RF%ncid)
  4168. ! date:
  4169. call MDF_Put_Var( RF%ncid, RF%varid_date, reshape(real(idate_f),(/6,1/)), status, &
  4170. start=(/1,1/), count=(/6,1/) )
  4171. IF_NOTOK_MDF(fid=RF%ncid)
  4172. end if ! first record
  4173. !
  4174. ! local time
  4175. !
  4176. if ( RF%trec > 1 ) then ! do not accumulate fields on 00:00
  4177. ! grid index offsets for GMT and local time
  4178. loctim=RF%local_time
  4179. if( loctim < 0 ) loctim=loctim+24*3600
  4180. gridboxtimestep=24*3600/gimr
  4181. itau = idate_f(4)*3600+idate_f(5)*60+idate_f(6)
  4182. itautoday= nint(real(mod(itau,24*3600)*gimr)/real(24*3600))
  4183. iloctim = nint(real(loctim *gimr)/real(24*3600))
  4184. ! determine longitude index wrt Greenwich from difference (local time - GMT)
  4185. ! also process neigboring longitudes (i-2 , i-1 , i , i+1 , i+2) depending on
  4186. ! number of longitudinal grid cells
  4187. ncells = ceiling( gimr / 24. )
  4188. window = ceiling( ncells / 2. )
  4189. do ilon = 1, ncells
  4190. i = 1 + mod( gimr + gimr/2 + iloctim - itautoday + (ilon - window),gimr )
  4191. if (i .ge. i1 .and. i.le. i2) then
  4192. RF%p_accu(i,j1:j2)= RF%p_accu(i,j1:j2)+sp_dat(region)%data(i,j1:j2,1)
  4193. RF%np_accu(i)= RF%np_accu(i)+1
  4194. ! loop over tracers to be written:
  4195. do k = 1, RF%ntr
  4196. ! global tracer index:
  4197. itr = RF%itr(k)
  4198. !!$#ifdef with_m7
  4199. !!$
  4200. !!$ ! ---------------------
  4201. !!$ ! AOD
  4202. !!$ ! ---------------------
  4203. !!$ if( RF%laod(k) ) then
  4204. !!$
  4205. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4206. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4207. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4208. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4209. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4210. !!$ allocate( ....... ) )
  4211. !!$
  4212. !!$ call PMx_Integrate_3d( region, RF%sizepmx(k), pmx, status )
  4213. !!$ IF_NOTOK_RETURN(status=1)
  4214. !!$
  4215. !!$ ! root only:
  4216. !!$ if ( myid == root ) then
  4217. !!$
  4218. !!$ status = pnf90_put_var( RF%ncid, RF%varid_tr(k), &
  4219. !!$ reshape( pmx(ims:ime,jms:jme,lms:lme), (/imr,jmr,lmr,1/) ), &
  4220. !!$ start=(/1,1,1,RF%trec/), count=(/imr,jmr,lmr,1/) )
  4221. !!$
  4222. !!$ end if
  4223. !!$
  4224. !!$ deallocate( ............. )
  4225. !!$
  4226. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4227. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4228. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4229. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4230. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4231. !!$ ! .............. PUT HERE THE CODE FOR AOD ..................!
  4232. !!$ else
  4233. !!$
  4234. !!$#endif
  4235. ! transported or chemistry only ?
  4236. if ( (itr >= 1) .and. (itr <= ntracet) ) then
  4237. RF%accu(i,j1:j2,1:lmr,k)= RF%accu(i,j1:j2,1:lmr,k)+&
  4238. (mass_dat(region)%rm(i,j1:j2,1:lmr,itr)/ &
  4239. m_dat(region)%data(i,j1:j2,1:lmr))*fscale(itr)
  4240. RF%naccu(i,k)=RF%naccu(i,k)+1
  4241. else if ( (itr >= ntracet+1) .and. (itr <= ntrace) ) then
  4242. RF%accu(i,j1:j2,1:lmr,k)= RF%accu(i,j1:j2,1:lmr,k)+&
  4243. (chem_dat(region)%rm(i,j1:j2,1:lmr,itr)/ &
  4244. m_dat(region)%data(i,j1:j2,1:lmr))*fscale(itr)
  4245. RF%naccu(i,k)=RF%naccu(i,k)+1
  4246. end if
  4247. enddo
  4248. endif
  4249. enddo
  4250. endif ! do not accumulate fields on 00:00
  4251. call goLabel(); status = 0
  4252. END SUBROUTINE RF_LT_Write
  4253. !EOC
  4254. !--------------------------------------------------------------------------
  4255. ! TM5 !
  4256. !--------------------------------------------------------------------------
  4257. !BOP
  4258. !
  4259. ! !IROUTINE: RF_LT_Done
  4260. !
  4261. ! !DESCRIPTION: write final data, then close file #4
  4262. !\\
  4263. !\\
  4264. ! !INTERFACE:
  4265. !
  4266. SUBROUTINE RF_LT_Done( RF, region, status )
  4267. !
  4268. ! !USES:
  4269. !
  4270. use MeteoData, only : global_lli, levi
  4271. !
  4272. ! !INPUT/OUTPUT PARAMETERS:
  4273. !
  4274. type(TPdumpFile_LT), intent(inout) :: RF
  4275. !
  4276. ! !INPUT PARAMETERS:
  4277. !
  4278. integer, intent(in) :: region
  4279. !
  4280. ! !OUTPUT PARAMETERS:
  4281. !
  4282. integer, intent(out) :: status
  4283. !
  4284. ! !REVISION HISTORY:
  4285. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  4286. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  4287. ! - move averaging & writing here
  4288. !
  4289. !EOP
  4290. !------------------------------------------------------------------------
  4291. !BOC
  4292. character(len =*), parameter :: rname = mname//'/RF_LT_Done'
  4293. integer :: imr, jmr
  4294. real, allocatable :: field_out(:,:,:)
  4295. real, allocatable :: field_out_b(:,:)
  4296. integer :: i, ls, le, k, itr, i1, i2, j1, j2, lmr
  4297. ! --- begin -------------------------------------
  4298. call goLabel(rname)
  4299. !---------------------
  4300. ! average & write data
  4301. !---------------------
  4302. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  4303. imr=i2-i1+1
  4304. jmr=j2-j1+1
  4305. lmr = levi%nlev
  4306. allocate(field_out_b(i1:i2,j1:j2)); field_out_b = 0.0
  4307. do i = i1, i2
  4308. if (RF%np_accu(i).gt.0) then
  4309. field_out_b(i,:) =RF%p_accu(i,:)/RF%np_accu(i)
  4310. endif
  4311. enddo
  4312. call MDF_Put_Var( RF%ncid, RF%varid_ps, reshape(field_out_b(i1:i2,j1:j2), &
  4313. (/imr,jmr,1/) ), status, start=(/i1,j1,1/), count=(/imr,jmr,1/) )
  4314. IF_NOTOK_MDF(fid=RF%ncid)
  4315. deallocate(field_out_b)
  4316. TRACERS: do k = 1, RF%ntr
  4317. ! global tracer index:
  4318. itr = RF%itr(k)
  4319. if ( (itr >= 1) .and. (itr <= ntrace) ) then
  4320. ! normalize fields, if necessary
  4321. allocate(field_out(i1:i2,j1:j2,1:lmr)); field_out = 0.0
  4322. do i = i1,i2
  4323. if (RF%naccu(i,k).gt.0) then
  4324. field_out(i,:,1:lmr) =RF%accu(i,:,1:lmr,k)/RF%naccu(i,k)
  4325. endif
  4326. enddo
  4327. ! write fields:
  4328. call MDF_Put_Var( RF%ncid, RF%varid_tr(k) , &
  4329. reshape(field_out(i1:i2,j1:j2,1:lmr) , &
  4330. (/imr,jmr,lmr,1/) ) , &
  4331. status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,1/) )
  4332. IF_NOTOK_MDF(fid=RF%ncid)
  4333. deallocate(field_out)
  4334. endif
  4335. end do TRACERS
  4336. !---------------------
  4337. ! DONE
  4338. !---------------------
  4339. call MDF_Close( RF%ncid , status)
  4340. IF_NOTOK_RETURN(status=1)
  4341. deallocate(RF%accu)
  4342. deallocate(RF%naccu)
  4343. deallocate(RF%p_accu)
  4344. deallocate(RF%np_accu)
  4345. call goLabel() ; status = 0
  4346. END SUBROUTINE RF_LT_Done
  4347. !EOC
  4348. #ifdef with_budgets
  4349. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4350. ! FILE ##5 : 2D dry and wet deposition fields
  4351. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4352. !--------------------------------------------------------------------------
  4353. ! TM5 !
  4354. !--------------------------------------------------------------------------
  4355. !BOP
  4356. !
  4357. ! !IROUTINE: RF_DEPS_Init
  4358. !
  4359. ! !DESCRIPTION:
  4360. !\\
  4361. !\\
  4362. ! !INTERFACE:
  4363. !
  4364. subroutine RF_DEPS_Init( RF, fdir, model, expid, filetype, region, &
  4365. idate_f, dhour, tracer_names, status )
  4366. !
  4367. ! !USES:
  4368. !
  4369. use Binas, only : xmair
  4370. use GO, only : goReadFromLine, goUpCase
  4371. use GO, only : NewDate
  4372. use dims, only : im, jm
  4373. use chem_param, only : ntrace, names, ra
  4374. use partools, only : MPI_INFO_NULL, localComm
  4375. use MeteoData, only : global_lli, levi
  4376. !
  4377. ! !OUTPUT PARAMETERS:
  4378. !
  4379. type(TPdumpFile_DEPS), intent(out) :: RF
  4380. integer, intent(out) :: status
  4381. !
  4382. ! !INPUT PARAMETERS:
  4383. !
  4384. character(len=*), intent(in) :: fdir
  4385. character(len=*), intent(in) :: model
  4386. character(len=*), intent(in) :: expid
  4387. character(len=*), intent(in) :: filetype
  4388. integer, intent(in) :: region
  4389. integer, intent(in) :: idate_f(6)
  4390. integer, intent(in) :: dhour
  4391. character(len=*), intent(in) :: tracer_names
  4392. !
  4393. ! !REVISION HISTORY:
  4394. ! 1 Oct 2010 - Achim Strunk - retor -> pdump
  4395. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  4396. !
  4397. !EOP
  4398. !------------------------------------------------------------------------
  4399. !BOC
  4400. character(len=*), parameter :: rname = mname//'/RF_DEPS_Init'
  4401. ! --- local ------------------------------------
  4402. character(len=256) :: fname
  4403. integer :: varid
  4404. character(len=256) :: trnames
  4405. character(len=8) :: trname, tmname
  4406. integer :: k, itr
  4407. character(len=32) :: varname, varname_enti, varname_spec
  4408. character(len=64) :: cf_enti_stnd, cf_enti_long, cf_enti_unit
  4409. character(len=64) :: cf_spec_stnd, cf_spec_long
  4410. character(len=256) :: cf_name_stnd, cf_name_long, cf_name_unit
  4411. character(len=512) :: comment
  4412. logical :: with_wdep
  4413. integer :: imr, jmr, i1, i2, j1, j2
  4414. ! --- begin -------------------------------------
  4415. call goLabel(rname)
  4416. ! -- store arguments, init var
  4417. RF%dhour = dhour
  4418. RF%tracer_names = tracer_names
  4419. RF%ntr = 0
  4420. trnames = tracer_names
  4421. ! -- get dims
  4422. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  4423. imr=i2-i1+1
  4424. jmr=j2-j1+1
  4425. ! Switch to default .false., requires an extra call to PDUMP_Files_Write2 in OUTPUT_PDUMP_DONE
  4426. n_deps_rec = GET_N_TIME_RECORDS( idate_f, dhour*3600, mess='DPS_Init' )
  4427. !n_deps_rec = GET_N_TIME_RECORDS( idate_f, dhour*3600, .true., 'DPS_Init' )
  4428. if ( n_deps_rec == 0 ) then ! degenerated case
  4429. deps_apply = .false.
  4430. status=0
  4431. return
  4432. end if
  4433. ! -- tracer index for requested tracers:
  4434. if ( len_trim(trnames) == 0 ) then
  4435. deps_apply = .false.
  4436. write (gol,'("WARNING - NO tracers selected for depositions output!")') ; call goPr
  4437. write (gol,'(" - deps_apply set to False.")' ) ; call goPr
  4438. status=0
  4439. return
  4440. else
  4441. write (gol,'("selected tracers for depositions output:")'); call goPr
  4442. end if
  4443. do
  4444. if ( len_trim(trnames) == 0 ) exit
  4445. ! next number:
  4446. if ( RF%ntr == ntrace ) then
  4447. write (gol,'("number of elements in tracer names list exceeds ntrace=",i6)') ntrace; call goErr
  4448. TRACEBACK; status=1; return
  4449. end if
  4450. RF%ntr = RF%ntr + 1
  4451. ! extract leading name:
  4452. call goReadFromLine( trnames, trname, status, sep=' ' )
  4453. IF_NOTOK_RETURN(status=1)
  4454. ! store pdump name:
  4455. RF%name_tr(RF%ntr) = trname
  4456. ! convert to tm5 name:
  4457. select case ( trname )
  4458. case ( 'HCHO' ) ; tmname = 'CH2O'
  4459. case ( 'Rn', 'Radon' ) ; tmname = 'Rn222'
  4460. case ( 'Pb', 'Lead' ) ; tmname = 'Pb210'
  4461. case default ; tmname = trname
  4462. end select
  4463. ! wet deposition ?
  4464. with_wdep = .false.
  4465. select case ( trname )
  4466. case ( 'HNO3' ) ; with_wdep = .true.
  4467. case ( 'NOy' ) ; with_wdep = .true.
  4468. case ( 'NH3' ) ; with_wdep = .true.
  4469. case ( 'NH4' ) ; with_wdep = .true.
  4470. case ( 'SO4' ) ; with_wdep = .true.
  4471. end select
  4472. RF%with_wdep(RF%ntr) = with_wdep
  4473. ! NOy is a special ...
  4474. select case ( tmname )
  4475. case ( 'NOy' )
  4476. ! defined as ntrace+1
  4477. RF%itr(RF%ntr) = iNOy
  4478. write (gol,'(" ",i3," ",a10," (",a10,") ",f12.4,"; wdep : ",l1)') &
  4479. -1,trim(trname), '*', -1.0, with_wdep; call goPr
  4480. case default
  4481. ! loop over all names:
  4482. RF%itr(RF%ntr) = -1
  4483. do itr = 1, ntrace
  4484. ! case indendent match ?
  4485. if ( goUpCase(trim(tmname)) == goUpCase(trim(names(itr))) ) then
  4486. write (gol,'(" ",i3," ",a10," (",a10,") ",f12.4," ; wdep : ",l1)') &
  4487. itr, trim(trname), trim(names(itr)), ra(itr), with_wdep; call goPr
  4488. RF%itr(RF%ntr) = itr
  4489. exit
  4490. end if
  4491. end do
  4492. end select
  4493. ! not found ?
  4494. if ( RF%itr(RF%ntr) < 0 ) then
  4495. write (gol,'("tracer name not supported:") ') ; call goPr
  4496. write (gol,'(" list all : ",a) ') trim(tracer_names) ; call goPr
  4497. write (gol,'(" list element : ",i3) ') RF%ntr ; call goPr
  4498. write (gol,'(" pdump name : ",a) ') trim(trname) ; call goPr
  4499. write (gol,'(" tm5 name : ",a) ') trim(tmname) ; call goPr
  4500. write (gol,'(" tm5 tracers : ") ') ; call goPr
  4501. do itr = 1, ntrace
  4502. write (gol,'(" ",i3," ",a)') itr, trim(names(itr)); call goPr
  4503. end do
  4504. TRACEBACK; status=1; return
  4505. end if
  4506. end do
  4507. ! empty file ?
  4508. if ( RF%ntr < 1 ) then
  4509. write (gol,'("no tracers extracted from list :",a)') tracer_names; call goErr
  4510. TRACEBACK; status=1; return
  4511. end if
  4512. ! allocate storage:
  4513. allocate( RF%ddep_budget(imr,jmr,RF%ntr) ) ; RF%ddep_budget = 0.0
  4514. allocate( RF%wdep_budget(imr,jmr,RF%ntr) ) ; RF%wdep_budget = 0.0
  4515. ! store current time (when budgets are reset):
  4516. RF%t0_budget = NewDate(time6=idate_f)
  4517. ! o open file
  4518. write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
  4519. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), trim(filetype), idate_f(1:3)
  4520. #ifdef MPI
  4521. ! overwrite existing files (clobber), provide MPI stuff:
  4522. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  4523. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  4524. if (status/=0) then
  4525. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  4526. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  4527. TRACEBACK; status=1; return
  4528. end if
  4529. #else
  4530. ! overwrite existing files (clobber)
  4531. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  4532. IF_NOTOK_RETURN(status=1)
  4533. #endif
  4534. ! o global attributes
  4535. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title' , 'dry and wet deposition' , status)
  4536. IF_NOTOK_MDF(fid=RF%ncid)
  4537. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
  4538. IF_NOTOK_MDF(fid=RF%ncid)
  4539. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
  4540. IF_NOTOK_MDF(fid=RF%ncid)
  4541. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status)
  4542. IF_NOTOK_MDF(fid=RF%ncid)
  4543. ! o define dimensions
  4544. call MDF_Def_Dim( RF%ncid, 'lon' , global_lli(region)%nlon, RF%dimid_lon , status)
  4545. IF_NOTOK_MDF(fid=RF%ncid)
  4546. call MDF_Def_Dim( RF%ncid, 'lat' , global_lli(region)%nlat, RF%dimid_lat , status)
  4547. IF_NOTOK_MDF(fid=RF%ncid)
  4548. call MDF_Def_Dim( RF%ncid, 'time' , n_deps_rec , RF%dimid_time , status)
  4549. IF_NOTOK_MDF(fid=RF%ncid)
  4550. call MDF_Def_Dim( RF%ncid, 'datelen', 6 , RF%dimid_datelen, status)
  4551. IF_NOTOK_MDF(fid=RF%ncid)
  4552. ! o define variables
  4553. call MDF_Def_Var( RF%ncid, 'lon', mdf_float, (/RF%dimid_lon/), varid , status)
  4554. IF_NOTOK_MDF(fid=RF%ncid)
  4555. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  4556. IF_NOTOK_MDF(fid=RF%ncid)
  4557. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  4558. IF_NOTOK_MDF(fid=RF%ncid)
  4559. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'longitude' , status)
  4560. IF_NOTOK_MDF(fid=RF%ncid)
  4561. call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_east', status)
  4562. IF_NOTOK_MDF(fid=RF%ncid)
  4563. RF%varid_lon = varid
  4564. call MDF_Def_Var( RF%ncid, 'lat', mdf_float, (/RF%dimid_lat/), varid , status)
  4565. IF_NOTOK_MDF(fid=RF%ncid)
  4566. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  4567. IF_NOTOK_MDF(fid=RF%ncid)
  4568. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  4569. IF_NOTOK_MDF(fid=RF%ncid)
  4570. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'latitude' , status)
  4571. IF_NOTOK_MDF(fid=RF%ncid)
  4572. call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_north', status)
  4573. IF_NOTOK_MDF(fid=RF%ncid)
  4574. RF%varid_lat = varid
  4575. call MDF_Def_Var( RF%ncid, 'time', mdf_float, (/RF%dimid_time/), varid , status)
  4576. IF_NOTOK_MDF(fid=RF%ncid)
  4577. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  4578. IF_NOTOK_MDF(fid=RF%ncid)
  4579. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
  4580. IF_NOTOK_MDF(fid=RF%ncid)
  4581. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'time' , status)
  4582. IF_NOTOK_MDF(fid=RF%ncid)
  4583. call MDF_Put_Att( RF%ncid, varid, 'units' , 'days since 1950-01-01 00:00:00', status)
  4584. IF_NOTOK_MDF(fid=RF%ncid)
  4585. call MDF_Put_Att( RF%ncid, varid, 'calender' , 'gregorian' , status)
  4586. IF_NOTOK_MDF(fid=RF%ncid)
  4587. RF%varid_time = varid
  4588. call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  4589. IF_NOTOK_MDF(fid=RF%ncid)
  4590. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  4591. IF_NOTOK_MDF(fid=RF%ncid)
  4592. call MDF_Put_Att( RF%ncid, varid , 'long_name', 'date and time' , status)
  4593. IF_NOTOK_MDF(fid=RF%ncid)
  4594. call MDF_Put_Att( RF%ncid, varid , 'units' , 'year, month, day, hour, minute, second', status)
  4595. IF_NOTOK_MDF(fid=RF%ncid)
  4596. RF%varid_date = varid
  4597. call MDF_Def_Var( RF%ncid, 'accum', mdf_float , (/RF%dimid_time/) , varid, status)
  4598. IF_NOTOK_MDF(fid=RF%ncid)
  4599. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  4600. IF_NOTOK_MDF(fid=RF%ncid)
  4601. call MDF_Put_Att( RF%ncid, varid , 'long_name', 'length of accumulated time interval', status)
  4602. IF_NOTOK_MDF(fid=RF%ncid)
  4603. call MDF_Put_Att( RF%ncid, varid , 'units' , 'second' , status)
  4604. IF_NOTOK_MDF(fid=RF%ncid)
  4605. RF%varid_accum = varid
  4606. allocate( RF%time(n_deps_rec) )
  4607. allocate( RF%date(6,n_deps_rec) )
  4608. allocate( RF%dt(n_deps_rec) )
  4609. ! loop over tracer to be written:
  4610. do k = 1, RF%ntr
  4611. ! global tracer index
  4612. itr = RF%itr(k)
  4613. ! ~~ dry deposition
  4614. ! CF standard name for concentration/mixing ratio/column:
  4615. cf_enti_stnd = 'surface_dry_deposition_mole_flux'
  4616. cf_enti_unit = 'mole m-2 s-1'
  4617. cf_enti_long = 'dry deposition of '
  4618. ! start of dataset name:
  4619. varname_enti = 'dry'
  4620. ! no comment yet
  4621. comment = ''
  4622. ! standard names from CF conventions:
  4623. select case ( RF%name_tr(k) )
  4624. case ( 'CO', 'co' )
  4625. varname_spec = 'co'
  4626. cf_spec_stnd = 'carbon_monoxide'
  4627. cf_spec_long = 'CO'
  4628. case ( 'O3', 'o3' )
  4629. varname_spec = 'o3'
  4630. cf_spec_stnd = 'ozone'
  4631. cf_spec_long = 'O3'
  4632. case ( 'O3s', 'o3s' )
  4633. varname_spec = 'o3s'
  4634. cf_spec_stnd = 'ozone_from_stratosphere'
  4635. cf_spec_long = 'O3s'
  4636. case ( 'NO', 'no' )
  4637. varname_spec = 'no'
  4638. cf_spec_stnd = 'nitrogen_monoxide'
  4639. cf_spec_long = 'NO'
  4640. case ( 'NO2', 'no2' )
  4641. varname_spec = 'no2'
  4642. cf_spec_stnd = 'nitrogen_dioxide'
  4643. cf_spec_long = 'NO2'
  4644. case ( 'NOy', 'noy' )
  4645. varname_spec = 'noy'
  4646. cf_spec_stnd = 'all_nitrogen_oxides_as_nitrogen'
  4647. cf_spec_long = 'NOy'
  4648. comment = 'NOy = NOx + HNO3 + PAN + org.ntr., '// &
  4649. 'with NOx = NO + NO2 + NO3 + HNO4 + N2O5'
  4650. case ( 'CH2O', 'ch2o', 'CHOH', 'choh' )
  4651. varname_spec = 'ch2o'
  4652. cf_spec_stnd = 'formaldehyde'
  4653. cf_spec_long = 'CH2O'
  4654. case ( 'SO2', 'so2' )
  4655. varname_spec = 'so2'
  4656. cf_spec_stnd = 'sulfur_dioxide'
  4657. cf_spec_long = 'SO2'
  4658. case ( 'CH4', 'ch4' )
  4659. varname_spec = 'ch4'
  4660. cf_spec_stnd = 'methane'
  4661. cf_spec_long = 'CH4'
  4662. case ( 'OH', 'oh' )
  4663. varname_spec = 'oh'
  4664. cf_spec_stnd = 'hydroxyl_radical'
  4665. cf_spec_long = 'OH'
  4666. case ( 'H2O2', 'h2o2' )
  4667. varname_spec = 'h2o2'
  4668. cf_spec_stnd = 'hydrogen_peroxide'
  4669. cf_spec_long = 'H2O2'
  4670. case ( 'HNO3', 'hno3' )
  4671. varname_spec = 'hno3'
  4672. cf_spec_stnd = 'nitric_acid'
  4673. cf_spec_long = 'HNO3'
  4674. case ( 'NH3', 'nh3' )
  4675. varname_spec = 'nh3'
  4676. cf_spec_stnd = 'ammonia'
  4677. cf_spec_long = 'NH3'
  4678. case ( 'ORGNTR','orgntr' )
  4679. varname_spec = 'orgntr'
  4680. cf_spec_stnd = 'organic_nitrate'
  4681. cf_spec_long = 'ORGNTR'
  4682. case ( 'NH4', 'nh4' )
  4683. varname_spec = 'nh4'
  4684. cf_spec_stnd = 'ammonium'
  4685. cf_spec_long = 'NH4'
  4686. case ( 'PAN', 'pan' )
  4687. varname_spec = 'pan'
  4688. cf_spec_stnd = 'peroxyacetyl_nitrate'
  4689. cf_spec_long = 'PAN'
  4690. case ( 'Rn', 'rn', 'Radon', 'radon' )
  4691. varname_spec = 'rn'
  4692. cf_spec_stnd = 'radon'
  4693. cf_spec_long = 'Rn'
  4694. case ( 'Pb', 'pb', 'Lead', 'lead' )
  4695. varname_spec = 'pb'
  4696. cf_spec_stnd = 'lead'
  4697. cf_spec_long = 'Pb'
  4698. case default
  4699. write (gol,'("do not know how to match tracer with CF standard names : ",a)') RF%name_tr(k); call goErr
  4700. TRACEBACK; status=1; return
  4701. end select
  4702. write (varname,'(a,"_",a)') trim(varname_enti), trim(varname_spec)
  4703. ! define variable:
  4704. call MDF_Def_Var( RF%ncid, trim(varname), MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  4705. IF_NOTOK_MDF(fid=RF%ncid)
  4706. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  4707. IF_NOTOK_MDF(fid=RF%ncid)
  4708. ! total names:
  4709. cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)
  4710. cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)
  4711. cf_name_unit = trim(cf_enti_unit)
  4712. ! write attributes:
  4713. call MDF_Put_Att( RF%ncid , varid, 'standard_name' , trim(cf_name_stnd), status)
  4714. IF_NOTOK_MDF(fid=RF%ncid)
  4715. call MDF_Put_Att( RF%ncid , varid, 'long_name' , trim(cf_name_long), status)
  4716. IF_NOTOK_MDF(fid=RF%ncid)
  4717. call MDF_Put_Att( RF%ncid , varid, 'units' , trim(cf_name_unit), status)
  4718. IF_NOTOK_MDF(fid=RF%ncid)
  4719. if ( itr <= ntrace ) then
  4720. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', ra(itr)*1e3 , status)
  4721. IF_NOTOK_MDF(fid=RF%ncid)
  4722. else
  4723. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', -1.0 , status)
  4724. IF_NOTOK_MDF(fid=RF%ncid)
  4725. end if
  4726. call MDF_Put_Att( RF%ncid , varid, 'moleweight_air' , xmair*1e3 , status)
  4727. IF_NOTOK_MDF(fid=RF%ncid)
  4728. call MDF_Put_Att( RF%ncid , varid, 'moleweight_unit' , 'kg mole-1' , status)
  4729. IF_NOTOK_MDF(fid=RF%ncid)
  4730. if ( len_trim(comment) > 0 ) then
  4731. call MDF_Put_Att( RF%ncid, varid, 'comment' , trim(comment) , status)
  4732. IF_NOTOK_MDF(fid=RF%ncid)
  4733. end if
  4734. ! store varid
  4735. RF%varid_ddep(k) = varid
  4736. ! ~~ wet deposition
  4737. if ( RF%with_wdep(k) ) then
  4738. ! CF standard name for concentration/mixing ratio/column:
  4739. cf_enti_stnd = 'surface_wet_deposition_mole_flux'
  4740. cf_enti_unit = 'mole m-2 s-1'
  4741. cf_enti_long = 'wet deposition of '
  4742. ! start of dataset name:
  4743. varname_enti = 'wet'
  4744. ! by default no comment:
  4745. comment = ''
  4746. ! standard names from CF conventions:
  4747. select case ( RF%name_tr(k) )
  4748. case ( 'NOy', 'noy' )
  4749. varname_spec = 'noy'
  4750. cf_spec_stnd = 'all_nitrogen_oxides_as_nitrogen'
  4751. cf_spec_long = 'NOy'
  4752. comment = 'NOy = NOx + HNO3 + PAN + org.ntr., '// &
  4753. 'with NOx = NO + NO2 + NO3 + HNO4 + N2O5'
  4754. case ( 'HNO3', 'hno3' )
  4755. varname_spec = 'hno3'
  4756. cf_spec_stnd = 'nitric_acid'
  4757. cf_spec_long = 'HNO3'
  4758. case ( 'NH3', 'nh3' )
  4759. varname_spec = 'nh3'
  4760. cf_spec_stnd = 'ammonia'
  4761. cf_spec_long = 'NH3'
  4762. case ( 'NH4', 'nh4' )
  4763. varname_spec = 'nh4'
  4764. cf_spec_stnd = 'ammonium'
  4765. cf_spec_long = 'NH4'
  4766. case ( 'SO2', 'so2' )
  4767. varname_spec = 'so2'
  4768. cf_spec_stnd = 'sulfur_dioxide'
  4769. cf_spec_long = 'SO2'
  4770. case default
  4771. write (gol,'("unsupported tracer name for CF standard name : ",a)') RF%name_tr(k); call goPr
  4772. TRACEBACK; status=1; return
  4773. end select
  4774. write (varname,'(a,"_",a)') trim(varname_enti), trim(varname_spec)
  4775. ! define variable:
  4776. call MDF_Def_Var( RF%ncid, trim(varname), MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  4777. IF_NOTOK_MDF(fid=RF%ncid)
  4778. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  4779. IF_NOTOK_MDF(fid=RF%ncid)
  4780. ! total names:
  4781. cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)
  4782. cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)
  4783. cf_name_unit = trim(cf_enti_unit)
  4784. ! write attributes:
  4785. call MDF_Put_Att( RF%ncid , varid, 'standard_name' , trim(cf_name_stnd), status)
  4786. IF_NOTOK_MDF(fid=RF%ncid)
  4787. call MDF_Put_Att( RF%ncid , varid, 'long_name' , trim(cf_name_long), status)
  4788. IF_NOTOK_MDF(fid=RF%ncid)
  4789. call MDF_Put_Att( RF%ncid , varid, 'units' , trim(cf_name_unit), status)
  4790. IF_NOTOK_MDF(fid=RF%ncid)
  4791. if ( itr <= ntrace ) then
  4792. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', ra(itr)*1e3 , status)
  4793. IF_NOTOK_MDF(fid=RF%ncid)
  4794. else
  4795. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', -1.0 , status)
  4796. IF_NOTOK_MDF(fid=RF%ncid)
  4797. end if
  4798. call MDF_Put_Att( RF%ncid , varid, 'moleweight_air' , xmair*1e3 , status)
  4799. IF_NOTOK_MDF(fid=RF%ncid)
  4800. call MDF_Put_Att( RF%ncid , varid, 'moleweight_unit' , 'kg mole-1' , status)
  4801. IF_NOTOK_MDF(fid=RF%ncid)
  4802. if ( len_trim(comment) > 0 ) then
  4803. call MDF_Put_Att( RF%ncid, varid, 'comment' , trim(comment) , status)
  4804. IF_NOTOK_MDF(fid=RF%ncid)
  4805. end if
  4806. ! store varid
  4807. RF%varid_wdep(k) = varid
  4808. end if
  4809. end do
  4810. allocate( RF%data2d_dry(i1:i2, j1:j2, n_deps_rec, RF%ntr) )
  4811. allocate( RF%data2d_wet(i1:i2, j1:j2, n_deps_rec, RF%ntr) )
  4812. ! RF%data2d_dry = 0.
  4813. ! RF%data2d_wet = 0.
  4814. ! o end defintion mode
  4815. call MDF_EndDef( RF%ncid , status)
  4816. IF_NOTOK_MDF(fid=RF%ncid)
  4817. ! o
  4818. ! no records written yet
  4819. RF%trec = 0
  4820. call goLabel()
  4821. ! ok
  4822. status = 0
  4823. end subroutine RF_DEPS_Init
  4824. !EOC
  4825. !--------------------------------------------------------------------------
  4826. ! TM5 !
  4827. !--------------------------------------------------------------------------
  4828. !BOP
  4829. !
  4830. ! !IROUTINE: RF_DEPS_Write
  4831. !
  4832. ! !DESCRIPTION:
  4833. !\\
  4834. !\\
  4835. ! !INTERFACE:
  4836. !
  4837. SUBROUTINE RF_DEPS_Write( RF, region, idate_f, status )
  4838. !
  4839. ! !USES:
  4840. !
  4841. use GO, only : TDate, NewDate, Set, iTotal, rTotal, operator(-), wrtgol
  4842. use Grid, only : AreaOper
  4843. use MeteoData, only : global_lli, levi, lli
  4844. #ifndef without_chemistry
  4845. use ebischeme, only : buddrydep_dat => buddep_dat
  4846. #endif
  4847. #ifndef without_wet_deposition
  4848. use wet_deposition, only : buddep_dat
  4849. #endif
  4850. !
  4851. ! !INPUT/OUTPUT PARAMETERS:
  4852. !
  4853. type(TPdumpFile_DEPS), intent(inout) :: RF
  4854. !
  4855. ! !INPUT PARAMETERS:
  4856. !
  4857. integer, intent(in) :: region
  4858. integer, intent(in) :: idate_f(6)
  4859. !
  4860. ! !OUTPUT PARAMETERS:
  4861. !
  4862. integer, intent(out) :: status
  4863. !
  4864. ! !REVISION HISTORY:
  4865. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  4866. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  4867. !
  4868. !EOP
  4869. !------------------------------------------------------------------------
  4870. !BOC
  4871. character(len=*), parameter :: rname = mname//'/RF_DEPS_Write'
  4872. ! --- local ------------------------------------
  4873. integer :: imr, jmr, lmr
  4874. type(TDate) :: t, t0
  4875. real :: time
  4876. real :: dt_sec
  4877. integer :: k, itr, i1, i2, j1, j2
  4878. real, allocatable :: budget(:,:)
  4879. real, allocatable :: budget_loc(:,:)
  4880. real, allocatable :: depflux(:,:)
  4881. integer :: icomp
  4882. ! --- begin -------------------------------------
  4883. ! for multiple of dhour only ...
  4884. if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
  4885. status=0; return
  4886. end if
  4887. call goLabel(rname)
  4888. ! grid size
  4889. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  4890. imr = i2-i1+1
  4891. jmr = j2-j1+1
  4892. lmr = levi%nlev
  4893. ! temporary storage:
  4894. allocate( budget_loc(imr,jmr) )
  4895. allocate( depflux (imr,jmr) )
  4896. ! next time record:
  4897. RF%trec = RF%trec + 1
  4898. if(okdebug)then
  4899. write(gol,*) "RF_DEPS_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
  4900. end if
  4901. ! time since 1950-1-1 00:00
  4902. t0 = NewDate( time6=time_reftime6 )
  4903. t = NewDate( time6=idate_f )
  4904. time = rTotal( t - t0, 'day' )
  4905. ! length of time interval:
  4906. dt_sec = iTotal( t - RF%t0_budget, 'sec' )
  4907. ! zero time interval ? routine should not have been called ...
  4908. if ( dt_sec == 0 ) then
  4909. write (gol,'("routine called after zero lenght time interval:")'); call goErr
  4910. call wrtgol( ' t0_budget : ', RF%t0_budget ); call goErr
  4911. call wrtgol( ' t : ', t ); call goErr
  4912. !status=1
  4913. TRACEBACK
  4914. end if
  4915. ! reset timer:
  4916. call Set( RF%t0_budget, time6=idate_f )
  4917. !---------------
  4918. ! Write GRID
  4919. !---------------
  4920. if ( RF%trec == 1 ) then
  4921. ! longitudes
  4922. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
  4923. IF_NOTOK_MDF(fid=RF%ncid)
  4924. ! latitudes
  4925. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
  4926. IF_NOTOK_MDF(fid=RF%ncid)
  4927. end if
  4928. !---------------
  4929. ! FILL DIAGNOSTIC ARRAYS
  4930. !---------------
  4931. !--------------- time
  4932. rf%time(rf%trec) = time
  4933. rf%date(:,rf%trec) = real(idate_f)
  4934. rf%dt(rf%trec) = dt_sec
  4935. !--------------- dry deposition
  4936. do k = 1, RF%ntr
  4937. ! global tracer index:
  4938. itr = RF%itr(k)
  4939. ! extract current budget
  4940. #ifndef without_chemistry
  4941. if ( itr == iNOy ) then
  4942. ! add contributions of all NOy components:
  4943. budget_loc = 0.0
  4944. do icomp = 1, nNOyt
  4945. budget_loc = budget_loc + buddrydep_dat(region)%dry(:,:,iNOyt(icomp))
  4946. end do
  4947. else
  4948. ! extract budget for requested tracer:
  4949. budget_loc = buddrydep_dat(region)%dry(:,:,itr)
  4950. end if
  4951. #else
  4952. budget_loc = 0.0
  4953. #endif
  4954. ! deposition flux ~ (current budget - previous budget)/dt
  4955. depflux = ( budget_loc - RF%ddep_budget(:,:,k) ) / dt_sec ! mole/s
  4956. call AreaOper( lli(region), depflux, '/', 'm2', status ) ! mole/m2/s
  4957. IF_NOTOK_RETURN(status=1)
  4958. ! save current budget & store record
  4959. RF%ddep_budget(:,:,k) = budget_loc
  4960. rf%data2d_dry(:,:,RF%trec,k)= depflux
  4961. end do
  4962. !--------------- wet deposition
  4963. do k = 1, RF%ntr
  4964. ! skip ?
  4965. if ( .not. RF%with_wdep(k) ) cycle
  4966. ! global tracer index:
  4967. itr = RF%itr(k)
  4968. ! extract current budget
  4969. #ifndef without_wet_deposition
  4970. if ( itr == iNOy ) then
  4971. ! add contributions of all NOy components:
  4972. budget_loc = 0.0
  4973. do icomp = 1, nNOyt
  4974. ! add wet depositions for large scale and convective precip; total column:
  4975. budget_loc = budget_loc + sum(buddep_dat(region)%lsp(:,:,:,iNOyt(icomp)),3) + &
  4976. sum(buddep_dat(region)% cp(:,:,:,iNOyt(icomp)),3)
  4977. end do
  4978. else
  4979. ! extract budget for requested tracer;
  4980. ! add wet depositions for large scale and convective precip; total column:
  4981. budget_loc = sum(buddep_dat(region)%lsp(:,:,:,itr),3) + &
  4982. sum(buddep_dat(region)% cp(:,:,:,itr),3)
  4983. end if
  4984. #else
  4985. budget_loc = 0.0
  4986. #endif
  4987. ! deposition flux ~ (current budget - previous budget)/dt
  4988. depflux = ( budget_loc - RF%wdep_budget(:,:,k) ) / dt_sec ! mole/s
  4989. call AreaOper( lli(region), depflux, '/', 'm2', status ) ! mole/m2/s
  4990. IF_NOTOK_RETURN(status=1)
  4991. ! save current budget & store record
  4992. RF%wdep_budget(:,:,k) = budget_loc
  4993. RF%data2d_wet(:,:,RF%trec,k)= depflux
  4994. end do
  4995. !----------------
  4996. ! WRITE
  4997. !----------------
  4998. if ( RF%trec == n_deps_rec ) then
  4999. call MDF_Put_Var( RF%ncid, RF%varid_time, rf%time, status)
  5000. IF_NOTOK_MDF(fid=RF%ncid)
  5001. call MDF_Put_Var( RF%ncid, RF%varid_date, rf%date, status)
  5002. IF_NOTOK_MDF(fid=RF%ncid)
  5003. ! accumulation interval
  5004. call MDF_Put_Var( RF%ncid, RF%varid_accum, rf%dt , status)
  5005. IF_NOTOK_MDF(fid=RF%ncid)
  5006. ! deposition flux
  5007. do k = 1, RF%ntr
  5008. call MDF_Put_Var( RF%ncid, RF%varid_ddep(k), rf%data2d_dry(:,:,:,k), status, start=(/i1,j1,1/) )
  5009. IF_NOTOK_MDF(fid=RF%ncid)
  5010. if ( .not. RF%with_wdep(k) ) cycle
  5011. call MDF_Put_Var( RF%ncid, RF%varid_wdep(k), rf%data2d_wet(:,:,:,k), status, start=(/i1,j1,1/) )
  5012. IF_NOTOK_MDF(fid=RF%ncid)
  5013. end do
  5014. end if
  5015. !----------------
  5016. ! DONE
  5017. !----------------
  5018. deallocate( budget_loc )
  5019. deallocate( depflux )
  5020. call goLabel()
  5021. status = 0
  5022. END SUBROUTINE RF_DEPS_Write
  5023. !EOC
  5024. !--------------------------------------------------------------------------
  5025. ! TM5 !
  5026. !--------------------------------------------------------------------------
  5027. !BOP
  5028. !
  5029. ! !IROUTINE: RF_DEPS_Done
  5030. !
  5031. ! !DESCRIPTION: close file #5
  5032. !\\
  5033. !\\
  5034. ! !INTERFACE:
  5035. !
  5036. SUBROUTINE RF_DEPS_Done( RF, status )
  5037. !
  5038. ! !INPUT/OUTPUT PARAMETERS:
  5039. !
  5040. type(TPdumpFile_DEPS), intent(inout) :: RF
  5041. !
  5042. ! !OUTPUT PARAMETERS:
  5043. !
  5044. integer, intent(out) :: status
  5045. !
  5046. ! !REVISION HISTORY:
  5047. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  5048. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  5049. !
  5050. !EOP
  5051. !------------------------------------------------------------------------
  5052. !BOC
  5053. character(len=*), parameter :: rname = mname//'/RF_DEPS_Done'
  5054. ! --- begin -------------------------------------
  5055. call goLabel(rname)
  5056. ! close file
  5057. call MDF_Close( RF%ncid , status)
  5058. IF_NOTOK_RETURN(status=1)
  5059. ! clear
  5060. deallocate( RF%ddep_budget )
  5061. deallocate( RF%wdep_budget )
  5062. deallocate( rf%time, rf%date, rf%dt, rf%data2d_dry, rf%data2d_wet )
  5063. call goLabel() ; status = 0
  5064. END SUBROUTINE RF_DEPS_Done
  5065. !EOC
  5066. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5067. ! FILE #6 : deposition velocities
  5068. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5069. !--------------------------------------------------------------------------
  5070. ! TM5 !
  5071. !--------------------------------------------------------------------------
  5072. !BOP
  5073. !
  5074. ! !IROUTINE: RF_DEPV_Init
  5075. !
  5076. ! !DESCRIPTION:
  5077. !\\
  5078. !\\
  5079. ! !INTERFACE:
  5080. !
  5081. subroutine RF_DEPV_Init( RF, fdir, model, expid, filetype, region, &
  5082. idate_f, dhour, tracer_names, status )
  5083. !
  5084. ! !USES:
  5085. !
  5086. use Binas, only : xmair
  5087. use GO, only : goReadFromLine, goUpCase
  5088. use GO, only : NewDate
  5089. use dims, only : im, jm
  5090. use chem_param, only : ntrace, names, ra
  5091. use partools, only : MPI_INFO_NULL, localComm
  5092. use MeteoData, only : global_lli, levi
  5093. !
  5094. ! !OUTPUT PARAMETERS:
  5095. !
  5096. type(TPdumpFile_DEPV), intent(out) :: RF
  5097. !
  5098. ! !INPUT PARAMETERS:
  5099. !
  5100. character(len=*), intent(in) :: fdir
  5101. character(len=*), intent(in) :: model
  5102. character(len=*), intent(in) :: expid
  5103. character(len=*), intent(in) :: filetype
  5104. integer, intent(in) :: region
  5105. integer, intent(in) :: idate_f(6)
  5106. integer, intent(in) :: dhour
  5107. character(len=*), intent(in) :: tracer_names
  5108. integer, intent(out) :: status
  5109. !
  5110. ! !REVISION HISTORY:
  5111. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  5112. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  5113. !
  5114. !EOP
  5115. !------------------------------------------------------------------------
  5116. !BOC
  5117. character(len=*), parameter :: rname = mname//'/RF_DEPV_Init'
  5118. ! --- local ------------------------------------
  5119. character(len=256) :: fname
  5120. integer :: varid, i1, i2, j1, j2
  5121. character(len=256) :: trnames
  5122. character(len=8) :: trname, tmname
  5123. integer :: k, itr
  5124. character(len=32) :: varname, varname_enti, varname_spec
  5125. character(len=64) :: cf_enti_stnd, cf_enti_long, cf_enti_unit
  5126. character(len=64) :: cf_spec_stnd, cf_spec_long
  5127. character(len=256) :: cf_name_stnd, cf_name_long, cf_name_unit
  5128. character(len=512) :: comment
  5129. ! --- begin -------------------------------------
  5130. call goLabel(rname)
  5131. ! store arguments
  5132. RF%dhour = dhour
  5133. RF%tracer_names = tracer_names
  5134. RF%ntr = 0
  5135. trnames = tracer_names
  5136. ! get dims
  5137. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  5138. n_depv_rec = GET_N_TIME_RECORDS( idate_f, dhour*3600, mess='DEPV_Init' )
  5139. if ( n_depv_rec == 0 ) then ! degenerated cases
  5140. depv_apply = .false.
  5141. status=0
  5142. return
  5143. end if
  5144. ! tracer index for requested tracers
  5145. if ( len_trim(trnames) == 0 ) then
  5146. depv_apply = .false.
  5147. write (gol,'("WARNING - NO tracers selected for depositions velocity output!")') ; call goPr
  5148. write (gol,'(" - depv_apply set to False.")' ) ; call goPr
  5149. status=0
  5150. return
  5151. else
  5152. write (gol,'("selected tracers for deposition velocity output:")'); call goPr
  5153. end if
  5154. do
  5155. if ( len_trim(trnames) == 0 ) exit
  5156. ! next number:
  5157. if ( RF%ntr == ntrace ) then
  5158. write (gol,'("number of elements in tracer names list exceeds ntrace=",i6)') ntrace; call goErr
  5159. TRACEBACK; status=1; return
  5160. end if
  5161. RF%ntr = RF%ntr + 1
  5162. ! extract leading name:
  5163. call goReadFromLine( trnames, trname, status, sep=' ' )
  5164. IF_NOTOK_RETURN(status=1)
  5165. ! store pdump name:
  5166. RF%name_tr(RF%ntr) = trname
  5167. ! convert to tm5 name:
  5168. select case ( trname )
  5169. case ( 'HCHO' ) ; tmname = 'CH2O'
  5170. case ( 'Rn', 'Radon' ) ; tmname = 'Rn222'
  5171. case ( 'Pb', 'Lead' ) ; tmname = 'Pb210'
  5172. case default ; tmname = trname
  5173. end select
  5174. ! loop over all names:
  5175. RF%itr(RF%ntr) = -1
  5176. do itr = 1, ntrace
  5177. ! case indendent match ?
  5178. if ( goUpCase(trim(tmname)) == goUpCase(trim(names(itr))) ) then
  5179. write (gol,'(" ",i3," ",a10," (",a10,")",f12.4)') &
  5180. itr, trim(trname), trim(names(itr)), ra(itr); call goPr
  5181. RF%itr(RF%ntr) = itr
  5182. exit
  5183. end if
  5184. end do
  5185. ! not found ?
  5186. if ( RF%itr(RF%ntr) < 0 ) then
  5187. write (gol,'("tracer name not supported:") ') ; call goPr
  5188. write (gol,'(" list all : ",a) ') trim(tracer_names) ; call goPr
  5189. write (gol,'(" list element : ",i3) ') RF%ntr ; call goPr
  5190. write (gol,'(" pdump name : ",a) ') trim(trname) ; call goPr
  5191. write (gol,'(" tm5 name : ",a) ') trim(tmname) ; call goPr
  5192. write (gol,'(" tm5 tracers : ") ') ; call goPr
  5193. do itr = 1, ntrace
  5194. write (gol,'(" ",i3," ",a)') itr, trim(names(itr)); call goPr
  5195. end do
  5196. TRACEBACK; status=1; return
  5197. end if
  5198. end do
  5199. ! empty file ?
  5200. if ( RF%ntr < 1 ) then
  5201. write (gol,'("no tracers extracted from list :",a)') tracer_names; call goErr
  5202. TRACEBACK; status=1; return
  5203. end if
  5204. ! o open file
  5205. ! write filename
  5206. write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
  5207. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), trim(filetype), idate_f(1:3)
  5208. ! open:
  5209. #ifdef MPI
  5210. ! overwrite existing files (clobber), provide MPI stuff:
  5211. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  5212. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  5213. if (status/=0) then
  5214. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  5215. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  5216. TRACEBACK; status=1; return
  5217. end if
  5218. #else
  5219. ! overwrite existing files (clobber)
  5220. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  5221. IF_NOTOK_RETURN(status=1)
  5222. #endif
  5223. ! o global attributes
  5224. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title' , 'volume mixing ratios' , status)
  5225. IF_NOTOK_MDF(fid=RF%ncid)
  5226. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
  5227. IF_NOTOK_MDF(fid=RF%ncid)
  5228. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution), status)
  5229. IF_NOTOK_MDF(fid=RF%ncid)
  5230. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status)
  5231. IF_NOTOK_MDF(fid=RF%ncid)
  5232. ! o define dimensions
  5233. call MDF_Def_Dim( RF%ncid, 'lon' , global_lli(region)%nlon, RF%dimid_lon , status)
  5234. IF_NOTOK_MDF(fid=RF%ncid)
  5235. call MDF_Def_Dim( RF%ncid, 'lat' , global_lli(region)%nlat, RF%dimid_lat , status)
  5236. IF_NOTOK_MDF(fid=RF%ncid)
  5237. call MDF_Def_Dim( RF%ncid, 'time' , n_depv_rec , RF%dimid_time , status)
  5238. IF_NOTOK_MDF(fid=RF%ncid)
  5239. call MDF_Def_Dim( RF%ncid, 'datelen', 6 , RF%dimid_datelen, status)
  5240. IF_NOTOK_MDF(fid=RF%ncid)
  5241. ! o define variables
  5242. call MDF_Def_Var( RF%ncid, 'lon', mdf_float, (/RF%dimid_lon/), varid , status)
  5243. IF_NOTOK_MDF(fid=RF%ncid)
  5244. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  5245. IF_NOTOK_MDF(fid=RF%ncid)
  5246. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  5247. IF_NOTOK_MDF(fid=RF%ncid)
  5248. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'longitude' , status)
  5249. IF_NOTOK_MDF(fid=RF%ncid)
  5250. call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_east', status)
  5251. IF_NOTOK_MDF(fid=RF%ncid)
  5252. RF%varid_lon = varid
  5253. call MDF_Def_Var( RF%ncid, 'lat', mdf_float, (/RF%dimid_lat/), varid , status)
  5254. IF_NOTOK_MDF(fid=RF%ncid)
  5255. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  5256. IF_NOTOK_MDF(fid=RF%ncid)
  5257. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  5258. IF_NOTOK_MDF(fid=RF%ncid)
  5259. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'latitude' , status)
  5260. IF_NOTOK_MDF(fid=RF%ncid)
  5261. call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_north', status)
  5262. IF_NOTOK_MDF(fid=RF%ncid)
  5263. RF%varid_lat = varid
  5264. call MDF_Def_Var( RF%ncid, 'time', mdf_float, (/RF%dimid_time/), varid , status)
  5265. IF_NOTOK_MDF(fid=RF%ncid)
  5266. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  5267. IF_NOTOK_MDF(fid=RF%ncid)
  5268. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
  5269. IF_NOTOK_MDF(fid=RF%ncid)
  5270. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'time' , status)
  5271. IF_NOTOK_MDF(fid=RF%ncid)
  5272. call MDF_Put_Att( RF%ncid, varid, 'units' , 'days since 1950-01-01 00:00:00', status)
  5273. IF_NOTOK_MDF(fid=RF%ncid)
  5274. call MDF_Put_Att( RF%ncid, varid, 'calender' , 'gregorian' , status)
  5275. IF_NOTOK_MDF(fid=RF%ncid)
  5276. RF%varid_time = varid
  5277. allocate( rf%time(n_depv_rec) )
  5278. call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen, RF%dimid_time/), varid , status)
  5279. IF_NOTOK_MDF(fid=RF%ncid)
  5280. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  5281. IF_NOTOK_MDF(fid=RF%ncid)
  5282. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
  5283. IF_NOTOK_MDF(fid=RF%ncid)
  5284. call MDF_Put_Att( RF%ncid, varid, 'units' , 'year, month, day, hour, minute, second' , status)
  5285. IF_NOTOK_MDF(fid=RF%ncid)
  5286. RF%varid_date = varid
  5287. allocate( rf%date(6,n_depv_rec) )
  5288. ! loop over tracer to be written:
  5289. do k = 1, RF%ntr
  5290. ! global tracer index
  5291. itr = RF%itr(k)
  5292. ! CF standard name for concentration/mixing ratio/column:
  5293. cf_enti_stnd = 'surface_dry_deposition_velocity_due_to_turbulence'
  5294. cf_enti_unit = 'mole m-2 s-1'
  5295. cf_enti_long = 'dry deposition of '
  5296. ! start of dataset name:
  5297. varname_enti = 'ddepvel'
  5298. ! by default no comment:
  5299. comment = ''
  5300. ! standard names from CF conventions:
  5301. select case ( RF%name_tr(k) )
  5302. case ( 'CO', 'co' )
  5303. varname_spec = 'co'
  5304. cf_spec_stnd = 'carbon_monoxide'
  5305. cf_spec_long = 'CO'
  5306. case ( 'O3', 'o3' )
  5307. varname_spec = 'o3'
  5308. cf_spec_stnd = 'ozone'
  5309. cf_spec_long = 'O3'
  5310. case ( 'O3s', 'o3s' )
  5311. varname_spec = 'o3s'
  5312. cf_spec_stnd = 'ozone_from_stratosphere'
  5313. cf_spec_long = 'O3s'
  5314. case ( 'NO', 'no' )
  5315. varname_spec = 'no'
  5316. cf_spec_stnd = 'nitrogen_monoxide'
  5317. cf_spec_long = 'NO'
  5318. case ( 'NO2', 'no2' )
  5319. varname_spec = 'no2'
  5320. cf_spec_stnd = 'nitrogen_dioxide'
  5321. cf_spec_long = 'NO2'
  5322. case ( 'NOy', 'noy' )
  5323. varname_spec = 'noy'
  5324. cf_spec_stnd = 'all_nitrogen_oxides_as_nitrogen'
  5325. cf_spec_long = 'NOy'
  5326. comment = 'NOy = NOx + HNO3 + PAN + org.ntr., '// &
  5327. 'with NOx = NO + NO2 + NO3 + HNO4 + N2O5'
  5328. case ( 'CH2O', 'ch2o', 'CHOH', 'choh' )
  5329. varname_spec = 'ch2o'
  5330. cf_spec_stnd = 'formaldehyde'
  5331. cf_spec_long = 'CH2O'
  5332. case ( 'SO2', 'so2' )
  5333. varname_spec = 'so2'
  5334. cf_spec_stnd = 'sulfur_dioxide'
  5335. cf_spec_long = 'SO2'
  5336. case ( 'CH4', 'ch4' )
  5337. varname_spec = 'ch4'
  5338. cf_spec_stnd = 'methane'
  5339. cf_spec_long = 'CH4'
  5340. case ( 'OH', 'oh' )
  5341. varname_spec = 'oh'
  5342. cf_spec_stnd = 'hydroxyl_radical'
  5343. cf_spec_long = 'OH'
  5344. case ( 'H2O2', 'h2o2' )
  5345. varname_spec = 'h2o2'
  5346. cf_spec_stnd = 'hydrogen_peroxide'
  5347. cf_spec_long = 'H2O2'
  5348. case ( 'HNO3', 'hno3' )
  5349. varname_spec = 'hno3'
  5350. cf_spec_stnd = 'nitric_acid'
  5351. cf_spec_long = 'HNO3'
  5352. case ( 'PAN', 'pan' )
  5353. varname_spec = 'pan'
  5354. cf_spec_stnd = 'peroxyacetyl_nitrate'
  5355. cf_spec_long = 'PAN'
  5356. case ( 'Rn', 'rn', 'Radon', 'radon' )
  5357. varname_spec = 'rn'
  5358. cf_spec_stnd = 'radon'
  5359. cf_spec_long = 'Rn'
  5360. case ( 'Pb', 'pb', 'Lead', 'lead' )
  5361. varname_spec = 'pb'
  5362. cf_spec_stnd = 'lead'
  5363. cf_spec_long = 'Pb'
  5364. case ( 'NH3', 'nh3' )
  5365. varname_spec = 'nh3'
  5366. cf_spec_stnd = 'ammonia'
  5367. cf_spec_long = 'NH3'
  5368. case ( 'NH4', 'nh4' )
  5369. varname_spec = 'nh4'
  5370. cf_spec_stnd = 'ammonium'
  5371. cf_spec_long = 'NH4'
  5372. case default
  5373. write (gol,'("unsupported tracer name for CF standard name : ",a)') RF%name_tr(k); call goPr
  5374. TRACEBACK; status=1; return
  5375. end select
  5376. write (varname,'(a,"_",a)') trim(varname_enti), trim(varname_spec)
  5377. write (gol,'(" varname : ",a)') trim(varname); call goPr
  5378. ! define variable:
  5379. call MDF_Def_Var( RF%ncid, trim(varname), MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  5380. IF_NOTOK_MDF(fid=RF%ncid)
  5381. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  5382. IF_NOTOK_MDF(fid=RF%ncid)
  5383. ! total names:
  5384. cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)
  5385. cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)
  5386. cf_name_unit = trim(cf_enti_unit)
  5387. ! write attributes:
  5388. call MDF_Put_Att( RF%ncid , varid, 'standard_name' , trim(cf_name_stnd), status)
  5389. IF_NOTOK_MDF(fid=RF%ncid)
  5390. call MDF_Put_Att( RF%ncid , varid, 'long_name' , trim(cf_name_long), status)
  5391. IF_NOTOK_MDF(fid=RF%ncid)
  5392. call MDF_Put_Att( RF%ncid , varid, 'units' , trim(cf_name_unit), status)
  5393. IF_NOTOK_MDF(fid=RF%ncid)
  5394. call MDF_Put_Att( RF%ncid , varid, 'moleweight_tracer', ra(itr)*1e3 , status)
  5395. IF_NOTOK_MDF(fid=RF%ncid)
  5396. call MDF_Put_Att( RF%ncid , varid, 'moleweight_air' , xmair*1e3 , status)
  5397. IF_NOTOK_MDF(fid=RF%ncid)
  5398. call MDF_Put_Att( RF%ncid , varid, 'moleweight_unit' , 'kg mole-1' , status)
  5399. IF_NOTOK_MDF(fid=RF%ncid)
  5400. if ( len_trim(comment) > 0 ) then
  5401. call MDF_Put_Att( RF%ncid, varid, 'comment' , trim(comment) , status)
  5402. IF_NOTOK_MDF(fid=RF%ncid)
  5403. end if
  5404. ! store varid
  5405. RF%varid_tr(k) = varid
  5406. end do
  5407. allocate( rf%data2d(i1:i2, j1:j2, n_depv_rec, rf%ntr) )
  5408. ! o end defintion mode
  5409. call MDF_EndDef( RF%ncid , status)
  5410. IF_NOTOK_MDF(fid=RF%ncid)
  5411. ! o
  5412. ! no records written yet
  5413. RF%trec = 0
  5414. call goLabel() ; status = 0
  5415. END SUBROUTINE RF_DEPV_Init
  5416. !EOC
  5417. !--------------------------------------------------------------------------
  5418. ! TM5 !
  5419. !--------------------------------------------------------------------------
  5420. !BOP
  5421. !
  5422. ! !IROUTINE: RF_DEPV_Write
  5423. !
  5424. ! !DESCRIPTION:
  5425. !\\
  5426. !\\
  5427. ! !INTERFACE:
  5428. !
  5429. SUBROUTINE RF_DEPV_Write( RF, region, idate_f, status )
  5430. !
  5431. ! !USES:
  5432. !
  5433. use GO, only : TDate, NewDate, Set, iTotal, rTotal, operator(-), wrtgol
  5434. use Grid, only : AreaOper
  5435. use MeteoData, only : global_lli
  5436. #ifndef without_dry_deposition
  5437. use dry_deposition, only : vd
  5438. #endif
  5439. !
  5440. ! !INPUT/OUTPUT PARAMETERS:
  5441. !
  5442. type(TPdumpFile_DEPV), intent(inout) :: RF
  5443. !
  5444. ! !INPUT PARAMETERS:
  5445. !
  5446. integer, intent(in) :: region
  5447. integer, intent(in) :: idate_f(6)
  5448. !
  5449. ! !OUTPUT PARAMETERS:
  5450. !
  5451. integer, intent(out) :: status
  5452. !
  5453. ! !REVISION HISTORY:
  5454. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  5455. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  5456. !
  5457. !EOP
  5458. !------------------------------------------------------------------------
  5459. !BOC
  5460. character(len=*), parameter :: rname = mname//'/RF_DEPV_Write'
  5461. ! --- local ------------------------------------
  5462. integer :: imr, jmr
  5463. type(TDate) :: t, t0
  5464. real :: time
  5465. integer :: k, itr, i1, i2, j1, j2
  5466. real, allocatable :: depvel(:,:)
  5467. ! --- begin -------------------------------------
  5468. ! for multiple of dhour only ...
  5469. if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
  5470. status=0; return
  5471. end if
  5472. call goLabel(rname)
  5473. ! grid size
  5474. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  5475. imr=i2-i1+1
  5476. jmr=j2-j1+1
  5477. ! next time record:
  5478. RF%trec = RF%trec + 1
  5479. if(okdebug)then
  5480. write(gol,*) "RF_DEPV_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
  5481. end if
  5482. ! time since 1950-1-1 00:00
  5483. t0 = NewDate( time6=time_reftime6 )
  5484. t = NewDate( time6=idate_f )
  5485. time = rTotal( t - t0, 'day' )
  5486. ! Only once : Dimensions
  5487. if ( RF%trec == 1 ) then
  5488. ! write longitudes:
  5489. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
  5490. IF_NOTOK_MDF(fid=RF%ncid)
  5491. ! write latitudes:
  5492. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
  5493. IF_NOTOK_MDF(fid=RF%ncid)
  5494. end if
  5495. !-------- FILL DIAGNOSTIC ARRAYS
  5496. rf%time(rf%trec) = time
  5497. rf%date(:,rf%trec) = real(idate_f)
  5498. ! loop over tracers to be written:
  5499. do k = 1, RF%ntr
  5500. itr = RF%itr(k) ! global tracer index
  5501. #ifndef without_dry_deposition
  5502. rf%data2d(:,:,RF%trec,k) = vd(region,itr)%surf ! deposition velocity
  5503. #else
  5504. rf%data2d(:,:,RF%trec,k) = 0.0
  5505. #endif
  5506. end do
  5507. !-------- WRITE
  5508. if ( RF%trec == n_depv_rec ) then
  5509. call MDF_Put_Var( RF%ncid, RF%varid_time, rf%time, status)
  5510. IF_NOTOK_MDF(fid=RF%ncid)
  5511. call MDF_Put_Var( RF%ncid, RF%varid_date, rf%date, status)
  5512. IF_NOTOK_MDF(fid=RF%ncid)
  5513. ! loop over tracers to be written:
  5514. do k = 1, RF%ntr
  5515. call MDF_Put_Var( RF%ncid, RF%varid_tr(k), rf%data2d(:,:,:,k), status, start=(/i1,j1,1/))
  5516. IF_NOTOK_MDF(fid=RF%ncid)
  5517. end do
  5518. end if
  5519. call goLabel()
  5520. status = 0
  5521. END SUBROUTINE RF_DEPV_Write
  5522. !EOC
  5523. !--------------------------------------------------------------------------
  5524. ! TM5 !
  5525. !--------------------------------------------------------------------------
  5526. !BOP
  5527. !
  5528. ! !IROUTINE: RF_DEPV_Done
  5529. !
  5530. ! !DESCRIPTION:
  5531. !\\
  5532. !\\
  5533. ! !INTERFACE:
  5534. !
  5535. SUBROUTINE RF_DEPV_Done( RF, status )
  5536. !
  5537. ! !INPUT/OUTPUT PARAMETERS:
  5538. !
  5539. type(TPdumpFile_DEPV), intent(inout) :: RF
  5540. !
  5541. ! !OUTPUT PARAMETERS:
  5542. !
  5543. integer, intent(out) :: status
  5544. !
  5545. ! !REVISION HISTORY:
  5546. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  5547. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  5548. !
  5549. !EOP
  5550. !------------------------------------------------------------------------
  5551. !BOC
  5552. character(len=*), parameter :: rname = mname//'/RF_DEPV_Done'
  5553. ! --- begin -------------------------------------
  5554. call goLabel(rname)
  5555. ! close file
  5556. call MDF_Close( RF%ncid , status)
  5557. IF_NOTOK_RETURN(status=1)
  5558. deallocate( rf%time, rf%date, rf%data2d )
  5559. call goLabel() ; status = 0
  5560. END SUBROUTINE RF_DEPV_Done
  5561. !EOC
  5562. #endif
  5563. !--------------------------------------------------------------------------
  5564. ! TM5 !
  5565. !--------------------------------------------------------------------------
  5566. !BOP
  5567. !
  5568. ! !FUNCTION: strlowercase
  5569. !
  5570. ! !DESCRIPTION:
  5571. !
  5572. ! This function returns a copy of the input string 'struppercase' with all
  5573. ! letters changed to lowercase. All other characters remain unchanged.
  5574. !\\
  5575. !\\
  5576. ! !INTERFACE:
  5577. !
  5578. FUNCTION strlowercase(struppercase)
  5579. !
  5580. ! !USES:
  5581. !
  5582. IMPLICIT NONE
  5583. !
  5584. ! !INPUT PARAMETERS:
  5585. !
  5586. CHARACTER(LEN=*), INTENT(IN) :: struppercase
  5587. !
  5588. ! !RETURN VALUE:
  5589. !
  5590. CHARACTER(LEN=LEN(struppercase)) :: strlowercase
  5591. !
  5592. ! !REVISION HISTORY:
  5593. ! 1 Oct 2010 - Achim Strunk -
  5594. !
  5595. !EOP
  5596. !------------------------------------------------------------------------
  5597. !BOC
  5598. CHARACTER(LEN=1) :: u
  5599. INTEGER :: i,j
  5600. strlowercase = struppercase
  5601. DO i=1,LEN(struppercase)
  5602. u = struppercase(i:i)
  5603. j = IACHAR(u)
  5604. IF(j < 65 .OR. j > 90) CYCLE
  5605. strlowercase(i:i) = ACHAR(j+32)
  5606. END DO
  5607. !-------------------------------------------------------------------------------
  5608. END FUNCTION STRLOWERCASE
  5609. !EOC
  5610. !--------------------------------------------------------------------------
  5611. ! TM5 !
  5612. !--------------------------------------------------------------------------
  5613. !BOP
  5614. !
  5615. ! !FUNCTION: struppercase
  5616. !
  5617. ! !DESCRIPTION:
  5618. !
  5619. ! This function returns a copy of the input string 'struppercase' with all
  5620. ! letters changed to lowercase. All other characters remain unchanged.
  5621. !\\
  5622. !\\
  5623. ! !INTERFACE:
  5624. !
  5625. FUNCTION STRUPPERCASE(strlowercase)
  5626. !
  5627. ! !USES:
  5628. !
  5629. IMPLICIT NONE
  5630. !
  5631. ! !INPUT PARAMETERS:
  5632. !
  5633. CHARACTER(LEN=*), INTENT(IN) :: strlowercase
  5634. !
  5635. ! !RETURN VALUE:
  5636. !
  5637. CHARACTER(LEN=LEN(strlowercase)) :: struppercase
  5638. !
  5639. ! !REVISION HISTORY:
  5640. ! 1 Oct 2010 - Achim Strunk -
  5641. !
  5642. !EOP
  5643. !------------------------------------------------------------------------
  5644. !BOC
  5645. CHARACTER(LEN=1) :: u
  5646. INTEGER :: i,j
  5647. struppercase = strlowercase
  5648. DO i=1,LEN(strlowercase)
  5649. u = strlowercase(i:i)
  5650. j = IACHAR(u)
  5651. IF(j < 97 .OR. j > 122) CYCLE
  5652. struppercase(i:i) = ACHAR(j-32)
  5653. END DO
  5654. !-------------------------------------------------------------------------------
  5655. END FUNCTION STRUPPERCASE
  5656. !EOC
  5657. END MODULE USER_OUTPUT_PDUMP