user_output_pdump__co2.F90 135 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878
  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. ! Activation, tracers to account for, time step of the series, are set in the
  27. ! rcfile, following this template :
  28. !
  29. !
  30. ! SAMPLE RCFILE
  31. !
  32. ! output.pdump : T
  33. ! output.pdump.dataset.author : John Doe
  34. ! output.pdump.dataset.institution : MyFirm, Anytown, USA
  35. ! output.pdump.dataset.version : GEMS GRG; era2003 simulation
  36. ! output.pdump.fname.model : TM5
  37. ! output.pdump.fname.expid : V2
  38. ! output.pdump.fname.grid.300x200 : 3x2 ! short name, required if there is zoom regions
  39. ! output.pdump.fname.grid.100x100 : 1x1
  40. !
  41. ! output.pdump.griddef.apply : T
  42. !
  43. ! output.pdump.tp.apply : T
  44. ! output.pdump.tp.dhour : 1
  45. !
  46. ! output.pdump.vmr.n : 3
  47. !
  48. ! output.pdump.vmr.001.apply : T
  49. ! output.pdump.vmr.001.fname : vmr1
  50. ! output.pdump.vmr.001.dhour : 3
  51. ! output.pdump.vmr.001.tracers : CO2
  52. !
  53. ! output.pdump.lt.apply : T
  54. ! output.pdump.lt.tracers : CO2
  55. ! output.pdump.lt.localtime : 2
  56. !
  57. ! output.pdump.lt2.apply : F
  58. ! output.pdump.lt2.tracers : CO2
  59. ! output.pdump.lt2.localtime : 12
  60. !
  61. ! output.pdump.depositions.apply : F
  62. ! output.pdump.depositions.dhour : 3
  63. ! output.pdump.depositions.tracers : CO2
  64. !
  65. ! output.pdump.depvels.apply : F
  66. ! output.pdump.depvels.dhour : 3
  67. ! output.pdump.depvels.tracers : CO2
  68. !
  69. !\\
  70. !\\
  71. ! !INTERFACE:
  72. !
  73. MODULE USER_OUTPUT_PDUMP
  74. !
  75. ! !USES:
  76. !
  77. use GO, only : gol, goPr, goErr, goLabel
  78. use GO, only : TDate
  79. use dims, only : nregions, idatee, idatei, okdebug
  80. use chem_param, only : ntrace
  81. USE MDF
  82. USE TM5_DISTGRID, only : dgrid, Get_DistGrid, update_halo
  83. IMPLICIT NONE
  84. PRIVATE
  85. !
  86. ! !PUBLIC MEMBER FUNCTIONS:
  87. !
  88. public :: Output_PDUMP_Init
  89. public :: Output_PDUMP_Step
  90. public :: Output_PDUMP_Done
  91. !
  92. ! !PRIVATE DATA MEMBERS:
  93. !
  94. character(len=*), parameter :: mname = 'user_output_pdump'
  95. character(len=*), parameter :: outfileversnr = '0.1'
  96. integer, parameter :: time_reftime6(6) = (/1950,01,01,00,00,00/) ! reference time
  97. character(len=*), parameter :: time_units = 'days since 1950-01-01 00:00:00'
  98. !
  99. !
  100. type TPdumpFile_GridDef
  101. integer :: trec
  102. integer :: ncid
  103. integer :: dimid_scalar, dimid_lon, dimid_lat, dimid_lev, dimid_levi
  104. integer :: varid_lon, varid_lat, varid_time, varid_date
  105. integer :: varid_gridbox_area
  106. integer :: varid_a, varid_b
  107. integer :: varid_a_bnds, varid_b_bnds
  108. integer :: varid_p0
  109. !integer :: varid_ps
  110. !integer :: varid_geo_height
  111. end type TPdumpFile_GridDef
  112. type TPdumpFile_TP
  113. integer :: trec
  114. integer :: dhour
  115. integer :: ncid
  116. integer :: dimid_lon, dimid_lat, dimid_lev, dimid_time, dimid_datelen
  117. integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
  118. integer :: varid_ps
  119. integer :: varid_surface_temp
  120. integer :: varid_orog
  121. integer :: varid_geop
  122. integer :: varid_pressure
  123. integer :: varid_temp
  124. integer :: varid_humid
  125. integer :: varid_u, varid_v, varid_w
  126. real, allocatable :: data3d(:,:,:,:,:)
  127. real, allocatable :: data2d(:,:,:,:)
  128. real, allocatable :: time(:)
  129. real, allocatable :: date(:,:)
  130. end type TPdumpFile_TP
  131. type TPdumpFile_VMR
  132. integer :: trec, n_rec
  133. logical :: apply
  134. integer :: dhour
  135. character(len=256) :: tracer_names
  136. integer :: ncid
  137. integer :: dimid_lon, dimid_lat, dimid_lev, dimid_levi, dimid_time, dimid_datelen
  138. integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
  139. integer :: varid_temp
  140. integer :: varid_ps
  141. integer :: varid_a_bnds, varid_b_bnds
  142. integer :: ntr
  143. integer :: itr(ntrace)
  144. character(len=8) :: name_tr(ntrace)
  145. integer :: varid_tr(ntrace)
  146. character(len=4) :: varid_type(ntrace)
  147. real, allocatable :: data3d(:,:,:,:,:)
  148. real, allocatable :: data3d_t(:,:,:,:)
  149. real, allocatable :: sp(:,:,:)
  150. real, allocatable :: time(:)
  151. real, allocatable :: date(:,:)
  152. end type TPdumpFile_VMR
  153. type TPdumpFile_LT
  154. integer :: trec
  155. character(len=256) :: tracer_names
  156. integer :: ncid
  157. integer :: local_time
  158. integer :: dimid_lon, dimid_lat, dimid_lev, dimid_time, dimid_datelen
  159. integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
  160. integer :: varid_ps
  161. integer :: ntr
  162. integer :: itr(ntrace)
  163. character(len=8) :: name_tr(ntrace)
  164. integer :: varid_tr(ntrace)
  165. real,allocatable :: accu(:,:,:,:)
  166. real,allocatable :: naccu(:,:)
  167. real,allocatable :: p_accu(:,:)
  168. real,allocatable :: np_accu(:)
  169. end type TPdumpFile_LT
  170. type TPdumpFile_DEPS
  171. integer :: trec
  172. integer :: dhour
  173. character(len=256) :: tracer_names
  174. integer :: ncid
  175. integer :: dimid_lon, dimid_lat, dimid_time, dimid_datelen
  176. integer :: varid_lon, varid_lat, varid_time, varid_date, varid_accum
  177. integer :: ntr
  178. integer :: itr(ntrace)
  179. character(len=8) :: name_tr(ntrace)
  180. integer :: varid_ddep(ntrace)
  181. real, pointer :: ddep_budget(:,:,:)
  182. logical :: with_wdep(ntrace)
  183. integer :: varid_wdep(ntrace)
  184. real, pointer :: wdep_budget(:,:,:)
  185. type(TDate) :: t0_budget
  186. real, allocatable :: data2d_dry(:,:,:,:)
  187. real, allocatable :: data2d_wet(:,:,:,:)
  188. real, allocatable :: time(:), dt(:)
  189. real, allocatable :: date(:,:)
  190. end type TPdumpFile_DEPS
  191. type TPdumpFile_DEPV
  192. integer :: trec
  193. integer :: dhour
  194. character(len=256) :: tracer_names
  195. integer :: ncid
  196. integer :: dimid_lon, dimid_lat, dimid_time, dimid_datelen
  197. integer :: varid_lon, varid_lat, varid_time, varid_date
  198. integer :: ntr
  199. integer :: itr(ntrace)
  200. character(len=8) :: name_tr(ntrace)
  201. integer :: varid_tr(ntrace)
  202. real, allocatable :: data2d(:,:,:,:)
  203. real, allocatable :: time(:)
  204. real, allocatable :: date(:,:)
  205. end type TPdumpFile_DEPV
  206. ! --- var -----------------------------
  207. integer :: fid ! file id for IF_NOTOK_MDF macro
  208. integer :: access_mode ! netcdf-4 access mode
  209. integer :: curr_day(nregions,3)
  210. logical :: firstday
  211. logical :: lastday ! it is last day and not a full day (ie day does not end at 00 of next day)
  212. character(len=32) :: fname_model
  213. character(len=8) :: fname_expid, meteo_class
  214. character(len=32) :: fname_grid(nregions)
  215. character(len=256) :: dataset_author, institution, dataset_version
  216. logical, save :: griddef_apply
  217. type(TPdumpFile_GridDef), save :: RF_GridDef(nregions)
  218. logical, save :: tp_apply
  219. integer :: tp_dhour, n_tp_rec
  220. type(TPdumpFile_TP), save :: RF_TP(nregions)
  221. integer, save :: nvmr
  222. logical, allocatable :: vmr_apply(:)
  223. real, allocatable :: vmr_sregbord(:,:)
  224. character(len=16), allocatable :: vmr_fname(:)
  225. integer, allocatable :: vmr_dhour(:)
  226. character(len=256), allocatable :: vmr_tracer_names(:)
  227. type(TPdumpFile_VMR), allocatable, save :: RF_VMR(:,:)
  228. logical, save :: lt_apply
  229. character(len=16) :: lt_fname
  230. character(len=256) :: lt_tracer_names
  231. integer :: lt_localtime
  232. type(TPdumpFile_LT), save :: RF_LT(nregions)
  233. logical, save :: lt2_apply
  234. character(len=16) :: lt2_fname
  235. character(len=256) :: lt2_tracer_names
  236. integer :: lt2_localtime
  237. type(TPdumpFile_LT), save :: RF_LT2(nregions)
  238. logical, save :: deps_apply
  239. character(len=16) :: deps_fname
  240. integer :: deps_dhour, n_deps_rec
  241. character(len=256) :: deps_tracer_names
  242. type(TPdumpFile_DEPS), save :: RF_DEPS(nregions)
  243. logical, save :: depv_apply
  244. character(len=16) :: depv_fname
  245. integer :: depv_dhour, n_depv_rec
  246. character(len=256) :: depv_tracer_names
  247. type(TPdumpFile_DEPV), save :: RF_DEPV(nregions)
  248. !
  249. ! !REVISION HISTORY:
  250. !
  251. ! 1 Oct 2010 - Achim Strunk - revised older RETRO ouptut :
  252. ! add 2nd local time, regional output
  253. ! 10 Jul 2012 - Ph. Le Sager - switch from pnetcdf to netcdf4_par (through
  254. ! MDF); get rid of the with_tendencies code.
  255. ! 12 Nov 2012 - Ph. Le Sager - adapted for lon-lat MPI decomposition.
  256. ! - get rid of unlimited dimensions so we can
  257. ! write in collective mode.
  258. ! - store series to write them only at end-of-day
  259. ! to speed-up code
  260. ! 10 Oct 2013 - Ph. Le Sager - fixed GET_N_TIME_RECORDS and several 'init'
  261. ! and write' routines.
  262. ! 14 Apr 2014 - Ph. Le Sager + JEW - tropomi add-ons in VMR: Temperature,
  263. ! As, Bs, better CF
  264. !
  265. ! !REMARKS:
  266. !
  267. ! (1) Initially called RETRO output for GEMS GRG, the module has been adapted
  268. ! for CLIMAQS project and renamed PDUMP.
  269. ! (2) Previous remarks "as is":
  270. ! - longitudes from [0,360] ?
  271. ! this is imposible for zoom area's such as for the heatwave
  272. ! - levels from surface to top
  273. ! - time from 1950-01-01 00:00
  274. ! (3) This is supposed to work with netcdf4_parallel. You cannot use
  275. ! MPI with a non-parallel version of netcdf4 here.
  276. ! (4) The parallel writing is done in COLLECTIVE mode, but remain
  277. ! expensive on some system. Possible optimization : output one file
  278. ! per month (chunk/leg), and/or per field, and/or per processor.
  279. !
  280. !EOP
  281. !------------------------------------------------------------------------
  282. CONTAINS
  283. !--------------------------------------------------------------------------
  284. ! TM5 !
  285. !--------------------------------------------------------------------------
  286. !BOP
  287. !
  288. ! !FUNCTION: GET_N_TIME_RECORDS
  289. !
  290. ! !DESCRIPTION: return number of time steps for a daily timeseries file
  291. !\\
  292. !\\
  293. ! !INTERFACE:
  294. !
  295. FUNCTION GET_N_TIME_RECORDS( date, dh, isDEPS, mess )
  296. !
  297. ! !USES:
  298. !
  299. USE GO , only : TDate, NewDate, rTotal, operator(-)
  300. !
  301. ! !RETURN VALUE:
  302. !
  303. integer :: get_n_time_records
  304. !
  305. ! !INPUT PARAMETERS:
  306. !
  307. integer, intent(in) :: date(6) ! 1st time step of the day (date[4] should be 1 unless 1st day)
  308. integer, intent(in) :: dh ! time step for timeseries (should divide 24)
  309. logical, optional, intent(in) :: isDEPS ! to differentiate b/w DEPS and others
  310. character(len=*), optional, intent(in) :: mess ! message (if okdebug)
  311. !
  312. ! !REVISION HISTORY:
  313. ! 9 Nov 2012 - Ph. Le Sager - v0
  314. ! 9 Oct 2013 - Ph. Le Sager - fix to work with default "output.after.step: v"
  315. !
  316. ! !REMARKS:
  317. ! - assumed dynamic timestep of 1h. It may be smaller at some steps (CFL
  318. ! violation) but that's ok, since it is never zero and we are looking
  319. ! at "integer-hours" for output. Only issue is if dynamic timestep is
  320. ! LARGER than timestep of timeseries: deemed too exotic, but we could
  321. ! add a test in init to avoid that.
  322. !
  323. ! !TODO:
  324. ! - need to check if Oct 2013 fix works with runs that do NOT stop at
  325. ! midnight (labelled "lastday" cases in the code). Deemed exotic for now.
  326. ! - check if anything changes with other possible values of "output.after.step"
  327. !
  328. !EOP
  329. !------------------------------------------------------------------------
  330. !BOC
  331. integer :: is, ie, delta, dynstep
  332. logical :: deps
  333. type(TDate) :: t, t0
  334. real :: time
  335. ! Type of record (standard=vmr, tp, depv) or special (deps)
  336. deps=.false.
  337. if (present(isDEPS)) deps=isDEPS
  338. ! Start index
  339. delta=date(4)
  340. if (deps) delta=date(4)+1 ! one DYNAMIC time step done to output something
  341. if (modulo(delta,dh)==0) then
  342. is=delta/dh
  343. else
  344. is=(delta+dh)/dh
  345. end if
  346. ! End index
  347. ie = 23 / dh ! 23 = 24 - dynamic time step
  348. if (deps) then ! there will be an extra step if run goes further than midnight
  349. t0 = NewDate( time6=date )
  350. t = NewDate( time6=idatee )
  351. time = rTotal( t - t0, 'day' )
  352. if (time > 1) ie=24/dh
  353. end if
  354. ! Case of last day stopping before midnite. (Need testing again - see
  355. ! !TODO. Probaly alright for VMR/TP/DEPV, but check required for DEPS)
  356. if (lastday) ie=idatee(4)/dh
  357. ! length
  358. get_n_time_records = ie-is+1
  359. if(okdebug)then
  360. if (present(mess))then
  361. write(gol,*) 'GET_N_TIME_RECORDS -'//trim(mess); call goPr
  362. end if
  363. write(gol,*) "GET_N_TIME_RECORDS - is, ie, deps, firstday, lastday, get_n_time_records:"; call goPr
  364. write(gol,*) "GET_N_TIME_RECORDS - ", is, ie, deps, firstday, lastday, get_n_time_records; call goPr
  365. end if
  366. return
  367. END FUNCTION GET_N_TIME_RECORDS
  368. !EOC
  369. !--------------------------------------------------------------------------
  370. ! TM5 !
  371. !--------------------------------------------------------------------------
  372. !BOP
  373. !
  374. ! !IROUTINE: OUTPUT_PDUMP_INIT
  375. !
  376. ! !DESCRIPTION: reads rc file keys relevant for pdump
  377. !\\
  378. !\\
  379. ! !INTERFACE:
  380. !
  381. SUBROUTINE OUTPUT_PDUMP_INIT( rcF, dhour_min, status )
  382. !
  383. ! !USES:
  384. !
  385. use GO, only : TrcFile, ReadRc
  386. use MeteoData, only : lli, set
  387. use MeteoData, only : sp_dat, oro_dat, temper_dat, humid_dat, pu_dat, pv_dat
  388. use MeteoData, only : mfw_dat, gph_dat, t2m_dat
  389. !
  390. ! !INPUT/OUTPUT PARAMETERS:
  391. !
  392. type(TrcFile), intent(inout) :: rcF
  393. !
  394. ! !OUTPUT PARAMETERS:
  395. !
  396. integer, intent(out) :: dhour_min
  397. integer, intent(out) :: status
  398. !
  399. ! !REVISION HISTORY:
  400. ! 1 Oct 2010 - Achim Strunk - upgrade from RETRO to PDUMP
  401. ! 8 Nov 2012 - Ph. Le Sager - added access mode switch
  402. !
  403. !EOP
  404. !------------------------------------------------------------------------
  405. !BOC
  406. character(len=*), parameter :: rname = mname//'/Output_PDUMP_Init'
  407. ! --- local ------------------------------
  408. integer :: region
  409. character(len=64) :: key
  410. character(len=3) :: nr
  411. integer :: ivmr
  412. ! --- begin -------------------------------
  413. call goLabel(rname)
  414. #ifdef MPI
  415. #ifdef with_netcdf4_par
  416. access_mode = MDF_COLLECTIVE
  417. #else
  418. write(gol,'("Time Series output (PDUMP) requires netcdf4 with parallel access enabled")') ; call goErr
  419. TRACEBACK
  420. status=1; return
  421. #endif
  422. #else
  423. access_mode = MDF_INDEPENDENT
  424. #endif
  425. ! which day
  426. firstday = .true.
  427. lastday = .true.
  428. if (any(idatei(1:3)/=idatee(1:3))) lastday=.false. ! i.e. at least one full day
  429. ! dataset keys:
  430. call ReadRc( rcF, 'output.pdump.dataset.author' , dataset_author , status )
  431. IF_NOTOK_RETURN(status=1)
  432. call ReadRc( rcF, 'output.pdump.dataset.institution', institution , status )
  433. IF_NOTOK_RETURN(status=1)
  434. call ReadRc( rcF, 'output.pdump.dataset.version' , dataset_version , status )
  435. IF_NOTOK_RETURN(status=1)
  436. ! filename keys:
  437. call ReadRc( rcF, 'output.pdump.fname.model', fname_model, status )
  438. IF_NOTOK_RETURN(status=1)
  439. call ReadRc( rcF, 'output.pdump.fname.expid', fname_expid, status )
  440. IF_NOTOK_RETURN(status=1)
  441. ! prefix grid name in case of zooming regions:
  442. if ( nregions > 1 ) then
  443. ! loop over regions:
  444. do region = 1, nregions
  445. ! short grid name from rcfile:
  446. call ReadRc( rcF, 'output.pdump.fname.grid.'//trim(lli(region)%name), key, status )
  447. IF_NOTOK_RETURN(status=1)
  448. ! fill grid extenstion to file names:
  449. fname_grid(region) = '-'//trim(key)
  450. end do
  451. else
  452. ! empty
  453. fname_grid = ''
  454. end if
  455. ! griddef file ?
  456. call ReadRc( rcF, 'output.pdump.griddef.apply', griddef_apply, status )
  457. IF_NOTOK_RETURN(status=1)
  458. ! temperature, pressure, etc file ?
  459. call ReadRc( rcF, 'output.pdump.tp.apply', tp_apply, status )
  460. IF_NOTOK_RETURN(status=1)
  461. if (tp_apply) then
  462. ! ensure that required meteo is loaded
  463. do region=1,nregions
  464. call Set( sp_dat(region), status, used=.true. )
  465. call Set( oro_dat(region), status, used=.true. )
  466. call Set( temper_dat(region), status, used=.true. )
  467. call Set( t2m_dat(region), status, used=.true. )
  468. call Set( humid_dat(region), status, used=.true. )
  469. call Set( pu_dat(region), status, used=.true. )
  470. call Set( pv_dat(region), status, used=.true. )
  471. call Set( mfw_dat(region), status, used=.true. )
  472. call Set( gph_dat(region), status, used=.true. ) ! used to compute vertical wind
  473. end do
  474. end if
  475. ! time resolution (1 hour by default)
  476. call ReadRc( rcF, 'output.pdump.tp.dhour', tp_dhour, status, default=1 )
  477. IF_ERROR_RETURN(status=1)
  478. ! VMR files
  479. call ReadRc( rcF, 'output.pdump.vmr.n', nvmr, status ) ! number of vmr files to be written
  480. IF_NOTOK_RETURN(status=1)
  481. if ( nvmr < 0 ) then
  482. write (gol,'("strange specification of number of vmr files : ",i6)') nvmr; call goErr
  483. TRACEBACK; status=1; return
  484. end if
  485. ! meteo
  486. call ReadRc( rcF, 'my.meteo.class', meteo_class, status, default='unknown' )
  487. IF_ERROR_RETURN(status=1)
  488. ! write any vmr files ?
  489. if ( nvmr > 0 ) then
  490. ! storage:
  491. allocate( vmr_apply(nvmr) ) ; vmr_apply = .false.
  492. allocate( vmr_fname(nvmr) ) ; vmr_fname = ''
  493. allocate( vmr_dhour(nvmr) ) ; vmr_dhour = -1
  494. allocate( vmr_tracer_names(nvmr) ) ; vmr_tracer_names = ''
  495. allocate( vmr_sregbord(nvmr,4) ) ; vmr_sregbord = -999.9
  496. allocate( RF_VMR(nregions,nvmr) )
  497. #ifdef tropomi
  498. do region=1,nregions
  499. call Set( temper_dat(region), status, used=.true. )
  500. end do
  501. #endif
  502. ! loop over vmr files:
  503. do ivmr = 1, nvmr
  504. ! number in rc keys:
  505. write (nr,'(i3.3)') ivmr
  506. ! apply ?
  507. call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.apply', vmr_apply(ivmr), status )
  508. IF_NOTOK_RETURN(status=1)
  509. rf_vmr(:,ivmr)%apply = vmr_apply(ivmr)
  510. ! proceed ?
  511. if ( vmr_apply(ivmr) ) then
  512. ! first part of filename:
  513. call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.fname', vmr_fname(ivmr), status )
  514. IF_NOTOK_RETURN(status=1)
  515. ! time resolution:
  516. call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.dhour', vmr_dhour(ivmr), status )
  517. IF_NOTOK_RETURN(status=1)
  518. ! tracers to be written:
  519. call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.tracers', vmr_tracer_names(ivmr), status )
  520. IF_NOTOK_RETURN(status=1)
  521. end if ! apply ?
  522. end do ! vmr numbers
  523. ! required meteo
  524. if (any(vmr_apply)) then
  525. do region=1,nregions
  526. call Set( sp_dat(region), status, used=.true. )
  527. end do
  528. end if
  529. end if ! nvmr > 0
  530. ! ---------------------
  531. ! local time:
  532. ! ---------------------
  533. ! file 1
  534. lt_fname = 'lt'
  535. call ReadRc( rcF, 'output.pdump.lt.apply', lt_apply, status )
  536. IF_NOTOK_RETURN(status=1)
  537. if ( lt_apply ) then
  538. call ReadRc( rcF, 'output.pdump.lt.tracers', lt_tracer_names, status )
  539. IF_NOTOK_RETURN(status=1)
  540. call ReadRc( rcF, 'output.pdump.lt.localtime', lt_localtime, status )
  541. IF_NOTOK_RETURN(status=1)
  542. end if
  543. ! file 2
  544. lt2_fname = 'lt2'
  545. call ReadRc( rcF, 'output.pdump.lt2.apply', lt2_apply, status )
  546. IF_NOTOK_RETURN(status=1)
  547. if ( lt2_apply ) then
  548. call ReadRc( rcF, 'output.pdump.lt2.tracers', lt2_tracer_names, status )
  549. IF_NOTOK_RETURN(status=1)
  550. call ReadRc( rcF, 'output.pdump.lt2.localtime', lt2_localtime, status )
  551. IF_NOTOK_RETURN(status=1)
  552. end if
  553. if (lt_apply .or. lt2_apply) then
  554. do region=1,nregions
  555. call Set( sp_dat(region), status, used=.true. )
  556. end do
  557. end if
  558. ! ---------------------
  559. ! deposition fluxes:
  560. ! ---------------------
  561. deps_fname = 'depositions'
  562. call ReadRc( rcF, 'output.pdump.depositions.apply', deps_apply, status )
  563. IF_NOTOK_RETURN(status=1)
  564. if ( deps_apply ) then
  565. call ReadRc( rcF, 'output.pdump.depositions.dhour', deps_dhour, status )
  566. IF_NOTOK_RETURN(status=1)
  567. call ReadRc( rcF, 'output.pdump.depositions.tracers', deps_tracer_names, status )
  568. IF_NOTOK_RETURN(status=1)
  569. end if
  570. ! ---------------------
  571. ! deposition velocities:
  572. ! ---------------------
  573. depv_fname = 'depvels'
  574. call ReadRc( rcF, 'output.pdump.depvels.apply', depv_apply, status )
  575. IF_NOTOK_RETURN(status=1)
  576. if ( depv_apply ) then
  577. call ReadRc( rcF, 'output.pdump.depvels.dhour', depv_dhour, status )
  578. IF_NOTOK_RETURN(status=1)
  579. call ReadRc( rcF, 'output.pdump.depvels.tracers', depv_tracer_names, status )
  580. IF_NOTOK_RETURN(status=1)
  581. end if
  582. ! no files open yet
  583. curr_day = -1
  584. ! lowest time frequency is 1 hour
  585. dhour_min = 1
  586. call goLabel()
  587. ! ok
  588. status = 0
  589. END SUBROUTINE OUTPUT_PDUMP_INIT
  590. !EOC
  591. !--------------------------------------------------------------------------
  592. ! TM5 !
  593. !--------------------------------------------------------------------------
  594. !BOP
  595. !
  596. ! !IROUTINE: OUTPUT_PDUMP_STEP
  597. !
  598. ! !DESCRIPTION:
  599. !\\
  600. !\\
  601. ! !INTERFACE:
  602. !
  603. SUBROUTINE OUTPUT_PDUMP_STEP( region, idate_f, status )
  604. !
  605. ! !INPUT PARAMETERS:
  606. !
  607. integer, intent(in) :: region
  608. integer, intent(in) :: idate_f(6)
  609. !
  610. ! !OUTPUT PARAMETERS:
  611. !
  612. integer, intent(out) :: status
  613. !
  614. ! !REVISION HISTORY:
  615. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  616. !
  617. ! !REMARKS:
  618. ! (1) called every hour.
  619. !
  620. !EOP
  621. !------------------------------------------------------------------------
  622. !BOC
  623. character(len=*), parameter :: rname = mname//'/Output_PDUMP_Step'
  624. ! --- begin -------------------------------
  625. call goLabel(rname)
  626. !----------------------
  627. ! close if necessary
  628. !----------------------
  629. ! if a file is open, and it is a new day
  630. if ( all(curr_day(region,:) > 0) .and. any(idate_f(1:3) /= curr_day(region,:)) ) then
  631. ! write in previous day file end-of-interval data
  632. call PDUMP_Files_Write2( region, idate_f, status )
  633. IF_NOTOK_RETURN(status=1)
  634. ! close all
  635. call PDUMP_Files_Close( region, status )
  636. IF_NOTOK_RETURN(status=1)
  637. ! no files open ...
  638. curr_day(region,:) = -1
  639. firstday = .false.
  640. end if
  641. !----------------------
  642. ! open if necessary
  643. !----------------------
  644. if ( any(curr_day(region,:) < 0) ) then
  645. if (all(idate_f(1:3)==idatee(1:3))) lastday=.true. ! means last day is not a full day
  646. write(gol,*) "U_O_Pdump open [idate_f, last day] = ", idate_f, lastday; call goPr
  647. call PDUMP_Files_Open( region, idate_f, status )
  648. IF_NOTOK_RETURN(status=1)
  649. ! store date of current day
  650. curr_day(region,:) = idate_f(1:3)
  651. end if
  652. !----------------------
  653. ! write
  654. !----------------------
  655. call PDUMP_Files_Write( region, idate_f, status )
  656. IF_NOTOK_RETURN(status=1)
  657. ! if not midnight, write end-of-interval data
  658. if ( any(idate_f(4:6) > 0) ) then
  659. call PDUMP_Files_Write2( region, idate_f, status )
  660. IF_NOTOK_RETURN(status=1)
  661. end if
  662. !----------------------
  663. ! done
  664. !----------------------
  665. call goLabel()
  666. status = 0
  667. END SUBROUTINE OUTPUT_PDUMP_STEP
  668. !EOC
  669. !--------------------------------------------------------------------------
  670. ! TM5 !
  671. !--------------------------------------------------------------------------
  672. !BOP
  673. !
  674. ! !IROUTINE: OUTPUT_PDUMP_DONE
  675. !
  676. ! !DESCRIPTION:
  677. !\\
  678. !\\
  679. ! !INTERFACE:
  680. !
  681. SUBROUTINE OUTPUT_PDUMP_DONE( status )
  682. !
  683. ! !OUTPUT PARAMETERS:
  684. !
  685. integer, intent(out) :: status
  686. !
  687. ! !REVISION HISTORY:
  688. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  689. ! 31 Aug 2012 - P. Le Sager - reverse order in which regions are dealt with (MDF issue)
  690. !
  691. !EOP
  692. !------------------------------------------------------------------------
  693. !BOC
  694. character(len=*), parameter :: rname = mname//'/Output_PDUMP_Done'
  695. integer :: region
  696. ! --- begin -------------------------------
  697. ! close files:
  698. do region = nregions, 1, -1
  699. call PDUMP_Files_Close( region, status )
  700. IF_NOTOK_RETURN(status=1)
  701. end do
  702. ! clear:
  703. if ( nvmr > 0 ) then
  704. deallocate( vmr_apply )
  705. deallocate( vmr_fname )
  706. deallocate( vmr_dhour )
  707. deallocate( vmr_tracer_names )
  708. deallocate( vmr_sregbord )
  709. deallocate( RF_VMR )
  710. end if
  711. ! ok
  712. status = 0
  713. END SUBROUTINE OUTPUT_PDUMP_DONE
  714. !EOC
  715. ! ********************************************************************
  716. ! ***
  717. ! *** open/write/close pdump files
  718. ! ***
  719. ! ********************************************************************
  720. !--------------------------------------------------------------------------
  721. ! TM5 !
  722. !--------------------------------------------------------------------------
  723. !BOP
  724. !
  725. ! !IROUTINE: PDUMP_FILES_OPEN
  726. !
  727. ! !DESCRIPTION: call init method of each output file.
  728. !\\
  729. !\\
  730. ! !INTERFACE:
  731. !
  732. subroutine PDUMP_Files_Open( region, idate_f, status )
  733. !
  734. ! !USES:
  735. !
  736. use global_data, only : outdir
  737. !
  738. ! !INPUT PARAMETERS:
  739. !
  740. integer, intent(in) :: region
  741. integer, intent(in) :: idate_f(6)
  742. !
  743. ! !OUTPUT PARAMETERS:
  744. !
  745. integer, intent(out) :: status
  746. !
  747. ! !REVISION HISTORY:
  748. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  749. !
  750. !EOP
  751. !------------------------------------------------------------------------
  752. !BOC
  753. character(len=*), parameter :: rname = mname//'/PDUMP_Files_Open'
  754. ! --- local -------------------------------
  755. integer :: ivmr
  756. ! --- begin -------------------------------
  757. ! grid definition:
  758. if ( griddef_apply ) then
  759. call RF_GridDef_Init( RF_GridDef(region), outdir, fname_model, fname_expid, region, status )
  760. IF_NOTOK_RETURN(status=1)
  761. end if
  762. ! dynamics:
  763. if ( tp_apply ) then
  764. call RF_TP_Init ( RF_TP(region) , outdir, fname_model, fname_expid, &
  765. region, idate_f, tp_dhour, status )
  766. IF_NOTOK_RETURN(status=1)
  767. end if
  768. ! tracer concentrations:
  769. do ivmr = 1, nvmr
  770. if ( .not. vmr_apply(ivmr) ) cycle
  771. call RF_VMR_Init( RF_VMR(region,ivmr), outdir, fname_model, fname_expid, &
  772. vmr_fname(ivmr), region, idate_f, &
  773. vmr_dhour(ivmr), vmr_tracer_names(ivmr), status )
  774. IF_NOTOK_RETURN(status=1)
  775. vmr_apply(ivmr) = rf_vmr(region,ivmr)%apply
  776. end do
  777. ! lt output:
  778. if ( lt_apply ) then
  779. call RF_LT_Init( RF_LT(region), outdir, fname_model, fname_expid, &
  780. lt_fname, region, idate_f, &
  781. lt_localtime, lt_tracer_names, status )
  782. IF_NOTOK_RETURN(status=1)
  783. end if
  784. if ( lt2_apply ) then
  785. call RF_LT_Init( RF_LT2(region), outdir, fname_model, fname_expid, &
  786. lt2_fname, region, idate_f, &
  787. lt2_localtime, lt2_tracer_names, status )
  788. IF_NOTOK_RETURN(status=1)
  789. end if
  790. ! deposition fluxes:
  791. ! if ( deps_apply ) then
  792. ! call RF_DEPS_Init( RF_DEPS(region), outdir, fname_model, fname_expid, &
  793. ! deps_fname, region, idate_f, &
  794. ! deps_dhour, deps_tracer_names, status )
  795. ! IF_NOTOK_RETURN(status=1)
  796. ! end if
  797. ! ! deposition velocities:
  798. ! if ( depv_apply ) then
  799. ! call RF_DEPV_Init( RF_DEPV(region), outdir, fname_model, fname_expid, &
  800. ! depv_fname, region, idate_f, &
  801. ! depv_dhour, depv_tracer_names, status )
  802. ! IF_NOTOK_RETURN(status=1)
  803. ! end if
  804. ! ok
  805. status = 0
  806. END SUBROUTINE PDUMP_FILES_OPEN
  807. !EOC
  808. !--------------------------------------------------------------------------
  809. ! TM5 !
  810. !--------------------------------------------------------------------------
  811. !BOP
  812. !
  813. ! !IROUTINE: PDUMP_FILES_WRITE
  814. !
  815. ! !DESCRIPTION: call write method for each output file.
  816. !\\
  817. !\\
  818. ! !INTERFACE:
  819. !
  820. SUBROUTINE PDUMP_FILES_WRITE( region, idate_f, status )
  821. !
  822. ! !INPUT PARAMETERS:
  823. !
  824. integer, intent(in) :: region
  825. integer, intent(in) :: idate_f(6)
  826. !
  827. ! !OUTPUT PARAMETERS:
  828. !
  829. integer, intent(out) :: status
  830. !
  831. ! !REVISION HISTORY:
  832. ! 1 Oct 2010 - Achim Strunk -
  833. !
  834. !EOP
  835. !------------------------------------------------------------------------
  836. !BOC
  837. character(len=*), parameter :: rname = mname//'/PDUMP_Files_Write'
  838. integer :: ivmr
  839. ! --- begin -------------------------------
  840. ! grid definition:
  841. if ( griddef_apply ) then
  842. call RF_GridDef_Write( RF_GridDef(region), region, status )
  843. IF_NOTOK_RETURN(status=1)
  844. end if
  845. ! dynamics:
  846. if ( tp_apply ) then
  847. call RF_TP_Write( RF_TP(region), region, idate_f, status )
  848. IF_NOTOK_RETURN(status=1)
  849. end if
  850. ! tracer fields:
  851. do ivmr = 1, nvmr
  852. if ( .not. vmr_apply(ivmr) ) cycle
  853. call RF_VMR_Write( RF_VMR(region,ivmr), region, idate_f, status )
  854. IF_NOTOK_RETURN(status=1)
  855. end do
  856. ! lt output:
  857. if ( lt_apply ) then
  858. call RF_LT_Write( RF_LT(region), region, idate_f, status )
  859. IF_NOTOK_RETURN(status=1)
  860. end if
  861. if ( lt2_apply ) then
  862. call RF_LT_Write( RF_LT2(region), region, idate_f, status )
  863. IF_NOTOK_RETURN(status=1)
  864. end if
  865. ! ! deposition velocities:
  866. ! if ( depv_apply ) then
  867. ! call RF_DEPV_Write( RF_DEPV(region), region, idate_f, status )
  868. ! IF_NOTOK_RETURN(status=1)
  869. ! end if
  870. status = 0
  871. END SUBROUTINE PDUMP_FILES_WRITE
  872. !EOC
  873. !--------------------------------------------------------------------------
  874. ! TM5 !
  875. !--------------------------------------------------------------------------
  876. !BOP
  877. !
  878. ! !IROUTINE: PDUMP_FILES_WRITE2
  879. !
  880. ! !DESCRIPTION: write at end of time interval
  881. !
  882. !\\
  883. !\\
  884. ! !INTERFACE:
  885. !
  886. SUBROUTINE PDUMP_FILES_WRITE2( region, idate_f, status )
  887. !
  888. ! !INPUT PARAMETERS:
  889. !
  890. integer, intent(in) :: region
  891. integer, intent(in) :: idate_f(6)
  892. !
  893. ! !OUTPUT PARAMETERS:
  894. !
  895. integer, intent(out) :: status
  896. !
  897. ! !REVISION HISTORY:
  898. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  899. !
  900. !EOP
  901. !------------------------------------------------------------------------
  902. !BOC
  903. character(len=*), parameter :: rname = mname//'/PDUMP_Files_Write2'
  904. ! --- begin -------------------------------
  905. ! deposition fluxes:
  906. ! if ( deps_apply ) then
  907. ! call RF_DEPS_Write( RF_DEPS(region), region, idate_f, status )
  908. ! IF_NOTOK_RETURN(status=1)
  909. ! end if
  910. ! lt output:
  911. if ( lt_apply ) then
  912. call RF_LT_Write( RF_LT(region), region, idate_f, status )
  913. IF_NOTOK_RETURN(status=1)
  914. end if
  915. if ( lt2_apply ) then
  916. call RF_LT_Write( RF_LT2(region), region, idate_f, status )
  917. IF_NOTOK_RETURN(status=1)
  918. end if
  919. ! ok
  920. status = 0
  921. END SUBROUTINE PDUMP_FILES_WRITE2
  922. !EOC
  923. !--------------------------------------------------------------------------
  924. ! TM5 !
  925. !--------------------------------------------------------------------------
  926. !BOP
  927. !
  928. ! !IROUTINE: PDUMP_FILES_CLOSE
  929. !
  930. ! !DESCRIPTION: call done method of each output file.
  931. !\\
  932. !\\
  933. ! !INTERFACE:
  934. !
  935. SUBROUTINE PDUMP_FILES_CLOSE( region, status )
  936. !
  937. ! !INPUT PARAMETERS:
  938. !
  939. integer, intent(in) :: region
  940. !
  941. ! !OUTPUT PARAMETERS:
  942. !
  943. integer, intent(out) :: status
  944. !
  945. ! !REVISION HISTORY:
  946. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  947. ! 31 Aug 2012 - Ph. Le Sager - switch closing order, since it was giving issues on some machine.
  948. !
  949. !EOP
  950. !------------------------------------------------------------------------
  951. !BOC
  952. character(len=*), parameter :: rname = mname//'/PDUMP_Files_Close'
  953. ! --- local -------------------------------
  954. integer :: ivmr
  955. ! --- begin -------------------------------
  956. ! if ( depv_apply ) then
  957. ! call RF_DEPV_Done( RF_DEPV(region), status )
  958. ! IF_NOTOK_RETURN(status=1)
  959. ! end if
  960. ! if ( deps_apply ) then
  961. ! call RF_DEPS_Done( RF_DEPS(region), status )
  962. ! IF_NOTOK_RETURN(status=1)
  963. ! end if
  964. if ( lt2_apply ) then
  965. call RF_LT_Done( RF_LT2(region), region, status )
  966. IF_NOTOK_RETURN(status=1)
  967. end if
  968. if ( lt_apply ) then
  969. call RF_LT_Done( RF_LT(region), region, status )
  970. IF_NOTOK_RETURN(status=1)
  971. end if
  972. do ivmr = nvmr, 1, -1
  973. if ( .not. vmr_apply(ivmr) ) cycle
  974. call RF_VMR_Done( RF_VMR(region,ivmr), status )
  975. IF_NOTOK_RETURN(status=1)
  976. end do
  977. if ( tp_apply ) then
  978. call RF_TP_Done ( RF_TP(region) , status )
  979. IF_NOTOK_RETURN(status=1)
  980. end if
  981. if ( griddef_apply ) then
  982. call RF_GridDef_Done( RF_GridDef(region), status )
  983. IF_NOTOK_RETURN(status=1)
  984. end if
  985. status = 0
  986. end subroutine PDUMP_Files_Close
  987. !EOC
  988. !--------------------------------------------------------------------------
  989. ! TM5 !
  990. !--------------------------------------------------------------------------
  991. !BOP
  992. !
  993. ! !IROUTINE: RF_GRIDDEF_INIT
  994. !
  995. ! !DESCRIPTION:
  996. !
  997. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  998. ! FILE 1: Model horizontal grid definition
  999. ! (longitude, latitude, size of gridbox [m2] ).
  1000. ! For documentation purposes, please also include the native vertical
  1001. ! grid definition from your model (hybrid level coefficients) and the
  1002. ! formula used to calculate pressure.
  1003. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1004. !
  1005. !\\
  1006. !\\
  1007. ! !INTERFACE:
  1008. !
  1009. subroutine RF_GridDef_Init( RF, fdir, model, expid, region, status )
  1010. !
  1011. ! !USES:
  1012. !
  1013. use partools, only : MPI_INFO_NULL, localComm
  1014. use MeteoData, only : global_lli, levi
  1015. !
  1016. ! !OUTPUT PARAMETERS:
  1017. !
  1018. type(TPdumpFile_GridDef), intent(out) :: RF
  1019. !
  1020. ! !INPUT PARAMETERS:
  1021. !
  1022. character(len=*), intent(in) :: fdir
  1023. character(len=*), intent(in) :: model
  1024. character(len=*), intent(in) :: expid
  1025. integer, intent(in) :: region
  1026. integer, intent(out) :: status
  1027. !
  1028. ! !REVISION HISTORY:
  1029. ! 1 Oct 2010 - Achim Strunk -
  1030. ! 10 Jul 2012 - Ph. Le Sager - switch to MDF_NETCDF4
  1031. !
  1032. !EOP
  1033. !------------------------------------------------------------------------
  1034. !BOC
  1035. character(len=*), parameter :: rname = mname//'/RF_GridDef_Init'
  1036. character(len=256) :: fname
  1037. integer :: varid
  1038. integer :: rtype
  1039. ! --- begin -------------------------------------
  1040. call goLabel(rname)
  1041. ! o open file
  1042. ! write filename
  1043. write (fname,'(a,"/",a,a,"_",a,"_",a,".nc")') &
  1044. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), 'griddef'
  1045. #ifdef MPI
  1046. ! overwrite existing files (clobber), provide MPI stuff:
  1047. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  1048. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  1049. if (status/=0) then
  1050. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  1051. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  1052. TRACEBACK; status=1; return
  1053. end if
  1054. #else
  1055. ! overwrite existing files (clobber)
  1056. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  1057. IF_NOTOK_RETURN(status=1)
  1058. #endif
  1059. ! o global attributes
  1060. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title', 'model horizontal definition' , status)
  1061. IF_NOTOK_MDF(fid=RF%ncid)
  1062. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
  1063. IF_NOTOK_MDF(fid=RF%ncid)
  1064. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
  1065. IF_NOTOK_MDF(fid=RF%ncid)
  1066. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status)
  1067. IF_NOTOK_MDF(fid=RF%ncid)
  1068. ! o define dimensions
  1069. call MDF_Def_Dim( RF%ncid, 'scalar', 1, RF%dimid_scalar , status)
  1070. IF_NOTOK_MDF(fid=RF%ncid)
  1071. call MDF_Def_Dim( RF%ncid, 'lon', global_lli(region)%nlon, RF%dimid_lon , status)
  1072. IF_NOTOK_MDF(fid=RF%ncid)
  1073. call MDF_Def_Dim( RF%ncid, 'lat', global_lli(region)%nlat, RF%dimid_lat , status)
  1074. IF_NOTOK_MDF(fid=RF%ncid)
  1075. call MDF_Def_Dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
  1076. IF_NOTOK_MDF(fid=RF%ncid)
  1077. call MDF_Def_Dim( RF%ncid, 'levi', levi%nlev+1, RF%dimid_levi , status)
  1078. IF_NOTOK_MDF(fid=RF%ncid)
  1079. !call MDF_Def_Dim( RF%ncid, 'time', NTS, RF%dimid_time , status)
  1080. !IF_NOTOK_MDF(fid=RF%ncid)
  1081. !call MDF_Def_Dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
  1082. !IF_NOTOK_MDF(fid=RF%ncid)
  1083. ! o define variables
  1084. rtype = MDF_FLOAT
  1085. call MDF_Def_Var( RF%ncid, 'lon', rtype, (/RF%dimid_lon/), varid , status)
  1086. IF_NOTOK_MDF(fid=RF%ncid)
  1087. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1088. IF_NOTOK_MDF(fid=RF%ncid)
  1089. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  1090. IF_NOTOK_MDF(fid=RF%ncid)
  1091. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'longitude' , status)
  1092. IF_NOTOK_MDF(fid=RF%ncid)
  1093. call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_east' , status)
  1094. IF_NOTOK_MDF(fid=RF%ncid)
  1095. RF%varid_lon = varid
  1096. call MDF_Def_Var( RF%ncid, 'lat', MDF_FLOAT, (/RF%dimid_lat/), varid , status)
  1097. IF_NOTOK_MDF(fid=RF%ncid)
  1098. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1099. IF_NOTOK_MDF(fid=RF%ncid)
  1100. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  1101. IF_NOTOK_MDF(fid=RF%ncid)
  1102. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'latitude' , status)
  1103. IF_NOTOK_MDF(fid=RF%ncid)
  1104. call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_north' , status)
  1105. IF_NOTOK_MDF(fid=RF%ncid)
  1106. RF%varid_lat = varid
  1107. !call MDF_Def_Var( RF%ncid, 'time', MDF_FLOAT, RF%dimid_time, varid , status)
  1108. !IF_NOTOK_MDF(fid=RF%ncid)
  1109. !call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1110. !IF_NOTOK_MDF(fid=RF%ncid)
  1111. !call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
  1112. !IF_NOTOK_MDF(fid=RF%ncid)
  1113. !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'time' , status)
  1114. !IF_NOTOK_MDF(fid=RF%ncid)
  1115. !call MDF_Put_Att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
  1116. !IF_NOTOK_MDF(fid=RF%ncid)
  1117. !call MDF_Put_Att( RF%ncid, varid, 'calender', 'gregorian' , status)
  1118. !IF_NOTOK_MDF(fid=RF%ncid)
  1119. !RF%varid_time = varid
  1120. !call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  1121. !IF_NOTOK_MDF(fid=RF%ncid)
  1122. !call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1123. !IF_NOTOK_MDF(fid=RF%ncid)
  1124. !call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'date' , status)
  1125. !IF_NOTOK_MDF(fid=RF%ncid)
  1126. !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
  1127. !IF_NOTOK_MDF(fid=RF%ncid)
  1128. !call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
  1129. !IF_NOTOK_MDF(fid=RF%ncid)
  1130. !RF%varid_date = varid
  1131. call MDF_Def_Var( RF%ncid, 'area', MDF_FLOAT, (/RF%dimid_lon,RF%dimid_lat/), varid , status)
  1132. IF_NOTOK_MDF(fid=RF%ncid)
  1133. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1134. IF_NOTOK_MDF(fid=RF%ncid)
  1135. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'grid_cell_area' , status)
  1136. IF_NOTOK_MDF(fid=RF%ncid)
  1137. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'grid-cell area' , status)
  1138. IF_NOTOK_MDF(fid=RF%ncid)
  1139. call MDF_Put_Att( RF%ncid, varid, 'units', 'm2' , status)
  1140. IF_NOTOK_MDF(fid=RF%ncid)
  1141. RF%varid_gridbox_area = varid
  1142. call MDF_Def_Var( RF%ncid, 'a', MDF_FLOAT, (/RF%dimid_lev/), varid , status)
  1143. IF_NOTOK_MDF(fid=RF%ncid)
  1144. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1145. IF_NOTOK_MDF(fid=RF%ncid)
  1146. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  1147. IF_NOTOK_MDF(fid=RF%ncid)
  1148. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient' , status)
  1149. IF_NOTOK_MDF(fid=RF%ncid)
  1150. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  1151. IF_NOTOK_MDF(fid=RF%ncid)
  1152. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a(k)*p0 + b(k)*ps(n,j,i)' , status)
  1153. IF_NOTOK_MDF(fid=RF%ncid)
  1154. call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up' , status)
  1155. IF_NOTOK_MDF(fid=RF%ncid)
  1156. RF%varid_a = varid
  1157. call MDF_Def_Var( RF%ncid, 'b', mdf_float, (/RF%dimid_lev/), varid , status)
  1158. IF_NOTOK_MDF(fid=RF%ncid)
  1159. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1160. IF_NOTOK_MDF(fid=RF%ncid)
  1161. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  1162. IF_NOTOK_MDF(fid=RF%ncid)
  1163. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient' , status)
  1164. IF_NOTOK_MDF(fid=RF%ncid)
  1165. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  1166. IF_NOTOK_MDF(fid=RF%ncid)
  1167. call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a(k)*p0 + b(k)*ps(n,j,i)' , status)
  1168. IF_NOTOK_MDF(fid=RF%ncid)
  1169. call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up' , status)
  1170. IF_NOTOK_MDF(fid=RF%ncid)
  1171. RF%varid_b = varid
  1172. call MDF_Def_Var( RF%ncid, 'a_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
  1173. IF_NOTOK_MDF(fid=RF%ncid)
  1174. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1175. IF_NOTOK_MDF(fid=RF%ncid)
  1176. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  1177. IF_NOTOK_MDF(fid=RF%ncid)
  1178. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
  1179. IF_NOTOK_MDF(fid=RF%ncid)
  1180. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  1181. IF_NOTOK_MDF(fid=RF%ncid)
  1182. 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)
  1183. IF_NOTOK_MDF(fid=RF%ncid)
  1184. RF%varid_a_bnds = varid
  1185. call MDF_Def_Var( RF%ncid, 'b_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
  1186. IF_NOTOK_MDF(fid=RF%ncid)
  1187. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1188. IF_NOTOK_MDF(fid=RF%ncid)
  1189. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  1190. IF_NOTOK_MDF(fid=RF%ncid)
  1191. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
  1192. IF_NOTOK_MDF(fid=RF%ncid)
  1193. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  1194. IF_NOTOK_MDF(fid=RF%ncid)
  1195. 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)
  1196. IF_NOTOK_MDF(fid=RF%ncid)
  1197. RF%varid_b_bnds = varid
  1198. call MDF_Def_Var( RF%ncid, 'p0', mdf_float, (/RF%dimid_scalar/), varid , status)
  1199. IF_NOTOK_MDF(fid=RF%ncid)
  1200. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1201. IF_NOTOK_MDF(fid=RF%ncid)
  1202. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'reference pressure value' , status)
  1203. IF_NOTOK_MDF(fid=RF%ncid)
  1204. call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
  1205. IF_NOTOK_MDF(fid=RF%ncid)
  1206. RF%varid_p0 = varid
  1207. !status = pnf90_def_var( RF%ncid, 'ps', MDF_FLOAT, &
  1208. ! (/RF%dimid_lon,RF%dimid_lat,RF%dimid_time/), varid )
  1209. !IF_NOTOK_MDF(fid=RF%ncid)
  1210. !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
  1211. !IF_NOTOK_MDF(fid=RF%ncid)
  1212. !call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
  1213. !IF_NOTOK_MDF(fid=RF%ncid)
  1214. !RF%varid_ps = varid
  1215. !status = pnf90_def_var( RF%ncid, 'geo_height', MDF_FLOAT, &
  1216. ! (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid )
  1217. !IF_NOTOK_MDF(fid=RF%ncid)
  1218. !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'geopotential height' , status)
  1219. !IF_NOTOK_MDF(fid=RF%ncid)
  1220. !call MDF_Put_Att( RF%ncid, varid, 'units', 'm' , status)
  1221. !IF_NOTOK_MDF(fid=RF%ncid)
  1222. !call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up; lower half level; top value implicit infinity' , status)
  1223. !IF_NOTOK_MDF(fid=RF%ncid)
  1224. !RF%varid_geo_height = varid
  1225. ! o end defintion mode
  1226. call MDF_EndDef( RF%ncid , status)
  1227. IF_NOTOK_MDF(fid=RF%ncid)
  1228. ! no records written yet
  1229. RF%trec = 0
  1230. call goLabel() ; status = 0
  1231. END SUBROUTINE RF_GRIDDEF_INIT
  1232. !EOC
  1233. !--------------------------------------------------------------------------
  1234. ! TM5 !
  1235. !--------------------------------------------------------------------------
  1236. !BOP
  1237. !
  1238. ! !IROUTINE: RF_GridDef_Write
  1239. !
  1240. ! !DESCRIPTION:
  1241. !\\
  1242. !\\
  1243. ! !INTERFACE:
  1244. !
  1245. SUBROUTINE RF_GRIDDEF_WRITE( RF, region, status )
  1246. !
  1247. ! !USES:
  1248. !
  1249. use GO, only : TDate, NewDate, rTotal, operator(-)
  1250. use Grid, only : AreaOper
  1251. use MeteoData, only : global_lli, levi, sp_dat
  1252. !
  1253. ! !INPUT/OUTPUT PARAMETERS:
  1254. !
  1255. type(TPdumpFile_GridDef), intent(inout) :: RF
  1256. !
  1257. ! !INPUT PARAMETERS:
  1258. !
  1259. integer, intent(in) :: region
  1260. !
  1261. ! !OUTPUT PARAMETERS:
  1262. !
  1263. integer, intent(out) :: status
  1264. !
  1265. ! !REVISION HISTORY:
  1266. ! 1 Oct 2010 - Achim Strunk -
  1267. ! 10 Jul 2012 - Ph. Le Sager - switch to MDF_NETCDF4
  1268. !
  1269. !EOP
  1270. !------------------------------------------------------------------------
  1271. !BOC
  1272. character(len=*), parameter :: rname = mname//'/RF_GridDef_Write'
  1273. integer :: imr, jmr, lmr
  1274. real, allocatable :: ll(:,:)
  1275. real :: time
  1276. ! --- begin -------------------------------------
  1277. call goLabel(rname)
  1278. ! grid size
  1279. imr = global_lli(region)%nlon
  1280. jmr = global_lli(region)%nlat
  1281. lmr = levi%nlev
  1282. ! next time record:
  1283. RF%trec = RF%trec + 1
  1284. ! o write data
  1285. if ( RF%trec == 1 ) then
  1286. ! lat/lon field:
  1287. allocate( ll(imr,jmr) )
  1288. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg, status)
  1289. IF_NOTOK_MDF(fid=RF%ncid)
  1290. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg, status)
  1291. IF_NOTOK_MDF(fid=RF%ncid)
  1292. ll = 1.0
  1293. call AreaOper( global_lli(region), ll, '*', 'm2', status )
  1294. IF_NOTOK_RETURN(status=1)
  1295. call MDF_Put_Var( RF%ncid, RF%varid_gridbox_area, ll , status)
  1296. IF_NOTOK_MDF(fid=RF%ncid)
  1297. call MDF_Put_Var( RF%ncid, RF%varid_a, levi%fa , status)
  1298. IF_NOTOK_MDF(fid=RF%ncid)
  1299. call MDF_Put_Var( RF%ncid, RF%varid_b, levi%fb , status)
  1300. IF_NOTOK_MDF(fid=RF%ncid)
  1301. call MDF_Put_Var( RF%ncid, RF%varid_a_bnds, levi%a(0:levi%nlev) , status)
  1302. IF_NOTOK_MDF(fid=RF%ncid)
  1303. call MDF_Put_Var( RF%ncid, RF%varid_b_bnds, levi%b(0:levi%nlev) , status)
  1304. IF_NOTOK_MDF(fid=RF%ncid)
  1305. call MDF_Put_Var( RF%ncid, RF%varid_p0, (/1.0/) , status)
  1306. IF_NOTOK_MDF(fid=RF%ncid)
  1307. deallocate( ll )
  1308. end if
  1309. !call MDF_Put_Var( RF%ncid, RF%varid_time, time, index=RF%trec , status)
  1310. !IF_NOTOK_MDF(fid=RF%ncid)
  1311. !call MDF_Put_Var( RF%ncid, RF%varid_date, reshape(real(idate_f),(/6,1/), status), &
  1312. ! start=(/1,RF%trec/), count=(/6,1/) )
  1313. !IF_NOTOK_MDF(fid=RF%ncid)
  1314. !status = pnf90_put_var( RF%ncid, RF%varid_ps, &
  1315. ! reshape(sp_dat(region)%data(1:imr,1:jmr,1:1),(/imr,jmr,1/)), &
  1316. ! start=(/1,1,RF%trec/), count=(/imr,jmr,1/) )
  1317. !IF_NOTOK_MDF(fid=RF%ncid)
  1318. !status = pnf90_put_var( RF%ncid, RF%varid_geo_height, &
  1319. ! reshape(gph_dat(region)%data(1:imr,1:jmr,1:lmr),(/imr,jmr,lmr,1/)), &
  1320. ! start=(/1,1,1,RF%trec/), count=(/imr,jmr,lmr,1/) )
  1321. !IF_NOTOK_MDF(fid=RF%ncid)
  1322. call goLabel()
  1323. status = 0
  1324. END SUBROUTINE RF_GridDef_Write
  1325. !EOC
  1326. !--------------------------------------------------------------------------
  1327. ! TM5 !
  1328. !--------------------------------------------------------------------------
  1329. !BOP
  1330. !
  1331. ! !IROUTINE: RF_GRIDDEF_DONE
  1332. !
  1333. ! !DESCRIPTION: close file-1
  1334. !\\
  1335. !\\
  1336. ! !INTERFACE:
  1337. !
  1338. SUBROUTINE RF_GridDef_Done( RF, status )
  1339. !
  1340. ! !INPUT/OUTPUT PARAMETERS:
  1341. !
  1342. type(TPdumpFile_GridDef), intent(inout) :: RF
  1343. !
  1344. ! !OUTPUT PARAMETERS:
  1345. !
  1346. integer, intent(out) :: status
  1347. !
  1348. ! !REVISION HISTORY:
  1349. ! 1 Oct 2010 - Achim Strunk -
  1350. !
  1351. !EOP
  1352. !------------------------------------------------------------------------
  1353. !BOC
  1354. character(len=*), parameter :: rname = mname//'/RF_GridDef_Done'
  1355. ! --- begin -------------------------------------
  1356. call goLabel(rname)
  1357. call MDF_Close( RF%ncid , status)
  1358. IF_NOTOK_RETURN(status=1)
  1359. call goLabel()
  1360. status = 0
  1361. END SUBROUTINE RF_GRIDDEF_DONE
  1362. !EOC
  1363. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1364. ! FILE2: 3D field of monthly Model pressure [Pa] and temperature [K].
  1365. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1366. !--------------------------------------------------------------------------
  1367. ! TM5 !
  1368. !--------------------------------------------------------------------------
  1369. !BOP
  1370. !
  1371. ! !IROUTINE: RF_TP_INIT
  1372. !
  1373. ! !DESCRIPTION: file-2 : open and define var/att
  1374. !
  1375. !\\
  1376. !\\
  1377. ! !INTERFACE:
  1378. !
  1379. SUBROUTINE RF_TP_Init( RF, fdir, model, expid, region, idate_f, dhour, status )
  1380. !
  1381. ! !USES:
  1382. !
  1383. use partools, only : MPI_INFO_NULL, localComm
  1384. use MeteoData, only : global_lli, levi
  1385. !
  1386. ! !OUTPUT PARAMETERS:
  1387. !
  1388. type(TPdumpFile_TP), intent(out) :: RF
  1389. integer, intent(out) :: status
  1390. !
  1391. ! !INPUT PARAMETERS:
  1392. !
  1393. character(len=*), intent(in) :: fdir
  1394. character(len=*), intent(in) :: model
  1395. character(len=*), intent(in) :: expid
  1396. integer, intent(in) :: region
  1397. integer, intent(in) :: idate_f(6)
  1398. integer, intent(in) :: dhour
  1399. !
  1400. ! !REVISION HISTORY:
  1401. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  1402. ! 7 Aug 2012 - Ph. Le Sager - switch to netcdf-4 thru MDF
  1403. !
  1404. !EOP
  1405. !------------------------------------------------------------------------
  1406. !BOC
  1407. character(len=*), parameter :: rname = mname//'/RF_TP_Init'
  1408. ! --- local ------------------------------------
  1409. character(len=256) :: fname
  1410. integer :: varid, i1, i2, j1, j2
  1411. ! --- begin -------------------------------------
  1412. call goLabel(rname)
  1413. ! store arguments
  1414. RF%dhour = dhour
  1415. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1416. n_tp_rec = GET_N_TIME_RECORDS( idate_f, dhour, mess='TP_Init' )
  1417. if ( n_tp_rec == 0 ) then
  1418. tp_apply = .false.
  1419. status=0
  1420. return
  1421. end if
  1422. ! o open file
  1423. ! write filename
  1424. write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
  1425. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), 'TP', idate_f(1:3)
  1426. ! open, overwrite existing files (clobber)
  1427. #ifdef MPI
  1428. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  1429. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  1430. if (status/=0) then
  1431. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  1432. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  1433. TRACEBACK; status=1; return
  1434. end if
  1435. #else
  1436. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  1437. IF_NOTOK_RETURN(status=1)
  1438. #endif
  1439. ! o global attributes
  1440. call mdf_put_att( RF%ncid, MDF_GLOBAL, 'title', 'model pressure and temperature', status)
  1441. IF_NOTOK_MDF(fid=RF%ncid)
  1442. call mdf_put_att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
  1443. IF_NOTOK_MDF(fid=RF%ncid)
  1444. call mdf_put_att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
  1445. IF_NOTOK_MDF(fid=RF%ncid)
  1446. call mdf_put_att( RF%ncid, MDF_GLOBAL, 'dataset_version', trim(dataset_version) , status)
  1447. IF_NOTOK_MDF(fid=RF%ncid)
  1448. ! o define dimensions
  1449. call mdf_def_dim( RF%ncid, 'lon', global_lli(region)%nlon, RF%dimid_lon , status)
  1450. IF_NOTOK_MDF(fid=RF%ncid)
  1451. call mdf_def_dim( RF%ncid, 'lat', global_lli(region)%nlat, RF%dimid_lat , status)
  1452. IF_NOTOK_MDF(fid=RF%ncid)
  1453. call mdf_def_dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
  1454. IF_NOTOK_MDF(fid=RF%ncid)
  1455. call mdf_def_dim( RF%ncid, 'time', n_tp_rec, RF%dimid_time , status)
  1456. IF_NOTOK_MDF(fid=RF%ncid)
  1457. call mdf_def_dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
  1458. IF_NOTOK_MDF(fid=RF%ncid)
  1459. ! o define variables
  1460. call mdf_def_var( RF%ncid, 'lon', MDF_FLOAT, (/RF%dimid_lon/), varid , status)
  1461. IF_NOTOK_MDF(fid=RF%ncid)
  1462. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1463. IF_NOTOK_MDF(fid=RF%ncid)
  1464. call mdf_put_att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  1465. IF_NOTOK_MDF(fid=RF%ncid)
  1466. call mdf_put_att( RF%ncid, varid, 'long_name', 'longitude' , status)
  1467. IF_NOTOK_MDF(fid=RF%ncid)
  1468. call mdf_put_att( RF%ncid, varid, 'units', 'degrees_east' , status)
  1469. IF_NOTOK_MDF(fid=RF%ncid)
  1470. RF%varid_lon = varid
  1471. call mdf_def_var( RF%ncid, 'lat', MDF_FLOAT, (/RF%dimid_lat/), varid , status)
  1472. IF_NOTOK_MDF(fid=RF%ncid)
  1473. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1474. IF_NOTOK_MDF(fid=RF%ncid)
  1475. call mdf_put_att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  1476. IF_NOTOK_MDF(fid=RF%ncid)
  1477. call mdf_put_att( RF%ncid, varid, 'long_name', 'latitude' , status)
  1478. IF_NOTOK_MDF(fid=RF%ncid)
  1479. call mdf_put_att( RF%ncid, varid, 'units', 'degrees_north' , status)
  1480. IF_NOTOK_MDF(fid=RF%ncid)
  1481. RF%varid_lat = varid
  1482. call mdf_def_var( RF%ncid, 'lev', MDF_FLOAT, (/RF%dimid_lev/), varid , status)
  1483. IF_NOTOK_MDF(fid=RF%ncid)
  1484. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1485. IF_NOTOK_MDF(fid=RF%ncid)
  1486. call mdf_put_att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
  1487. IF_NOTOK_MDF(fid=RF%ncid)
  1488. call mdf_put_att( RF%ncid, varid, 'long_name', 'level' , status)
  1489. IF_NOTOK_MDF(fid=RF%ncid)
  1490. call mdf_put_att( RF%ncid, varid, 'units', '1' , status)
  1491. IF_NOTOK_MDF(fid=RF%ncid)
  1492. 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)
  1493. IF_NOTOK_MDF(fid=RF%ncid)
  1494. RF%varid_lev = varid
  1495. call mdf_def_var( RF%ncid, 'time', MDF_FLOAT, (/RF%dimid_time/), varid , status)
  1496. IF_NOTOK_MDF(fid=RF%ncid)
  1497. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1498. IF_NOTOK_MDF(fid=RF%ncid)
  1499. call mdf_put_att( RF%ncid, varid, 'standard_name', 'time' , status)
  1500. IF_NOTOK_MDF(fid=RF%ncid)
  1501. call mdf_put_att( RF%ncid, varid, 'long_name', 'time' , status)
  1502. IF_NOTOK_MDF(fid=RF%ncid)
  1503. call mdf_put_att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
  1504. IF_NOTOK_MDF(fid=RF%ncid)
  1505. call mdf_put_att( RF%ncid, varid, 'calender', 'gregorian' , status)
  1506. IF_NOTOK_MDF(fid=RF%ncid)
  1507. RF%varid_time = varid
  1508. allocate(RF%time(n_tp_rec))
  1509. call mdf_def_var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  1510. IF_NOTOK_MDF(fid=RF%ncid)
  1511. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1512. IF_NOTOK_MDF(fid=RF%ncid)
  1513. call mdf_put_att( RF%ncid, varid, 'long_name', 'date and time' , status)
  1514. IF_NOTOK_MDF(fid=RF%ncid)
  1515. call mdf_put_att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
  1516. IF_NOTOK_MDF(fid=RF%ncid)
  1517. RF%varid_date = varid
  1518. allocate(RF%date(6,n_tp_rec))
  1519. call mdf_def_var( RF%ncid, 'ps', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  1520. IF_NOTOK_MDF(fid=RF%ncid)
  1521. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1522. IF_NOTOK_MDF(fid=RF%ncid)
  1523. call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_air_pressure' , status)
  1524. IF_NOTOK_MDF(fid=RF%ncid)
  1525. call mdf_put_att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
  1526. IF_NOTOK_MDF(fid=RF%ncid)
  1527. call mdf_put_att( RF%ncid, varid, 'units', 'Pa' , status)
  1528. IF_NOTOK_MDF(fid=RF%ncid)
  1529. RF%varid_ps = varid
  1530. call mdf_def_var( RF%ncid, 'orog', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  1531. IF_NOTOK_MDF(fid=RF%ncid)
  1532. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1533. IF_NOTOK_MDF(fid=RF%ncid)
  1534. call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_altitude' , status)
  1535. IF_NOTOK_MDF(fid=RF%ncid)
  1536. call mdf_put_att( RF%ncid, varid, 'long_name', 'surface altitude' , status)
  1537. IF_NOTOK_MDF(fid=RF%ncid)
  1538. call mdf_put_att( RF%ncid, varid, 'units', 'm' , status)
  1539. IF_NOTOK_MDF(fid=RF%ncid)
  1540. RF%varid_orog = varid
  1541. call mdf_def_var( RF%ncid, 'surface_temp', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status)
  1542. IF_NOTOK_MDF(fid=RF%ncid)
  1543. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1544. IF_NOTOK_MDF(fid=RF%ncid)
  1545. call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_temperature' , status)
  1546. IF_NOTOK_MDF(fid=RF%ncid)
  1547. call mdf_put_att( RF%ncid, varid, 'long_name', 'surface temperature' , status)
  1548. IF_NOTOK_MDF(fid=RF%ncid)
  1549. call mdf_put_att( RF%ncid, varid, 'units', 'K' , status)
  1550. IF_NOTOK_MDF(fid=RF%ncid)
  1551. call mdf_put_att( RF%ncid, varid, 'comment', &
  1552. '2m temperature from MARS archive or IFS model (grib 167, 2T)' , status)
  1553. IF_NOTOK_MDF(fid=RF%ncid)
  1554. RF%varid_surface_temp = varid
  1555. allocate( RF%data2d(i1:i2, j1:j2, n_tp_rec, 3) )
  1556. call mdf_def_var( RF%ncid, 'geopotential', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1557. IF_NOTOK_MDF(fid=RF%ncid)
  1558. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1559. IF_NOTOK_MDF(fid=RF%ncid)
  1560. call mdf_put_att( RF%ncid, varid, 'standard_name', 'geopotential' , status)
  1561. IF_NOTOK_MDF(fid=RF%ncid)
  1562. call mdf_put_att( RF%ncid, varid, 'long_name', 'geopotential' , status)
  1563. IF_NOTOK_MDF(fid=RF%ncid)
  1564. call mdf_put_att( RF%ncid, varid, 'units', 'm2 s-2' , status)
  1565. IF_NOTOK_MDF(fid=RF%ncid)
  1566. call mdf_put_att( RF%ncid, varid, 'comment', 'at mid levels' , status)
  1567. IF_NOTOK_MDF(fid=RF%ncid)
  1568. RF%varid_geop = varid
  1569. call mdf_def_var( RF%ncid, 'pressure', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1570. IF_NOTOK_MDF(fid=RF%ncid)
  1571. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1572. IF_NOTOK_MDF(fid=RF%ncid)
  1573. call mdf_put_att( RF%ncid, varid, 'standard_name', 'pressure' , status)
  1574. IF_NOTOK_MDF(fid=RF%ncid)
  1575. call mdf_put_att( RF%ncid, varid, 'long_name', 'pressure' , status)
  1576. IF_NOTOK_MDF(fid=RF%ncid)
  1577. call mdf_put_att( RF%ncid, varid, 'units', 'Pa' , status)
  1578. IF_NOTOK_MDF(fid=RF%ncid)
  1579. call mdf_put_att( RF%ncid, varid, 'comment', 'at mid levels' , status)
  1580. IF_NOTOK_MDF(fid=RF%ncid)
  1581. RF%varid_pressure = varid
  1582. call mdf_def_var( RF%ncid, 'temp', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1583. IF_NOTOK_MDF(fid=RF%ncid)
  1584. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1585. IF_NOTOK_MDF(fid=RF%ncid)
  1586. call mdf_put_att( RF%ncid, varid, 'standard_name', 'air_temperature' , status)
  1587. IF_NOTOK_MDF(fid=RF%ncid)
  1588. call mdf_put_att( RF%ncid, varid, 'long_name', 'temperature' , status)
  1589. IF_NOTOK_MDF(fid=RF%ncid)
  1590. call mdf_put_att( RF%ncid, varid, 'units', 'K' , status)
  1591. IF_NOTOK_MDF(fid=RF%ncid)
  1592. call mdf_put_att( RF%ncid, varid, 'comment', 'bottom-up; full levels' , status)
  1593. IF_NOTOK_MDF(fid=RF%ncid)
  1594. RF%varid_temp = varid
  1595. call mdf_def_var( RF%ncid, 'specific_humidity', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1596. IF_NOTOK_MDF(fid=RF%ncid)
  1597. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1598. IF_NOTOK_MDF(fid=RF%ncid)
  1599. call mdf_put_att( RF%ncid, varid, 'standard_name', 'specific_humidity' , status)
  1600. IF_NOTOK_MDF(fid=RF%ncid)
  1601. call mdf_put_att( RF%ncid, varid, 'long_name', 'specific humidity' , status)
  1602. IF_NOTOK_MDF(fid=RF%ncid)
  1603. call mdf_put_att( RF%ncid, varid, 'units', 'kg kg-1' , status)
  1604. IF_NOTOK_MDF(fid=RF%ncid)
  1605. call mdf_put_att( RF%ncid, varid, 'comment', 'mass fraction of water vapor in moist air; (kg water)/(kg air)' , status)
  1606. IF_NOTOK_MDF(fid=RF%ncid)
  1607. RF%varid_humid = varid
  1608. call mdf_def_var( RF%ncid, 'U', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1609. IF_NOTOK_MDF(fid=RF%ncid)
  1610. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1611. IF_NOTOK_MDF(fid=RF%ncid)
  1612. call mdf_put_att( RF%ncid, varid, 'standard_name', 'eastward_wind' , status)
  1613. IF_NOTOK_MDF(fid=RF%ncid)
  1614. call mdf_put_att( RF%ncid, varid, 'long_name', 'zonal wind' , status)
  1615. IF_NOTOK_MDF(fid=RF%ncid)
  1616. call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
  1617. IF_NOTOK_MDF(fid=RF%ncid)
  1618. call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
  1619. IF_NOTOK_MDF(fid=RF%ncid)
  1620. RF%varid_u = varid
  1621. call mdf_def_var( RF%ncid, 'V', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1622. IF_NOTOK_MDF(fid=RF%ncid)
  1623. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1624. IF_NOTOK_MDF(fid=RF%ncid)
  1625. call mdf_put_att( RF%ncid, varid, 'standard_name', 'northward_wind' , status)
  1626. IF_NOTOK_MDF(fid=RF%ncid)
  1627. call mdf_put_att( RF%ncid, varid, 'long_name', 'meridional wind' , status)
  1628. IF_NOTOK_MDF(fid=RF%ncid)
  1629. call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
  1630. IF_NOTOK_MDF(fid=RF%ncid)
  1631. call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
  1632. IF_NOTOK_MDF(fid=RF%ncid)
  1633. RF%varid_v = varid
  1634. call mdf_def_var( RF%ncid, 'W', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  1635. IF_NOTOK_MDF(fid=RF%ncid)
  1636. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  1637. IF_NOTOK_MDF(fid=RF%ncid)
  1638. call mdf_put_att( RF%ncid, varid, 'long_name', 'vertical wind velocity' , status)
  1639. IF_NOTOK_MDF(fid=RF%ncid)
  1640. call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
  1641. IF_NOTOK_MDF(fid=RF%ncid)
  1642. call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
  1643. IF_NOTOK_MDF(fid=RF%ncid)
  1644. RF%varid_w = varid
  1645. allocate( RF%data3d(i1:i2, j1:j2, levi%nlev, n_tp_rec, 7) )
  1646. ! o end defintion mode
  1647. call mdf_enddef( RF%ncid , status)
  1648. IF_NOTOK_MDF(fid=RF%ncid)
  1649. ! o
  1650. ! no records written yet
  1651. RF%trec = 0
  1652. call goLabel()
  1653. ! ok
  1654. status = 0
  1655. END SUBROUTINE RF_TP_Init
  1656. !EOC
  1657. !--------------------------------------------------------------------------
  1658. ! TM5 !
  1659. !--------------------------------------------------------------------------
  1660. !BOP
  1661. !
  1662. ! !IROUTINE: RF_TP_Write
  1663. !
  1664. ! !DESCRIPTION: store records, and if last time step write data to file
  1665. !\\
  1666. !\\
  1667. ! !INTERFACE:
  1668. !
  1669. SUBROUTINE RF_TP_Write( RF, region, idate_f, status )
  1670. !
  1671. ! !USES:
  1672. !
  1673. use Binas , only : grav
  1674. use Phys , only : GeoPotentialHeight
  1675. use Grid , only : FPressure, HPressure
  1676. use GO , only : TDate, NewDate, rTotal, operator(-)
  1677. use partools , only : myid, root
  1678. use MeteoData , only : global_lli, lli, levi
  1679. use MeteoData , only : sp_dat, temper_dat, humid_dat, pu_dat, pv_dat, mfw_dat, gph_dat, oro_dat, t2m_dat
  1680. use MeteoData , only : m_dat
  1681. use global_data, only : mass_dat
  1682. !
  1683. ! !INPUT/OUTPUT PARAMETERS:
  1684. !
  1685. type(TPdumpFile_TP), intent(inout) :: RF
  1686. !
  1687. ! !INPUT PARAMETERS:
  1688. !
  1689. integer, intent(in) :: region
  1690. integer, intent(in) :: idate_f(6)
  1691. !
  1692. ! !OUTPUT PARAMETERS:
  1693. !
  1694. integer, intent(out) :: status
  1695. !
  1696. ! !REVISION HISTORY:
  1697. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  1698. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  1699. !
  1700. !EOP
  1701. !------------------------------------------------------------------------
  1702. !BOC
  1703. character(len=*), parameter :: rname = mname//'/RF_TP_Write'
  1704. ! --- local ------------------------------------
  1705. integer :: i, j, l, i1, i2, j1, j2
  1706. integer :: imr, jmr, lmr, klm
  1707. real :: lev(levi%nlev)
  1708. type(TDate) :: t, t0
  1709. real :: time
  1710. real, allocatable :: field3d(:,:,:)
  1711. real :: p_hlev(0:levi%nlev)
  1712. ! --- begin -------------------------------------
  1713. ! for multiple of dhour only ...
  1714. if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
  1715. status=0; return
  1716. end if
  1717. call goLabel(rname)
  1718. ! grid size
  1719. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1720. imr=i2-i1+1
  1721. jmr=j2-j1+1
  1722. lmr = levi%nlev
  1723. ! next time record:
  1724. RF%trec = RF%trec + 1
  1725. ! time since reftime:
  1726. t0 = NewDate( time6=time_reftime6 )
  1727. t = NewDate( time6=idate_f )
  1728. time = rTotal( t - t0, 'day' )
  1729. if(okdebug)then
  1730. write(gol,*) "RF_TP_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
  1731. end if
  1732. ! o write data
  1733. if ( RF%trec == 1 ) then
  1734. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
  1735. IF_NOTOK_MDF(fid=RF%ncid)
  1736. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
  1737. IF_NOTOK_MDF(fid=RF%ncid)
  1738. do l = 1, lmr
  1739. lev(l) = real(l)
  1740. end do
  1741. call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
  1742. IF_NOTOK_MDF(fid=RF%ncid)
  1743. end if
  1744. ! temporary storage for 3D fields
  1745. allocate( field3d(i1:i2,j1:j2,1:lmr) ) ; field3d = 0.
  1746. !-------- FILL DIAGNOSTIC ARRAYS
  1747. RF%time(RF%trec) = time
  1748. RF%date(:,RF%trec) = real(idate_f)
  1749. RF%data2d(:,:,RF%trec,1) = sp_dat(region)%data(i1:i2,j1:j2,1)
  1750. RF%data2d(:,:,RF%trec,2) = oro_dat(region)%data(i1:i2,j1:j2,1)
  1751. RF%data2d(:,:,RF%trec,3) = t2m_dat(region)%data(i1:i2,j1:j2,1)
  1752. ! o geopotential
  1753. ! fill mid level geopotential:
  1754. do j = j1, j2
  1755. do i = i1, i2
  1756. ! half level pressures
  1757. call HPressure( levi, sp_dat(region)%data(i,j,1), p_hlev, status )
  1758. IF_NOTOK_RETURN(status=1)
  1759. ! mid level gph (m)
  1760. call GeoPotentialHeight( lmr, p_hlev, temper_dat(region)%data(i,j,:), &
  1761. humid_dat(region)%data(i,j,:), oro_dat(region)%data(i,j,1)/grav, &
  1762. field3d(i,j,:) ) ! m
  1763. end do
  1764. end do
  1765. ! multiply with gravity for correct unit:
  1766. field3d = field3d * grav ! m2/s2
  1767. RF%data3d(:,:,:,RF%trec,1) = field3d
  1768. ! o pressure
  1769. ! fill mid level pressure
  1770. call FPressure( levi, sp_dat(region)%data(i1:i2,j1:j2,1), field3d, status )
  1771. IF_NOTOK_RETURN(status=1)
  1772. RF%data3d(:,:,:,RF%trec,2) = field3d
  1773. ! o temperature
  1774. RF%data3d(:,:,:,RF%trec,3) = temper_dat(region)%data(i1:i2,j1:j2,1:lmr)
  1775. ! o specific humidity
  1776. RF%data3d(:,:,:,RF%trec,4) = humid_dat(region)%data(i1:i2,j1:j2,1:lmr)
  1777. ! o wind fields
  1778. CALL UPDATE_HALO( dgrid(region), pu_dat(region)%data, pu_dat(region)%halo, status)
  1779. IF_NOTOK_RETURN(status=1)
  1780. CALL UPDATE_HALO( dgrid(region), pv_dat(region)%data, pv_dat(region)%halo, status)
  1781. IF_NOTOK_RETURN(status=1)
  1782. ! average U wind
  1783. 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) ) &
  1784. / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
  1785. do j = j1, j2
  1786. field3d(:,j,:) = field3d(:,j,:) * lli(region)%dx(j-j1+1) ! m/s
  1787. end do
  1788. RF%data3d(:,:,:,RF%trec,5) = field3d
  1789. ! average V wind:
  1790. 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) ) &
  1791. / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
  1792. field3d = field3d * lli(region)%dy ! m/s
  1793. RF%data3d(:,:,:,RF%trec,6) = field3d
  1794. ! from downward massflux to upward average W wind:
  1795. field3d = 0.5 * ( mfw_dat(region)%data(i1:i2,j1:j2,0:lmr-1) + mfw_dat(region)%data(i1:i2,j1:j2,1:lmr) ) &
  1796. / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
  1797. do l = 1, lmr
  1798. field3d(:,:,l) = - 1.0 * field3d(:,:,l) * &
  1799. abs( gph_dat(region)%data(i1:i2,j1:j2,l+1) - gph_dat(region)%data(i1:i2,j1:j2,l) ) ! m/s
  1800. end do
  1801. RF%data3d(:,:,:,RF%trec,7) = field3d
  1802. !-------- WRITE ARRAYS
  1803. if ( RF%trec == n_tp_rec ) then
  1804. ! time
  1805. call MDF_Put_Var( RF%ncid, RF%varid_time, RF%time, status)!, start=(/1/), count=(/n_tp_rec/))
  1806. IF_NOTOK_MDF(fid=RF%ncid)
  1807. ! date
  1808. call MDF_Put_Var( RF%ncid, RF%varid_date, RF%date, status )!, &
  1809. ! start=(/1,1/), count=(/6,1/) )
  1810. IF_NOTOK_MDF(fid=RF%ncid)
  1811. ! surface pressure
  1812. call MDF_Put_Var( RF%ncid, RF%varid_ps, RF%data2d(:,:,:,1), status, start=(/i1,j1,1/), count=(/imr,jmr,n_tp_rec/) )
  1813. IF_NOTOK_MDF(fid=RF%ncid)
  1814. ! orography (in m!)
  1815. call MDF_Put_Var( RF%ncid, RF%varid_orog, RF%data2d(:,:,:,2), status, start=(/i1,j1,1/), count=(/imr,jmr,n_tp_rec/) )
  1816. IF_NOTOK_MDF(fid=RF%ncid)
  1817. ! surface temperature = 2m temperature
  1818. call MDF_Put_Var( RF%ncid, RF%varid_surface_temp, RF%data2d(:,:,:,3), status, start=(/i1,j1,1/) ) !, count=(/imr,jmr,1/) )
  1819. IF_NOTOK_MDF(fid=RF%ncid)
  1820. ! geopotential
  1821. 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/) )
  1822. IF_NOTOK_MDF(fid=RF%ncid)
  1823. ! pressure
  1824. call MDF_Put_Var( RF%ncid, RF%varid_pressure, RF%data3d(:,:,:,:,2), status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,n_tp_rec/) )
  1825. IF_NOTOK_MDF(fid=RF%ncid)
  1826. ! temperature
  1827. 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/) )
  1828. IF_NOTOK_MDF(fid=RF%ncid)
  1829. ! specific humidity
  1830. 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/) )
  1831. IF_NOTOK_MDF(fid=RF%ncid)
  1832. ! winds
  1833. 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/) )
  1834. IF_NOTOK_MDF(fid=RF%ncid)
  1835. 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/) )
  1836. IF_NOTOK_MDF(fid=RF%ncid)
  1837. 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/) )
  1838. IF_NOTOK_MDF(fid=RF%ncid)
  1839. end if
  1840. ! Done
  1841. deallocate( field3d )
  1842. call goLabel()
  1843. status = 0
  1844. END SUBROUTINE RF_TP_Write
  1845. !EOC
  1846. !--------------------------------------------------------------------------
  1847. ! TM5 !
  1848. !--------------------------------------------------------------------------
  1849. !BOP
  1850. !
  1851. ! !IROUTINE: RF_TP_Done
  1852. !
  1853. ! !DESCRIPTION: close file #2
  1854. !\\
  1855. !\\
  1856. ! !INTERFACE:
  1857. !
  1858. subroutine RF_TP_Done( RF, status )
  1859. !
  1860. ! !INPUT/OUTPUT PARAMETERS:
  1861. !
  1862. type(TPdumpFile_TP), intent(inout) :: RF
  1863. !
  1864. ! !OUTPUT PARAMETERS:
  1865. !
  1866. integer, intent(out) :: status
  1867. !
  1868. ! !REVISION HISTORY:
  1869. ! 1 Oct 2010 - Achim Strunk -
  1870. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  1871. !
  1872. !EOP
  1873. !------------------------------------------------------------------------
  1874. !BOC
  1875. character(len=*), parameter :: rname = mname//'/RF_TP_Done'
  1876. ! --- begin -------------------------------------
  1877. call goLabel(rname)
  1878. call MDF_Close( RF%ncid , status)
  1879. IF_NOTOK_RETURN(status=1)
  1880. deallocate( rf%time, rf%date, rf%data2d, rf%data3d )
  1881. call goLabel() ; status = 0
  1882. end subroutine RF_TP_Done
  1883. !EOC
  1884. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1885. ! FILE3: 3D fields for CO2 Volume Mixing Ratios
  1886. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1887. !--------------------------------------------------------------------------
  1888. ! TM5 !
  1889. !--------------------------------------------------------------------------
  1890. !BOP
  1891. !
  1892. ! !IROUTINE: RF_VMR_Init
  1893. !
  1894. ! !DESCRIPTION: open and define variables/attribute for file #3
  1895. !\\
  1896. !\\
  1897. ! !INTERFACE:
  1898. !
  1899. subroutine RF_VMR_Init( RF, fdir, model, expid, filetype, region, &
  1900. idate_f, dhour, tracer_names, status )
  1901. !
  1902. ! !USES:
  1903. !
  1904. use Binas, only : xmair
  1905. use GO, only : goReadFromLine, goUpCase
  1906. use chem_param, only : ntrace, names, ra
  1907. use partools, only : MPI_INFO_NULL, localComm
  1908. use MeteoData, only : global_lli, lli, levi, sp_dat
  1909. use dims, only : xbeg, xend, ybeg, yend, dx, dy, dz, xref, yref, zref
  1910. use dims, only : zbeg, zend
  1911. !
  1912. ! !INPUT/OUTPUT PARAMETERS:
  1913. !
  1914. type(TPdumpFile_VMR), intent(inout) :: RF
  1915. !
  1916. ! !INPUT PARAMETERS:
  1917. !
  1918. character(len=*), intent(in) :: fdir
  1919. character(len=*), intent(in) :: model
  1920. character(len=*), intent(in) :: expid
  1921. character(len=*), intent(in) :: filetype
  1922. integer, intent(in) :: region
  1923. integer, intent(in) :: idate_f(6)
  1924. integer, intent(in) :: dhour
  1925. character(len=*), intent(in) :: tracer_names
  1926. !
  1927. ! !OUTPUT PARAMETERS:
  1928. !
  1929. integer, intent(out) :: status
  1930. !
  1931. ! !REVISION HISTORY:
  1932. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  1933. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  1934. ! 15 Apr 2014 - Ph. Le Sager - tropomi add-ons
  1935. !
  1936. !EOP
  1937. !------------------------------------------------------------------------
  1938. !BOC
  1939. character(len=*), parameter :: rname = mname//'/RF_VMR_Init'
  1940. ! --- local ------------------------------------
  1941. character(len=256) :: fname, history, sysdate, model_meteo
  1942. integer :: varid, i1, i2, j1, j2
  1943. integer, dimension(8) :: isysdate
  1944. character(len=256) :: trnames
  1945. character(len=8) :: trname, tmname
  1946. integer :: k, itr, posend, pospoint
  1947. integer :: imr, jmr, lmr, si, ei, ix, jy
  1948. character(len=32) :: varname_spec
  1949. character(len=5) :: zone
  1950. character(len=64) :: cf_medium_stnd, cf_medium_long
  1951. character(len=64) :: cf_enti_stnd, cf_enti_long, cf_enti_unit
  1952. character(len=64) :: cf_spec_stnd, cf_spec_long
  1953. character(len=4) :: cf_enti_type
  1954. character(len=256) :: cf_name_stnd, cf_name_long, cf_name_unit
  1955. character(len=512) :: comment
  1956. character(len=6) :: csize
  1957. ! --- begin -------------------------------------
  1958. call goLabel(rname)
  1959. ! store arguments
  1960. RF%dhour = dhour
  1961. RF%tracer_names = tracer_names
  1962. ! size
  1963. imr = global_lli(region)%nlon
  1964. jmr = global_lli(region)%nlat
  1965. lmr = levi%nlev
  1966. ! number of time steps
  1967. rf%n_rec = GET_N_TIME_RECORDS( idate_f, dhour, mess='VMR_Init' )
  1968. ! degenerated cases (eg, very short runs)
  1969. if ( rf%n_rec == 0 ) then
  1970. rf%apply = .false.
  1971. status=0
  1972. return
  1973. end if
  1974. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1975. ! set tracer index for requested tracers:
  1976. write (gol,'("selected tracers for VMR output:")'); call goPr
  1977. ! initialise RF
  1978. RF%ntr = 0
  1979. RF%itr = -1
  1980. trnames = tracer_names
  1981. do
  1982. ! empty ?
  1983. if ( len_trim(trnames) == 0 ) exit
  1984. ! next number:
  1985. if ( RF%ntr == ntrace ) then
  1986. write (gol,'("number of elements in tracer names list exceeds ntrace=",i6)') ntrace; call goErr
  1987. TRACEBACK; status=1; return
  1988. end if
  1989. RF%ntr = RF%ntr + 1
  1990. ! extract leading name:
  1991. call goReadFromLine( trnames, trname, status, sep=' ' )
  1992. IF_NOTOK_RETURN(status=1)
  1993. ! convert to tm5 name:
  1994. select case ( trim(strlowercase(trname)) )
  1995. case default ; tmname = trname
  1996. end select
  1997. ! --------------------------------
  1998. ! NOy and M7 are special cases ...
  1999. ! --------------------------------
  2000. select case ( trim(strlowercase(tmname)) )
  2001. case default
  2002. ! --------------------------------
  2003. ! `regular` constituents
  2004. ! --------------------------------
  2005. ! loop over all names:
  2006. RF%itr(RF%ntr) = -1
  2007. do itr = 1, ntrace
  2008. ! case indendent match ?
  2009. if ( goUpCase(trim(tmname)) == goUpCase(trim(names(itr))) ) then
  2010. write (gol,'(" ",i3," ",a10," (",a10,") ",f12.4)') itr, trim(trname), trim(names(itr)), ra(itr); call goPr
  2011. RF%itr(RF%ntr) = itr
  2012. exit
  2013. end if
  2014. end do
  2015. end select
  2016. ! not found ?
  2017. if ( RF%itr(RF%ntr) < 0 ) then
  2018. write (gol,'("tracer name not supported:")'); call goPr
  2019. write (gol,'(" list all : ",a)') trim(tracer_names); call goPr
  2020. write (gol,'(" list element : ",i3)') RF%ntr; call goPr
  2021. write (gol,'(" pdump name : ",a)') trim(trname); call goPr
  2022. write (gol,'(" tm5 name : ",a)') trim(tmname); call goPr
  2023. write (gol,'(" tm5 tracers : ")'); call goPr
  2024. do itr = 1, ntrace
  2025. write (gol,'(" ",i3," ",a)') itr, trim(names(itr)); call goPr
  2026. end do
  2027. TRACEBACK; status=1; return
  2028. end if ! RF%itr
  2029. ! store pdump name:
  2030. RF%name_tr(RF%ntr) = tmname
  2031. end do
  2032. ! empty file ?
  2033. if ( RF%ntr < 1 ) then
  2034. write (gol,'("no tracers extracted from list :",a)') tracer_names; call goErr
  2035. TRACEBACK; status=1; return
  2036. end if
  2037. ! o open file
  2038. ! write filename
  2039. write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
  2040. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), trim(filetype), idate_f(1:3)
  2041. ! open:
  2042. #ifdef MPI
  2043. ! overwrite existing files (clobber), provide MPI stuff:
  2044. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  2045. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  2046. if (status/=0) then
  2047. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  2048. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  2049. TRACEBACK; status=1; return
  2050. end if
  2051. #else
  2052. ! overwrite existing files (clobber)
  2053. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  2054. IF_NOTOK_RETURN(status=1)
  2055. #endif
  2056. ! o global attributes
  2057. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title' , 'mixing ratios & concentrations' , status )
  2058. IF_NOTOK_MDF(fid=RF%ncid)
  2059. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status )
  2060. IF_NOTOK_MDF(fid=RF%ncid)
  2061. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status )
  2062. IF_NOTOK_MDF(fid=RF%ncid)
  2063. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'file_version_number', trim(outfileversnr) , status )
  2064. IF_NOTOK_MDF(fid=RF%ncid)
  2065. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'im' , imr , status )
  2066. IF_NOTOK_MDF(fid=RF%ncid)
  2067. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'jm' , jmr , status )
  2068. IF_NOTOK_MDF(fid=RF%ncid)
  2069. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'lm' , lmr , status )
  2070. IF_NOTOK_MDF(fid=RF%ncid)
  2071. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dx' , dx/xref(region) , status )
  2072. IF_NOTOK_MDF(fid=RF%ncid)
  2073. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dy' , dy/yref(region) , status )
  2074. IF_NOTOK_MDF(fid=RF%ncid)
  2075. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dz' , dz/zref(region) , status )
  2076. IF_NOTOK_MDF(fid=RF%ncid)
  2077. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'xbeg' , xbeg(region) , status )
  2078. IF_NOTOK_MDF(fid=RF%ncid)
  2079. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'xend' , xend(region) , status )
  2080. IF_NOTOK_MDF(fid=RF%ncid)
  2081. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'ybeg' , ybeg(region) , status )
  2082. IF_NOTOK_MDF(fid=RF%ncid)
  2083. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'yend' , yend(region) , status )
  2084. IF_NOTOK_MDF(fid=RF%ncid)
  2085. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'zbeg' , zbeg(region) , status )
  2086. IF_NOTOK_MDF(fid=RF%ncid)
  2087. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'zend' , zend(region) , status )
  2088. IF_NOTOK_MDF(fid=RF%ncid)
  2089. ! Meteo attribute
  2090. if (trim(meteo_class)=='ei') then
  2091. model_meteo='analysis (ERA-Interim)'
  2092. elseif (trim(meteo_class)=='od') then
  2093. model_meteo='forecast (IFS)'
  2094. else
  2095. write (gol,'("Meteo Model not known !")'); call goErr
  2096. TRACEBACK; status=1; return
  2097. endif
  2098. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'meteo_model', trim(model_meteo), status )
  2099. IF_NOTOK_MDF(fid=RF%ncid)
  2100. ! History attribute for audit trail: date, time of day, user name, program name
  2101. call date_and_time(values=isysdate, zone=zone)
  2102. write (sysdate, '(i4.4,"-",i2.2,"-",i2.2," ",i2.2,":",i2.2,":",i2.2," ",a)') &
  2103. isysdate(1), isysdate(2), isysdate(3), isysdate(5), isysdate(6), isysdate(7), zone
  2104. write(history,'("Created ",a," by ",a," with TM5.")') trim(sysdate),trim(dataset_author)
  2105. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'history', trim(history), status )
  2106. IF_NOTOK_MDF(fid=RF%ncid)
  2107. ! o define dimensions
  2108. call MDF_Def_Dim( RF%ncid, 'lon', imr, RF%dimid_lon , status)
  2109. IF_NOTOK_MDF(fid=RF%ncid)
  2110. call MDF_Def_Dim( RF%ncid, 'lat', jmr, RF%dimid_lat , status)
  2111. IF_NOTOK_MDF(fid=RF%ncid)
  2112. call MDF_Def_Dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
  2113. IF_NOTOK_MDF(fid=RF%ncid)
  2114. call MDF_Def_Dim( RF%ncid, 'time', rf%n_rec, RF%dimid_time , status)
  2115. IF_NOTOK_MDF(fid=RF%ncid)
  2116. call MDF_Def_Dim( RF%ncid, 'levi', levi%nlev+1, RF%dimid_levi , status)
  2117. IF_NOTOK_MDF(fid=RF%ncid)
  2118. call MDF_Def_Dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
  2119. IF_NOTOK_MDF(fid=RF%ncid)
  2120. ! o define variables
  2121. call MDF_Def_Var( RF%ncid, 'lon', mdf_float, (/RF%dimid_lon/), varid , status)
  2122. IF_NOTOK_MDF(fid=RF%ncid)
  2123. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2124. IF_NOTOK_MDF(fid=RF%ncid)
  2125. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  2126. IF_NOTOK_MDF(fid=RF%ncid)
  2127. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'longitude' , status)
  2128. IF_NOTOK_MDF(fid=RF%ncid)
  2129. call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_east' , status)
  2130. IF_NOTOK_MDF(fid=RF%ncid)
  2131. RF%varid_lon = varid
  2132. call MDF_Def_Var( RF%ncid, 'lat', mdf_float, (/RF%dimid_lat/), varid , status)
  2133. IF_NOTOK_MDF(fid=RF%ncid)
  2134. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2135. IF_NOTOK_MDF(fid=RF%ncid)
  2136. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  2137. IF_NOTOK_MDF(fid=RF%ncid)
  2138. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'latitude' , status)
  2139. IF_NOTOK_MDF(fid=RF%ncid)
  2140. call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_north' , status)
  2141. IF_NOTOK_MDF(fid=RF%ncid)
  2142. RF%varid_lat = varid
  2143. call MDF_Def_Var( RF%ncid, 'lev', mdf_float, (/RF%dimid_lev/), varid , status)
  2144. IF_NOTOK_MDF(fid=RF%ncid)
  2145. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2146. IF_NOTOK_MDF(fid=RF%ncid)
  2147. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
  2148. IF_NOTOK_MDF(fid=RF%ncid)
  2149. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'level' , status)
  2150. IF_NOTOK_MDF(fid=RF%ncid)
  2151. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  2152. IF_NOTOK_MDF(fid=RF%ncid)
  2153. 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)
  2154. IF_NOTOK_MDF(fid=RF%ncid)
  2155. RF%varid_lev = varid
  2156. call MDF_Def_Var( RF%ncid, 'time', mdf_double, (/RF%dimid_time/), varid , status)
  2157. IF_NOTOK_MDF(fid=RF%ncid)
  2158. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2159. IF_NOTOK_MDF(fid=RF%ncid)
  2160. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
  2161. IF_NOTOK_MDF(fid=RF%ncid)
  2162. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'time' , status)
  2163. IF_NOTOK_MDF(fid=RF%ncid)
  2164. call MDF_Put_Att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
  2165. IF_NOTOK_MDF(fid=RF%ncid)
  2166. call MDF_Put_Att( RF%ncid, varid, 'calender', 'gregorian' , status)
  2167. IF_NOTOK_MDF(fid=RF%ncid)
  2168. RF%varid_time = varid
  2169. allocate(RF%time(rf%n_rec))
  2170. call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  2171. IF_NOTOK_MDF(fid=RF%ncid)
  2172. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2173. IF_NOTOK_MDF(fid=RF%ncid)
  2174. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
  2175. IF_NOTOK_MDF(fid=RF%ncid)
  2176. call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
  2177. IF_NOTOK_MDF(fid=RF%ncid)
  2178. RF%varid_date = varid
  2179. allocate(RF%date(6,rf%n_rec))
  2180. call MDF_Def_Var( RF%ncid, 'ps', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
  2181. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2182. IF_NOTOK_MDF(fid=RF%ncid)
  2183. IF_NOTOK_MDF(fid=RF%ncid)
  2184. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'surface_air_pressure' , status)
  2185. IF_NOTOK_MDF(fid=RF%ncid)
  2186. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
  2187. IF_NOTOK_MDF(fid=RF%ncid)
  2188. call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
  2189. IF_NOTOK_MDF(fid=RF%ncid)
  2190. RF%varid_ps = varid
  2191. allocate( RF%sp(i1:i2, j1:j2, rf%n_rec) )
  2192. #ifdef tropomi
  2193. call MDF_Def_Var( RF%ncid, 'temp', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
  2194. IF_NOTOK_MDF(fid=RF%ncid)
  2195. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2196. IF_NOTOK_MDF(fid=RF%ncid)
  2197. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'air_temperature' , status)
  2198. IF_NOTOK_MDF(fid=RF%ncid)
  2199. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'temperature' , status)
  2200. IF_NOTOK_MDF(fid=RF%ncid)
  2201. call MDF_Put_Att( RF%ncid, varid, 'units', 'K' , status)
  2202. IF_NOTOK_MDF(fid=RF%ncid)
  2203. call MDF_put_att( RF%ncid, varid, 'comment', 'bottom-up; full levels' , status)
  2204. IF_NOTOK_MDF(fid=RF%ncid)
  2205. RF%varid_temp = varid
  2206. allocate( RF%data3d_t(i1:i2, j1:j2, levi%nlev, rf%n_rec) )
  2207. #endif
  2208. call MDF_Def_Var( RF%ncid, 'a_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
  2209. IF_NOTOK_MDF(fid=RF%ncid)
  2210. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2211. IF_NOTOK_MDF(fid=RF%ncid)
  2212. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  2213. IF_NOTOK_MDF(fid=RF%ncid)
  2214. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
  2215. IF_NOTOK_MDF(fid=RF%ncid)
  2216. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  2217. IF_NOTOK_MDF(fid=RF%ncid)
  2218. 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)
  2219. IF_NOTOK_MDF(fid=RF%ncid)
  2220. RF%varid_a_bnds = varid
  2221. call MDF_Def_Var( RF%ncid, 'b_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
  2222. IF_NOTOK_MDF(fid=RF%ncid)
  2223. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2224. IF_NOTOK_MDF(fid=RF%ncid)
  2225. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
  2226. IF_NOTOK_MDF(fid=RF%ncid)
  2227. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
  2228. IF_NOTOK_MDF(fid=RF%ncid)
  2229. call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
  2230. IF_NOTOK_MDF(fid=RF%ncid)
  2231. 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)
  2232. IF_NOTOK_MDF(fid=RF%ncid)
  2233. RF%varid_b_bnds = varid
  2234. ! loop over tracer to be written:
  2235. do k = 1, RF%ntr
  2236. ! ----------------------------
  2237. ! setting defaults (gas phase)
  2238. ! ----------------------------
  2239. ! CF standard name for concentration/mixing ratio/column:
  2240. cf_enti_stnd = 'mole_fraction'
  2241. cf_enti_unit = 'mole mole-1'
  2242. cf_enti_long = 'volume mixing ratio'
  2243. cf_medium_stnd = 'in_air'
  2244. cf_medium_long = 'in humid air'
  2245. RF%varid_type(k) = 'mixr'
  2246. ! global tracer index
  2247. itr = RF%itr(k)
  2248. ! no comment yet
  2249. comment = ''
  2250. ! standard names from CF conventions:
  2251. select case ( strlowercase(RF%name_tr(k)) )
  2252. case ( 'co2' )
  2253. varname_spec = 'co2'
  2254. cf_spec_stnd = 'carbon_dioxide'
  2255. cf_spec_long = 'CO2'
  2256. case default
  2257. write (gol,'("do not know how to match tracer with CF standard names : ",a)') RF%name_tr(k); call goErr
  2258. TRACEBACK; status=1; return
  2259. end select
  2260. ! define variable:
  2261. call MDF_Def_Var( RF%ncid, trim(varname_spec), MDF_FLOAT, &
  2262. (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid, status )
  2263. IF_NOTOK_MDF(fid=RF%ncid)
  2264. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2265. IF_NOTOK_MDF(fid=RF%ncid)
  2266. ! total names:
  2267. cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)//'_'//trim(cf_medium_stnd)
  2268. cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)//' '//trim(cf_medium_long)
  2269. cf_name_unit = trim(cf_enti_unit)
  2270. ! write attributes:
  2271. call MDF_Put_Att( RF%ncid, varid, 'standard_name', trim(cf_name_stnd) , status)
  2272. IF_NOTOK_MDF(fid=RF%ncid)
  2273. call MDF_Put_Att( RF%ncid, varid, 'long_name', trim(cf_name_long) , status)
  2274. IF_NOTOK_MDF(fid=RF%ncid)
  2275. call MDF_Put_Att( RF%ncid, varid, 'units', trim(cf_name_unit) , status)
  2276. IF_NOTOK_MDF(fid=RF%ncid)
  2277. ! moleweights; ra from chem_param is in g/mol .
  2278. if ( itr <= ntrace .and. itr > 0 ) then
  2279. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', ra(itr)*1e3 , status)
  2280. IF_NOTOK_MDF(fid=RF%ncid)
  2281. else
  2282. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', -1.0 , status)
  2283. IF_NOTOK_MDF(fid=RF%ncid)
  2284. end if
  2285. call MDF_Put_Att( RF%ncid , varid, 'moleweight_air' , xmair*1e3 , status)
  2286. IF_NOTOK_MDF(fid=RF%ncid)
  2287. call MDF_Put_Att( RF%ncid , varid, 'moleweight_unit' , 'kg mole-1' , status)
  2288. IF_NOTOK_MDF(fid=RF%ncid)
  2289. if ( len_trim(comment) > 0 ) then
  2290. call MDF_Put_Att( RF%ncid, varid, 'comment' , trim(comment), status)
  2291. IF_NOTOK_MDF(fid=RF%ncid)
  2292. end if
  2293. ! store varid
  2294. RF%varid_tr(k) = varid
  2295. end do
  2296. ! storage
  2297. allocate(rf%data3d(i1:i2,j1:j2,lmr,rf%n_rec,rf%ntr))
  2298. ! o end defintion mode
  2299. call MDF_EndDef( RF%ncid , status)
  2300. IF_NOTOK_MDF(fid=RF%ncid)
  2301. ! o
  2302. ! no records written yet
  2303. RF%trec = 0
  2304. call goLabel()
  2305. status = 0
  2306. END SUBROUTINE RF_VMR_Init
  2307. !EOC
  2308. !--------------------------------------------------------------------------
  2309. ! TM5 !
  2310. !--------------------------------------------------------------------------
  2311. !BOP
  2312. !
  2313. ! !IROUTINE: RF_VMR_Write
  2314. !
  2315. ! !DESCRIPTION:
  2316. !\\
  2317. !\\
  2318. ! !INTERFACE:
  2319. !
  2320. SUBROUTINE RF_VMR_Write( RF, region, idate_f, status )
  2321. !
  2322. ! !USES:
  2323. !
  2324. use Binas, only : xmair
  2325. use GO, only : TDate, NewDate, rTotal, operator(-)
  2326. use binas, only : Rgas
  2327. use chem_param, only : ntrace, ntracet, fscale, ra
  2328. use tracer_data, only : mass_dat, chem_dat
  2329. use Grid, only : FPressure
  2330. use MeteoData, only : global_lli, levi, m_dat, temper_dat, sp_dat
  2331. !
  2332. ! !INPUT/OUTPUT PARAMETERS:
  2333. !
  2334. type(TPdumpFile_VMR), intent(inout) :: RF
  2335. !
  2336. ! !INPUT PARAMETERS:
  2337. !
  2338. integer, intent(in) :: region
  2339. integer, intent(in) :: idate_f(6)
  2340. !
  2341. ! !OUTPUT PARAMETERS:
  2342. !
  2343. integer, intent(out) :: status
  2344. !
  2345. ! !REVISION HISTORY:
  2346. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  2347. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  2348. ! 2 Oct 2012 - Ph. Le Sager - adapted for lat-lon mpi decomp
  2349. ! - no more sub-regions available
  2350. !
  2351. ! !REMARKS:
  2352. ! (1)
  2353. !
  2354. !EOP
  2355. !------------------------------------------------------------------------
  2356. !BOC
  2357. character(len=*), parameter :: rname = mname//'/RF_VMR_Write'
  2358. ! --- local ------------------------------------
  2359. integer :: imr, jmr, lmr, i1, i2, j1, j2
  2360. real, allocatable :: lev(:)
  2361. integer :: l
  2362. type(TDate) :: t, t0
  2363. real :: time
  2364. integer :: k, itr
  2365. integer :: k_comp, itr_comp
  2366. integer :: ims, ime, jms, jme, lms, lme
  2367. integer :: gimr, gjmr, glmr
  2368. real, allocatable :: compo_k(:,:,:)
  2369. real, allocatable :: field_t(:,:,:)
  2370. real, allocatable :: field_k(:,:,:)
  2371. real, allocatable :: pres3d(:,:,:), pmx(:,:,:)
  2372. integer :: numtrac
  2373. integer :: listtrac(10)
  2374. ! --- begin -------------------------------------
  2375. ! for multiple of dhour only ...
  2376. if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
  2377. status=0; return
  2378. end if
  2379. call goLabel(rname)
  2380. ! grid sizes
  2381. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  2382. imr=i2-i1+1
  2383. jmr=j2-j1+1
  2384. lmr = levi%nlev
  2385. gimr = global_lli(region)%nlon
  2386. gjmr = global_lli(region)%nlat
  2387. ! yet to change ??
  2388. lms = 1
  2389. lme = levi%nlev
  2390. lmr = levi%nlev
  2391. glmr = levi%nlev
  2392. ! next time record:
  2393. RF%trec = RF%trec + 1
  2394. if(okdebug)then
  2395. write(gol,*) "RF_VMR_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
  2396. end if
  2397. ! time since 1950-1-1 00:00
  2398. t0 = NewDate( time6=time_reftime6 )
  2399. t = NewDate( time6=idate_f )
  2400. time = rTotal( t - t0, 'day' )
  2401. ! only once ...
  2402. if ( RF%trec == 1 ) then
  2403. ! write longitudes:
  2404. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
  2405. IF_NOTOK_MDF(fid=RF%ncid)
  2406. ! write latitudes:
  2407. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
  2408. IF_NOTOK_MDF(fid=RF%ncid)
  2409. ! write level indices:
  2410. allocate( lev(lmr) )
  2411. do l = lms, lme
  2412. lev(l) = real(l)
  2413. end do
  2414. call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
  2415. IF_NOTOK_MDF(fid=RF%ncid)
  2416. deallocate(lev)
  2417. ! As and Bs
  2418. call MDF_Put_Var( RF%ncid, RF%varid_a_bnds, levi%a(0:levi%nlev) , status)
  2419. IF_NOTOK_MDF(fid=RF%ncid)
  2420. call MDF_Put_Var( RF%ncid, RF%varid_b_bnds, levi%b(0:levi%nlev) , status)
  2421. IF_NOTOK_MDF(fid=RF%ncid)
  2422. end if ! first record
  2423. RF%time(RF%trec) = time
  2424. RF%date(:,RF%trec) = real(idate_f)
  2425. RF%sp(:,:,RF%trec) = sp_dat(region)%data(i1:i2,j1:j2,1)
  2426. #ifdef tropomi
  2427. RF%data3d_t(:,:,:,RF%trec) = temper_dat(region)%data(i1:i2,j1:j2,1:lmr)
  2428. #endif
  2429. ! loop over all tracers to be written:
  2430. do k = 1, RF%ntr
  2431. ! global tracer index:
  2432. itr = RF%itr(k)
  2433. ! ---------
  2434. ! transported or chemistry only ?
  2435. ! ---------
  2436. select case( itr )
  2437. case( 1:ntracet )
  2438. ! ----------------------------------------------------
  2439. ! distinguish between mixing ratios and concentrations
  2440. ! ----------------------------------------------------
  2441. select case( RF%varid_type(k) )
  2442. case( 'conc' )
  2443. ! write slab of concentrations
  2444. ! m(trace) pressure xm(trace)
  2445. ! C = -------- * fscale * ----------- * ---------
  2446. ! m(air) temperature Rgas
  2447. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  2448. ! reshape( mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr) / &
  2449. ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  2450. ! pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  2451. ! Rgas, (/imr,jmr,lmr,1/) ), &
  2452. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  2453. rf%data3d(:,:,:, rf%trec, k) = mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr) / &
  2454. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  2455. pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  2456. Rgas
  2457. case( 'mixr' )
  2458. ! write slab of volume mixing ratios
  2459. ! m(trace)
  2460. ! X = -------- * fscale
  2461. ! m(air)
  2462. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  2463. ! reshape( mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr)/ &
  2464. ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr), &
  2465. ! (/imr,jmr,lmr,1/) ), &
  2466. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  2467. rf%data3d(:,:,:, rf%trec, k) = mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr)/ &
  2468. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr)
  2469. case default
  2470. write (gol,'("no such unit type",a)') RF%varid_type(k); call goErr
  2471. status=1
  2472. end select
  2473. ! IF_NOTOK_MDF(fid=RF%ncid)
  2474. ! ---------
  2475. case( ntracet+1:ntrace )
  2476. ! ---------
  2477. ! ----------------------------------------------------
  2478. ! distinguish between mixing ratios and concentrations
  2479. ! ----------------------------------------------------
  2480. select case( RF%varid_type(k) )
  2481. case( 'conc' )
  2482. ! write slab of concentrations
  2483. ! m(trace) pressure xm(trace)
  2484. ! C = -------- * fscale * ----------- * ---------
  2485. ! m(air) temperature Rgas
  2486. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  2487. ! reshape( chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr) / &
  2488. ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  2489. ! pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  2490. ! Rgas, (/imr,jmr,lmr,1/) ), &
  2491. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  2492. rf%data3d(:,:,:, rf%trec, k) = chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr) / &
  2493. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
  2494. pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
  2495. Rgas
  2496. case( 'mixr' )
  2497. ! write slab of volume mixing ratios
  2498. ! m(trace)
  2499. ! X = -------- * fscale
  2500. ! m(air)
  2501. ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
  2502. ! reshape( chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr)/ &
  2503. ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr), &
  2504. ! (/imr,jmr,lmr,1/) ), &
  2505. ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
  2506. rf%data3d(:,:,:, rf%trec, k) = chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr)/ &
  2507. m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr)
  2508. case default
  2509. write (gol,'("no such unit type",a)') RF%varid_type(k); call goErr
  2510. status=1
  2511. end select
  2512. IF_NOTOK_MDF(fid=RF%ncid)
  2513. ! -------------------
  2514. case default
  2515. ! -------------------
  2516. write (gol,'("strange tracer index requested : ",i6)') itr; call goErr
  2517. TRACEBACK; status=1; return
  2518. end select
  2519. end do ! tracer
  2520. !----------------
  2521. ! WRITE
  2522. !----------------
  2523. if ( RF%trec == rf%n_rec ) then
  2524. call MDF_Put_Var( RF%ncid, RF%varid_time, rf%time, status)
  2525. IF_NOTOK_MDF(fid=RF%ncid)
  2526. call MDF_Put_Var( RF%ncid, RF%varid_date, rf%date, status)
  2527. IF_NOTOK_MDF(fid=RF%ncid)
  2528. ! surface presure
  2529. call MDF_Put_Var( RF%ncid, RF%varid_ps, rf%sp, status, start=(/i1,j1,1/) )
  2530. IF_NOTOK_MDF(fid=RF%ncid)
  2531. #ifdef tropomi
  2532. ! temperature
  2533. 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/) )
  2534. IF_NOTOK_MDF(fid=RF%ncid)
  2535. #endif
  2536. ! vmr
  2537. do k = 1, RF%ntr
  2538. call MDF_Put_Var( RF%ncid, RF%varid_tr(k), RF%data3d(:,:,:,:,k), status, start=(/i1,j1,1,1/) )
  2539. IF_NOTOK_MDF(fid=RF%ncid)
  2540. end do
  2541. end if
  2542. !----------------
  2543. ! DONE
  2544. !----------------
  2545. call goLabel()
  2546. status = 0
  2547. END SUBROUTINE RF_VMR_Write
  2548. !EOC
  2549. !--------------------------------------------------------------------------
  2550. ! TM5 !
  2551. !--------------------------------------------------------------------------
  2552. !BOP
  2553. !
  2554. ! !IROUTINE: RF_VMR_Done
  2555. !
  2556. ! !DESCRIPTION: close file #3
  2557. !\\
  2558. !\\
  2559. ! !INTERFACE:
  2560. !
  2561. SUBROUTINE RF_VMR_Done( RF, status )
  2562. !
  2563. ! !INPUT/OUTPUT PARAMETERS:
  2564. !
  2565. type(TPdumpFile_VMR), intent(inout) :: RF
  2566. !
  2567. ! !OUTPUT PARAMETERS:
  2568. !
  2569. integer, intent(out) :: status
  2570. !
  2571. ! !REVISION HISTORY:
  2572. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  2573. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  2574. !
  2575. !EOP
  2576. !------------------------------------------------------------------------
  2577. !BOC
  2578. character(len=*), parameter :: rname = mname//'/RF_VMR_Done'
  2579. ! --- begin -------------------------------------
  2580. call goLabel(rname)
  2581. call MDF_Close( RF%ncid, status )
  2582. IF_NOTOK_RETURN(status=1)
  2583. deallocate(rf%date, rf%time, rf%sp, rf%data3d )
  2584. #ifdef tropomi
  2585. deallocate(rf%data3d_t)
  2586. #endif
  2587. call goLabel() ; status = 0
  2588. END SUBROUTINE RF_VMR_Done
  2589. !EOC
  2590. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2591. ! FILE: 2D LT output
  2592. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2593. !--------------------------------------------------------------------------
  2594. ! TM5 !
  2595. !--------------------------------------------------------------------------
  2596. !BOP
  2597. !
  2598. ! !IROUTINE: RF_LT_Init
  2599. !
  2600. ! !DESCRIPTION:
  2601. !\\
  2602. !\\
  2603. ! !INTERFACE:
  2604. !
  2605. subroutine RF_LT_Init( RF, fdir, model, expid, filetype, region, &
  2606. idate_f, local_time, tracer_names, status )
  2607. !
  2608. ! !USES:
  2609. !
  2610. use Binas, only : xmair
  2611. use GO, only : goReadFromLine, goUpCase
  2612. use GO, only : NewDate
  2613. use dims, only : im, jm
  2614. use chem_param, only : ntrace, names, ra
  2615. use partools, only : MPI_INFO_NULL, localComm
  2616. use MeteoData, only : global_lli, levi, sp_dat, Set
  2617. !
  2618. ! !OUTPUT PARAMETERS:
  2619. !
  2620. type(TPdumpFile_LT), intent(out) :: RF
  2621. !
  2622. ! !INPUT PARAMETERS:
  2623. !
  2624. character(len=*), intent(in) :: fdir
  2625. character(len=*), intent(in) :: model
  2626. character(len=*), intent(in) :: expid
  2627. character(len=*), intent(in) :: filetype
  2628. integer, intent(in) :: region
  2629. integer, intent(in) :: idate_f(6)
  2630. integer, intent(in) :: local_time
  2631. character(len=*), intent(in) :: tracer_names
  2632. integer, intent(out) :: status
  2633. !
  2634. ! !REVISION HISTORY:
  2635. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  2636. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  2637. !
  2638. !EOP
  2639. !------------------------------------------------------------------------
  2640. !BOC
  2641. character(len=*), parameter :: rname = mname//'/RF_LT_Init'
  2642. ! --- local ------------------------------------
  2643. character(len=256) :: fname
  2644. integer :: varid
  2645. integer :: imr, jmr, lmr
  2646. character(len=256) :: trnames
  2647. character(len=8) :: trname, tmname
  2648. character(len=3) :: cwavel
  2649. integer :: k, itr, i1, i2, j1, j2
  2650. character(len=32) :: varname, varname_enti, varname_spec
  2651. character(len=64) :: cf_medium_stnd, cf_medium_long
  2652. character(len=64) :: cf_enti_stnd, cf_enti_long, cf_enti_unit
  2653. character(len=64) :: cf_spec_stnd, cf_spec_long
  2654. character(len=256) :: cf_name_stnd, cf_name_long, cf_name_unit
  2655. character(len=512) :: comment
  2656. ! --- begin -------------------------------------
  2657. call goLabel(rname)
  2658. ! store arguments
  2659. RF%local_time = local_time
  2660. RF%tracer_names = tracer_names
  2661. ! set tracer index for requested tracers:
  2662. write (gol,'("selected tracers for LT output:")'); call goPr
  2663. RF%ntr = 0
  2664. RF%itr = -1
  2665. trnames = tracer_names
  2666. do
  2667. ! empty ?
  2668. if ( len_trim(trnames) == 0 ) exit
  2669. ! next number:
  2670. if ( RF%ntr == ntrace ) then
  2671. write (gol,'("number of elements in tracer names list exceeds ntrace=",i6)') ntrace; call goErr
  2672. TRACEBACK; status=1; return
  2673. end if
  2674. RF%ntr = RF%ntr + 1
  2675. ! extract leading name:
  2676. call goReadFromLine( trnames, trname, status, sep=' ' )
  2677. IF_NOTOK_RETURN(status=1)
  2678. ! convert to tm5 name:
  2679. select case ( trim(strlowercase(trname)) )
  2680. case default ; tmname = trname
  2681. end select
  2682. ! NOy is a special ...
  2683. select case ( trim(strlowercase(tmname)) )
  2684. case default
  2685. ! loop over all names:
  2686. RF%itr(RF%ntr) = -1
  2687. do itr = 1, ntrace
  2688. ! case indendent match ?
  2689. if ( goUpCase(trim(tmname)) == goUpCase(trim(names(itr))) ) then
  2690. write (gol,'(" ",i3," ",a10," (",a10,") ",f12.4)') itr, trim(trname), trim(names(itr)), ra(itr); call goPr
  2691. RF%itr(RF%ntr) = itr
  2692. exit
  2693. end if
  2694. end do
  2695. end select ! not found ?
  2696. if ( RF%itr(RF%ntr) < 0 ) then
  2697. write (gol,'("tracer name not supported:")'); call goPr
  2698. write (gol,'(" list all : ",a)') trim(tracer_names); call goPr
  2699. write (gol,'(" list element : ",i3)') RF%ntr; call goPr
  2700. write (gol,'(" pdump name : ",a)') trim(trname); call goPr
  2701. write (gol,'(" tm5 name : ",a)') trim(tmname); call goPr
  2702. write (gol,'(" tm5 tracers : ")'); call goPr
  2703. do itr = 1, ntrace
  2704. write (gol,'(" ",i3," ",a)') itr, trim(names(itr)); call goPr
  2705. end do
  2706. TRACEBACK; status=1; return
  2707. end if
  2708. ! store pdump name:
  2709. RF%name_tr(RF%ntr) = trname
  2710. end do
  2711. ! empty file ?
  2712. if ( RF%ntr < 1 ) then
  2713. write (gol,'("no tracers extracted from list :",a)') tracer_names; call goErr
  2714. TRACEBACK; status=1; return
  2715. end if
  2716. ! grid size
  2717. imr = global_lli(region)%nlon
  2718. jmr = global_lli(region)%nlat
  2719. lmr = levi%nlev
  2720. ! o open file
  2721. ! write filename
  2722. write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
  2723. trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), trim(filetype), idate_f(1:3)
  2724. ! open:
  2725. #ifdef MPI
  2726. ! overwrite existing files (clobber), provide MPI stuff:
  2727. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
  2728. mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
  2729. if (status/=0) then
  2730. write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
  2731. write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
  2732. TRACEBACK; status=1; return
  2733. end if
  2734. #else
  2735. ! overwrite existing files (clobber)
  2736. call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
  2737. IF_NOTOK_RETURN(status=1)
  2738. #endif
  2739. ! o global attributes
  2740. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title' , 'local time output' , status)
  2741. IF_NOTOK_MDF(fid=RF%ncid)
  2742. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
  2743. IF_NOTOK_MDF(fid=RF%ncid)
  2744. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
  2745. IF_NOTOK_MDF(fid=RF%ncid)
  2746. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status)
  2747. IF_NOTOK_MDF(fid=RF%ncid)
  2748. call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'file_version_number', trim(outfileversnr) , status)
  2749. IF_NOTOK_MDF(fid=RF%ncid)
  2750. ! o define dimensions
  2751. call MDF_Def_Dim( RF%ncid, 'lon' , global_lli(region)%nlon, RF%dimid_lon , status)
  2752. IF_NOTOK_MDF(fid=RF%ncid)
  2753. call MDF_Def_Dim( RF%ncid, 'lat' , global_lli(region)%nlat, RF%dimid_lat , status)
  2754. IF_NOTOK_MDF(fid=RF%ncid)
  2755. call MDF_Def_Dim( RF%ncid, 'lev' , levi%nlev , RF%dimid_lev , status)
  2756. IF_NOTOK_MDF(fid=RF%ncid)
  2757. call MDF_Def_Dim( RF%ncid, 'time' , 1 , RF%dimid_time , status)
  2758. IF_NOTOK_MDF(fid=RF%ncid)
  2759. call MDF_Def_Dim( RF%ncid, 'datelen', 6 , RF%dimid_datelen, status)
  2760. IF_NOTOK_MDF(fid=RF%ncid)
  2761. ! o define variables
  2762. call MDF_Def_Var( RF%ncid, 'lon', mdf_float, (/RF%dimid_lon/), varid , status)
  2763. IF_NOTOK_MDF(fid=RF%ncid)
  2764. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2765. IF_NOTOK_MDF(fid=RF%ncid)
  2766. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
  2767. IF_NOTOK_MDF(fid=RF%ncid)
  2768. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'longitude' , status)
  2769. IF_NOTOK_MDF(fid=RF%ncid)
  2770. call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_east', status)
  2771. IF_NOTOK_MDF(fid=RF%ncid)
  2772. RF%varid_lon = varid
  2773. call MDF_Def_Var( RF%ncid, 'lat', mdf_float, (/RF%dimid_lat/), varid , status)
  2774. IF_NOTOK_MDF(fid=RF%ncid)
  2775. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2776. IF_NOTOK_MDF(fid=RF%ncid)
  2777. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
  2778. IF_NOTOK_MDF(fid=RF%ncid)
  2779. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'latitude' , status)
  2780. IF_NOTOK_MDF(fid=RF%ncid)
  2781. call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_north', status)
  2782. IF_NOTOK_MDF(fid=RF%ncid)
  2783. RF%varid_lat = varid
  2784. call MDF_Def_Var( RF%ncid, 'lev', mdf_float, (/RF%dimid_lev/), varid , status)
  2785. IF_NOTOK_MDF(fid=RF%ncid)
  2786. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2787. IF_NOTOK_MDF(fid=RF%ncid)
  2788. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
  2789. IF_NOTOK_MDF(fid=RF%ncid)
  2790. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'level' , status)
  2791. IF_NOTOK_MDF(fid=RF%ncid)
  2792. call MDF_Put_Att( RF%ncid, varid, 'units' , '1' , status)
  2793. IF_NOTOK_MDF(fid=RF%ncid)
  2794. 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)
  2795. IF_NOTOK_MDF(fid=RF%ncid)
  2796. RF%varid_lev = varid
  2797. call MDF_Def_Var( RF%ncid, 'time', mdf_float, (/RF%dimid_time/), varid , status)
  2798. IF_NOTOK_MDF(fid=RF%ncid)
  2799. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2800. IF_NOTOK_MDF(fid=RF%ncid)
  2801. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
  2802. IF_NOTOK_MDF(fid=RF%ncid)
  2803. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'time' , status)
  2804. IF_NOTOK_MDF(fid=RF%ncid)
  2805. call MDF_Put_Att( RF%ncid, varid, 'units' , 'days since 1950-01-01 00:00:00', status)
  2806. IF_NOTOK_MDF(fid=RF%ncid)
  2807. call MDF_Put_Att( RF%ncid, varid, 'calender' , 'gregorian' , status)
  2808. IF_NOTOK_MDF(fid=RF%ncid)
  2809. RF%varid_time = varid
  2810. call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
  2811. IF_NOTOK_MDF(fid=RF%ncid)
  2812. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2813. IF_NOTOK_MDF(fid=RF%ncid)
  2814. call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
  2815. IF_NOTOK_MDF(fid=RF%ncid)
  2816. call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
  2817. IF_NOTOK_MDF(fid=RF%ncid)
  2818. RF%varid_date = varid
  2819. call MDF_Def_Var( RF%ncid, 'ps', MDF_FLOAT, &
  2820. (/RF%dimid_lon,RF%dimid_lat,RF%dimid_time/), varid, status )
  2821. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2822. IF_NOTOK_MDF(fid=RF%ncid)
  2823. IF_NOTOK_MDF(fid=RF%ncid)
  2824. call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'surface_air_pressure', status)
  2825. IF_NOTOK_MDF(fid=RF%ncid)
  2826. call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'surface pressure' , status)
  2827. IF_NOTOK_MDF(fid=RF%ncid)
  2828. call MDF_Put_Att( RF%ncid, varid, 'units' , 'Pa' , status)
  2829. IF_NOTOK_MDF(fid=RF%ncid)
  2830. RF%varid_ps = varid
  2831. ! CF standard name for medium:
  2832. cf_medium_stnd = 'in_air' ; cf_medium_long = 'in humid air'
  2833. ! loop over tracer to be written:
  2834. do k = 1, RF%ntr
  2835. ! global tracer index
  2836. itr = RF%itr(k)
  2837. ! ~~ local time species info
  2838. ! CF standard name for concentration/mixing ratio/column:
  2839. cf_enti_stnd = 'mole_fraction'
  2840. cf_enti_unit = 'mole mole-1'
  2841. cf_enti_long = 'volume mixing ratio'
  2842. ! start of dataset name:
  2843. varname_enti = 'dry'
  2844. ! no comment yet
  2845. comment = ''
  2846. ! standard names from CF conventions:
  2847. select case ( RF%name_tr(k) )
  2848. case ( 'CO2', 'co2' )
  2849. varname_spec = 'co2'
  2850. cf_spec_stnd = 'carbon_dioxide'
  2851. cf_spec_long = 'CO2'
  2852. case default
  2853. write (gol,'("do not know how to match tracer with CF standard names : ",a)') RF%name_tr(k); call goPr
  2854. TRACEBACK; status=1; return
  2855. end select
  2856. ! define variable:
  2857. call MDF_Def_Var( RF%ncid, trim(varname_spec), MDF_FLOAT, &
  2858. (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid, status )
  2859. IF_NOTOK_MDF(fid=RF%ncid)
  2860. call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
  2861. IF_NOTOK_MDF(fid=RF%ncid)
  2862. ! total names:
  2863. cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)//'_'//trim(cf_medium_stnd)
  2864. cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)//' '//trim(cf_medium_long)
  2865. cf_name_unit = trim(cf_enti_unit)
  2866. ! write attributes:
  2867. call MDF_Put_Att( RF%ncid, varid, 'standard_name', trim(cf_name_stnd) , status)
  2868. IF_NOTOK_MDF(fid=RF%ncid)
  2869. call MDF_Put_Att( RF%ncid, varid, 'long_name', trim(cf_name_long) , status)
  2870. IF_NOTOK_MDF(fid=RF%ncid)
  2871. call MDF_Put_Att( RF%ncid, varid, 'units', trim(cf_name_unit) , status)
  2872. IF_NOTOK_MDF(fid=RF%ncid)
  2873. if ( itr <= ntrace .and. itr > 0 ) then
  2874. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', ra(itr)*1e3 , status)
  2875. IF_NOTOK_MDF(fid=RF%ncid)
  2876. else
  2877. call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', -1.0 , status)
  2878. IF_NOTOK_MDF(fid=RF%ncid)
  2879. end if
  2880. call MDF_Put_Att( RF%ncid, varid, 'moleweight_air', xmair*1e3 , status)
  2881. IF_NOTOK_MDF(fid=RF%ncid)
  2882. call MDF_Put_Att( RF%ncid, varid, 'moleweight_unit', 'kg mole-1' , status)
  2883. IF_NOTOK_MDF(fid=RF%ncid)
  2884. if ( len_trim(comment) > 0 ) then
  2885. call MDF_Put_Att( RF%ncid, varid, 'comment', trim(comment) , status)
  2886. IF_NOTOK_MDF(fid=RF%ncid)
  2887. end if
  2888. ! store varid
  2889. RF%varid_tr(k) = varid
  2890. end do
  2891. ! o end defintion mode
  2892. call MDF_EndDef( RF%ncid , status)
  2893. IF_NOTOK_MDF(fid=RF%ncid)
  2894. ! no records written yet
  2895. RF%trec = 0
  2896. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  2897. allocate(RF%accu (i1:i2, j1:j2, 1:lmr, RF%ntr)) ; RF%accu = 0
  2898. allocate(RF%naccu (i1:i2, RF%ntr )) ; RF%naccu = 0
  2899. allocate(RF%p_accu (i1:i2, j1:j2 )) ; RF%p_accu = 0
  2900. allocate(RF%np_accu(i1:i2 )) ; RF%np_accu = 0
  2901. call goLabel()
  2902. status = 0
  2903. END SUBROUTINE RF_LT_Init
  2904. !EOC
  2905. !--------------------------------------------------------------------------
  2906. ! TM5 !
  2907. !--------------------------------------------------------------------------
  2908. !BOP
  2909. !
  2910. ! !IROUTINE: RF_LT_Write
  2911. !
  2912. ! !DESCRIPTION: does not write anything, just get
  2913. !\\
  2914. !\\
  2915. ! !INTERFACE:
  2916. !
  2917. SUBROUTINE RF_LT_Write( RF, region, idate_f, status )
  2918. !
  2919. ! !USES:
  2920. !
  2921. use GO, only : TDate, NewDate, Set, iTotal, rTotal, operator(-), wrtgol
  2922. use chem_param, only : ntrace, ntracet, fscale
  2923. use tracer_data, only : mass_dat, chem_dat
  2924. use MeteoData, only : global_lli, levi, m_dat, sp_dat
  2925. !
  2926. ! !INPUT/OUTPUT PARAMETERS:
  2927. !
  2928. type(TPdumpFile_LT), intent(inout) :: RF
  2929. !
  2930. ! !INPUT PARAMETERS:
  2931. !
  2932. integer, intent(in) :: region
  2933. integer, intent(in) :: idate_f(6)
  2934. !
  2935. ! !OUTPUT PARAMETERS:
  2936. !
  2937. integer, intent(out) :: status
  2938. !
  2939. ! !REVISION HISTORY:
  2940. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  2941. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  2942. !
  2943. !EOP
  2944. !------------------------------------------------------------------------
  2945. !BOC
  2946. character(len=*), parameter :: rname = mname//'/RF_LT_Write'
  2947. ! --- local ------------------------------------
  2948. integer :: imr, jmr, lmr, gimr, i1, i2, j1, j2
  2949. real, allocatable :: lev(:)
  2950. real, allocatable :: field_out(:,:,:)
  2951. real, allocatable :: field_out_b(:,:)
  2952. integer :: l, ls, le
  2953. type(TDate) :: t, t0
  2954. real :: time
  2955. real :: dt_sec
  2956. integer :: i, j, k, itr, itau, loctim, gridboxtimestep
  2957. integer :: iloctim,itautoday,ilon
  2958. integer :: icomp, itr_loc, ncells, window
  2959. ! --- begin -------------------------------------
  2960. ! for multiple of dhour only ...
  2961. ! if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
  2962. ! status=0; return
  2963. ! end if
  2964. call goLabel(rname)
  2965. ! grid size
  2966. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  2967. imr=i2-i1+1
  2968. jmr=j2-j1+1
  2969. gimr = global_lli(region)%nlon
  2970. ! gjmr = global_lli(region)%nlat
  2971. lmr = levi%nlev
  2972. ! next time record:
  2973. RF%trec = RF%trec + 1
  2974. if(okdebug)then
  2975. write(gol,*) "RF_LT_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
  2976. end if
  2977. ! grid index offsets for GMT and local time
  2978. loctim=RF%local_time
  2979. if( loctim < 0 ) loctim=loctim+24*3600
  2980. ! time since 1950-1-1 00:00
  2981. t0 = NewDate( time6=time_reftime6 )
  2982. t = NewDate( time6=idate_f )
  2983. call SET( t, hour=0, min=0, sec=0 )
  2984. time = rTotal( t - t0, 'day' ) + loctim / 86400.
  2985. !
  2986. ! ~~ time, grid
  2987. !
  2988. ! only once ...
  2989. if ( RF%trec == 1 ) then
  2990. ! write longitudes:
  2991. call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
  2992. IF_NOTOK_MDF(fid=RF%ncid)
  2993. ! write latitudes:
  2994. call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
  2995. IF_NOTOK_MDF(fid=RF%ncid)
  2996. ! write level indices:
  2997. allocate( lev(lmr) )
  2998. do l = 1, lmr
  2999. lev(l) = real(l)
  3000. end do
  3001. call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
  3002. IF_NOTOK_MDF(fid=RF%ncid)
  3003. deallocate(lev)
  3004. ! time:
  3005. call MDF_Put_Var( RF%ncid, RF%varid_time, (/time/) , status, start=(/RF%trec/))
  3006. IF_NOTOK_MDF(fid=RF%ncid)
  3007. ! date:
  3008. call MDF_Put_Var( RF%ncid, RF%varid_date, reshape(real(idate_f),(/6,1/)), status, &
  3009. start=(/1,1/), count=(/6,1/) )
  3010. IF_NOTOK_MDF(fid=RF%ncid)
  3011. end if ! first record
  3012. !
  3013. ! local time
  3014. !
  3015. if ( RF%trec > 1 ) then ! do not accumulate fields on 00:00
  3016. ! grid index offsets for GMT and local time
  3017. loctim=RF%local_time
  3018. if( loctim < 0 ) loctim=loctim+24*3600
  3019. gridboxtimestep=24*3600/gimr
  3020. itau = idate_f(4)*3600+idate_f(5)*60+idate_f(6)
  3021. itautoday= nint(real(mod(itau,24*3600)*gimr)/real(24*3600))
  3022. iloctim = nint(real(loctim *gimr)/real(24*3600))
  3023. ! determine longitude index wrt Greenwich from difference (local time - GMT)
  3024. ! also process neigboring longitudes (i-2 , i-1 , i , i+1 , i+2) depending on
  3025. ! number of longitudinal grid cells
  3026. ncells = ceiling( gimr / 24. )
  3027. window = ceiling( ncells / 2. )
  3028. do ilon = 1, ncells
  3029. i = 1 + mod( gimr + gimr/2 + iloctim - itautoday + (ilon - window),gimr )
  3030. if (i .ge. i1 .and. i.le. i2) then
  3031. RF%p_accu(i,j1:j2)= RF%p_accu(i,j1:j2)+sp_dat(region)%data(i,j1:j2,1)
  3032. RF%np_accu(i)= RF%np_accu(i)+1
  3033. ! loop over tracers to be written:
  3034. do k = 1, RF%ntr
  3035. ! global tracer index:
  3036. itr = RF%itr(k)
  3037. ! transported or chemistry only ?
  3038. if ( (itr >= 1) .and. (itr <= ntracet) ) then
  3039. RF%accu(i,j1:j2,1:lmr,k)= RF%accu(i,j1:j2,1:lmr,k)+&
  3040. (mass_dat(region)%rm(i,j1:j2,1:lmr,itr)/ &
  3041. m_dat(region)%data(i,j1:j2,1:lmr))*fscale(itr)
  3042. RF%naccu(i,k)=RF%naccu(i,k)+1
  3043. else if ( (itr >= ntracet+1) .and. (itr <= ntrace) ) then
  3044. RF%accu(i,j1:j2,1:lmr,k)= RF%accu(i,j1:j2,1:lmr,k)+&
  3045. (chem_dat(region)%rm(i,j1:j2,1:lmr,itr)/ &
  3046. m_dat(region)%data(i,j1:j2,1:lmr))*fscale(itr)
  3047. RF%naccu(i,k)=RF%naccu(i,k)+1
  3048. end if
  3049. enddo
  3050. endif
  3051. enddo
  3052. endif ! do not accumulate fields on 00:00
  3053. call goLabel(); status = 0
  3054. END SUBROUTINE RF_LT_Write
  3055. !EOC
  3056. !--------------------------------------------------------------------------
  3057. ! TM5 !
  3058. !--------------------------------------------------------------------------
  3059. !BOP
  3060. !
  3061. ! !IROUTINE: RF_LT_Done
  3062. !
  3063. ! !DESCRIPTION: write final data, then close file #4
  3064. !\\
  3065. !\\
  3066. ! !INTERFACE:
  3067. !
  3068. SUBROUTINE RF_LT_Done( RF, region, status )
  3069. !
  3070. ! !USES:
  3071. !
  3072. use MeteoData, only : global_lli, levi
  3073. !
  3074. ! !INPUT/OUTPUT PARAMETERS:
  3075. !
  3076. type(TPdumpFile_LT), intent(inout) :: RF
  3077. !
  3078. ! !INPUT PARAMETERS:
  3079. !
  3080. integer, intent(in) :: region
  3081. !
  3082. ! !OUTPUT PARAMETERS:
  3083. !
  3084. integer, intent(out) :: status
  3085. !
  3086. ! !REVISION HISTORY:
  3087. ! 1 Oct 2010 - Achim Strunk - retro -> pdump
  3088. ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
  3089. ! - move averaging & writing here
  3090. !
  3091. !EOP
  3092. !------------------------------------------------------------------------
  3093. !BOC
  3094. character(len =*), parameter :: rname = mname//'/RF_LT_Done'
  3095. integer :: imr, jmr
  3096. real, allocatable :: field_out(:,:,:)
  3097. real, allocatable :: field_out_b(:,:)
  3098. integer :: i, ls, le, k, itr, i1, i2, j1, j2, lmr
  3099. ! --- begin -------------------------------------
  3100. call goLabel(rname)
  3101. !---------------------
  3102. ! average & write data
  3103. !---------------------
  3104. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3105. imr=i2-i1+1
  3106. jmr=j2-j1+1
  3107. lmr = levi%nlev
  3108. allocate(field_out_b(i1:i2,j1:j2)); field_out_b = 0.0
  3109. do i = i1, i2
  3110. if (RF%np_accu(i).gt.0) then
  3111. field_out_b(i,:) =RF%p_accu(i,:)/RF%np_accu(i)
  3112. endif
  3113. enddo
  3114. call MDF_Put_Var( RF%ncid, RF%varid_ps, reshape(field_out_b(i1:i2,j1:j2), &
  3115. (/imr,jmr,1/) ), status, start=(/i1,j1,1/), count=(/imr,jmr,1/) )
  3116. IF_NOTOK_MDF(fid=RF%ncid)
  3117. deallocate(field_out_b)
  3118. TRACERS: do k = 1, RF%ntr
  3119. ! global tracer index:
  3120. itr = RF%itr(k)
  3121. if ( (itr >= 1) .and. (itr <= ntrace) ) then
  3122. ! normalize fields, if necessary
  3123. allocate(field_out(i1:i2,j1:j2,1:lmr)); field_out = 0.0
  3124. do i = i1,i2
  3125. if (RF%naccu(i,k).gt.0) then
  3126. field_out(i,:,1:lmr) =RF%accu(i,:,1:lmr,k)/RF%naccu(i,k)
  3127. endif
  3128. enddo
  3129. ! write fields:
  3130. call MDF_Put_Var( RF%ncid, RF%varid_tr(k) , &
  3131. reshape(field_out(i1:i2,j1:j2,1:lmr) , &
  3132. (/imr,jmr,lmr,1/) ) , &
  3133. status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,1/) )
  3134. IF_NOTOK_MDF(fid=RF%ncid)
  3135. deallocate(field_out)
  3136. endif
  3137. end do TRACERS
  3138. !---------------------
  3139. ! DONE
  3140. !---------------------
  3141. call MDF_Close( RF%ncid , status)
  3142. IF_NOTOK_RETURN(status=1)
  3143. deallocate(RF%accu)
  3144. deallocate(RF%naccu)
  3145. deallocate(RF%p_accu)
  3146. deallocate(RF%np_accu)
  3147. call goLabel() ; status = 0
  3148. END SUBROUTINE RF_LT_Done
  3149. !EOC
  3150. !--------------------------------------------------------------------------
  3151. ! TM5 !
  3152. !--------------------------------------------------------------------------
  3153. !BOP
  3154. !
  3155. ! !FUNCTION: strlowercase
  3156. !
  3157. ! !DESCRIPTION:
  3158. !
  3159. ! This function returns a copy of the input string 'struppercase' with all
  3160. ! letters changed to lowercase. All other characters remain unchanged.
  3161. !\\
  3162. !\\
  3163. ! !INTERFACE:
  3164. !
  3165. FUNCTION strlowercase(struppercase)
  3166. !
  3167. ! !USES:
  3168. !
  3169. IMPLICIT NONE
  3170. !
  3171. ! !INPUT PARAMETERS:
  3172. !
  3173. CHARACTER(LEN=*), INTENT(IN) :: struppercase
  3174. !
  3175. ! !RETURN VALUE:
  3176. !
  3177. CHARACTER(LEN=LEN(struppercase)) :: strlowercase
  3178. !
  3179. ! !REVISION HISTORY:
  3180. ! 1 Oct 2010 - Achim Strunk -
  3181. !
  3182. !EOP
  3183. !------------------------------------------------------------------------
  3184. !BOC
  3185. CHARACTER(LEN=1) :: u
  3186. INTEGER :: i,j
  3187. strlowercase = struppercase
  3188. DO i=1,LEN(struppercase)
  3189. u = struppercase(i:i)
  3190. j = IACHAR(u)
  3191. IF(j < 65 .OR. j > 90) CYCLE
  3192. strlowercase(i:i) = ACHAR(j+32)
  3193. END DO
  3194. !-------------------------------------------------------------------------------
  3195. END FUNCTION STRLOWERCASE
  3196. !EOC
  3197. !--------------------------------------------------------------------------
  3198. ! TM5 !
  3199. !--------------------------------------------------------------------------
  3200. !BOP
  3201. !
  3202. ! !FUNCTION: struppercase
  3203. !
  3204. ! !DESCRIPTION:
  3205. !
  3206. ! This function returns a copy of the input string 'struppercase' with all
  3207. ! letters changed to lowercase. All other characters remain unchanged.
  3208. !\\
  3209. !\\
  3210. ! !INTERFACE:
  3211. !
  3212. FUNCTION STRUPPERCASE(strlowercase)
  3213. !
  3214. ! !USES:
  3215. !
  3216. IMPLICIT NONE
  3217. !
  3218. ! !INPUT PARAMETERS:
  3219. !
  3220. CHARACTER(LEN=*), INTENT(IN) :: strlowercase
  3221. !
  3222. ! !RETURN VALUE:
  3223. !
  3224. CHARACTER(LEN=LEN(strlowercase)) :: struppercase
  3225. !
  3226. ! !REVISION HISTORY:
  3227. ! 1 Oct 2010 - Achim Strunk -
  3228. !
  3229. !EOP
  3230. !------------------------------------------------------------------------
  3231. !BOC
  3232. CHARACTER(LEN=1) :: u
  3233. INTEGER :: i,j
  3234. struppercase = strlowercase
  3235. DO i=1,LEN(strlowercase)
  3236. u = strlowercase(i:i)
  3237. j = IACHAR(u)
  3238. IF(j < 97 .OR. j > 122) CYCLE
  3239. struppercase(i:i) = ACHAR(j-32)
  3240. END DO
  3241. !-------------------------------------------------------------------------------
  3242. END FUNCTION STRUPPERCASE
  3243. !EOC
  3244. END MODULE USER_OUTPUT_PDUMP