12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878 |
- #define TRACEBACK write (gol,'("in ",a," (",a,i6,")")') rname, __FILE__, __LINE__ ; call goErr
- #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
- #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
- #define IF_NOTOK_MDF(action) if (status/=0) then; TRACEBACK; action; call MDF_CLose(fid,status); status=1; return; end if
- !
- #include "tm5.inc"
- !-----------------------------------------------------------------------------
- ! TM5 !
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !MODULE: USER_OUTPUT_PDUMP
- !
- ! !DESCRIPTION:
- !
- ! Module to deal with time-series output. Output are in NetCDF-4 and use CF
- ! conventions. The following output are available:
- !
- ! - one file with grid definition
- ! - one file with time series of some met fields (pressure, temperature, winds, ...)
- ! - one or more files with time series of some tracers
- ! - one or two files with Local Time output for some tracers
- ! - one file with time series of wet and dry depositions
- ! - one file with time series of deposition velocity
- !
- ! Activation, tracers to account for, time step of the series, are set in the
- ! rcfile, following this template :
- !
- !
- ! SAMPLE RCFILE
- !
- ! output.pdump : T
- ! output.pdump.dataset.author : John Doe
- ! output.pdump.dataset.institution : MyFirm, Anytown, USA
- ! output.pdump.dataset.version : GEMS GRG; era2003 simulation
- ! output.pdump.fname.model : TM5
- ! output.pdump.fname.expid : V2
- ! output.pdump.fname.grid.300x200 : 3x2 ! short name, required if there is zoom regions
- ! output.pdump.fname.grid.100x100 : 1x1
- !
- ! output.pdump.griddef.apply : T
- !
- ! output.pdump.tp.apply : T
- ! output.pdump.tp.dhour : 1
- !
- ! output.pdump.vmr.n : 3
- !
- ! output.pdump.vmr.001.apply : T
- ! output.pdump.vmr.001.fname : vmr1
- ! output.pdump.vmr.001.dhour : 3
- ! output.pdump.vmr.001.tracers : CO2
- !
- ! output.pdump.lt.apply : T
- ! output.pdump.lt.tracers : CO2
- ! output.pdump.lt.localtime : 2
- !
- ! output.pdump.lt2.apply : F
- ! output.pdump.lt2.tracers : CO2
- ! output.pdump.lt2.localtime : 12
- !
- ! output.pdump.depositions.apply : F
- ! output.pdump.depositions.dhour : 3
- ! output.pdump.depositions.tracers : CO2
- !
- ! output.pdump.depvels.apply : F
- ! output.pdump.depvels.dhour : 3
- ! output.pdump.depvels.tracers : CO2
- !
- !\\
- !\\
- ! !INTERFACE:
- !
- MODULE USER_OUTPUT_PDUMP
- !
- ! !USES:
- !
- use GO, only : gol, goPr, goErr, goLabel
- use GO, only : TDate
- use dims, only : nregions, idatee, idatei, okdebug
- use chem_param, only : ntrace
-
- USE MDF
- USE TM5_DISTGRID, only : dgrid, Get_DistGrid, update_halo
-
- IMPLICIT NONE
- PRIVATE
- !
- ! !PUBLIC MEMBER FUNCTIONS:
- !
- public :: Output_PDUMP_Init
- public :: Output_PDUMP_Step
- public :: Output_PDUMP_Done
- !
- ! !PRIVATE DATA MEMBERS:
- !
- character(len=*), parameter :: mname = 'user_output_pdump'
- character(len=*), parameter :: outfileversnr = '0.1'
- integer, parameter :: time_reftime6(6) = (/1950,01,01,00,00,00/) ! reference time
- character(len=*), parameter :: time_units = 'days since 1950-01-01 00:00:00'
- !
- !
- type TPdumpFile_GridDef
- integer :: trec
- integer :: ncid
- integer :: dimid_scalar, dimid_lon, dimid_lat, dimid_lev, dimid_levi
- integer :: varid_lon, varid_lat, varid_time, varid_date
- integer :: varid_gridbox_area
- integer :: varid_a, varid_b
- integer :: varid_a_bnds, varid_b_bnds
- integer :: varid_p0
- !integer :: varid_ps
- !integer :: varid_geo_height
- end type TPdumpFile_GridDef
- type TPdumpFile_TP
- integer :: trec
- integer :: dhour
- integer :: ncid
- integer :: dimid_lon, dimid_lat, dimid_lev, dimid_time, dimid_datelen
- integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
- integer :: varid_ps
- integer :: varid_surface_temp
- integer :: varid_orog
- integer :: varid_geop
- integer :: varid_pressure
- integer :: varid_temp
- integer :: varid_humid
- integer :: varid_u, varid_v, varid_w
- real, allocatable :: data3d(:,:,:,:,:)
- real, allocatable :: data2d(:,:,:,:)
- real, allocatable :: time(:)
- real, allocatable :: date(:,:)
- end type TPdumpFile_TP
- type TPdumpFile_VMR
- integer :: trec, n_rec
- logical :: apply
- integer :: dhour
- character(len=256) :: tracer_names
- integer :: ncid
- integer :: dimid_lon, dimid_lat, dimid_lev, dimid_levi, dimid_time, dimid_datelen
- integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
- integer :: varid_temp
- integer :: varid_ps
- integer :: varid_a_bnds, varid_b_bnds
- integer :: ntr
- integer :: itr(ntrace)
- character(len=8) :: name_tr(ntrace)
- integer :: varid_tr(ntrace)
- character(len=4) :: varid_type(ntrace)
- real, allocatable :: data3d(:,:,:,:,:)
- real, allocatable :: data3d_t(:,:,:,:)
- real, allocatable :: sp(:,:,:)
- real, allocatable :: time(:)
- real, allocatable :: date(:,:)
- end type TPdumpFile_VMR
- type TPdumpFile_LT
- integer :: trec
- character(len=256) :: tracer_names
- integer :: ncid
- integer :: local_time
- integer :: dimid_lon, dimid_lat, dimid_lev, dimid_time, dimid_datelen
- integer :: varid_lon, varid_lat, varid_lev, varid_time, varid_date
- integer :: varid_ps
- integer :: ntr
- integer :: itr(ntrace)
- character(len=8) :: name_tr(ntrace)
- integer :: varid_tr(ntrace)
- real,allocatable :: accu(:,:,:,:)
- real,allocatable :: naccu(:,:)
- real,allocatable :: p_accu(:,:)
- real,allocatable :: np_accu(:)
- end type TPdumpFile_LT
- type TPdumpFile_DEPS
- integer :: trec
- integer :: dhour
- character(len=256) :: tracer_names
- integer :: ncid
- integer :: dimid_lon, dimid_lat, dimid_time, dimid_datelen
- integer :: varid_lon, varid_lat, varid_time, varid_date, varid_accum
- integer :: ntr
- integer :: itr(ntrace)
- character(len=8) :: name_tr(ntrace)
- integer :: varid_ddep(ntrace)
- real, pointer :: ddep_budget(:,:,:)
- logical :: with_wdep(ntrace)
- integer :: varid_wdep(ntrace)
- real, pointer :: wdep_budget(:,:,:)
- type(TDate) :: t0_budget
- real, allocatable :: data2d_dry(:,:,:,:)
- real, allocatable :: data2d_wet(:,:,:,:)
- real, allocatable :: time(:), dt(:)
- real, allocatable :: date(:,:)
- end type TPdumpFile_DEPS
- type TPdumpFile_DEPV
- integer :: trec
- integer :: dhour
- character(len=256) :: tracer_names
- integer :: ncid
- integer :: dimid_lon, dimid_lat, dimid_time, dimid_datelen
- integer :: varid_lon, varid_lat, varid_time, varid_date
- integer :: ntr
- integer :: itr(ntrace)
- character(len=8) :: name_tr(ntrace)
- integer :: varid_tr(ntrace)
- real, allocatable :: data2d(:,:,:,:)
- real, allocatable :: time(:)
- real, allocatable :: date(:,:)
- end type TPdumpFile_DEPV
- ! --- var -----------------------------
- integer :: fid ! file id for IF_NOTOK_MDF macro
- integer :: access_mode ! netcdf-4 access mode
- integer :: curr_day(nregions,3)
- logical :: firstday
- logical :: lastday ! it is last day and not a full day (ie day does not end at 00 of next day)
- character(len=32) :: fname_model
- character(len=8) :: fname_expid, meteo_class
- character(len=32) :: fname_grid(nregions)
- character(len=256) :: dataset_author, institution, dataset_version
- logical, save :: griddef_apply
- type(TPdumpFile_GridDef), save :: RF_GridDef(nregions)
- logical, save :: tp_apply
- integer :: tp_dhour, n_tp_rec
- type(TPdumpFile_TP), save :: RF_TP(nregions)
- integer, save :: nvmr
- logical, allocatable :: vmr_apply(:)
- real, allocatable :: vmr_sregbord(:,:)
- character(len=16), allocatable :: vmr_fname(:)
- integer, allocatable :: vmr_dhour(:)
- character(len=256), allocatable :: vmr_tracer_names(:)
- type(TPdumpFile_VMR), allocatable, save :: RF_VMR(:,:)
- logical, save :: lt_apply
- character(len=16) :: lt_fname
- character(len=256) :: lt_tracer_names
- integer :: lt_localtime
- type(TPdumpFile_LT), save :: RF_LT(nregions)
- logical, save :: lt2_apply
- character(len=16) :: lt2_fname
- character(len=256) :: lt2_tracer_names
- integer :: lt2_localtime
- type(TPdumpFile_LT), save :: RF_LT2(nregions)
- logical, save :: deps_apply
- character(len=16) :: deps_fname
- integer :: deps_dhour, n_deps_rec
- character(len=256) :: deps_tracer_names
- type(TPdumpFile_DEPS), save :: RF_DEPS(nregions)
- logical, save :: depv_apply
- character(len=16) :: depv_fname
- integer :: depv_dhour, n_depv_rec
- character(len=256) :: depv_tracer_names
- type(TPdumpFile_DEPV), save :: RF_DEPV(nregions)
- !
- ! !REVISION HISTORY:
- !
- ! 1 Oct 2010 - Achim Strunk - revised older RETRO ouptut :
- ! add 2nd local time, regional output
- ! 10 Jul 2012 - Ph. Le Sager - switch from pnetcdf to netcdf4_par (through
- ! MDF); get rid of the with_tendencies code.
- ! 12 Nov 2012 - Ph. Le Sager - adapted for lon-lat MPI decomposition.
- ! - get rid of unlimited dimensions so we can
- ! write in collective mode.
- ! - store series to write them only at end-of-day
- ! to speed-up code
- ! 10 Oct 2013 - Ph. Le Sager - fixed GET_N_TIME_RECORDS and several 'init'
- ! and write' routines.
- ! 14 Apr 2014 - Ph. Le Sager + JEW - tropomi add-ons in VMR: Temperature,
- ! As, Bs, better CF
- !
- ! !REMARKS:
- !
- ! (1) Initially called RETRO output for GEMS GRG, the module has been adapted
- ! for CLIMAQS project and renamed PDUMP.
- ! (2) Previous remarks "as is":
- ! - longitudes from [0,360] ?
- ! this is imposible for zoom area's such as for the heatwave
- ! - levels from surface to top
- ! - time from 1950-01-01 00:00
- ! (3) This is supposed to work with netcdf4_parallel. You cannot use
- ! MPI with a non-parallel version of netcdf4 here.
- ! (4) The parallel writing is done in COLLECTIVE mode, but remain
- ! expensive on some system. Possible optimization : output one file
- ! per month (chunk/leg), and/or per field, and/or per processor.
- !
- !EOP
- !------------------------------------------------------------------------
- CONTAINS
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !FUNCTION: GET_N_TIME_RECORDS
- !
- ! !DESCRIPTION: return number of time steps for a daily timeseries file
- !\\
- !\\
- ! !INTERFACE:
- !
- FUNCTION GET_N_TIME_RECORDS( date, dh, isDEPS, mess )
- !
- ! !USES:
- !
- USE GO , only : TDate, NewDate, rTotal, operator(-)
- !
- ! !RETURN VALUE:
- !
- integer :: get_n_time_records
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: date(6) ! 1st time step of the day (date[4] should be 1 unless 1st day)
- integer, intent(in) :: dh ! time step for timeseries (should divide 24)
- logical, optional, intent(in) :: isDEPS ! to differentiate b/w DEPS and others
- character(len=*), optional, intent(in) :: mess ! message (if okdebug)
- !
- ! !REVISION HISTORY:
- ! 9 Nov 2012 - Ph. Le Sager - v0
- ! 9 Oct 2013 - Ph. Le Sager - fix to work with default "output.after.step: v"
- !
- ! !REMARKS:
- ! - assumed dynamic timestep of 1h. It may be smaller at some steps (CFL
- ! violation) but that's ok, since it is never zero and we are looking
- ! at "integer-hours" for output. Only issue is if dynamic timestep is
- ! LARGER than timestep of timeseries: deemed too exotic, but we could
- ! add a test in init to avoid that.
- !
- ! !TODO:
- ! - need to check if Oct 2013 fix works with runs that do NOT stop at
- ! midnight (labelled "lastday" cases in the code). Deemed exotic for now.
- ! - check if anything changes with other possible values of "output.after.step"
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer :: is, ie, delta, dynstep
- logical :: deps
- type(TDate) :: t, t0
- real :: time
- ! Type of record (standard=vmr, tp, depv) or special (deps)
- deps=.false.
- if (present(isDEPS)) deps=isDEPS
- ! Start index
- delta=date(4)
- if (deps) delta=date(4)+1 ! one DYNAMIC time step done to output something
- if (modulo(delta,dh)==0) then
- is=delta/dh
- else
- is=(delta+dh)/dh
- end if
-
- ! End index
- ie = 23 / dh ! 23 = 24 - dynamic time step
- if (deps) then ! there will be an extra step if run goes further than midnight
-
- t0 = NewDate( time6=date )
- t = NewDate( time6=idatee )
- time = rTotal( t - t0, 'day' )
- if (time > 1) ie=24/dh
- end if
- ! Case of last day stopping before midnite. (Need testing again - see
- ! !TODO. Probaly alright for VMR/TP/DEPV, but check required for DEPS)
- if (lastday) ie=idatee(4)/dh
- ! length
- get_n_time_records = ie-is+1
- if(okdebug)then
- if (present(mess))then
- write(gol,*) 'GET_N_TIME_RECORDS -'//trim(mess); call goPr
- end if
-
- write(gol,*) "GET_N_TIME_RECORDS - is, ie, deps, firstday, lastday, get_n_time_records:"; call goPr
- write(gol,*) "GET_N_TIME_RECORDS - ", is, ie, deps, firstday, lastday, get_n_time_records; call goPr
- end if
-
- return
- END FUNCTION GET_N_TIME_RECORDS
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: OUTPUT_PDUMP_INIT
- !
- ! !DESCRIPTION: reads rc file keys relevant for pdump
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE OUTPUT_PDUMP_INIT( rcF, dhour_min, status )
- !
- ! !USES:
- !
- use GO, only : TrcFile, ReadRc
- use MeteoData, only : lli, set
- use MeteoData, only : sp_dat, oro_dat, temper_dat, humid_dat, pu_dat, pv_dat
- use MeteoData, only : mfw_dat, gph_dat, t2m_dat
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TrcFile), intent(inout) :: rcF
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: dhour_min
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - upgrade from RETRO to PDUMP
- ! 8 Nov 2012 - Ph. Le Sager - added access mode switch
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Output_PDUMP_Init'
- ! --- local ------------------------------
- integer :: region
- character(len=64) :: key
- character(len=3) :: nr
- integer :: ivmr
- ! --- begin -------------------------------
- call goLabel(rname)
- #ifdef MPI
- #ifdef with_netcdf4_par
- access_mode = MDF_COLLECTIVE
- #else
- write(gol,'("Time Series output (PDUMP) requires netcdf4 with parallel access enabled")') ; call goErr
- TRACEBACK
- status=1; return
- #endif
- #else
- access_mode = MDF_INDEPENDENT
- #endif
- ! which day
- firstday = .true.
- lastday = .true.
-
- if (any(idatei(1:3)/=idatee(1:3))) lastday=.false. ! i.e. at least one full day
- ! dataset keys:
- call ReadRc( rcF, 'output.pdump.dataset.author' , dataset_author , status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'output.pdump.dataset.institution', institution , status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'output.pdump.dataset.version' , dataset_version , status )
- IF_NOTOK_RETURN(status=1)
- ! filename keys:
- call ReadRc( rcF, 'output.pdump.fname.model', fname_model, status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'output.pdump.fname.expid', fname_expid, status )
- IF_NOTOK_RETURN(status=1)
- ! prefix grid name in case of zooming regions:
- if ( nregions > 1 ) then
- ! loop over regions:
- do region = 1, nregions
- ! short grid name from rcfile:
- call ReadRc( rcF, 'output.pdump.fname.grid.'//trim(lli(region)%name), key, status )
- IF_NOTOK_RETURN(status=1)
- ! fill grid extenstion to file names:
- fname_grid(region) = '-'//trim(key)
- end do
- else
- ! empty
- fname_grid = ''
- end if
- ! griddef file ?
- call ReadRc( rcF, 'output.pdump.griddef.apply', griddef_apply, status )
- IF_NOTOK_RETURN(status=1)
- ! temperature, pressure, etc file ?
- call ReadRc( rcF, 'output.pdump.tp.apply', tp_apply, status )
- IF_NOTOK_RETURN(status=1)
- if (tp_apply) then
- ! ensure that required meteo is loaded
- do region=1,nregions
- call Set( sp_dat(region), status, used=.true. )
- call Set( oro_dat(region), status, used=.true. )
- call Set( temper_dat(region), status, used=.true. )
- call Set( t2m_dat(region), status, used=.true. )
- call Set( humid_dat(region), status, used=.true. )
- call Set( pu_dat(region), status, used=.true. )
- call Set( pv_dat(region), status, used=.true. )
- call Set( mfw_dat(region), status, used=.true. )
- call Set( gph_dat(region), status, used=.true. ) ! used to compute vertical wind
- end do
- end if
- ! time resolution (1 hour by default)
- call ReadRc( rcF, 'output.pdump.tp.dhour', tp_dhour, status, default=1 )
- IF_ERROR_RETURN(status=1)
- ! VMR files
- call ReadRc( rcF, 'output.pdump.vmr.n', nvmr, status ) ! number of vmr files to be written
- IF_NOTOK_RETURN(status=1)
- if ( nvmr < 0 ) then
- write (gol,'("strange specification of number of vmr files : ",i6)') nvmr; call goErr
- TRACEBACK; status=1; return
- end if
- ! meteo
- call ReadRc( rcF, 'my.meteo.class', meteo_class, status, default='unknown' )
- IF_ERROR_RETURN(status=1)
-
-
- ! write any vmr files ?
- if ( nvmr > 0 ) then
- ! storage:
- allocate( vmr_apply(nvmr) ) ; vmr_apply = .false.
- allocate( vmr_fname(nvmr) ) ; vmr_fname = ''
- allocate( vmr_dhour(nvmr) ) ; vmr_dhour = -1
- allocate( vmr_tracer_names(nvmr) ) ; vmr_tracer_names = ''
- allocate( vmr_sregbord(nvmr,4) ) ; vmr_sregbord = -999.9
- allocate( RF_VMR(nregions,nvmr) )
-
- #ifdef tropomi
- do region=1,nregions
- call Set( temper_dat(region), status, used=.true. )
- end do
- #endif
- ! loop over vmr files:
- do ivmr = 1, nvmr
- ! number in rc keys:
- write (nr,'(i3.3)') ivmr
- ! apply ?
- call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.apply', vmr_apply(ivmr), status )
- IF_NOTOK_RETURN(status=1)
- rf_vmr(:,ivmr)%apply = vmr_apply(ivmr)
-
- ! proceed ?
- if ( vmr_apply(ivmr) ) then
- ! first part of filename:
- call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.fname', vmr_fname(ivmr), status )
- IF_NOTOK_RETURN(status=1)
- ! time resolution:
- call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.dhour', vmr_dhour(ivmr), status )
- IF_NOTOK_RETURN(status=1)
- ! tracers to be written:
- call ReadRc( rcF, 'output.pdump.vmr.'//nr//'.tracers', vmr_tracer_names(ivmr), status )
- IF_NOTOK_RETURN(status=1)
- end if ! apply ?
- end do ! vmr numbers
- ! required meteo
- if (any(vmr_apply)) then
- do region=1,nregions
- call Set( sp_dat(region), status, used=.true. )
- end do
- end if
-
- end if ! nvmr > 0
- ! ---------------------
- ! local time:
- ! ---------------------
- ! file 1
- lt_fname = 'lt'
- call ReadRc( rcF, 'output.pdump.lt.apply', lt_apply, status )
- IF_NOTOK_RETURN(status=1)
- if ( lt_apply ) then
- call ReadRc( rcF, 'output.pdump.lt.tracers', lt_tracer_names, status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'output.pdump.lt.localtime', lt_localtime, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! file 2
- lt2_fname = 'lt2'
- call ReadRc( rcF, 'output.pdump.lt2.apply', lt2_apply, status )
- IF_NOTOK_RETURN(status=1)
- if ( lt2_apply ) then
- call ReadRc( rcF, 'output.pdump.lt2.tracers', lt2_tracer_names, status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'output.pdump.lt2.localtime', lt2_localtime, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if (lt_apply .or. lt2_apply) then
- do region=1,nregions
- call Set( sp_dat(region), status, used=.true. )
- end do
- end if
- ! ---------------------
- ! deposition fluxes:
- ! ---------------------
- deps_fname = 'depositions'
- call ReadRc( rcF, 'output.pdump.depositions.apply', deps_apply, status )
- IF_NOTOK_RETURN(status=1)
- if ( deps_apply ) then
- call ReadRc( rcF, 'output.pdump.depositions.dhour', deps_dhour, status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'output.pdump.depositions.tracers', deps_tracer_names, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! ---------------------
- ! deposition velocities:
- ! ---------------------
- depv_fname = 'depvels'
- call ReadRc( rcF, 'output.pdump.depvels.apply', depv_apply, status )
- IF_NOTOK_RETURN(status=1)
- if ( depv_apply ) then
- call ReadRc( rcF, 'output.pdump.depvels.dhour', depv_dhour, status )
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'output.pdump.depvels.tracers', depv_tracer_names, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! no files open yet
- curr_day = -1
- ! lowest time frequency is 1 hour
- dhour_min = 1
- call goLabel()
- ! ok
- status = 0
- END SUBROUTINE OUTPUT_PDUMP_INIT
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: OUTPUT_PDUMP_STEP
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE OUTPUT_PDUMP_STEP( region, idate_f, status )
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- !
- ! !REMARKS:
- ! (1) called every hour.
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Output_PDUMP_Step'
- ! --- begin -------------------------------
- call goLabel(rname)
-
- !----------------------
- ! close if necessary
- !----------------------
- ! if a file is open, and it is a new day
- if ( all(curr_day(region,:) > 0) .and. any(idate_f(1:3) /= curr_day(region,:)) ) then
- ! write in previous day file end-of-interval data
- call PDUMP_Files_Write2( region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- ! close all
- call PDUMP_Files_Close( region, status )
- IF_NOTOK_RETURN(status=1)
- ! no files open ...
- curr_day(region,:) = -1
- firstday = .false.
- end if
- !----------------------
- ! open if necessary
- !----------------------
- if ( any(curr_day(region,:) < 0) ) then
- if (all(idate_f(1:3)==idatee(1:3))) lastday=.true. ! means last day is not a full day
- write(gol,*) "U_O_Pdump open [idate_f, last day] = ", idate_f, lastday; call goPr
- call PDUMP_Files_Open( region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- ! store date of current day
- curr_day(region,:) = idate_f(1:3)
- end if
- !----------------------
- ! write
- !----------------------
- call PDUMP_Files_Write( region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- ! if not midnight, write end-of-interval data
- if ( any(idate_f(4:6) > 0) ) then
- call PDUMP_Files_Write2( region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- end if
- !----------------------
- ! done
- !----------------------
- call goLabel()
- status = 0
- END SUBROUTINE OUTPUT_PDUMP_STEP
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: OUTPUT_PDUMP_DONE
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE OUTPUT_PDUMP_DONE( status )
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 31 Aug 2012 - P. Le Sager - reverse order in which regions are dealt with (MDF issue)
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/Output_PDUMP_Done'
- integer :: region
- ! --- begin -------------------------------
- ! close files:
- do region = nregions, 1, -1
- call PDUMP_Files_Close( region, status )
- IF_NOTOK_RETURN(status=1)
- end do
- ! clear:
- if ( nvmr > 0 ) then
- deallocate( vmr_apply )
- deallocate( vmr_fname )
- deallocate( vmr_dhour )
- deallocate( vmr_tracer_names )
- deallocate( vmr_sregbord )
- deallocate( RF_VMR )
- end if
- ! ok
- status = 0
- END SUBROUTINE OUTPUT_PDUMP_DONE
- !EOC
- ! ********************************************************************
- ! ***
- ! *** open/write/close pdump files
- ! ***
- ! ********************************************************************
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PDUMP_FILES_OPEN
- !
- ! !DESCRIPTION: call init method of each output file.
- !\\
- !\\
- ! !INTERFACE:
- !
- subroutine PDUMP_Files_Open( region, idate_f, status )
- !
- ! !USES:
- !
- use global_data, only : outdir
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/PDUMP_Files_Open'
- ! --- local -------------------------------
- integer :: ivmr
- ! --- begin -------------------------------
- ! grid definition:
- if ( griddef_apply ) then
- call RF_GridDef_Init( RF_GridDef(region), outdir, fname_model, fname_expid, region, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! dynamics:
- if ( tp_apply ) then
- call RF_TP_Init ( RF_TP(region) , outdir, fname_model, fname_expid, &
- region, idate_f, tp_dhour, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! tracer concentrations:
- do ivmr = 1, nvmr
- if ( .not. vmr_apply(ivmr) ) cycle
- call RF_VMR_Init( RF_VMR(region,ivmr), outdir, fname_model, fname_expid, &
- vmr_fname(ivmr), region, idate_f, &
- vmr_dhour(ivmr), vmr_tracer_names(ivmr), status )
- IF_NOTOK_RETURN(status=1)
- vmr_apply(ivmr) = rf_vmr(region,ivmr)%apply
- end do
- ! lt output:
- if ( lt_apply ) then
- call RF_LT_Init( RF_LT(region), outdir, fname_model, fname_expid, &
- lt_fname, region, idate_f, &
- lt_localtime, lt_tracer_names, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( lt2_apply ) then
- call RF_LT_Init( RF_LT2(region), outdir, fname_model, fname_expid, &
- lt2_fname, region, idate_f, &
- lt2_localtime, lt2_tracer_names, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! deposition fluxes:
- ! if ( deps_apply ) then
- ! call RF_DEPS_Init( RF_DEPS(region), outdir, fname_model, fname_expid, &
- ! deps_fname, region, idate_f, &
- ! deps_dhour, deps_tracer_names, status )
- ! IF_NOTOK_RETURN(status=1)
- ! end if
- ! ! deposition velocities:
- ! if ( depv_apply ) then
- ! call RF_DEPV_Init( RF_DEPV(region), outdir, fname_model, fname_expid, &
- ! depv_fname, region, idate_f, &
- ! depv_dhour, depv_tracer_names, status )
- ! IF_NOTOK_RETURN(status=1)
- ! end if
- ! ok
- status = 0
- END SUBROUTINE PDUMP_FILES_OPEN
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PDUMP_FILES_WRITE
- !
- ! !DESCRIPTION: call write method for each output file.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PDUMP_FILES_WRITE( region, idate_f, status )
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk -
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/PDUMP_Files_Write'
- integer :: ivmr
- ! --- begin -------------------------------
- ! grid definition:
- if ( griddef_apply ) then
- call RF_GridDef_Write( RF_GridDef(region), region, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! dynamics:
- if ( tp_apply ) then
- call RF_TP_Write( RF_TP(region), region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! tracer fields:
- do ivmr = 1, nvmr
- if ( .not. vmr_apply(ivmr) ) cycle
- call RF_VMR_Write( RF_VMR(region,ivmr), region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- end do
- ! lt output:
- if ( lt_apply ) then
- call RF_LT_Write( RF_LT(region), region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( lt2_apply ) then
- call RF_LT_Write( RF_LT2(region), region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! ! deposition velocities:
- ! if ( depv_apply ) then
- ! call RF_DEPV_Write( RF_DEPV(region), region, idate_f, status )
- ! IF_NOTOK_RETURN(status=1)
- ! end if
- status = 0
- END SUBROUTINE PDUMP_FILES_WRITE
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PDUMP_FILES_WRITE2
- !
- ! !DESCRIPTION: write at end of time interval
- !
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PDUMP_FILES_WRITE2( region, idate_f, status )
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/PDUMP_Files_Write2'
- ! --- begin -------------------------------
- ! deposition fluxes:
- ! if ( deps_apply ) then
- ! call RF_DEPS_Write( RF_DEPS(region), region, idate_f, status )
- ! IF_NOTOK_RETURN(status=1)
- ! end if
- ! lt output:
- if ( lt_apply ) then
- call RF_LT_Write( RF_LT(region), region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( lt2_apply ) then
- call RF_LT_Write( RF_LT2(region), region, idate_f, status )
- IF_NOTOK_RETURN(status=1)
- end if
- ! ok
- status = 0
- END SUBROUTINE PDUMP_FILES_WRITE2
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PDUMP_FILES_CLOSE
- !
- ! !DESCRIPTION: call done method of each output file.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PDUMP_FILES_CLOSE( region, status )
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 31 Aug 2012 - Ph. Le Sager - switch closing order, since it was giving issues on some machine.
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/PDUMP_Files_Close'
- ! --- local -------------------------------
- integer :: ivmr
- ! --- begin -------------------------------
- ! if ( depv_apply ) then
- ! call RF_DEPV_Done( RF_DEPV(region), status )
- ! IF_NOTOK_RETURN(status=1)
- ! end if
- ! if ( deps_apply ) then
- ! call RF_DEPS_Done( RF_DEPS(region), status )
- ! IF_NOTOK_RETURN(status=1)
- ! end if
- if ( lt2_apply ) then
- call RF_LT_Done( RF_LT2(region), region, status )
- IF_NOTOK_RETURN(status=1)
- end if
-
- if ( lt_apply ) then
- call RF_LT_Done( RF_LT(region), region, status )
- IF_NOTOK_RETURN(status=1)
- end if
- do ivmr = nvmr, 1, -1
- if ( .not. vmr_apply(ivmr) ) cycle
- call RF_VMR_Done( RF_VMR(region,ivmr), status )
- IF_NOTOK_RETURN(status=1)
- end do
- if ( tp_apply ) then
- call RF_TP_Done ( RF_TP(region) , status )
- IF_NOTOK_RETURN(status=1)
- end if
- if ( griddef_apply ) then
- call RF_GridDef_Done( RF_GridDef(region), status )
- IF_NOTOK_RETURN(status=1)
- end if
- status = 0
- end subroutine PDUMP_Files_Close
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_GRIDDEF_INIT
- !
- ! !DESCRIPTION:
- !
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! FILE 1: Model horizontal grid definition
- ! (longitude, latitude, size of gridbox [m2] ).
- ! For documentation purposes, please also include the native vertical
- ! grid definition from your model (hybrid level coefficients) and the
- ! formula used to calculate pressure.
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- !
- !\\
- !\\
- ! !INTERFACE:
- !
- subroutine RF_GridDef_Init( RF, fdir, model, expid, region, status )
- !
- ! !USES:
- !
- use partools, only : MPI_INFO_NULL, localComm
- use MeteoData, only : global_lli, levi
- !
- ! !OUTPUT PARAMETERS:
- !
- type(TPdumpFile_GridDef), intent(out) :: RF
- !
- ! !INPUT PARAMETERS:
- !
- character(len=*), intent(in) :: fdir
- character(len=*), intent(in) :: model
- character(len=*), intent(in) :: expid
- integer, intent(in) :: region
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk -
- ! 10 Jul 2012 - Ph. Le Sager - switch to MDF_NETCDF4
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_GridDef_Init'
- character(len=256) :: fname
- integer :: varid
- integer :: rtype
- ! --- begin -------------------------------------
- call goLabel(rname)
- ! o open file
- ! write filename
- write (fname,'(a,"/",a,a,"_",a,"_",a,".nc")') &
- trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), 'griddef'
- #ifdef MPI
- ! overwrite existing files (clobber), provide MPI stuff:
- call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
- mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
- if (status/=0) then
- write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
- write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
- TRACEBACK; status=1; return
- end if
- #else
- ! overwrite existing files (clobber)
- call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
- IF_NOTOK_RETURN(status=1)
- #endif
- ! o global attributes
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title', 'model horizontal definition' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! o define dimensions
- call MDF_Def_Dim( RF%ncid, 'scalar', 1, RF%dimid_scalar , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'lon', global_lli(region)%nlon, RF%dimid_lon , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'lat', global_lli(region)%nlat, RF%dimid_lat , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'levi', levi%nlev+1, RF%dimid_levi , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Def_Dim( RF%ncid, 'time', NTS, RF%dimid_time , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Def_Dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- ! o define variables
- rtype = MDF_FLOAT
- call MDF_Def_Var( RF%ncid, 'lon', rtype, (/RF%dimid_lon/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'longitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_east' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lon = varid
- call MDF_Def_Var( RF%ncid, 'lat', MDF_FLOAT, (/RF%dimid_lat/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'latitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_north' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lat = varid
- !call MDF_Def_Var( RF%ncid, 'time', MDF_FLOAT, RF%dimid_time, varid , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'time' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'calender', 'gregorian' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !RF%varid_time = varid
-
- !call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'date' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !RF%varid_date = varid
-
- call MDF_Def_Var( RF%ncid, 'area', MDF_FLOAT, (/RF%dimid_lon,RF%dimid_lat/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'grid_cell_area' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'grid-cell area' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'm2' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_gridbox_area = varid
- call MDF_Def_Var( RF%ncid, 'a', MDF_FLOAT, (/RF%dimid_lev/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a(k)*p0 + b(k)*ps(n,j,i)' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_a = varid
- call MDF_Def_Var( RF%ncid, 'b', mdf_float, (/RF%dimid_lev/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'formula_terms', 'p(n,k,j,i) = a(k)*p0 + b(k)*ps(n,j,i)' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_b = varid
- call MDF_Def_Var( RF%ncid, 'a_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- 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)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_a_bnds = varid
- call MDF_Def_Var( RF%ncid, 'b_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- 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)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_b_bnds = varid
- call MDF_Def_Var( RF%ncid, 'p0', mdf_float, (/RF%dimid_scalar/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'reference pressure value' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_p0 = varid
- !status = pnf90_def_var( RF%ncid, 'ps', MDF_FLOAT, &
- ! (/RF%dimid_lon,RF%dimid_lat,RF%dimid_time/), varid )
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !RF%varid_ps = varid
- !status = pnf90_def_var( RF%ncid, 'geo_height', MDF_FLOAT, &
- ! (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid )
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'long_name', 'geopotential height' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'units', 'm' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !call MDF_Put_Att( RF%ncid, varid, 'comment', 'bottom-up; lower half level; top value implicit infinity' , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
- !RF%varid_geo_height = varid
- ! o end defintion mode
- call MDF_EndDef( RF%ncid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! no records written yet
- RF%trec = 0
- call goLabel() ; status = 0
- END SUBROUTINE RF_GRIDDEF_INIT
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_GridDef_Write
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RF_GRIDDEF_WRITE( RF, region, status )
- !
- ! !USES:
- !
- use GO, only : TDate, NewDate, rTotal, operator(-)
- use Grid, only : AreaOper
- use MeteoData, only : global_lli, levi, sp_dat
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_GridDef), intent(inout) :: RF
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk -
- ! 10 Jul 2012 - Ph. Le Sager - switch to MDF_NETCDF4
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_GridDef_Write'
- integer :: imr, jmr, lmr
- real, allocatable :: ll(:,:)
- real :: time
- ! --- begin -------------------------------------
- call goLabel(rname)
- ! grid size
- imr = global_lli(region)%nlon
- jmr = global_lli(region)%nlat
- lmr = levi%nlev
- ! next time record:
- RF%trec = RF%trec + 1
- ! o write data
- if ( RF%trec == 1 ) then
- ! lat/lon field:
- allocate( ll(imr,jmr) )
- call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ll = 1.0
- call AreaOper( global_lli(region), ll, '*', 'm2', status )
- IF_NOTOK_RETURN(status=1)
- call MDF_Put_Var( RF%ncid, RF%varid_gridbox_area, ll , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_a, levi%fa , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_b, levi%fb , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_a_bnds, levi%a(0:levi%nlev) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_b_bnds, levi%b(0:levi%nlev) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_p0, (/1.0/) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- deallocate( ll )
- end if
-
- !call MDF_Put_Var( RF%ncid, RF%varid_time, time, index=RF%trec , status)
- !IF_NOTOK_MDF(fid=RF%ncid)
-
- !call MDF_Put_Var( RF%ncid, RF%varid_date, reshape(real(idate_f),(/6,1/), status), &
- ! start=(/1,RF%trec/), count=(/6,1/) )
- !IF_NOTOK_MDF(fid=RF%ncid)
-
- !status = pnf90_put_var( RF%ncid, RF%varid_ps, &
- ! reshape(sp_dat(region)%data(1:imr,1:jmr,1:1),(/imr,jmr,1/)), &
- ! start=(/1,1,RF%trec/), count=(/imr,jmr,1/) )
- !IF_NOTOK_MDF(fid=RF%ncid)
-
- !status = pnf90_put_var( RF%ncid, RF%varid_geo_height, &
- ! reshape(gph_dat(region)%data(1:imr,1:jmr,1:lmr),(/imr,jmr,lmr,1/)), &
- ! start=(/1,1,1,RF%trec/), count=(/imr,jmr,lmr,1/) )
- !IF_NOTOK_MDF(fid=RF%ncid)
-
- call goLabel()
- status = 0
- END SUBROUTINE RF_GridDef_Write
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_GRIDDEF_DONE
- !
- ! !DESCRIPTION: close file-1
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RF_GridDef_Done( RF, status )
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_GridDef), intent(inout) :: RF
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk -
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_GridDef_Done'
- ! --- begin -------------------------------------
- call goLabel(rname)
- call MDF_Close( RF%ncid , status)
- IF_NOTOK_RETURN(status=1)
- call goLabel()
- status = 0
- END SUBROUTINE RF_GRIDDEF_DONE
- !EOC
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! FILE2: 3D field of monthly Model pressure [Pa] and temperature [K].
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_TP_INIT
- !
- ! !DESCRIPTION: file-2 : open and define var/att
- !
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RF_TP_Init( RF, fdir, model, expid, region, idate_f, dhour, status )
- !
- ! !USES:
- !
- use partools, only : MPI_INFO_NULL, localComm
- use MeteoData, only : global_lli, levi
- !
- ! !OUTPUT PARAMETERS:
- !
- type(TPdumpFile_TP), intent(out) :: RF
- integer, intent(out) :: status
- !
- ! !INPUT PARAMETERS:
- !
- character(len=*), intent(in) :: fdir
- character(len=*), intent(in) :: model
- character(len=*), intent(in) :: expid
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- integer, intent(in) :: dhour
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 7 Aug 2012 - Ph. Le Sager - switch to netcdf-4 thru MDF
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_TP_Init'
- ! --- local ------------------------------------
- character(len=256) :: fname
- integer :: varid, i1, i2, j1, j2
- ! --- begin -------------------------------------
- call goLabel(rname)
- ! store arguments
- RF%dhour = dhour
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- n_tp_rec = GET_N_TIME_RECORDS( idate_f, dhour, mess='TP_Init' )
- if ( n_tp_rec == 0 ) then
- tp_apply = .false.
- status=0
- return
- end if
-
- ! o open file
- ! write filename
- write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
- trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), 'TP', idate_f(1:3)
- ! open, overwrite existing files (clobber)
- #ifdef MPI
- call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
- mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
- if (status/=0) then
- write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
- write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
- TRACEBACK; status=1; return
- end if
- #else
- call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
- IF_NOTOK_RETURN(status=1)
- #endif
- ! o global attributes
- call mdf_put_att( RF%ncid, MDF_GLOBAL, 'title', 'model pressure and temperature', status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, MDF_GLOBAL, 'dataset_version', trim(dataset_version) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! o define dimensions
-
- call mdf_def_dim( RF%ncid, 'lon', global_lli(region)%nlon, RF%dimid_lon , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_def_dim( RF%ncid, 'lat', global_lli(region)%nlat, RF%dimid_lat , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_def_dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_def_dim( RF%ncid, 'time', n_tp_rec, RF%dimid_time , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_def_dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! o define variables
- call mdf_def_var( RF%ncid, 'lon', MDF_FLOAT, (/RF%dimid_lon/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'longitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'longitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'degrees_east' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lon = varid
- call mdf_def_var( RF%ncid, 'lat', MDF_FLOAT, (/RF%dimid_lat/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'latitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'latitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'degrees_north' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lat = varid
- call mdf_def_var( RF%ncid, 'lev', MDF_FLOAT, (/RF%dimid_lev/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'level' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- 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)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lev = varid
- call mdf_def_var( RF%ncid, 'time', MDF_FLOAT, (/RF%dimid_time/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'calender', 'gregorian' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_time = varid
- allocate(RF%time(n_tp_rec))
-
- call mdf_def_var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'date and time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_date = varid
- allocate(RF%date(6,n_tp_rec))
-
- call mdf_def_var( RF%ncid, 'ps', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_air_pressure' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'Pa' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_ps = varid
- call mdf_def_var( RF%ncid, 'orog', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_altitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'surface altitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'm' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_orog = varid
- call mdf_def_var( RF%ncid, 'surface_temp', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'surface_temperature' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'surface temperature' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'K' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'comment', &
- '2m temperature from MARS archive or IFS model (grib 167, 2T)' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_surface_temp = varid
- allocate( RF%data2d(i1:i2, j1:j2, n_tp_rec, 3) )
- call mdf_def_var( RF%ncid, 'geopotential', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'geopotential' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'geopotential' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'm2 s-2' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'comment', 'at mid levels' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_geop = varid
- call mdf_def_var( RF%ncid, 'pressure', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'pressure' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'pressure' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'Pa' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'comment', 'at mid levels' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_pressure = varid
- call mdf_def_var( RF%ncid, 'temp', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'air_temperature' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'temperature' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'K' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'comment', 'bottom-up; full levels' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_temp = varid
- call mdf_def_var( RF%ncid, 'specific_humidity', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'specific_humidity' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'specific humidity' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'kg kg-1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'comment', 'mass fraction of water vapor in moist air; (kg water)/(kg air)' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_humid = varid
- call mdf_def_var( RF%ncid, 'U', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'eastward_wind' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'zonal wind' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_u = varid
- call mdf_def_var( RF%ncid, 'V', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'standard_name', 'northward_wind' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'meridional wind' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_v = varid
- call mdf_def_var( RF%ncid, 'W', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'long_name', 'vertical wind velocity' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'units', 'm s-1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call mdf_put_att( RF%ncid, varid, 'comment', 'computed from mass fluxes through grid box boundaries' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_w = varid
- allocate( RF%data3d(i1:i2, j1:j2, levi%nlev, n_tp_rec, 7) )
-
- ! o end defintion mode
- call mdf_enddef( RF%ncid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! o
- ! no records written yet
- RF%trec = 0
- call goLabel()
- ! ok
- status = 0
- END SUBROUTINE RF_TP_Init
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_TP_Write
- !
- ! !DESCRIPTION: store records, and if last time step write data to file
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RF_TP_Write( RF, region, idate_f, status )
- !
- ! !USES:
- !
- use Binas , only : grav
- use Phys , only : GeoPotentialHeight
- use Grid , only : FPressure, HPressure
- use GO , only : TDate, NewDate, rTotal, operator(-)
- use partools , only : myid, root
- use MeteoData , only : global_lli, lli, levi
- use MeteoData , only : sp_dat, temper_dat, humid_dat, pu_dat, pv_dat, mfw_dat, gph_dat, oro_dat, t2m_dat
- use MeteoData , only : m_dat
- use global_data, only : mass_dat
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_TP), intent(inout) :: RF
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_TP_Write'
- ! --- local ------------------------------------
- integer :: i, j, l, i1, i2, j1, j2
- integer :: imr, jmr, lmr, klm
- real :: lev(levi%nlev)
- type(TDate) :: t, t0
- real :: time
- real, allocatable :: field3d(:,:,:)
- real :: p_hlev(0:levi%nlev)
- ! --- begin -------------------------------------
- ! for multiple of dhour only ...
- if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
- status=0; return
- end if
- call goLabel(rname)
- ! grid size
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- imr=i2-i1+1
- jmr=j2-j1+1
- lmr = levi%nlev
- ! next time record:
- RF%trec = RF%trec + 1
- ! time since reftime:
- t0 = NewDate( time6=time_reftime6 )
- t = NewDate( time6=idate_f )
- time = rTotal( t - t0, 'day' )
-
- if(okdebug)then
- write(gol,*) "RF_TP_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
- end if
-
- ! o write data
- if ( RF%trec == 1 ) then
- call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- do l = 1, lmr
- lev(l) = real(l)
- end do
- call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- end if
- ! temporary storage for 3D fields
- allocate( field3d(i1:i2,j1:j2,1:lmr) ) ; field3d = 0.
- !-------- FILL DIAGNOSTIC ARRAYS
- RF%time(RF%trec) = time
- RF%date(:,RF%trec) = real(idate_f)
- RF%data2d(:,:,RF%trec,1) = sp_dat(region)%data(i1:i2,j1:j2,1)
- RF%data2d(:,:,RF%trec,2) = oro_dat(region)%data(i1:i2,j1:j2,1)
- RF%data2d(:,:,RF%trec,3) = t2m_dat(region)%data(i1:i2,j1:j2,1)
- ! o geopotential
- ! fill mid level geopotential:
- do j = j1, j2
- do i = i1, i2
- ! half level pressures
- call HPressure( levi, sp_dat(region)%data(i,j,1), p_hlev, status )
- IF_NOTOK_RETURN(status=1)
- ! mid level gph (m)
- call GeoPotentialHeight( lmr, p_hlev, temper_dat(region)%data(i,j,:), &
- humid_dat(region)%data(i,j,:), oro_dat(region)%data(i,j,1)/grav, &
- field3d(i,j,:) ) ! m
- end do
- end do
- ! multiply with gravity for correct unit:
- field3d = field3d * grav ! m2/s2
- RF%data3d(:,:,:,RF%trec,1) = field3d
-
- ! o pressure
- ! fill mid level pressure
- call FPressure( levi, sp_dat(region)%data(i1:i2,j1:j2,1), field3d, status )
- IF_NOTOK_RETURN(status=1)
- RF%data3d(:,:,:,RF%trec,2) = field3d
- ! o temperature
- RF%data3d(:,:,:,RF%trec,3) = temper_dat(region)%data(i1:i2,j1:j2,1:lmr)
- ! o specific humidity
- RF%data3d(:,:,:,RF%trec,4) = humid_dat(region)%data(i1:i2,j1:j2,1:lmr)
- ! o wind fields
- CALL UPDATE_HALO( dgrid(region), pu_dat(region)%data, pu_dat(region)%halo, status)
- IF_NOTOK_RETURN(status=1)
- CALL UPDATE_HALO( dgrid(region), pv_dat(region)%data, pv_dat(region)%halo, status)
- IF_NOTOK_RETURN(status=1)
-
- ! average U wind
- 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) ) &
- / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
- do j = j1, j2
- field3d(:,j,:) = field3d(:,j,:) * lli(region)%dx(j-j1+1) ! m/s
- end do
- RF%data3d(:,:,:,RF%trec,5) = field3d
- ! average V wind:
- 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) ) &
- / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
- field3d = field3d * lli(region)%dy ! m/s
- RF%data3d(:,:,:,RF%trec,6) = field3d
- ! from downward massflux to upward average W wind:
- field3d = 0.5 * ( mfw_dat(region)%data(i1:i2,j1:j2,0:lmr-1) + mfw_dat(region)%data(i1:i2,j1:j2,1:lmr) ) &
- / m_dat(region)%data(i1:i2,j1:j2,1:lmr) ! 1/s
- do l = 1, lmr
- field3d(:,:,l) = - 1.0 * field3d(:,:,l) * &
- abs( gph_dat(region)%data(i1:i2,j1:j2,l+1) - gph_dat(region)%data(i1:i2,j1:j2,l) ) ! m/s
- end do
- RF%data3d(:,:,:,RF%trec,7) = field3d
-
- !-------- WRITE ARRAYS
- if ( RF%trec == n_tp_rec ) then
- ! time
- call MDF_Put_Var( RF%ncid, RF%varid_time, RF%time, status)!, start=(/1/), count=(/n_tp_rec/))
- IF_NOTOK_MDF(fid=RF%ncid)
- ! date
- call MDF_Put_Var( RF%ncid, RF%varid_date, RF%date, status )!, &
- ! start=(/1,1/), count=(/6,1/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! surface pressure
- call MDF_Put_Var( RF%ncid, RF%varid_ps, RF%data2d(:,:,:,1), status, start=(/i1,j1,1/), count=(/imr,jmr,n_tp_rec/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! orography (in m!)
- call MDF_Put_Var( RF%ncid, RF%varid_orog, RF%data2d(:,:,:,2), status, start=(/i1,j1,1/), count=(/imr,jmr,n_tp_rec/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! surface temperature = 2m temperature
- call MDF_Put_Var( RF%ncid, RF%varid_surface_temp, RF%data2d(:,:,:,3), status, start=(/i1,j1,1/) ) !, count=(/imr,jmr,1/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! geopotential
- 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/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! pressure
- 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/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! temperature
- 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/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! specific humidity
- 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/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! winds
- 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/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- 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/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- 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/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- end if
-
- ! Done
- deallocate( field3d )
- call goLabel()
- status = 0
- END SUBROUTINE RF_TP_Write
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_TP_Done
- !
- ! !DESCRIPTION: close file #2
- !\\
- !\\
- ! !INTERFACE:
- !
- subroutine RF_TP_Done( RF, status )
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_TP), intent(inout) :: RF
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk -
- ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_TP_Done'
- ! --- begin -------------------------------------
- call goLabel(rname)
- call MDF_Close( RF%ncid , status)
- IF_NOTOK_RETURN(status=1)
- deallocate( rf%time, rf%date, rf%data2d, rf%data3d )
- call goLabel() ; status = 0
- end subroutine RF_TP_Done
- !EOC
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! FILE3: 3D fields for CO2 Volume Mixing Ratios
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_VMR_Init
- !
- ! !DESCRIPTION: open and define variables/attribute for file #3
- !\\
- !\\
- ! !INTERFACE:
- !
- subroutine RF_VMR_Init( RF, fdir, model, expid, filetype, region, &
- idate_f, dhour, tracer_names, status )
- !
- ! !USES:
- !
- use Binas, only : xmair
- use GO, only : goReadFromLine, goUpCase
- use chem_param, only : ntrace, names, ra
- use partools, only : MPI_INFO_NULL, localComm
- use MeteoData, only : global_lli, lli, levi, sp_dat
- use dims, only : xbeg, xend, ybeg, yend, dx, dy, dz, xref, yref, zref
- use dims, only : zbeg, zend
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_VMR), intent(inout) :: RF
- !
- ! !INPUT PARAMETERS:
- !
- character(len=*), intent(in) :: fdir
- character(len=*), intent(in) :: model
- character(len=*), intent(in) :: expid
- character(len=*), intent(in) :: filetype
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- integer, intent(in) :: dhour
- character(len=*), intent(in) :: tracer_names
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
- ! 15 Apr 2014 - Ph. Le Sager - tropomi add-ons
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_VMR_Init'
- ! --- local ------------------------------------
- character(len=256) :: fname, history, sysdate, model_meteo
- integer :: varid, i1, i2, j1, j2
- integer, dimension(8) :: isysdate
-
- character(len=256) :: trnames
- character(len=8) :: trname, tmname
- integer :: k, itr, posend, pospoint
- integer :: imr, jmr, lmr, si, ei, ix, jy
- character(len=32) :: varname_spec
- character(len=5) :: zone
- character(len=64) :: cf_medium_stnd, cf_medium_long
- character(len=64) :: cf_enti_stnd, cf_enti_long, cf_enti_unit
- character(len=64) :: cf_spec_stnd, cf_spec_long
- character(len=4) :: cf_enti_type
- character(len=256) :: cf_name_stnd, cf_name_long, cf_name_unit
- character(len=512) :: comment
- character(len=6) :: csize
- ! --- begin -------------------------------------
- call goLabel(rname)
- ! store arguments
- RF%dhour = dhour
- RF%tracer_names = tracer_names
- ! size
- imr = global_lli(region)%nlon
- jmr = global_lli(region)%nlat
- lmr = levi%nlev
- ! number of time steps
- rf%n_rec = GET_N_TIME_RECORDS( idate_f, dhour, mess='VMR_Init' )
- ! degenerated cases (eg, very short runs)
- if ( rf%n_rec == 0 ) then
- rf%apply = .false.
- status=0
- return
- end if
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
-
- ! set tracer index for requested tracers:
- write (gol,'("selected tracers for VMR output:")'); call goPr
- ! initialise RF
- RF%ntr = 0
- RF%itr = -1
- trnames = tracer_names
- do
- ! empty ?
- if ( len_trim(trnames) == 0 ) exit
- ! next number:
- if ( RF%ntr == ntrace ) then
- write (gol,'("number of elements in tracer names list exceeds ntrace=",i6)') ntrace; call goErr
- TRACEBACK; status=1; return
- end if
- RF%ntr = RF%ntr + 1
- ! extract leading name:
- call goReadFromLine( trnames, trname, status, sep=' ' )
- IF_NOTOK_RETURN(status=1)
- ! convert to tm5 name:
- select case ( trim(strlowercase(trname)) )
- case default ; tmname = trname
- end select
- ! --------------------------------
- ! NOy and M7 are special cases ...
- ! --------------------------------
- select case ( trim(strlowercase(tmname)) )
- case default
- ! --------------------------------
- ! `regular` constituents
- ! --------------------------------
- ! loop over all names:
- RF%itr(RF%ntr) = -1
- do itr = 1, ntrace
- ! case indendent match ?
- if ( goUpCase(trim(tmname)) == goUpCase(trim(names(itr))) ) then
- write (gol,'(" ",i3," ",a10," (",a10,") ",f12.4)') itr, trim(trname), trim(names(itr)), ra(itr); call goPr
- RF%itr(RF%ntr) = itr
- exit
- end if
- end do
- end select
- ! not found ?
- if ( RF%itr(RF%ntr) < 0 ) then
- write (gol,'("tracer name not supported:")'); call goPr
- write (gol,'(" list all : ",a)') trim(tracer_names); call goPr
- write (gol,'(" list element : ",i3)') RF%ntr; call goPr
- write (gol,'(" pdump name : ",a)') trim(trname); call goPr
- write (gol,'(" tm5 name : ",a)') trim(tmname); call goPr
- write (gol,'(" tm5 tracers : ")'); call goPr
- do itr = 1, ntrace
- write (gol,'(" ",i3," ",a)') itr, trim(names(itr)); call goPr
- end do
- TRACEBACK; status=1; return
- end if ! RF%itr
- ! store pdump name:
- RF%name_tr(RF%ntr) = tmname
- end do
- ! empty file ?
- if ( RF%ntr < 1 ) then
- write (gol,'("no tracers extracted from list :",a)') tracer_names; call goErr
- TRACEBACK; status=1; return
- end if
- ! o open file
- ! write filename
- write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
- trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), trim(filetype), idate_f(1:3)
- ! open:
- #ifdef MPI
- ! overwrite existing files (clobber), provide MPI stuff:
- call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
- mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
- if (status/=0) then
- write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
- write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
- TRACEBACK; status=1; return
- end if
- #else
- ! overwrite existing files (clobber)
- call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
- IF_NOTOK_RETURN(status=1)
- #endif
- ! o global attributes
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title' , 'mixing ratios & concentrations' , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'file_version_number', trim(outfileversnr) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'im' , imr , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'jm' , jmr , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'lm' , lmr , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dx' , dx/xref(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dy' , dy/yref(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dz' , dz/zref(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'xbeg' , xbeg(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'xend' , xend(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'ybeg' , ybeg(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'yend' , yend(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'zbeg' , zbeg(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'zend' , zend(region) , status )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! Meteo attribute
- if (trim(meteo_class)=='ei') then
- model_meteo='analysis (ERA-Interim)'
- elseif (trim(meteo_class)=='od') then
- model_meteo='forecast (IFS)'
- else
- write (gol,'("Meteo Model not known !")'); call goErr
- TRACEBACK; status=1; return
- endif
-
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'meteo_model', trim(model_meteo), status )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! History attribute for audit trail: date, time of day, user name, program name
- call date_and_time(values=isysdate, zone=zone)
- write (sysdate, '(i4.4,"-",i2.2,"-",i2.2," ",i2.2,":",i2.2,":",i2.2," ",a)') &
- isysdate(1), isysdate(2), isysdate(3), isysdate(5), isysdate(6), isysdate(7), zone
- write(history,'("Created ",a," by ",a," with TM5.")') trim(sysdate),trim(dataset_author)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'history', trim(history), status )
- IF_NOTOK_MDF(fid=RF%ncid)
-
- ! o define dimensions
- call MDF_Def_Dim( RF%ncid, 'lon', imr, RF%dimid_lon , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'lat', jmr, RF%dimid_lat , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'lev', levi%nlev, RF%dimid_lev , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'time', rf%n_rec, RF%dimid_time , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'levi', levi%nlev+1, RF%dimid_levi , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'datelen', 6, RF%dimid_datelen , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! o define variables
- call MDF_Def_Var( RF%ncid, 'lon', mdf_float, (/RF%dimid_lon/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'longitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_east' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lon = varid
- call MDF_Def_Var( RF%ncid, 'lat', mdf_float, (/RF%dimid_lat/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'latitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'degrees_north' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lat = varid
- call MDF_Def_Var( RF%ncid, 'lev', mdf_float, (/RF%dimid_lev/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'level' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- 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)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lev = varid
- call MDF_Def_Var( RF%ncid, 'time', mdf_double, (/RF%dimid_time/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'days since 1950-01-01 00:00:00' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'calender', 'gregorian' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_time = varid
- allocate(RF%time(rf%n_rec))
- call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_date = varid
- allocate(RF%date(6,rf%n_rec))
-
- call MDF_Def_Var( RF%ncid, 'ps', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_time/), varid, status )
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'surface_air_pressure' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'surface pressure' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'Pa' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_ps = varid
- allocate( RF%sp(i1:i2, j1:j2, rf%n_rec) )
- #ifdef tropomi
- call MDF_Def_Var( RF%ncid, 'temp', MDF_FLOAT, (/RF%dimid_lon, RF%dimid_lat, RF%dimid_lev, RF%dimid_time/), varid, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'air_temperature' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'temperature' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'K' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_put_att( RF%ncid, varid, 'comment', 'bottom-up; full levels' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_temp = varid
- allocate( RF%data3d_t(i1:i2, j1:j2, levi%nlev, rf%n_rec) )
- #endif
-
- call MDF_Def_Var( RF%ncid, 'a_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- 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)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_a_bnds = varid
- call MDF_Def_Var( RF%ncid, 'b_bnds', mdf_float, (/RF%dimid_levi/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'hybrid sigma coordinate a coefficient for layer bounds' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- 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)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_b_bnds = varid
- ! loop over tracer to be written:
- do k = 1, RF%ntr
- ! ----------------------------
- ! setting defaults (gas phase)
- ! ----------------------------
- ! CF standard name for concentration/mixing ratio/column:
- cf_enti_stnd = 'mole_fraction'
- cf_enti_unit = 'mole mole-1'
- cf_enti_long = 'volume mixing ratio'
- cf_medium_stnd = 'in_air'
- cf_medium_long = 'in humid air'
- RF%varid_type(k) = 'mixr'
- ! global tracer index
- itr = RF%itr(k)
- ! no comment yet
- comment = ''
- ! standard names from CF conventions:
- select case ( strlowercase(RF%name_tr(k)) )
- case ( 'co2' )
- varname_spec = 'co2'
- cf_spec_stnd = 'carbon_dioxide'
- cf_spec_long = 'CO2'
- case default
- write (gol,'("do not know how to match tracer with CF standard names : ",a)') RF%name_tr(k); call goErr
- TRACEBACK; status=1; return
- end select
- ! define variable:
- call MDF_Def_Var( RF%ncid, trim(varname_spec), MDF_FLOAT, &
- (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! total names:
- cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)//'_'//trim(cf_medium_stnd)
- cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)//' '//trim(cf_medium_long)
- cf_name_unit = trim(cf_enti_unit)
- ! write attributes:
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', trim(cf_name_stnd) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', trim(cf_name_long) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', trim(cf_name_unit) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! moleweights; ra from chem_param is in g/mol .
- if ( itr <= ntrace .and. itr > 0 ) then
- call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', ra(itr)*1e3 , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- else
- call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', -1.0 , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- end if
-
- call MDF_Put_Att( RF%ncid , varid, 'moleweight_air' , xmair*1e3 , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid , varid, 'moleweight_unit' , 'kg mole-1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- if ( len_trim(comment) > 0 ) then
- call MDF_Put_Att( RF%ncid, varid, 'comment' , trim(comment), status)
- IF_NOTOK_MDF(fid=RF%ncid)
- end if
- ! store varid
- RF%varid_tr(k) = varid
- end do
- ! storage
- allocate(rf%data3d(i1:i2,j1:j2,lmr,rf%n_rec,rf%ntr))
- ! o end defintion mode
- call MDF_EndDef( RF%ncid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! o
- ! no records written yet
- RF%trec = 0
- call goLabel()
- status = 0
- END SUBROUTINE RF_VMR_Init
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_VMR_Write
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RF_VMR_Write( RF, region, idate_f, status )
- !
- ! !USES:
- !
- use Binas, only : xmair
- use GO, only : TDate, NewDate, rTotal, operator(-)
- use binas, only : Rgas
- use chem_param, only : ntrace, ntracet, fscale, ra
- use tracer_data, only : mass_dat, chem_dat
- use Grid, only : FPressure
- use MeteoData, only : global_lli, levi, m_dat, temper_dat, sp_dat
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_VMR), intent(inout) :: RF
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
- ! 2 Oct 2012 - Ph. Le Sager - adapted for lat-lon mpi decomp
- ! - no more sub-regions available
- !
- ! !REMARKS:
- ! (1)
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_VMR_Write'
- ! --- local ------------------------------------
- integer :: imr, jmr, lmr, i1, i2, j1, j2
- real, allocatable :: lev(:)
- integer :: l
- type(TDate) :: t, t0
- real :: time
- integer :: k, itr
- integer :: k_comp, itr_comp
- integer :: ims, ime, jms, jme, lms, lme
- integer :: gimr, gjmr, glmr
- real, allocatable :: compo_k(:,:,:)
- real, allocatable :: field_t(:,:,:)
- real, allocatable :: field_k(:,:,:)
- real, allocatable :: pres3d(:,:,:), pmx(:,:,:)
- integer :: numtrac
- integer :: listtrac(10)
- ! --- begin -------------------------------------
- ! for multiple of dhour only ...
- if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
- status=0; return
- end if
-
- call goLabel(rname)
- ! grid sizes
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- imr=i2-i1+1
- jmr=j2-j1+1
- lmr = levi%nlev
-
- gimr = global_lli(region)%nlon
- gjmr = global_lli(region)%nlat
- ! yet to change ??
- lms = 1
- lme = levi%nlev
- lmr = levi%nlev
- glmr = levi%nlev
- ! next time record:
- RF%trec = RF%trec + 1
- if(okdebug)then
- write(gol,*) "RF_VMR_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
- end if
- ! time since 1950-1-1 00:00
- t0 = NewDate( time6=time_reftime6 )
- t = NewDate( time6=idate_f )
- time = rTotal( t - t0, 'day' )
-
- ! only once ...
- if ( RF%trec == 1 ) then
-
- ! write longitudes:
- call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! write latitudes:
- call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! write level indices:
- allocate( lev(lmr) )
- do l = lms, lme
- lev(l) = real(l)
- end do
- call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- deallocate(lev)
- ! As and Bs
- call MDF_Put_Var( RF%ncid, RF%varid_a_bnds, levi%a(0:levi%nlev) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_b_bnds, levi%b(0:levi%nlev) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- end if ! first record
- RF%time(RF%trec) = time
- RF%date(:,RF%trec) = real(idate_f)
- RF%sp(:,:,RF%trec) = sp_dat(region)%data(i1:i2,j1:j2,1)
- #ifdef tropomi
- RF%data3d_t(:,:,:,RF%trec) = temper_dat(region)%data(i1:i2,j1:j2,1:lmr)
- #endif
- ! loop over all tracers to be written:
- do k = 1, RF%ntr
- ! global tracer index:
- itr = RF%itr(k)
- ! ---------
- ! transported or chemistry only ?
- ! ---------
- select case( itr )
- case( 1:ntracet )
-
- ! ----------------------------------------------------
- ! distinguish between mixing ratios and concentrations
- ! ----------------------------------------------------
- select case( RF%varid_type(k) )
- case( 'conc' )
- ! write slab of concentrations
- ! m(trace) pressure xm(trace)
- ! C = -------- * fscale * ----------- * ---------
- ! m(air) temperature Rgas
- ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
- ! reshape( mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr) / &
- ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
- ! pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
- ! Rgas, (/imr,jmr,lmr,1/) ), &
- ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
- rf%data3d(:,:,:, rf%trec, k) = mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr) / &
- m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
- pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
- Rgas
-
- case( 'mixr' )
- ! write slab of volume mixing ratios
- ! m(trace)
- ! X = -------- * fscale
- ! m(air)
- ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
- ! reshape( mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr)/ &
- ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr), &
- ! (/imr,jmr,lmr,1/) ), &
- ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
- rf%data3d(:,:,:, rf%trec, k) = mass_dat(region)%rm(i1:i2,j1:j2,lms:lme,itr)/ &
- m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr)
-
- case default
- write (gol,'("no such unit type",a)') RF%varid_type(k); call goErr
- status=1
- end select
- ! IF_NOTOK_MDF(fid=RF%ncid)
-
- ! ---------
- case( ntracet+1:ntrace )
- ! ---------
- ! ----------------------------------------------------
- ! distinguish between mixing ratios and concentrations
- ! ----------------------------------------------------
- select case( RF%varid_type(k) )
- case( 'conc' )
- ! write slab of concentrations
- ! m(trace) pressure xm(trace)
- ! C = -------- * fscale * ----------- * ---------
- ! m(air) temperature Rgas
- ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
- ! reshape( chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr) / &
- ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
- ! pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
- ! Rgas, (/imr,jmr,lmr,1/) ), &
- ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
- rf%data3d(:,:,:, rf%trec, k) = chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr) / &
- m_dat(region)%data(i1:i2,j1:j2,lms:lme) * xmair * 1.E-03 * &
- pres3d(i1:i2,j1:j2,lms:lme) / temper_dat(region)%data(i1:i2,j1:j2,lms:lme) / &
- Rgas
-
- case( 'mixr' )
- ! write slab of volume mixing ratios
- ! m(trace)
- ! X = -------- * fscale
- ! m(air)
- ! call MDF_Put_Var( RF%ncid, RF%varid_tr(k), &
- ! reshape( chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr)/ &
- ! m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr), &
- ! (/imr,jmr,lmr,1/) ), &
- ! status, start=(/i1,j1,lms,RF%trec/), count=(/imr,jmr,lmr,1/) )
- rf%data3d(:,:,:, rf%trec, k) = chem_dat(region)%rm(i1:i2,j1:j2,1:lmr,itr)/ &
- m_dat(region)%data(i1:i2,j1:j2,lms:lme) * fscale(itr)
-
- case default
- write (gol,'("no such unit type",a)') RF%varid_type(k); call goErr
- status=1
- end select
-
- IF_NOTOK_MDF(fid=RF%ncid)
- ! -------------------
- case default
- ! -------------------
- write (gol,'("strange tracer index requested : ",i6)') itr; call goErr
- TRACEBACK; status=1; return
- end select
- end do ! tracer
- !----------------
- ! WRITE
- !----------------
- if ( RF%trec == rf%n_rec ) then
- call MDF_Put_Var( RF%ncid, RF%varid_time, rf%time, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Var( RF%ncid, RF%varid_date, rf%date, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! surface presure
- call MDF_Put_Var( RF%ncid, RF%varid_ps, rf%sp, status, start=(/i1,j1,1/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- #ifdef tropomi
- ! temperature
- 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/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- #endif
- ! vmr
- do k = 1, RF%ntr
- call MDF_Put_Var( RF%ncid, RF%varid_tr(k), RF%data3d(:,:,:,:,k), status, start=(/i1,j1,1,1/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- end do
- end if
- !----------------
- ! DONE
- !----------------
- call goLabel()
- status = 0
- END SUBROUTINE RF_VMR_Write
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_VMR_Done
- !
- ! !DESCRIPTION: close file #3
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RF_VMR_Done( RF, status )
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_VMR), intent(inout) :: RF
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_VMR_Done'
- ! --- begin -------------------------------------
- call goLabel(rname)
- call MDF_Close( RF%ncid, status )
- IF_NOTOK_RETURN(status=1)
- deallocate(rf%date, rf%time, rf%sp, rf%data3d )
- #ifdef tropomi
- deallocate(rf%data3d_t)
- #endif
-
- call goLabel() ; status = 0
- END SUBROUTINE RF_VMR_Done
- !EOC
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ! FILE: 2D LT output
- ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_LT_Init
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- subroutine RF_LT_Init( RF, fdir, model, expid, filetype, region, &
- idate_f, local_time, tracer_names, status )
- !
- ! !USES:
- !
- use Binas, only : xmair
- use GO, only : goReadFromLine, goUpCase
- use GO, only : NewDate
- use dims, only : im, jm
- use chem_param, only : ntrace, names, ra
- use partools, only : MPI_INFO_NULL, localComm
- use MeteoData, only : global_lli, levi, sp_dat, Set
- !
- ! !OUTPUT PARAMETERS:
- !
- type(TPdumpFile_LT), intent(out) :: RF
- !
- ! !INPUT PARAMETERS:
- !
- character(len=*), intent(in) :: fdir
- character(len=*), intent(in) :: model
- character(len=*), intent(in) :: expid
- character(len=*), intent(in) :: filetype
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- integer, intent(in) :: local_time
- character(len=*), intent(in) :: tracer_names
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_LT_Init'
- ! --- local ------------------------------------
- character(len=256) :: fname
- integer :: varid
- integer :: imr, jmr, lmr
- character(len=256) :: trnames
- character(len=8) :: trname, tmname
- character(len=3) :: cwavel
- integer :: k, itr, i1, i2, j1, j2
- character(len=32) :: varname, varname_enti, varname_spec
- character(len=64) :: cf_medium_stnd, cf_medium_long
- character(len=64) :: cf_enti_stnd, cf_enti_long, cf_enti_unit
- character(len=64) :: cf_spec_stnd, cf_spec_long
- character(len=256) :: cf_name_stnd, cf_name_long, cf_name_unit
- character(len=512) :: comment
- ! --- begin -------------------------------------
- call goLabel(rname)
- ! store arguments
- RF%local_time = local_time
- RF%tracer_names = tracer_names
- ! set tracer index for requested tracers:
- write (gol,'("selected tracers for LT output:")'); call goPr
- RF%ntr = 0
- RF%itr = -1
- trnames = tracer_names
- do
- ! empty ?
- if ( len_trim(trnames) == 0 ) exit
-
- ! next number:
- if ( RF%ntr == ntrace ) then
- write (gol,'("number of elements in tracer names list exceeds ntrace=",i6)') ntrace; call goErr
- TRACEBACK; status=1; return
- end if
- RF%ntr = RF%ntr + 1
- ! extract leading name:
- call goReadFromLine( trnames, trname, status, sep=' ' )
- IF_NOTOK_RETURN(status=1)
- ! convert to tm5 name:
- select case ( trim(strlowercase(trname)) )
- case default ; tmname = trname
- end select
- ! NOy is a special ...
- select case ( trim(strlowercase(tmname)) )
- case default
- ! loop over all names:
- RF%itr(RF%ntr) = -1
- do itr = 1, ntrace
- ! case indendent match ?
- if ( goUpCase(trim(tmname)) == goUpCase(trim(names(itr))) ) then
- write (gol,'(" ",i3," ",a10," (",a10,") ",f12.4)') itr, trim(trname), trim(names(itr)), ra(itr); call goPr
- RF%itr(RF%ntr) = itr
- exit
- end if
- end do
- end select ! not found ?
- if ( RF%itr(RF%ntr) < 0 ) then
- write (gol,'("tracer name not supported:")'); call goPr
- write (gol,'(" list all : ",a)') trim(tracer_names); call goPr
- write (gol,'(" list element : ",i3)') RF%ntr; call goPr
- write (gol,'(" pdump name : ",a)') trim(trname); call goPr
- write (gol,'(" tm5 name : ",a)') trim(tmname); call goPr
- write (gol,'(" tm5 tracers : ")'); call goPr
- do itr = 1, ntrace
- write (gol,'(" ",i3," ",a)') itr, trim(names(itr)); call goPr
- end do
- TRACEBACK; status=1; return
- end if
- ! store pdump name:
- RF%name_tr(RF%ntr) = trname
- end do
-
- ! empty file ?
- if ( RF%ntr < 1 ) then
- write (gol,'("no tracers extracted from list :",a)') tracer_names; call goErr
- TRACEBACK; status=1; return
- end if
- ! grid size
- imr = global_lli(region)%nlon
- jmr = global_lli(region)%nlat
- lmr = levi%nlev
- ! o open file
- ! write filename
- write (fname,'(a,"/",a,a,"_",a,"_",a,"_",i4.4,"_",i2.2,"_",i2.2,".nc")') &
- trim(fdir), trim(model), trim(fname_grid(region)), trim(expid), trim(filetype), idate_f(1:3)
- ! open:
- #ifdef MPI
- ! overwrite existing files (clobber), provide MPI stuff:
- call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status, &
- mpi_comm=localComm, mpi_info=MPI_INFO_NULL )
- if (status/=0) then
- write (gol,'("from creating NetCDF4 file for writing in parallel;")'); call goErr
- write (gol,'("MDF module not compiled with netcdf4_par support ?")'); call goErr
- TRACEBACK; status=1; return
- end if
- #else
- ! overwrite existing files (clobber)
- call MDF_Create( trim(fname), MDF_NETCDF4, MDF_REPLACE, RF%ncid, status )
- IF_NOTOK_RETURN(status=1)
- #endif
-
- ! o global attributes
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'title' , 'local time output' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_author' , trim(dataset_author) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'institution' , trim(institution) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'dataset_version' , trim(dataset_version) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, MDF_GLOBAL, 'file_version_number', trim(outfileversnr) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! o define dimensions
- call MDF_Def_Dim( RF%ncid, 'lon' , global_lli(region)%nlon, RF%dimid_lon , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'lat' , global_lli(region)%nlat, RF%dimid_lat , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'lev' , levi%nlev , RF%dimid_lev , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'time' , 1 , RF%dimid_time , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Def_Dim( RF%ncid, 'datelen', 6 , RF%dimid_datelen, status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! o define variables
- call MDF_Def_Var( RF%ncid, 'lon', mdf_float, (/RF%dimid_lon/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'longitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'longitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_east', status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lon = varid
- call MDF_Def_Var( RF%ncid, 'lat', mdf_float, (/RF%dimid_lat/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'latitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'latitude' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units' , 'degrees_north', status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lat = varid
- call MDF_Def_Var( RF%ncid, 'lev', mdf_float, (/RF%dimid_lev/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'atmosphere_hybrid_sigma_pressure_coordinate' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'level' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units' , '1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- 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)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_lev = varid
- call MDF_Def_Var( RF%ncid, 'time', mdf_float, (/RF%dimid_time/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units' , 'days since 1950-01-01 00:00:00', status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'calender' , 'gregorian' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_time = varid
- call MDF_Def_Var( RF%ncid, 'date', MDF_FLOAT, (/RF%dimid_datelen,RF%dimid_time/), varid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', 'date and time' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', 'year, month, day, hour, minute, second' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_date = varid
- call MDF_Def_Var( RF%ncid, 'ps', MDF_FLOAT, &
- (/RF%dimid_lon,RF%dimid_lat,RF%dimid_time/), varid, status )
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', 'surface_air_pressure', status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name' , 'surface pressure' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units' , 'Pa' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- RF%varid_ps = varid
- ! CF standard name for medium:
- cf_medium_stnd = 'in_air' ; cf_medium_long = 'in humid air'
- ! loop over tracer to be written:
- do k = 1, RF%ntr
- ! global tracer index
- itr = RF%itr(k)
- ! ~~ local time species info
- ! CF standard name for concentration/mixing ratio/column:
- cf_enti_stnd = 'mole_fraction'
- cf_enti_unit = 'mole mole-1'
- cf_enti_long = 'volume mixing ratio'
- ! start of dataset name:
- varname_enti = 'dry'
- ! no comment yet
- comment = ''
- ! standard names from CF conventions:
- select case ( RF%name_tr(k) )
- case ( 'CO2', 'co2' )
- varname_spec = 'co2'
- cf_spec_stnd = 'carbon_dioxide'
- cf_spec_long = 'CO2'
- case default
- write (gol,'("do not know how to match tracer with CF standard names : ",a)') RF%name_tr(k); call goPr
- TRACEBACK; status=1; return
- end select
- ! define variable:
- call MDF_Def_Var( RF%ncid, trim(varname_spec), MDF_FLOAT, &
- (/RF%dimid_lon,RF%dimid_lat,RF%dimid_lev,RF%dimid_time/), varid, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Var_Par_Access( RF%ncid, varid, access_mode, status )
- IF_NOTOK_MDF(fid=RF%ncid)
- ! total names:
- cf_name_stnd = trim(cf_enti_stnd)//'_of_'//trim(cf_spec_stnd)//'_'//trim(cf_medium_stnd)
- cf_name_long = trim(cf_enti_long)//' of '//trim(cf_spec_long)//' '//trim(cf_medium_long)
- cf_name_unit = trim(cf_enti_unit)
- ! write attributes:
- call MDF_Put_Att( RF%ncid, varid, 'standard_name', trim(cf_name_stnd) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'long_name', trim(cf_name_long) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'units', trim(cf_name_unit) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
-
- if ( itr <= ntrace .and. itr > 0 ) then
- call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', ra(itr)*1e3 , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- else
- call MDF_Put_Att( RF%ncid, varid, 'moleweight_tracer', -1.0 , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- end if
- call MDF_Put_Att( RF%ncid, varid, 'moleweight_air', xmair*1e3 , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- call MDF_Put_Att( RF%ncid, varid, 'moleweight_unit', 'kg mole-1' , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- if ( len_trim(comment) > 0 ) then
- call MDF_Put_Att( RF%ncid, varid, 'comment', trim(comment) , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- end if
-
- ! store varid
- RF%varid_tr(k) = varid
-
- end do
- ! o end defintion mode
- call MDF_EndDef( RF%ncid , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! no records written yet
- RF%trec = 0
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
-
- allocate(RF%accu (i1:i2, j1:j2, 1:lmr, RF%ntr)) ; RF%accu = 0
- allocate(RF%naccu (i1:i2, RF%ntr )) ; RF%naccu = 0
- allocate(RF%p_accu (i1:i2, j1:j2 )) ; RF%p_accu = 0
- allocate(RF%np_accu(i1:i2 )) ; RF%np_accu = 0
- call goLabel()
- status = 0
- END SUBROUTINE RF_LT_Init
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_LT_Write
- !
- ! !DESCRIPTION: does not write anything, just get
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RF_LT_Write( RF, region, idate_f, status )
- !
- ! !USES:
- !
- use GO, only : TDate, NewDate, Set, iTotal, rTotal, operator(-), wrtgol
- use chem_param, only : ntrace, ntracet, fscale
- use tracer_data, only : mass_dat, chem_dat
- use MeteoData, only : global_lli, levi, m_dat, sp_dat
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_LT), intent(inout) :: RF
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- integer, intent(in) :: idate_f(6)
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/RF_LT_Write'
- ! --- local ------------------------------------
- integer :: imr, jmr, lmr, gimr, i1, i2, j1, j2
- real, allocatable :: lev(:)
- real, allocatable :: field_out(:,:,:)
- real, allocatable :: field_out_b(:,:)
- integer :: l, ls, le
- type(TDate) :: t, t0
- real :: time
- real :: dt_sec
- integer :: i, j, k, itr, itau, loctim, gridboxtimestep
- integer :: iloctim,itautoday,ilon
- integer :: icomp, itr_loc, ncells, window
- ! --- begin -------------------------------------
- ! for multiple of dhour only ...
- ! if ( (modulo(idate_f(4),RF%dhour)/=0) .or. any(idate_f(5:6)/=0) ) then
- ! status=0; return
- ! end if
- call goLabel(rname)
- ! grid size
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- imr=i2-i1+1
- jmr=j2-j1+1
- gimr = global_lli(region)%nlon
- ! gjmr = global_lli(region)%nlat
- lmr = levi%nlev
- ! next time record:
- RF%trec = RF%trec + 1
- if(okdebug)then
- write(gol,*) "RF_LT_Write - idate_f(6), RF%trec=", idate_f, RF%trec; call goPr
- end if
- ! grid index offsets for GMT and local time
- loctim=RF%local_time
- if( loctim < 0 ) loctim=loctim+24*3600
- ! time since 1950-1-1 00:00
- t0 = NewDate( time6=time_reftime6 )
- t = NewDate( time6=idate_f )
- call SET( t, hour=0, min=0, sec=0 )
- time = rTotal( t - t0, 'day' ) + loctim / 86400.
- !
- ! ~~ time, grid
- !
-
- ! only once ...
- if ( RF%trec == 1 ) then
- ! write longitudes:
- call MDF_Put_Var( RF%ncid, RF%varid_lon, global_lli(region)%lon_deg , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! write latitudes:
- call MDF_Put_Var( RF%ncid, RF%varid_lat, global_lli(region)%lat_deg , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- ! write level indices:
- allocate( lev(lmr) )
- do l = 1, lmr
- lev(l) = real(l)
- end do
- call MDF_Put_Var( RF%ncid, RF%varid_lev, lev , status)
- IF_NOTOK_MDF(fid=RF%ncid)
- deallocate(lev)
- ! time:
- call MDF_Put_Var( RF%ncid, RF%varid_time, (/time/) , status, start=(/RF%trec/))
- IF_NOTOK_MDF(fid=RF%ncid)
- ! date:
- call MDF_Put_Var( RF%ncid, RF%varid_date, reshape(real(idate_f),(/6,1/)), status, &
- start=(/1,1/), count=(/6,1/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- end if ! first record
-
- !
- ! local time
- !
- if ( RF%trec > 1 ) then ! do not accumulate fields on 00:00
- ! grid index offsets for GMT and local time
- loctim=RF%local_time
- if( loctim < 0 ) loctim=loctim+24*3600
- gridboxtimestep=24*3600/gimr
- itau = idate_f(4)*3600+idate_f(5)*60+idate_f(6)
- itautoday= nint(real(mod(itau,24*3600)*gimr)/real(24*3600))
- iloctim = nint(real(loctim *gimr)/real(24*3600))
- ! determine longitude index wrt Greenwich from difference (local time - GMT)
- ! also process neigboring longitudes (i-2 , i-1 , i , i+1 , i+2) depending on
- ! number of longitudinal grid cells
- ncells = ceiling( gimr / 24. )
- window = ceiling( ncells / 2. )
- do ilon = 1, ncells
- i = 1 + mod( gimr + gimr/2 + iloctim - itautoday + (ilon - window),gimr )
- if (i .ge. i1 .and. i.le. i2) then
- RF%p_accu(i,j1:j2)= RF%p_accu(i,j1:j2)+sp_dat(region)%data(i,j1:j2,1)
- RF%np_accu(i)= RF%np_accu(i)+1
- ! loop over tracers to be written:
- do k = 1, RF%ntr
- ! global tracer index:
- itr = RF%itr(k)
- ! transported or chemistry only ?
- if ( (itr >= 1) .and. (itr <= ntracet) ) then
- RF%accu(i,j1:j2,1:lmr,k)= RF%accu(i,j1:j2,1:lmr,k)+&
- (mass_dat(region)%rm(i,j1:j2,1:lmr,itr)/ &
- m_dat(region)%data(i,j1:j2,1:lmr))*fscale(itr)
- RF%naccu(i,k)=RF%naccu(i,k)+1
- else if ( (itr >= ntracet+1) .and. (itr <= ntrace) ) then
- RF%accu(i,j1:j2,1:lmr,k)= RF%accu(i,j1:j2,1:lmr,k)+&
- (chem_dat(region)%rm(i,j1:j2,1:lmr,itr)/ &
- m_dat(region)%data(i,j1:j2,1:lmr))*fscale(itr)
- RF%naccu(i,k)=RF%naccu(i,k)+1
- end if
- enddo
- endif
- enddo
- endif ! do not accumulate fields on 00:00
- call goLabel(); status = 0
- END SUBROUTINE RF_LT_Write
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RF_LT_Done
- !
- ! !DESCRIPTION: write final data, then close file #4
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RF_LT_Done( RF, region, status )
- !
- ! !USES:
- !
- use MeteoData, only : global_lli, levi
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- type(TPdumpFile_LT), intent(inout) :: RF
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk - retro -> pdump
- ! 7 Aug 2012 - Ph. Le Sager - netcdf4 thru mdf
- ! - move averaging & writing here
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len =*), parameter :: rname = mname//'/RF_LT_Done'
- integer :: imr, jmr
- real, allocatable :: field_out(:,:,:)
- real, allocatable :: field_out_b(:,:)
- integer :: i, ls, le, k, itr, i1, i2, j1, j2, lmr
- ! --- begin -------------------------------------
- call goLabel(rname)
- !---------------------
- ! average & write data
- !---------------------
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- imr=i2-i1+1
- jmr=j2-j1+1
- lmr = levi%nlev
- allocate(field_out_b(i1:i2,j1:j2)); field_out_b = 0.0
- do i = i1, i2
- if (RF%np_accu(i).gt.0) then
- field_out_b(i,:) =RF%p_accu(i,:)/RF%np_accu(i)
- endif
- enddo
- call MDF_Put_Var( RF%ncid, RF%varid_ps, reshape(field_out_b(i1:i2,j1:j2), &
- (/imr,jmr,1/) ), status, start=(/i1,j1,1/), count=(/imr,jmr,1/) )
- IF_NOTOK_MDF(fid=RF%ncid)
-
- deallocate(field_out_b)
- TRACERS: do k = 1, RF%ntr
- ! global tracer index:
- itr = RF%itr(k)
- if ( (itr >= 1) .and. (itr <= ntrace) ) then
- ! normalize fields, if necessary
- allocate(field_out(i1:i2,j1:j2,1:lmr)); field_out = 0.0
- do i = i1,i2
- if (RF%naccu(i,k).gt.0) then
- field_out(i,:,1:lmr) =RF%accu(i,:,1:lmr,k)/RF%naccu(i,k)
- endif
- enddo
- ! write fields:
- call MDF_Put_Var( RF%ncid, RF%varid_tr(k) , &
- reshape(field_out(i1:i2,j1:j2,1:lmr) , &
- (/imr,jmr,lmr,1/) ) , &
- status, start=(/i1,j1,1,1/), count=(/imr,jmr,lmr,1/) )
- IF_NOTOK_MDF(fid=RF%ncid)
- deallocate(field_out)
- endif
- end do TRACERS
- !---------------------
- ! DONE
- !---------------------
- call MDF_Close( RF%ncid , status)
- IF_NOTOK_RETURN(status=1)
- deallocate(RF%accu)
- deallocate(RF%naccu)
- deallocate(RF%p_accu)
- deallocate(RF%np_accu)
- call goLabel() ; status = 0
- END SUBROUTINE RF_LT_Done
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !FUNCTION: strlowercase
- !
- ! !DESCRIPTION:
- !
- ! This function returns a copy of the input string 'struppercase' with all
- ! letters changed to lowercase. All other characters remain unchanged.
- !\\
- !\\
- ! !INTERFACE:
- !
- FUNCTION strlowercase(struppercase)
- !
- ! !USES:
- !
- IMPLICIT NONE
- !
- ! !INPUT PARAMETERS:
- !
- CHARACTER(LEN=*), INTENT(IN) :: struppercase
- !
- ! !RETURN VALUE:
- !
- CHARACTER(LEN=LEN(struppercase)) :: strlowercase
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk -
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- CHARACTER(LEN=1) :: u
- INTEGER :: i,j
- strlowercase = struppercase
- DO i=1,LEN(struppercase)
- u = struppercase(i:i)
- j = IACHAR(u)
- IF(j < 65 .OR. j > 90) CYCLE
- strlowercase(i:i) = ACHAR(j+32)
- END DO
- !-------------------------------------------------------------------------------
- END FUNCTION STRLOWERCASE
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !FUNCTION: struppercase
- !
- ! !DESCRIPTION:
- !
- ! This function returns a copy of the input string 'struppercase' with all
- ! letters changed to lowercase. All other characters remain unchanged.
- !\\
- !\\
- ! !INTERFACE:
- !
- FUNCTION STRUPPERCASE(strlowercase)
- !
- ! !USES:
- !
- IMPLICIT NONE
- !
- ! !INPUT PARAMETERS:
- !
- CHARACTER(LEN=*), INTENT(IN) :: strlowercase
- !
- ! !RETURN VALUE:
- !
- CHARACTER(LEN=LEN(strlowercase)) :: struppercase
- !
- ! !REVISION HISTORY:
- ! 1 Oct 2010 - Achim Strunk -
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- CHARACTER(LEN=1) :: u
- INTEGER :: i,j
- struppercase = strlowercase
- DO i=1,LEN(strlowercase)
- u = strlowercase(i:i)
- j = IACHAR(u)
- IF(j < 97 .OR. j > 122) CYCLE
- struppercase(i:i) = ACHAR(j-32)
- END DO
- !-------------------------------------------------------------------------------
- END FUNCTION STRUPPERCASE
- !EOC
- END MODULE USER_OUTPUT_PDUMP
|