user_output_aerchemmip.F90 195 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229
  1. #define TRACEBACK write (gol,'("in ",a," (",a,i6,")")') rname, __FILE__, __LINE__ ; call goErr
  2. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  3. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  4. #define IF_NOTOK_MDF(action) if (status/=0) then; TRACEBACK; action; call MDF_CLose(fid,status); status=1; return; end if
  5. !
  6. #include "tm5.inc"
  7. !
  8. !-----------------------------------------------------------------------------
  9. ! TM5 !
  10. !-----------------------------------------------------------------------------
  11. !BOP
  12. !
  13. ! !MODULE: USER_OUTPUT_AERCHEMMIP
  14. !
  15. ! !DESCRIPTION:
  16. ! isoanus,isoaais,isoaacs,isoacos,isoaaii
  17. ! This module provides the code needed to produce the CMIP6 AERCHEMMIP
  18. ! output from TM5. Code is based on the user_output_aerocom.
  19. !
  20. ! output_aerchemmip_init:
  21. ! - initialise the list of variables (allvars)
  22. ! - initialise the data holder within each variable (2Ddata/3Ddata,...)
  23. ! - initialise the output netcdf files, one for eacht variable
  24. ! output_aerchemmip_accumulate:
  25. ! - do accumulation for all variables and save data to either
  26. ! 2Ddata or 3Ddata holder of the variable (excluding optical vars)
  27. ! output_aerchemmip_write
  28. ! - write the monthly variable data to netcdf-file
  29. ! - initialise the dataholders for accumulation of new month
  30. ! output_aerchemmip_write_hourly
  31. ! - write the hourly variable data to netcdf-file
  32. ! - initialise the dataholders for accumulation of new hour
  33. ! output_aerchemmip_write_daily
  34. ! - write the daily variable data to netcdf-file
  35. ! - initialise the dataholders for accumulation of new day
  36. ! write_var
  37. !
  38. ! calculate_optics
  39. ! - calculate the abss,aods and extinctions
  40. ! - directly accumulate the data containers of these variables
  41. !
  42. ! mode_fraction
  43. ! - calculate the fraction of a M7 mode that is under a size limit
  44. !\\
  45. !\\
  46. ! !INTERFACE:
  47. !
  48. MODULE USER_OUTPUT_AERCHEMMIP
  49. !
  50. ! !USES:
  51. !
  52. use go, only : gol, goErr, goPr, goLabel
  53. use GO, ONLY : GO_Timer_Def, GO_Timer_End, GO_Timer_Start
  54. use dims, only : nregions !=1, support for zooming with larger values not available for AERCHEMMIP
  55. use optics, only : wavelendep
  56. use meteodata, only : global_lli, levi
  57. !use chem_param, only : nmod,xmc2h6,xmc3h6,xmc3h8,xmch4,xmco,xmdms,xmh2o,xmhno3,xmisop,xmno,xmno2,xmo3,xmoh,xmpan,xmso2
  58. use MDF
  59. use TM5_DISTGRID, only : dgrid, Get_DistGrid, update_halo, update_halo_iband
  60. use chem_param
  61. use m7_data, only : h2o_mode
  62. implicit none
  63. private
  64. !
  65. ! !PUBLIC MEMBER FUNCTIONS:
  66. !
  67. public :: output_aerchemmip_init
  68. !public :: output_aerchemmip_step
  69. public :: output_aerchemmip_write
  70. public :: output_aerchemmip_write_hourly
  71. public :: output_aerchemmip_write_6hourly
  72. public :: output_aerchemmip_write_daily
  73. public :: output_aerchemmip_done
  74. public :: accumulate_data
  75. public :: wdep_out
  76. logical, public :: aerchemmip_1h = .true. ! signal for hourly AERCHEMMIP diagnostics
  77. character(len=*), parameter :: mname = 'user_output_aerchemmip'
  78. ! max indices, at maximum 7, one for each mode
  79. integer,parameter :: n_indices=11
  80. type varfile
  81. integer :: itm5 !
  82. character(len=16) :: vname !
  83. character(len=64) :: lname !
  84. character(len=11) :: unit !
  85. character(len=10) :: positive !
  86. character(len=130) :: standard_name !
  87. ! real,dimension (:,:),pointer :: dataZonal !
  88. real,dimension (:,:),pointer :: data2D !
  89. real,dimension (:,:,:),pointer :: data3D !
  90. real,dimension (:,:,:),pointer :: budgetdata !
  91. integer :: varid !
  92. integer :: fileunit ! file unit number
  93. character(len=200) :: filename !
  94. integer :: dimensions !
  95. integer :: lon_varid !
  96. integer :: lat_varid !
  97. integer :: lev_varid !
  98. integer :: time_varid
  99. integer :: hyam_varid
  100. integer :: hybm_varid
  101. integer :: hyai_varid
  102. integer :: hybi_varid
  103. integer :: bounds_varid
  104. integer :: dims
  105. character(len=10) :: freq
  106. character(len=9) :: class ! which class of variable :emi, ddep, wdep,conc,aod,met,crescendo
  107. integer,dimension(n_indices) :: indices
  108. real :: xmgas
  109. character(len=20) :: table_id
  110. end type varfile
  111. type dimdata
  112. integer :: nlon ! size of x dimension of requested field
  113. integer :: nlat ! size of y dimension of requested field
  114. integer :: nlev ! size of z dimension of requested field
  115. real,dimension(:),pointer :: lon ! x dimension of requested field
  116. real,dimension(:),pointer :: lat ! y dimension of requested field
  117. real,dimension(:),pointer :: lev ! z dimension of requested field
  118. integer :: lonid ! x dimension id in nc
  119. integer :: latid ! y dimension id in nc
  120. integer :: levid ! z dimension id in nc
  121. integer :: timeid ! time dimension id in nc
  122. integer :: time_varid
  123. end type dimdata
  124. type(dimdata)::dimension_data
  125. type budgetstore
  126. real, dimension(:,:,:), allocatable :: f2dslast
  127. integer :: lasttime
  128. end type budgetstore
  129. type(budgetstore), dimension(nregions), save :: drydepos, wetdepos, emission
  130. ! type experimentdata
  131. ! character(len=16) ::
  132. ! end type experimentdata
  133. ! wavelength information
  134. type(wavelendep), dimension(:), allocatable :: wdep_out
  135. !!!!
  136. integer::test_fileunit
  137. !!!!
  138. integer :: n_vars=0
  139. type(varfile), dimension(:), allocatable :: allvars
  140. type(varfile), dimension(:), allocatable :: fixedvars
  141. integer :: n_var_max=300
  142. integer :: n_fixed=3
  143. integer, public :: n_days_in_month
  144. real :: sfo3_molmol
  145. character(len=20), public :: aerchemmip_exper ! AeroCom experiment name
  146. integer, save :: od550aer, &
  147. ec550aer,&
  148. ec550aermon,&
  149. od550aerdaily, &
  150. od550so4, &
  151. od550bc, &
  152. od550oa,&
  153. od550soa,&
  154. od550ss,&
  155. od550dust,&
  156. od440dustday,&
  157. od550dust2dday,&
  158. od550dust3dday,&
  159. od550no3,&
  160. od550aerh2o,&
  161. od550lt1aer,&
  162. abs550aer,&
  163. od440aer,&
  164. od350aer,&
  165. od870aer,&
  166. od440aerhr,&
  167. od440aermonthly,&
  168. od440aerdaily,&
  169. od550aerhr,&
  170. areacella,&
  171. sftlf,&
  172. orog
  173. integer :: fid ! file id for IF_NOTOK_MDF macro
  174. integer :: access_mode
  175. integer :: accumulation_mon,accumulation_day,accumulation_hr,accumulation_6hr
  176. integer :: timeidx_mon,timeidx_hr,timeidx_day,timeidx_6hr
  177. logical,public::crescendo_out=.false.
  178. integer,parameter::iemiunit=1
  179. integer,parameter::iddepunit=1 !same dimensions as emi
  180. integer,parameter::iwdepunit=1 !same dimensions as emi
  181. integer,parameter::iprod3dunit=2
  182. integer,parameter::immrunit=3
  183. integer,parameter::idimensionlessunit=4
  184. integer,parameter::iheightunit=5
  185. integer,parameter::itempunit=6
  186. integer,parameter::io3unit=7
  187. integer,parameter::ipresunit=8
  188. integer,parameter::ivmrunit=9
  189. integer,parameter::irateunit=10
  190. integer,parameter::iloadunit=11
  191. integer,parameter::iextunit=12
  192. integer,parameter::iccunit=13
  193. integer,parameter::im3unit=14
  194. integer,parameter::imassunit=15
  195. character(len=11),dimension(15),parameter::units=(/'kg m-2 s-1','kg m-3 s-1','kg kg-1','1','m','K','DU','Pa','mole mole-1',&
  196. 's-1','kg m-2','m-1','cm-3','m-3','kg'/)
  197. !CRESCENDO
  198. !3D
  199. Character(len=11),dimension(40),parameter :: crescendo3D= (/'nd1', 'nd2', 'nd3', 'nd4', 'nd5', 'nd6', 'nd7', &
  200. 'mmrsu1', 'mmrsu2', 'mmrsu3', 'mmrsu4', 'mmrsoa1', 'mmrsoa2', 'mmrsoa3', 'mmrsoa4', 'mmrsoa5', 'mmroa2', &
  201. 'mmroa3', 'mmroa4', 'mmroa5', 'mmrbc2', 'mmrbc3', 'mmrbc4', 'mmrbc5', 'mmrss3', 'mmrss4', 'mmrdu3', 'mmrdu4', &
  202. 'mmrdu6', 'mmrdu7', 'mmraerh2o_1', 'mmraerh2o_2', 'mmraerh2o_3', 'mmraerh2o_4', 'mono', 'nh3', 'ndtot', &
  203. 'ec550aer', 'chepsoa3d','emilnox'/)
  204. Character(len=11),dimension(40),parameter :: crescendo3Dunit=(/units(im3unit), units(im3unit), units(im3unit), &
  205. units(im3unit), units(im3unit), units(im3unit), units(im3unit), units(immrunit), units(immrunit), units(immrunit), &
  206. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit),&
  207. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), &
  208. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), &
  209. units(immrunit), units(immrunit), units(immrunit), units(ivmrunit), units(ivmrunit), units(im3unit), units(iextunit), &
  210. units(iemiunit),units(iemiunit)/)
  211. Character(len=11),dimension(2),parameter :: crescendo3Dday=(/'co', 'od5503ddust'/)
  212. Character(len=11),dimension(2),parameter :: crescendo3Ddayunit=(/units(ivmrunit),units(idimensionlessunit)/)
  213. !2D
  214. !mon
  215. Character(len=8),dimension(14),parameter :: crescendo2Dmon=(/'drydms', 'wetdms', 'wetno3', 'dryhno3', 'wethno3', &
  216. 'dryno2', 'dryno', 'drypan', 'emimono', 'dmsos', 'seddust', 'uas', 'vas', 'sfcWind'/)
  217. Character(len=11),dimension(14),parameter :: crescendo2Dmonunit=(/units(iddepunit), units(iddepunit), units(iddepunit), &
  218. units(iddepunit), units(iddepunit), units(iddepunit), units(iddepunit), units(iddepunit), units(iddepunit), &
  219. 'kg m-3',units(iddepunit),'m s-1', 'm s-1', 'm s-1'/)
  220. ! 2d
  221. ! 6hr
  222. Character(len=16),dimension(19),parameter :: crescendo2D6hr=(/'sfmmrso4', 'sfmmrss', 'sfmmroa', 'sfmmrsoa', 'sfmmrbc', &
  223. 'sfmmrdustabv1', 'sfmmrdustabv10', 'sfmmrdustbel1', 'sfdms', 'sfisop', 'sfmono', 'emidms', 'emiss', 'emioa', &
  224. 'emiisop', 'emimono', 'sfndtot', 'sfnd100', 'chepsoa2d'/)
  225. Character(len=11),dimension(19),parameter :: crescendo2D6hrunit=(/units(immrunit), units(immrunit), units(immrunit),&
  226. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(ivmrunit), &
  227. units(ivmrunit), units(ivmrunit), units(iemiunit), units(iemiunit), units(iemiunit), units(iemiunit), &
  228. units(iemiunit), units(im3unit), units(im3unit),'kgm-2s-1'/)
  229. !2d
  230. !day
  231. Character(len=16),dimension(52),parameter :: crescendo2Dday=(/'sfnd1', 'sfnd2', 'sfnd3', 'sfnd4', 'sfnd5', 'sfnd6', &
  232. 'sfnd7', 'sfmmrsu1', 'sfmmrsu2', 'sfmmrsu3', 'sfmmrsu4', 'sfmmrsoa1', 'sfmmrsoa2', 'sfmmrsoa3', 'sfmmrsoa4', &
  233. 'sfmmrsoa5', 'sfmmroa2', 'sfmmroa3', 'sfmmroa4', 'sfmmroa5', 'sfmmrbc2', 'sfmmrbc3', 'sfmmrbc4', 'sfmmrbc5', &
  234. 'sfmmrss3', 'sfmmrss4', 'sfmmrdu3', 'sfmmrdu4', 'sfmmrdu6', 'sfmmrdu7', 'sfmmraerh2o_1', 'sfmmraerh2o_2', &
  235. 'sfmmraerh2o_3', 'sfmmraerh2o_4', 'sfmmrno3', 'sfmmrnh4', 'sfmmrnh3', 'sfsh', 'od440aer', 'od440dust', &
  236. 'od550dust', 'depdustbel1', 'depdustabv1', 'depdustabv10', 'sfmmrdust', 'drynh4', 'wetnh4', 'dryno3', &
  237. 'wetno3', 'dryhno3','drydust','wetdust'/)
  238. Character(len=11),dimension(52),parameter :: crescendo2Ddayunit=(/units(im3unit), units(im3unit), units(im3unit), &
  239. units(im3unit), units(im3unit), units(im3unit), units(im3unit), units(immrunit), units(immrunit), units(immrunit), &
  240. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit),&
  241. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), &
  242. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit),&
  243. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit),&
  244. units(idimensionlessunit), units(idimensionlessunit), units(idimensionlessunit), units(idimensionlessunit), units(iddepunit),&
  245. units(iddepunit), units(iddepunit), units(immrunit), units(iddepunit), units(iddepunit), units(iddepunit), units(iddepunit), &
  246. units(iddepunit), units(iddepunit), units(iddepunit)/)
  247. !2d
  248. !hr
  249. Character(len=9), dimension(5), parameter :: crescendo2Dhr=(/'od550aer', 'od440aer', 'sfno', 'sfnh3', 'sfhno3'/)
  250. Character(len=11), dimension(5), parameter :: crescendo2Dhrunit=(/units(idimensionlessunit), units(idimensionlessunit), &
  251. units(ivmrunit), units(ivmrunit), units(ivmrunit)/)
  252. !Character(len=11),dimension(6,2),parameter :: crescendo2Dtest=reshape(&
  253. ! (/'od550aer', 'od440aer', 'sfno' ,'sfnh3' ,'sfhno3' ,'chepsoa2d' ,&
  254. ! '1' ,'1' ,units(ivmrunit), units(ivmrunit), units(ivmrunit),'kgm-2s-1'/),(/6,2/))
  255. !METEO
  256. !3D
  257. Character(len=7),dimension(11),parameter :: meteo3D=(/'ta', 'pfull', 'phalf', 'hus', 'zg', 'airmass', 'emilnox', &
  258. 'jno2', 'ua', 'va', 'wa'/)
  259. Character(len=11),dimension(11),parameter :: meteo3Dunit=(/units(itempunit), units(ipresunit), units(ipresunit), &
  260. units(idimensionlessunit), units(iheightunit), units(iloadunit), 'kg N/m2/month', units(irateunit),'ms-1', 'ms-1', 'ms-1'/)
  261. !2D
  262. Character(len=7),dimension(9),parameter :: meteo2D=(/'ps', 'ptp', 'tatp', 'ztp', 'bldep', 'pr', 'tropoz', 'toz', 'albsrfc'/)
  263. Character(len=11),dimension(9),parameter :: meteo2Dunit=(/units(ipresunit), units(ipresunit), units(itempunit), &
  264. units(iheightunit), units(iheightunit), units(iemiunit), units(io3unit), units(io3unit), units(idimensionlessunit)/)
  265. !OPTICS
  266. Character(len=11),dimension(13),parameter :: opticscomp=(/'od550aer', 'od550so4', 'od550bc', 'od550oa', 'od550soa',&
  267. 'od550ss', 'od550dust', 'od550no3', 'od550aerh2o', 'od550lt1aer', 'od440aer', 'od870aer', 'abs550aer'/)!
  268. !AEROSOL compounds
  269. Character(len=3),dimension(6),parameter :: comp=(/'BC', 'POM', 'SO4', 'DU', 'SS', 'SOA'/)!SOA
  270. !CHEMICAL
  271. Character(len=6),dimension(2),parameter :: checomp=(/'aqpso4', 'gpso4'/)
  272. Character(len=6),dimension(1),parameter :: chepcomp=(/'soa'/)
  273. Character(len=7),dimension(4),parameter :: o3chepcomp=(/'o3loss', 'o3prod','lossch4','lossco'/)
  274. !Emon
  275. Character(len=9),dimension(8),parameter :: emonout=(/'flashrate', 'depdust','seddustCI','md','loaddust','concdust','conccn','sconcss'/)
  276. Character(len=11),dimension(8),parameter :: emonoutunit=(/'km-2 s-1', units(iddepunit),units(iddepunit),'m','kg m-2','kg m-3','m-3','kg m-3'/)
  277. !BUDGET (EMI+REMOVAL)
  278. Character(len=4),dimension(14),parameter :: emicomp=(/'bvoc', 'co', 'dms', 'isop', 'nox', 'nh3', 'oa', 'so2', 'bc', &
  279. 'so4', 'dust', 'ss', 'voc','poa'/)
  280. Character(len=4),dimension(12),parameter :: ddepcomp=(/'nh3', 'noy', 'o3', 'oa', 'so2', 'bc', 'so4', 'dust', 'ss', &
  281. 'soa', 'nh4', 'no3'/)
  282. Character(len=4),dimension(10),parameter :: wdepcomp=(/'bc', 'dust', 'nh3', 'nh4', 'noy', 'oa', 'so2', 'so4', 'ss', 'soa'/)
  283. !MIXING ratios
  284. Character(len=6),dimension(13),parameter :: aerommrcomp=(/'bc', 'dust', 'nh3', 'nh4', 'no3', 'oa', 'so4', 'ss', 'pm1', &
  285. 'pm2p5', 'pm10', 'aerh2o', 'soa'/)
  286. Character(len=8),dimension(20),parameter :: gascomp=(/'c2h6', 'c3h6', 'c3h8', 'ch3coch3', 'ch4', 'co', 'co2', 'dms', &
  287. 'h2o', 'hno3', 'isop', 'no', 'no2', 'o3', 'oh', 'pan', 'so2', 'voc', 'hcho', 'o3ste'/)
  288. !Molecular weights
  289. real,dimension(20),parameter :: xmgascomp=(/xmc2h6, xmc3h6, xmc3h8, xmacet, xmch4, xmco, -1.0, xmdms, xmh2o, xmhno3, &
  290. xmisop, xmno, xmno2, xmo3, xmoh, xmpan, xmso2, 1.0, xmch2o,xmo3/)!VOC=1,
  291. !hcho=ch2o in TM5, but output for hcho is needed.
  292. ! HOURLY and 6-HOURLY
  293. character(len=8), dimension(2), parameter :: hr6_var=(/'ps','ec550aer'/)
  294. character(len=11), dimension(2), parameter :: hr6_unit=(/units(ipresunit), units(iextunit)/)
  295. character(len=8), dimension(5), parameter :: hourly_var=(/'ps', 'sfno2', 'sfo3', 'sfpm25', 'tas'/)
  296. character(len=11), dimension(5), parameter :: hourly_varunit=(/units(ipresunit), units(ivmrunit), units(ivmrunit), &
  297. units(immrunit), units(itempunit)/)
  298. !DAILY
  299. character(len=8),dimension(10),parameter:: daily_var=(/'od550aer', 'toz', 'maxpblz', 'minpblz', 'tasmin', 'tasmax', &
  300. 'pr', 'sfo3max', 'tas','ps'/)
  301. character(len=11),dimension(10),parameter:: daily_varunit=(/units(idimensionlessunit), units(io3unit), &
  302. units(iheightunit), units(iheightunit), units(itempunit), units(itempunit), units(iemiunit), units(ivmrunit), units(itempunit),units(ipresunit)/)
  303. !ZONAL
  304. character(len=6),dimension(8),parameter:: zonal_var=(/'ch4', 'hno3', 'ho2', 'noy', 'ta', 'zg', 'o3', 'oh'/)
  305. character(len=11),dimension(8),parameter:: zonal_varunit=(/units(ivmrunit), units(ivmrunit), units(ivmrunit), &
  306. units(ivmrunit), units(itempunit), units(iheightunit), units(ivmrunit), units(ivmrunit)/)
  307. integer,dimension(8),parameter:: zonal_idx=(/ich4,ihno3,iho2,-1,-1,-1,io3,ioh/)
  308. !AERCHEMMIP global attributes that might change with run or something else
  309. character(len=3),parameter::grid='3x2'!'250 km'
  310. character(len=3),parameter::grid_label='gn'!'gnz' for zonal means
  311. character(len=300),parameter::source='EC-Earth3-AerChem (2017): atmosphere: IFS cy36r4 (TL255, linearly &
  312. &reduced Gaussian grid equivalent to 512 x 256, 91 levels, top level: 0.01 hPa);atmospheric_chemistry: &
  313. &TM5 (3 deg. (long.) x 2 deg. (lat.), 34 levels, top level: 0.1 hPa; aerosol: TM5'
  314. character(len=17),parameter::source_id='EC-Earth3-AerChem'
  315. character(len=20),public ::source_type!='AOGCM CHEM AER' !or 'AGCM CHEM AER' for amip-runs
  316. character(len=60),public ::realm
  317. character(len=60),public::experiment_id
  318. character(len=60),public::experiment
  319. character(len=1),public::realization_i='1'
  320. character(len=1),public::physics_i='1'
  321. character(len=1),public::forcing_i='1'
  322. character(len=1),public::initialization_i='1'
  323. integer, public:: aerchemmip_dhour
  324. ! Timers
  325. integer :: itim_init, itim_addvar, itim_write, itim_accu, itim_attr, itim_accu_opt, itim_write_hour, itim_write_day, &
  326. itim_write_mon, itim_write_gather
  327. contains
  328. subroutine output_aerchemmip_init(status)
  329. ! Open files
  330. ! allocate dataholders
  331. use dims, only : newsrun,itau,mlen
  332. use global_data, only : outdir
  333. use datetime, only : tau2date, date2tau
  334. use partools, only : MPI_INFO_NULL, localComm
  335. use optics, only : Optics_Init
  336. use sedimentation, only : ised,nsed
  337. use partools , only : isRoot,myid
  338. use global_data, only : region_dat
  339. use tm5_distgrid, only : gather
  340. use meteodata , only : lsmask_dat,oro_dat
  341. use Binas , only : grav
  342. implicit none
  343. ! OUTPUT parameters
  344. integer, intent(out) :: status
  345. ! LOCAL parameters
  346. integer :: region !iterator for regions
  347. integer :: nlon_region
  348. integer :: nlat_region
  349. integer :: nlev_region ! also global
  350. integer :: j_var
  351. integer :: itrac
  352. integer :: i_sed
  353. integer :: i,i1,i2,j1,j2,k,j,imr,jmr
  354. character(len=*), parameter :: rname = mname//'/output_aerchemmip_init'
  355. ! FIXED VARS
  356. real, dimension(:),pointer :: dxyp
  357. real, allocatable :: arr2d(:,:)
  358. real ::xmcomp
  359. call goLabel(rname)
  360. ! define timers:
  361. call GO_Timer_Def( itim_init, 'output aerchemmip init', status )
  362. IF_NOTOK_RETURN(status=1)
  363. call GO_Timer_Def( itim_write, 'output aerchemmip write', status )
  364. IF_NOTOK_RETURN(status=1)
  365. call GO_Timer_Def( itim_write_gather, 'output aerchemmip write gather', status )
  366. IF_NOTOK_RETURN(status=1)
  367. call GO_Timer_Def( itim_write_day, 'output aerchemmip write day', status )
  368. IF_NOTOK_RETURN(status=1)
  369. call GO_Timer_Def( itim_write_hour, 'output aerchemmip write hour', status )
  370. IF_NOTOK_RETURN(status=1)
  371. call GO_Timer_Def( itim_write_mon, 'output aerchemmip write mon', status )
  372. IF_NOTOK_RETURN(status=1)
  373. call GO_Timer_Def( itim_accu, 'output aerchemmip accu', status )
  374. IF_NOTOK_RETURN(status=1)
  375. call GO_Timer_Def( itim_accu_opt, 'output aerchemmip accu _optics', status )
  376. IF_NOTOK_RETURN(status=1)
  377. call GO_Timer_Def( itim_attr, 'output aerchemmip attr', status )
  378. IF_NOTOK_RETURN(status=1)
  379. call GO_Timer_Def( itim_addvar, 'output aerchemmip addvar', status )
  380. IF_NOTOK_RETURN(status=1)
  381. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  382. if (newsrun) then
  383. !optics?
  384. ! ensure that required meteo is loaded:
  385. ! call Set( sp_dat(region), status, used=.true. )
  386. ! set wavelength information
  387. ! wl: wavelength in microns
  388. ! split: whether to split into contributions from
  389. ! M7 constituents (incl. water)
  390. !TB Have to keep insitu part, since optics-module uses it for comparisons.
  391. allocate( wdep_out( 3 ) )
  392. wdep_out(1)%wl = 0.550 ; wdep_out(1)%split = .true. ; wdep_out(1)%insitu = .false.
  393. wdep_out(2)%wl = 0.440 ; wdep_out(2)%split = .true. ; wdep_out(2)%insitu = .false.
  394. wdep_out(3)%wl = 0.870 ; wdep_out(3)%split = .false. ; wdep_out(3)%insitu = .false.
  395. !wdep_out(4)%wl = 0.350 ; wdep_out(4)%split = .false. ; wdep_out(4)%insitu = .false.
  396. ! get the optics code prepared
  397. call Optics_Init(size(wdep_out), wdep_out, status )
  398. IF_NOTOK_RETURN(status=1)
  399. accumulation_mon=0.0
  400. accumulation_hr=0.0
  401. accumulation_6hr=0.0
  402. accumulation_day=0.0
  403. region=1
  404. ! intermediate structures for budgets
  405. allocate(drydepos(region)%f2dslast(i1:i2,j1:j2,18))
  406. allocate(wetdepos(region)%f2dslast(i1:i2,j1:j2,13))
  407. allocate(emission(region)%f2dslast(i1:i2,j1:j2,13))
  408. ! these here are the initial budgets (monthly): 0.0
  409. drydepos(region)%f2dslast = 0.0
  410. wetdepos(region)%f2dslast = 0.0
  411. emission(region)%f2dslast = 0.0
  412. imr = global_lli(1)%nlon
  413. jmr = global_lli(1)%nlat
  414. ! for areacella, orog, sftlf
  415. if (isRoot) then
  416. allocate( arr2d(imr,jmr) )
  417. else
  418. allocate( arr2d(1,1) )
  419. endif
  420. arr2d(:,:)=0.0
  421. ! for monthly output, initialise with 31 for january
  422. n_days_in_month=31
  423. end if
  424. call GO_Timer_Start( itim_init, status )
  425. IF_NOTOK_RETURN(status=1)
  426. ! AERCHEMMIP only available for global-> region=1
  427. region=1
  428. ! Initialize grid definitions
  429. nlon_region = global_lli(region)%nlon
  430. nlat_region = global_lli(region)%nlat
  431. nlev_region = levi%nlev
  432. dimension_data%nlon= nlon_region
  433. dimension_data%nlat= nlat_region
  434. dimension_data%nlev= nlev_region
  435. allocate(dimension_data%lon(nlon_region))
  436. allocate(dimension_data%lat(nlat_region))
  437. allocate(dimension_data%lev(nlev_region))
  438. dimension_data%lon=global_lli(region)%lon_deg
  439. dimension_data%lat=global_lli(region)%lat_deg
  440. ! initialise output timeidx used for keeping track which output steps is written
  441. timeidx_mon=1
  442. timeidx_day=1
  443. timeidx_hr=1
  444. timeidx_6hr=1
  445. ! allocate room for variables
  446. allocate(allvars(n_var_max))
  447. allocate(fixedvars(n_fixed))
  448. if (crescendo_out)then
  449. do i=1,size(crescendo3D)
  450. if (trim(crescendo3D(i))=='mono')then
  451. xmcomp=xmterp
  452. else if (trim(crescendo3D(i))=='nh3')then
  453. xmcomp=xmnh3
  454. else
  455. write(gol,*) 'CRESCENDO 3D monthly with negative molar mass'
  456. xmcomp=-1.0
  457. end if
  458. call add_variable(-1,trim(crescendo3D(i)),trim(crescendo3D(i)),crescendo3Dunit(i),3,status,'crescendo','AERmon',xmcomp)
  459. end do
  460. do i=1,size(crescendo3Dday)
  461. if (trim(crescendo3Dday(i))=='co')then
  462. xmcomp=xmco
  463. else
  464. write(gol,*) 'CRESCENDO 3D daily with negative molar mass'
  465. xmcomp=-1.0
  466. end if
  467. call add_variable(-1,trim(crescendo3Dday(i)),trim(crescendo3Dday(i)),crescendo3Ddayunit(i),3,status,'crescendo','AERday',xmcomp)
  468. end do
  469. do i=1,size(crescendo2D6hr)
  470. if (trim(crescendo2D6hr(i))=='sfdms')then
  471. xmcomp=xmdms
  472. else if (trim(crescendo2D6hr(i))=='sfisop')then
  473. xmcomp=xmisop
  474. else if (trim(crescendo2D6hr(i))=='sfmono')then
  475. xmcomp=xmterp
  476. else
  477. write(gol,*) 'CRESCENDO 2D 6hr with negative molar mass'
  478. write(gol,*) 'gascomp with negative molar mass'
  479. xmcomp=-1.0
  480. end if
  481. call add_variable(-1,trim(crescendo2D6hr(i)),trim(crescendo2D6hr(i)),crescendo2D6hrunit(i),2,status,'crescendo','AER6hr',xmcomp)
  482. end do
  483. do i=1,size(crescendo2Dmon)
  484. call add_variable(-1,trim(crescendo2Dmon(i)),trim(crescendo2Dmon(i)),crescendo2Dmonunit(i),2,status,'crescendo','AERmon',-1.0)
  485. end do
  486. do i=1,size(crescendo2Dhr)
  487. if (trim(crescendo2Dhr(i))=='sfno')then
  488. xmcomp=xmno
  489. else if (trim(crescendo2Dhr(i))=='sfnh3')then
  490. xmcomp=xmnh3
  491. else if (trim(crescendo2Dhr(i))=='sfhno3')then
  492. xmcomp=xmhno3
  493. else
  494. ! -1 so that missing molar mass will be noticed easily
  495. write(gol,*) 'CRESCENDO 2D hr with negative molar mass'
  496. xmcomp=-1.0
  497. end if
  498. call add_variable(-1,trim(crescendo2Dhr(i)),trim(crescendo2Dhr(i)),crescendo2Dhrunit(i),2,status,'crescendo','AERhr',xmcomp)
  499. end do
  500. do i=1,size(crescendo2Dday)
  501. call add_variable(-1,trim(crescendo2Dday(i)),trim(crescendo2Dday(i)),crescendo2Ddayunit(i),2,status,'crescendo','AERday',-1.0)
  502. !call add_variable(-1,trim(crescendo2Dday_new(i,1)),trim(crescendo2Dday_new(i,1)),crescendo2Dday_new(i,2),2,status,'crescendo','AERday',-1.0)
  503. end do
  504. end if
  505. do i=1,size(hr6_var)
  506. if (trim(hr6_var(i))=='ec550aer')then
  507. call add_variable(-1,trim(hr6_var(i)),'optics '//trim(hr6_var(i)), hr6_unit(i),3,status,'optics','AER6hr',-1.0)
  508. else
  509. call add_variable(-1,trim(hr6_var(i)),trim(hr6_var(i)),hr6_unit(i),2,status,'ps6h','AER6hr',-1.0)
  510. endif
  511. end do
  512. ! add deposition variables
  513. do i=1,size(emicomp)
  514. call add_variable(-1,'emi'//trim(emicomp(i)),'emission '//trim(emicomp(i)), units(iemiunit),2,status,'emi','AERmon',-1.0)
  515. end do
  516. ! add 3D chemical production fields
  517. do i=1,size(checomp)
  518. call add_variable(-1,'che'//trim(checomp(i)),'chemical production of '//trim(checomp(i)), units(iemiunit),3,status,'chep','AERmon',-1.0)
  519. end do
  520. ! add 3D ozone prod loss
  521. do i=1,size(o3chepcomp)
  522. call add_variable(-1,trim(o3chepcomp(i)),'tendency_'//trim(o3chepcomp(i)),'mol m-3 s-1',3,status,'chep','AERmon',-1.0)
  523. end do
  524. ! add 2D chemical production fields
  525. do i=1,size(chepcomp)
  526. call add_variable(-1,'chep'//trim(chepcomp(i)),'chemical production of '//trim(chepcomp(i)), units(iemiunit),2,status,'chep','AERmon',-1.0)
  527. end do
  528. ! add Emon fields
  529. do i=1,size(emonout)
  530. select case (trim(emonout(i)))
  531. case( 'md','concdust','conccn')
  532. call add_variable(-1,trim(emonout(i)),trim(emonout(i)), emonoutunit(i),3,status,'emon','Emon',-1.0)
  533. case('flashrate','depdust','seddustCI','loaddust','sconcss')
  534. call add_variable(-1,trim(emonout(i)),trim(emonout(i)), emonoutunit(i),2,status,'emon','Emon',-1.0)
  535. end select
  536. end do
  537. ! add dry deposition fields
  538. do i=1,size(ddepcomp)
  539. call add_variable(-1,'dry'//trim(ddepcomp(i)),'dry deposition '//trim(ddepcomp(i)), units(iddepunit),2,status,'dry','AERmon',-1.0)
  540. end do
  541. ! add wetdep variables
  542. do i=1,size(wdepcomp)
  543. call add_variable(-1,'wet'//trim(wdepcomp(i)),'wet deposition '//trim(wdepcomp(i)), units(iwdepunit),2,status,'wet','AERmon',-1.0)
  544. end do
  545. ! add optics fields
  546. do i=1,size(opticscomp)
  547. !if (trim(opticscomp(i))=='ec550aer') then
  548. ! call add_variable(-1,trim(opticscomp(i)),'optics '//trim(opticscomp(i)), units(iextunit),3,status,'optics','AER6hr',-1.0)
  549. !else
  550. call add_variable(-1,trim(opticscomp(i)),'optics '//trim(opticscomp(i)), units(idimensionlessunit),2,status,'optics','AERmon',-1.0)
  551. end do
  552. ! Aerosol species mass mixing ratios
  553. do i=1,size(aerommrcomp)
  554. call add_variable(-1,'mmr'//trim(aerommrcomp(i)),'mass mixing ratio of '//trim(aerommrcomp(i)), units(immrunit),3,status,'mmr','AERmon',-1.0)
  555. end do
  556. ! Gas-phase species volume mixingratios
  557. do i=1,size(gascomp)
  558. if (xmgascomp(i)>0.0) then
  559. call add_variable(-1,trim(gascomp(i)),'volume mixing ratio of '//trim(gascomp(i)), units(ivmrunit),3,status,'gas','AERmon',xmgascomp(i))
  560. else
  561. write(gol,*) 'gascomp with negative molar mass'
  562. end if
  563. end do
  564. ! add meterorological fields
  565. do i=1,size(meteo3D)
  566. call add_variable(-1,trim(meteo3D(i)),trim(meteo3D(i)),meteo3Dunit(i),3,status,'meteo3D','AERmon',-1.0)
  567. end do
  568. ! surface meteorological fields
  569. do i=1,size(meteo2D)
  570. call add_variable(-1,trim(meteo2D(i)),trim(meteo2D(i)),meteo2Dunit(i),2,status,'meteo2D','AERmon',-1.0)
  571. end do
  572. ! add hourly output
  573. if ( aerchemmip_1h ) then
  574. do i=1,size(hourly_var)
  575. call add_variable(-1,trim(hourly_var(i)),trim(hourly_var(i)),hourly_varunit(i),2,status,'sf1h','AERhr',-1.0)
  576. end do
  577. end if
  578. ! add daily fields
  579. do i=1,size(daily_var)
  580. call add_variable(-1,trim(daily_var(i)),trim(daily_var(i)),daily_varunit(i),2,status,'sf1d','AERday',-1.0)
  581. end do
  582. ! add zonal fields, some fields are repeated (3d/zonal)
  583. do i=1,size(zonal_var)
  584. call add_variable(zonal_idx(i),trim(zonal_var(i)),trim(zonal_var(i)),zonal_varunit(i),3,status,'zonal','AERmonZ',-1.0)
  585. end do
  586. ! Fixed fields
  587. call add_variable(-1,'areacella','cell area','m2',2,status,'fixed','AERfx',-1.0)
  588. call add_variable(-1,'orog','surface_altitude','m',2,status,'fixed','AERfx',-1.0)
  589. call add_variable(-1,'sftlf','land_area_fraction','1',2,status,'fixed','AERfx',-1.0)
  590. ! Initialize a single file for each variables as per AERCHEMMIP specification
  591. do j_var = 1, n_vars
  592. ! overwrite existing files (clobber)
  593. if (isroot)call MDF_Create( allvars(j_var)%filename, MDF_NETCDF4, MDF_REPLACE, allvars(j_var)%fileunit, status )
  594. IF_NOTOK_RETURN(status=1)
  595. ! write grid dimension attributes
  596. if (isroot) call write_dimensions(status, j_var)
  597. IF_NOTOK_RETURN(status=1)
  598. ! write global attributes
  599. if (isroot) call write_attributes(status, j_var)
  600. IF_NOTOK_RETURN(status=1)
  601. ! write dimension variables
  602. if (isroot) call write_var(status,j_var)
  603. IF_NOTOK_RETURN(status=1)
  604. ! Fixed fields
  605. if (allvars(j_var)%table_id=='AERfx')then
  606. if (trim(allvars(j_var)%vname)=='areacella')then
  607. ! Gridbox area
  608. dxyp => region_dat(1)%dxyp
  609. do j=j1,j2
  610. allvars(j_var)%data2D(i1:i2,j)=dxyp(j)
  611. end do
  612. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  613. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  614. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  615. else if (trim(allvars(j_var)%vname)=='orog')then
  616. ! Orography
  617. allvars(j_var)%data2D(i1:i2,j1:j2) =oro_dat(region)%data(i1:i2,j1:j2,1)/grav
  618. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  619. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  620. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  621. else if (trim(allvars(j_var)%vname)=='sftlf')then
  622. ! LSM
  623. allvars(j_var)%data2D(i1:i2,j1:j2)=lsmask_dat(1)%data(i1:i2,j1:j2,1)/100.
  624. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  625. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  626. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  627. end if
  628. end if
  629. end do
  630. deallocate(arr2d)
  631. call GO_Timer_End( itim_init, status )
  632. IF_NOTOK_RETURN(status=1)
  633. call goLabel()
  634. status = 0
  635. end subroutine output_aerchemmip_init
  636. subroutine output_aerchemmip_write(region,newhour,status)
  637. use MeteoData, only : temper_dat,sst_dat,albedo_dat,ci_dat,lsp_dat,cp_dat,ssr_dat,str_dat,&
  638. blh_dat,gph_dat,lwc_dat,iwc_dat,cco_dat,cc_dat,humid_dat, m_dat,phlb_dat,sp_dat !
  639. use global_data, only : conv_dat
  640. use GO, only : TDate, NewDate
  641. use go_date,only: days_in_month!
  642. use datetime, only : tau2date,date2tau,julday !
  643. use dims, only : itau,iyear0 !current time
  644. use ebischeme, only : AC_diag_prod,AC_O3_lp,AC_loss
  645. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  646. use partools , only : isRoot,myid
  647. ! use domain_decomp, only: gather
  648. implicit none
  649. logical,intent(in) ::newhour
  650. integer,intent(out)::status
  651. integer::region
  652. integer:: j_var
  653. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  654. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write'
  655. real, allocatable :: arr3d(:,:,:),arr3dh(:,:,:),arr2d(:,:)
  656. integer, dimension(6) :: curdate
  657. ! reference time:
  658. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  659. integer(kind=8) :: itauref ! reftime in seconds
  660. real :: reftime ! seconds from reference time
  661. real :: rangemon
  662. type(Tdate)::curdate_tdate
  663. call goLabel(rname)
  664. call GO_Timer_Start( itim_write_mon, status )
  665. IF_NOTOK_RETURN(status=1)
  666. if (region > 1) then
  667. write(gol,*) 'output_aerhemmip_write: region >1, only available in global mode!'
  668. call goErr
  669. status=1
  670. return
  671. end if
  672. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  673. ! entire region grid size
  674. imr = global_lli(1)%nlon
  675. jmr = global_lli(1)%nlat
  676. lmr = levi%nlev
  677. ! define the reference time in seconds (itauref)
  678. ! (for now in days since 1850-01-01 00:00, local variable)
  679. ! returns the difference to current time, beginning of new step
  680. !
  681. call date2tau( time_reftime6, itauref )
  682. ! calculate reftime as fractional days from itauref, hence division by 86400
  683. ! call date2tau( idater, itaucur )
  684. ! itau is the 1st day of new month at 00:00 so we need to fix the reftime back half a month (15th day)
  685. ! ((cursecond - reftimesecond) / seconds_in_day) - days_in_last_month + 15days
  686. !reftime = (itau - itauref -n_days_in_month*24*3600 + 15*24*3600) / 86400.
  687. reftime = (itau - itauref ) / 86400.
  688. !get current date in integers
  689. call tau2date(itau, curdate)
  690. ! create a TDATE date variable of the previous month (curdate(3)-1)
  691. curdate_tdate=newdate(curdate(1),curdate(2),curdate(3)-1,curdate(4),curdate(5),curdate(6),calender='greg')
  692. ! get days in month and save for next step
  693. n_days_in_month=days_in_month(curdate_tdate)
  694. ! change reftime to beginning of last month (the month data is from)
  695. reftime=reftime-n_days_in_month
  696. !length of the month-1s(in days) for the time_bounds
  697. rangemon=n_days_in_month !-(1.0/86400.0)
  698. ! allocate 3D and 4D global arrays for gathering data
  699. ! only root needs the full array, but it must be allocated in all tasks
  700. if (isRoot) then
  701. allocate( arr3d(imr,jmr,lmr) )
  702. allocate( arr3dh(imr,jmr,lmr+1) )
  703. allocate( arr2d(imr,jmr) )
  704. else
  705. allocate( arr3d(1,1,1) )
  706. allocate( arr3dh(1,1,1) )
  707. allocate( arr2d(1,1) )
  708. endif
  709. arr2d(:,:)=0.0
  710. arr3d(:,:,:)=0.0
  711. arr3dh(:,:,:)=0.0
  712. do j_var =1,n_vars
  713. ! hourly and daily variables are handled separately
  714. if (allvars(j_var)%table_id=='AERhr'.or.allvars(j_var)%table_id=='AER6hr'.or.&
  715. allvars(j_var)%table_id=='AERday'.or.allvars(j_var)%table_id=='AERfx')then
  716. cycle
  717. end if
  718. if (allvars(j_var)%dims==2)then !2D
  719. if (trim(allvars(j_var)%vname)/='minpblz'.and.trim(allvars(j_var)%vname)/='tasmin'.and. &
  720. trim(allvars(j_var)%vname)/='maxpblz'.and.trim(allvars(j_var)%vname)/='tasmax')then
  721. allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_mon)
  722. end if
  723. call GO_Timer_Start( itim_write_gather, status )
  724. IF_NOTOK_RETURN(status=1)
  725. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  726. call GO_Timer_End( itim_write_gather, status )
  727. IF_NOTOK_RETURN(status=1)
  728. IF_NOTOK_RETURN(status=1)
  729. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1,timeidx_mon/), &
  730. count=(/imr,jmr,1/) )
  731. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  732. ! Zero out the accumulated and written data for the next interval
  733. if (trim(allvars(j_var)%vname)=='minpblz' .or. trim(allvars(j_var)%vname)=='tasmin') then
  734. ! put high number so simple comparison is needed for finding minimum
  735. allvars(j_var)%data2D(i1:i2,j1:j2)=1e10
  736. else
  737. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  738. end if
  739. else !3D
  740. if (trim( allvars(j_var)%vname)=='phalf') then !lmr+1
  741. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr+1)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr+1)/real(accumulation_mon)
  742. call GO_Timer_Start( itim_write_gather, status )
  743. IF_NOTOK_RETURN(status=1)
  744. call gather( dgrid(1), allvars(j_var)%data3D , arr3dh(:,:,:), 0, status)
  745. IF_NOTOK_RETURN(status=1)
  746. call GO_Timer_End( itim_write_gather, status )
  747. IF_NOTOK_RETURN(status=1)
  748. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr3dh , status, start=(/1,1,1,timeidx_mon/), &
  749. count=(/imr,jmr,lmr+1,1/) )
  750. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  751. else
  752. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_mon)
  753. call GO_Timer_Start( itim_write_gather, status )
  754. IF_NOTOK_RETURN(status=1)
  755. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  756. IF_NOTOK_RETURN(status=1)
  757. call GO_Timer_End( itim_write_gather, status )
  758. IF_NOTOK_RETURN(status=1)
  759. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr3d , status, start=(/1,1,1,timeidx_mon/), &
  760. count=(/imr,jmr,lmr,1/) )
  761. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  762. end if
  763. ! Zero out the accumulated and written data for the next interval
  764. allvars(j_var)%data3D(i1:i2,j1:j2,:)=0.0
  765. end if
  766. !end if
  767. ! write the date for timestep
  768. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime+real(rangemon/2)/) , status, start=(/timeidx_mon/), count=(/1/) )
  769. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  770. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%bounds_varid,(/ reftime,reftime+rangemon/) , status, &
  771. start=(/1,timeidx_mon/), count=(/2,1/) )
  772. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  773. end do
  774. deallocate( arr3d,arr3dh,arr2d)
  775. ! change time index
  776. timeidx_mon= timeidx_mon + 1
  777. ! accululated time to zero
  778. accumulation_mon=0
  779. ! zero out the chemical production (for mongthly output)
  780. !AC_diag_prod(region)%prod(i1:i2,j1:j2,:,1:3)=0.0
  781. ! zero out the chemical production
  782. !AC_O3_lp(region)%prod(i1:i2,j1:j2,:,1:2)=0.0
  783. ! zero out the chemical production
  784. !AC_loss(region)%prod(i1:i2,j1:j2,:,1:2)=0.0
  785. !status=1
  786. !return
  787. call GO_Timer_End( itim_write_mon, status )
  788. IF_NOTOK_RETURN(status=1)
  789. call goLabel()
  790. status = 0
  791. end subroutine output_aerchemmip_write
  792. subroutine output_aerchemmip_write_daily(region,newday,status)
  793. use MeteoData, only : temper_dat, sst_dat, albedo_dat, ci_dat, lsp_dat, cp_dat, ssr_dat, str_dat, &
  794. blh_dat, gph_dat, lwc_dat, iwc_dat, cco_dat, cc_dat, humid_dat, m_dat, phlb_dat, sp_dat !
  795. use meteodata , only : global_lli, levi
  796. use partools , only : isRoot,myid
  797. use GO, only : TDate, NewDate!
  798. use datetime, only : tau2date,date2tau,julday !
  799. use dims, only : itau,iyear0 !current time
  800. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  801. implicit none
  802. logical,intent(in) ::newday
  803. integer,intent(out)::status
  804. integer::region
  805. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  806. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write'
  807. integer:: j_var
  808. ! reference time:
  809. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  810. integer(kind=8) :: itauref ! reftime in seconds
  811. real :: reftime ! seconds from reference time
  812. real :: rangeday ! for bounds
  813. ! root writes netcdf arrays
  814. real, allocatable :: arr3d(:,:,:), arr2d(:,:)
  815. integer:: imr_f,jmr_f,lmr_f
  816. call goLabel(rname)
  817. call GO_Timer_Start( itim_write_day, status )
  818. IF_NOTOK_RETURN(status=1)
  819. if (region > 1) then
  820. write(gol,*) 'output_aerhemmip_write: region >1, only available in global mode!'
  821. call goErr
  822. status=1
  823. return
  824. end if
  825. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  826. ! entire region grid size
  827. imr = global_lli(1)%nlon
  828. jmr = global_lli(1)%nlat
  829. lmr = levi%nlev
  830. ! allocate 3D and 4D global arrays for gathering data
  831. if (isRoot) then
  832. allocate( arr3d(imr,jmr,lmr) )
  833. allocate( arr2d(imr,jmr) )
  834. else
  835. allocate( arr3d(1,1,1) )
  836. allocate( arr2d(1,1) )
  837. endif
  838. arr2d(:,:)=0.0
  839. arr3d(:,:,:)=0.0
  840. ! define the reference time in seconds (itauref)
  841. ! (for now in days since 1850-01-01 00:00, local variable)
  842. call date2tau( time_reftime6, itauref )
  843. ! calculate reftime as fractional days from itauref, hence division by 86400
  844. ! call date2tau( idater, itaucur )
  845. reftime = (itau - itauref) / 86400. - 1.0
  846. !23h59 as days
  847. rangeday=1.0!(23.0*3600.0+59.0*60.0+59.0)/86400.0
  848. do j_var =1,n_vars
  849. if (allvars(j_var)%table_id/='AERday')then
  850. cycle
  851. end if
  852. if (allvars(j_var)%dims==2)then
  853. if ( trim(allvars(j_var)%vname)/='minpblz' .and. trim(allvars(j_var)%vname)/='tasmin' .and. &
  854. trim(allvars(j_var)%vname)/='maxpblz' .and. trim(allvars(j_var)%vname)/='tasmax' .and. &
  855. trim(allvars(j_var)%vname)/='sfo3max' ) then
  856. allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_day)
  857. end if
  858. call GO_Timer_Start( itim_write_gather, status )
  859. IF_NOTOK_RETURN(status=1)
  860. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0, status)
  861. IF_NOTOK_RETURN(status=1)
  862. call GO_Timer_End( itim_write_gather, status )
  863. IF_NOTOK_RETURN(status=1)
  864. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1,timeidx_day/), count=(/imr,jmr,1/) )
  865. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  866. if (trim(allvars(j_var)%vname)=='minpblz' .or. trim(allvars(j_var)%vname)=='tasmin') then
  867. ! put high number so simple comparison is needed for finding minimum
  868. allvars(j_var)%data2D(i1:i2,j1:j2)=1e10
  869. else
  870. ! Zero out the accumulated and written data for the next interval
  871. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  872. end if
  873. else
  874. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_day)
  875. !end if
  876. call GO_Timer_Start( itim_write_gather, status )
  877. IF_NOTOK_RETURN(status=1)
  878. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  879. call GO_Timer_End( itim_write_gather, status )
  880. IF_NOTOK_RETURN(status=1) !if (trim(allvars(j_var)%vname)=='od5503ddust')then
  881. IF_NOTOK_RETURN(status=1)
  882. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr3d, status, start=(/1,1,1,timeidx_day/), count=(/imr,jmr,lmr,1/) )
  883. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  884. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=0.0
  885. end if
  886. ! write the date for timestep
  887. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime+0.5/) , status, start=(/timeidx_day/), count=(/1/) )
  888. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  889. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%bounds_varid,(/ reftime,reftime+ rangeday/) , status, start=(/1,timeidx_day/), count=(/2,1/) )
  890. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  891. end do
  892. deallocate(arr3d, arr2d)
  893. ! Timeindex to next day
  894. timeidx_day= timeidx_day + 1
  895. ! daily accumulated time to zero
  896. accumulation_day=0.0
  897. !status=1
  898. !return
  899. call GO_Timer_End( itim_write_day, status )
  900. IF_NOTOK_RETURN(status=1)
  901. call goLabel()
  902. status = 0
  903. end subroutine output_aerchemmip_write_daily
  904. subroutine output_aerchemmip_write_hourly(region,newhour,status)
  905. use MeteoData, only : temper_dat,sst_dat,albedo_dat,ci_dat,lsp_dat,cp_dat,ssr_dat,str_dat,blh_dat,gph_dat,lwc_dat,iwc_dat,cco_dat,cc_dat,humid_dat, m_dat,phlb_dat,sp_dat !
  906. use GO, only : TDate, NewDate!
  907. use datetime, only : tau2date,date2tau,julday !
  908. use dims, only : itau,iyear0 !current time
  909. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  910. use partools , only : isRoot,myid
  911. implicit none
  912. logical,intent(in) ::newhour
  913. integer,intent(out)::status
  914. integer:: j_var
  915. integer::region
  916. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  917. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write_hourly'
  918. real :: rangehr,range6hr ! hour in days for bounds in NC-file
  919. ! reference time:
  920. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  921. integer(kind=8) :: itauref ! reftime in seconds
  922. real :: reftime ! seconds from reference time
  923. ! root writes netcdf arrays
  924. real, allocatable :: arr3d(:,:,:) , arr2d(:,:)
  925. call goLabel(rname)
  926. call GO_Timer_Start( itim_write_hour, status )
  927. IF_NOTOK_RETURN(status=1)
  928. if (region > 1) then
  929. write(gol,*) 'output_aerhemmip_write: region >1, only available in global mode!'
  930. call goErr
  931. status=1
  932. return
  933. end if
  934. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  935. ! entire region grid size
  936. imr = global_lli(1)%nlon
  937. jmr = global_lli(1)%nlat
  938. lmr = levi%nlev
  939. ! allocate 3D and 4D global arrays for gathering data
  940. if (isRoot) then
  941. allocate( arr3d(imr,jmr,lmr) )
  942. allocate( arr2d(imr,jmr) )
  943. else
  944. ! other than root need the variable, but no space
  945. allocate( arr3d(1,1,1) )
  946. allocate( arr2d(1,1) )
  947. endif
  948. arr2d(:,:)=0.0
  949. arr3d(:,:,:)=0.0
  950. ! define the reference time in seconds (itauref)
  951. ! (for now in days since 1850-01-01 00:00, local variable)
  952. call date2tau( time_reftime6, itauref )
  953. ! call date2tau( idater, itaucur )
  954. rangehr=1.0/24.0!(3600)/86400.0
  955. do j_var =1,n_vars
  956. if (allvars(j_var)%table_id/='AERhr' .and. allvars(j_var)%table_id/='AER6hr' )then
  957. cycle
  958. end if
  959. if (allvars(j_var)%dims==2)then
  960. if ( trim(allvars(j_var)%table_id)=='AERhr') then
  961. reftime = (itau - itauref) / 86400. - (1./24)
  962. allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_hr)
  963. call GO_Timer_Start( itim_write_gather, status )
  964. IF_NOTOK_RETURN(status=1)
  965. call gather( dgrid(1), allvars(j_var)%data2D , arr3d(:,:,1), 0, status)
  966. IF_NOTOK_RETURN(status=1)
  967. call GO_Timer_End( itim_write_gather, status )
  968. IF_NOTOK_RETURN(status=1)
  969. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid,arr3d(:,:,1), status, start=(/1,1,timeidx_hr/), count=(/imr,jmr,1/) )
  970. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  971. ! write the date for timestep
  972. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime+(0.5/24.0)/) , status, start=(/timeidx_hr/), count=(/1/) )
  973. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  974. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%bounds_varid,(/ reftime,reftime+rangehr/) , status, start=(/1,timeidx_hr/), count=(/2,1/) )
  975. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  976. ! Zero out the accumulated and written data for the next interval
  977. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  978. end if
  979. else
  980. if ( trim(allvars(j_var)%table_id)=='AERhr') then
  981. reftime = (itau - itauref) / 86400. - (1./24)
  982. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_hr)
  983. call GO_Timer_Start( itim_write_gather, status )
  984. IF_NOTOK_RETURN(status=1)
  985. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  986. call GO_Timer_End( itim_write_gather, status )
  987. IF_NOTOK_RETURN(status=1)
  988. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid,arr3d, status, start=(/1,1,1,timeidx_hr/), count=(/imr,jmr,lmr,1/) )
  989. ! write the date for timestep
  990. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime+(0.5/24.0)/) , status, start=(/timeidx_hr/), count=(/1/) )
  991. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  992. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%bounds_varid,(/ reftime,reftime+(1./24.)/) , status, start=(/1,timeidx_hr/), count=(/2,1/) )
  993. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  994. ! Zero out the accumulated and written data for the next interval
  995. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=0.0
  996. end if
  997. end if
  998. !end if
  999. end do
  1000. deallocate(arr3d, arr2d)
  1001. ! changed index to next hour
  1002. timeidx_hr= timeidx_hr + 1
  1003. ! accumulated hours to zero, actually this will always be 1h
  1004. accumulation_hr=0.0
  1005. !status=1
  1006. !return
  1007. call GO_Timer_End( itim_write_hour, status )
  1008. IF_NOTOK_RETURN(status=1)
  1009. call goLabel()
  1010. status = 0
  1011. end subroutine output_aerchemmip_write_hourly
  1012. subroutine output_aerchemmip_write_6hourly(region,newhour,status)
  1013. use MeteoData, only : temper_dat,sst_dat,albedo_dat,ci_dat,lsp_dat,cp_dat,ssr_dat,str_dat,blh_dat,gph_dat,lwc_dat,iwc_dat,cco_dat,cc_dat,humid_dat, m_dat,phlb_dat,sp_dat !
  1014. use GO, only : TDate, NewDate!
  1015. use datetime, only : tau2date,date2tau,julday !
  1016. use dims, only : itau,iyear0 !current time
  1017. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  1018. use partools , only : isRoot,myid
  1019. use ebischeme, only : AC_diag_prod,iprod_soa2dhour
  1020. implicit none
  1021. logical,intent(in) ::newhour
  1022. integer,intent(out)::status
  1023. integer::region
  1024. integer:: j_var
  1025. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  1026. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write'
  1027. ! reference time:
  1028. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  1029. integer(kind=8) :: itauref ! reftime in seconds
  1030. real :: reftime ! seconds from reference time
  1031. ! root writes netcdf arrays
  1032. real, allocatable :: arr3d(:,:,:) , arr2d(:,:)
  1033. call goLabel(rname)
  1034. call GO_Timer_Start( itim_write_hour, status )
  1035. IF_NOTOK_RETURN(status=1)
  1036. if (region > 1) then
  1037. write(gol,*) 'output_aerhemmip_write: region >1, only available in global mode!'
  1038. call goErr
  1039. status=1
  1040. return
  1041. end if
  1042. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  1043. ! entire region grid size
  1044. imr = global_lli(1)%nlon
  1045. jmr = global_lli(1)%nlat
  1046. lmr = levi%nlev
  1047. ! allocate 3D and 4D global arrays for gathering data
  1048. if (isRoot) then
  1049. allocate( arr3d(imr,jmr,lmr) )
  1050. allocate( arr2d(imr,jmr) )
  1051. else
  1052. ! other than root need the variable, but no space
  1053. allocate( arr3d(1,1,1) )
  1054. allocate( arr2d(1,1) )
  1055. endif
  1056. arr2d(:,:)=0.0
  1057. arr3d(:,:,:)=0.0
  1058. ! define the reference time in seconds (itauref)
  1059. ! (for now in days since 1850-01-01 00:00, local variable)
  1060. call date2tau( time_reftime6, itauref )
  1061. ! call date2tau( idater, itaucur )
  1062. reftime = (itau - itauref) / 86400.
  1063. do j_var =1,n_vars
  1064. if ( allvars(j_var)%table_id/='AER6hr' )then
  1065. cycle
  1066. end if
  1067. if (allvars(j_var)%dims==2)then
  1068. !allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_6hr)
  1069. call GO_Timer_Start( itim_write_gather, status )
  1070. IF_NOTOK_RETURN(status=1)
  1071. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0, status)
  1072. IF_NOTOK_RETURN(status=1)
  1073. call GO_Timer_End( itim_write_gather, status )
  1074. IF_NOTOK_RETURN(status=1)
  1075. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid,arr2d, status, start=(/1,1,timeidx_6hr/), count=(/imr,jmr,1/) )
  1076. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1077. ! write the date for timestep
  1078. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime/) , status, start=(/timeidx_6hr/), count=(/1/) )
  1079. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1080. ! Zero out the accumulated and written data for the next interval
  1081. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  1082. else
  1083. !allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_6hr)
  1084. call GO_Timer_Start( itim_write_gather, status )
  1085. IF_NOTOK_RETURN(status=1)
  1086. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  1087. call GO_Timer_End( itim_write_gather, status )
  1088. IF_NOTOK_RETURN(status=1)
  1089. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid,arr3d, status, start=(/1,1,1,timeidx_6hr/), count=(/imr,jmr,lmr,1/) )
  1090. ! write the date for timestep
  1091. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime/) , status, start=(/timeidx_6hr/), count=(/1/) )
  1092. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1093. !start=(/i1,j1,1,timeidx_mon/), count=(/imr,jmr,lmr,1/) )
  1094. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1095. ! Zero out the accumulated and written data for the next interval
  1096. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=0.0
  1097. end if
  1098. end do
  1099. deallocate(arr3d,arr2d)
  1100. ! changed index to next 6hour
  1101. timeidx_6hr= timeidx_6hr + 1
  1102. ! exception for one 6hr field, no need to do another subroutine for it
  1103. accumulation_6hr=0.0
  1104. ! zero out the chemical production (SOA for hourly output)
  1105. ! now used fro 6h output
  1106. !AC_diag_prod(region)%prod(i1:i2,j1:j2,:,iprod_soa2dhour)=0.0
  1107. call GO_Timer_End( itim_write_hour, status )
  1108. IF_NOTOK_RETURN(status=1)
  1109. call goLabel()
  1110. status = 0
  1111. end subroutine output_aerchemmip_write_6hourly
  1112. subroutine accumulate_data(dhour,l_do_ec550aer_only,status)
  1113. use GO , only : TDate, NewDate, rTotal, operator(-)
  1114. use Grid , only : FPressure,HPressure
  1115. use binas, only : rgas, rol,xmair,Dobs,Avog
  1116. USE toolbox, only : ltropo_ifs, lvlpress
  1117. !use datetime, only : tau2date
  1118. use MeteoData, only : temper_dat, sst_dat, albedo_dat, ci_dat, lsp_dat, cp_dat, ssr_dat, str_dat, blh_dat, &
  1119. gph_dat, lwc_dat, iwc_dat, cco_dat, cc_dat, humid_dat, m_dat, phlb_dat, sp_dat, pu_dat, pv_dat,pw_dat
  1120. use photolysis_data,only:phot_dat !
  1121. use global_data, only : mass_dat, region_dat,conv_dat
  1122. use tracer_data, only : chem_dat
  1123. use dims, only : lm,sec_month
  1124. use chem_param, only : iso4acs, iso4cos, iduacs, iso4ais, ibccos, ibcaii, xmair, xmo3,nmhc,xmcb5,ncb5, o3p, o3l,ino3_a,xmn,ra
  1125. !use chem_param, only : iso4nus, isscos, ino3_a, issacs, iducos, iduaci, nmod
  1126. !use chem_param, only : iducoi, ibcacs, ipomcos, ipomaii, ibcais, ipomacs, ipomais
  1127. !use chem_param, only : imsa, inh4
  1128. !use chem_param, only : ntrace,names,mode_end_so4
  1129. !use mo_aero_m7, only : nmod!,nsol
  1130. !use optics, only : optics_aop_get
  1131. use m7_data, only : h2o_mode, rw_mode, rwd_mode
  1132. use sedimentation, only : nsed,ised ,sindex
  1133. use sedimentation, only : deposition => buddep_m7_dat !(i,j,lev,nsed)
  1134. use wet_deposition,only : wetdep=>buddep_dat !(i,j,lev,ntrace)
  1135. use emission_data, only : budemi_dat
  1136. use ebischeme, only : buddry_dat => buddep_dat
  1137. use chem_param, only : xmso2, xmso4, xmdms, xmpom, xmbc, xmdust, xmnacl,xmo3,xmnh4,ino,ino2,ino3,ihno3,ino3_a,ihno4,ihono,ich3o2no2,ipan,iorgntr,ra
  1138. use calc_pm, only : PMx_Integrate_3d,PMx_integrate_0d
  1139. use emission_nox, only : eminox_lightning
  1140. use ebischeme, only : diag_prod,AC_diag_prod,AC_O3_lp,AC_loss,iloss_ch4,iloss_co,iprod_gasso4,iprod_aqso4,iprod_soa3dmon,iprod_soa2dhour
  1141. use partools , only : isRoot,myid
  1142. use dims, only: gtor, dx, dy, ybeg, xref, yref,ndyn
  1143. use binas, only: ae
  1144. use emission_nox, only: flashrate_lightning
  1145. implicit none
  1146. character(len=*), parameter :: rname = mname//'/output_aerchemmip_accumulate_data'
  1147. ! integer :: indices(7)
  1148. integer :: itrac,gasind
  1149. integer :: i_sed
  1150. integer :: i_emi
  1151. integer :: i, j, k, imr, jmr, lmr, lwl, dtime,index,imode,m
  1152. integer :: i1, i2, j1, j2
  1153. integer :: ie, je ! indices for subdomain extended with halo cells
  1154. integer,intent(in) :: dhour
  1155. integer :: status
  1156. integer :: j_var,region,i_var,i_wdep,sedindex,icomp
  1157. real :: dens
  1158. real :: vol
  1159. real :: tempbud,xmcomp,temp
  1160. real, dimension(:,:,:,:), pointer :: tracers ! transported tracers
  1161. real, dimension(:,:,:,:), pointer :: tracers_c ! non-transported
  1162. real, dimension(:), pointer :: dxyp
  1163. integer, dimension(n_indices) :: indices
  1164. real::xmgas
  1165. real, dimension(:,:,:), allocatable :: pres3d
  1166. real, dimension(:,:,:), allocatable :: temp_pm
  1167. real, dimension(:,:,:), allocatable :: pres3dh
  1168. real :: pm_sizelimit
  1169. integer::emi_index,wet_index,dry_index
  1170. ! tropopause calculations
  1171. real, dimension(:), allocatable :: gphx, tx
  1172. real, dimension(:,:,:), pointer :: gph ! height (incl. oro)
  1173. real, dimension(:,:,:), pointer :: t ! temperature (K)
  1174. integer :: itropo
  1175. real::xres,yres,dxx,dyy,uwind,vwind,lat,wwind,dz,meanwind
  1176. integer, dimension(4) :: modes_dust=(/3,4,6,7/)
  1177. !
  1178. !EC550AER
  1179. logical,intent(in) :: l_do_ec550aer_only
  1180. call goLabel(rname)
  1181. call GO_Timer_Start( itim_accu, status )
  1182. IF_NOTOK_RETURN(status=1)
  1183. region=1
  1184. ! grid size
  1185. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  1186. imr = i2-i1+1
  1187. jmr = j2-j1+1
  1188. lmr = levi%nlev
  1189. ! for tropopause variables
  1190. allocate(gphx(0:lm(region))) ! note now from 0-->lm
  1191. allocate(tx(lm(region)))
  1192. t => temper_dat (region)%data
  1193. gph => gph_dat (region)%data
  1194. allocate( temp_pm(i1:i2,j1:j2,lmr) )
  1195. temp_pm=0.0
  1196. allocate( pres3d(i1:i2,j1:j2,lmr) )
  1197. allocate( pres3dh(i1:i2,j1:j2,0:lmr) )
  1198. ! fill mid level pressure
  1199. call FPressure( levi, sp_dat(region)%data(i1:i2,j1:j2,1), pres3d, status )
  1200. IF_NOTOK_RETURN(status=1)
  1201. ! fill interface pressure
  1202. call HPressure( levi, sp_dat(region)%data(i1:i2,j1:j2,1), pres3dh, status )
  1203. IF_NOTOK_RETURN(status=1)
  1204. accumulation_6hr=0.0!accumulation_6hr+dtime
  1205. ! Gridbox area
  1206. dxyp => region_dat(region)%dxyp
  1207. ! mass_dat and chem_data keep data in kg/gridbox
  1208. !
  1209. tracers => mass_dat(region)%rm
  1210. tracers_c => chem_dat(region)%rm
  1211. if (.not. l_do_ec550aer_only) then
  1212. dtime = dhour*3600
  1213. accumulation_mon=accumulation_mon+dtime
  1214. accumulation_hr=accumulation_hr+dtime
  1215. accumulation_day=accumulation_day+dtime
  1216. do j_var = 1, n_vars
  1217. indices(:)=allvars(j_var)%indices(:)
  1218. !Here we use the tm5-indices to collect data for output
  1219. !
  1220. if (trim(allvars(j_var)%class)=='meteo2D') then
  1221. do j = j1,j2
  1222. do i=i1,i2
  1223. tx(:)=t(i,j,:)
  1224. gphx(0:lm(region))=gph(i,j,1:lm(region)+1) !note the bounds
  1225. !ibase = lubottom(i,j)
  1226. !itop = lutop(i,j)
  1227. itropo = ltropo_ifs(region,i,j,tx,lm(region))
  1228. ! density for conversion of aerosol mass densities ( ---> 1/m3 )
  1229. ! (conversion factor 1.E-03 is for g --> kg)
  1230. !dens = pres3d(i,j,k) / temper_dat(region)%data(i,j,k) * xmair * 1.E-3 / (m_dat(region)%data(i,j,k) * rgas)
  1231. if (trim(allvars(j_var)%vname)=='ps')then
  1232. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)
  1233. else if (trim(allvars(j_var)%vname)=='ptp')then
  1234. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+pres3d(i,j,itropo)*dtime
  1235. else if (trim(allvars(j_var)%vname)=='tropoz')then
  1236. ! conversion (in order of execution):
  1237. !kg->g (1e3), g->molec (xmo3), m2->cm2(1e-4) , molec-> molec/m2(dxyp) , molec/cm2->dobson (DOBS)
  1238. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*sum(tracers(i,j,1:itropo,io3)*1e3/xmo3*Avog*1e-4/dxyp(j)/Dobs)
  1239. else if (trim(allvars(j_var)%vname)=='toz')then
  1240. ! conversion (in order of execution):
  1241. !kg->g (1e3), g->molec (xmo3), m2->cm2(1e-4) , molec-> molec/m2(dxyp) , molec/cm2->dobson (DOBS)
  1242. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*sum(tracers(i,j,:,io3)*1e3/xmo3*Avog*1e-4/dxyp(j)/Dobs)
  1243. else if (trim(allvars(j_var)%vname)=='tos')then
  1244. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)!+dtime*sst_dat(1)%data(i,j,1)
  1245. else if (trim(allvars(j_var)%vname)=='sic')then
  1246. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*ci_dat(1)%data(i,j,1)
  1247. else if (trim(allvars(j_var)%vname)=='tatp')then
  1248. ! t at the gridpoint center ->mean at the interface value
  1249. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*t(i,j,itropo)
  1250. else if (trim(allvars(j_var)%vname)=='ztp')then
  1251. !gph at interface
  1252. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(gph(i,j,itropo+1)+gph(i,j,itropo))/2
  1253. else if (trim(allvars(j_var)%vname)=='bldep')then
  1254. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*conv_dat(1)%blh(i,j)
  1255. else if (trim(allvars(j_var)%vname)=='pr')then
  1256. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(lsp_dat(1)%data(i,j,1)+ cp_dat(1)%data(i,j,1))
  1257. else if (trim(allvars(j_var)%vname)=='albsrfc')then
  1258. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*albedo_dat(1)%data(i,j,1)
  1259. end if
  1260. end do
  1261. end do
  1262. !end if
  1263. else if (trim(allvars(j_var)%class)=='meteo3D') then
  1264. do j = j1,j2
  1265. do i=i1,i2
  1266. if (trim(allvars(j_var)%vname)=='phalf')then
  1267. do k=1,lmr+1
  1268. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*pres3dh(i,j,k-1)
  1269. end do
  1270. else
  1271. do k =1,lmr
  1272. if(trim(allvars(j_var)%vname)=='ta')then
  1273. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*temper_dat(1)%data(i,j,k)
  1274. else if (trim(allvars(j_var)%vname)=='emilnox')then
  1275. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime* eminox_lightning(region)%d3(i,j,k) / dxyp(j)
  1276. else if (trim(allvars(j_var)%vname)=='jno2')then
  1277. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*phot_dat(region)%jno2(i,j,k)
  1278. else if (trim(allvars(j_var)%vname)=='airmass')then
  1279. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime* m_dat(region)%data(i,j,k) / dxyp(j)
  1280. else if (trim(allvars(j_var)%vname)=='pfull')then
  1281. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*pres3d(i,j,k)
  1282. ! else if (trim(allvars(j_var)%vname)=='phalf')then
  1283. ! allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*pres3dh(i,j,k)
  1284. else if (trim(allvars(j_var)%vname)=='hus')then
  1285. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*humid_dat(1)%data(i,j,k)
  1286. else if (trim(allvars(j_var)%vname)=='zg')then
  1287. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*gph_dat(1)%data(i,j,k)
  1288. else if (trim(allvars(j_var)%vname)=='ua')then
  1289. ! distance of single gridbox
  1290. yres = dy/yref(1)
  1291. xres = dx/xref(1)
  1292. lat = ybeg(1) + 0.5 * yres + yres * (j-1)
  1293. dxx = ae * xres * gtor * cos(lat*gtor)
  1294. uwind=dxx*(pu_dat(1)%data(i,j,k) + pu_dat(1)%data(i-1,j,k))*0.5 / m_dat(1)%data(i,j,k)
  1295. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*uwind
  1296. else if (trim(allvars(j_var)%vname)=='va')then
  1297. yres = dy/yref(1)
  1298. dyy = ae * yres * gtor
  1299. vwind= dyy *(pv_dat(1)%data(i,j,k) + pv_dat(1)%data(i,j+1,k))*0.5 / m_dat(1)%data(i,j,k)
  1300. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*vwind
  1301. else if (trim(allvars(j_var)%vname)=='wa')then
  1302. dz = gph_dat(1)%data(i,j,k+1) - gph_dat(1)%data(i,j,k)
  1303. wwind= dz*(pw_dat(1)%data1(i,j,k-1) + pw_dat(1)%data1(i,j,k))*0.5 / m_dat(1)%data(i,j,k)
  1304. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*wwind
  1305. end if
  1306. end do
  1307. end if
  1308. end do
  1309. end do
  1310. !end if
  1311. else if (trim(allvars(j_var)%class)=='emon') then
  1312. !Sedimented indices in deposition%sed
  1313. !do i_sed=1,nsed
  1314. !gridpoints
  1315. do j = j1,j2
  1316. do i=i1,i2
  1317. select case ( trim(allvars(j_var)%vname))
  1318. case('loaddust')
  1319. do m=1,n_indices
  1320. index=allvars(j_var)%indices(m)
  1321. if (index==0) cycle
  1322. do k=1,lmr
  1323. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,k,index))/ dxyp(j)
  1324. end do
  1325. end do
  1326. case('concdust')
  1327. do m=1,n_indices
  1328. index=allvars(j_var)%indices(m)
  1329. if (index==0) cycle
  1330. do k=1,lmr
  1331. vol = (gph_dat(region)%data(i,j,k+1)-gph_dat(region)%data(i,j,k)) * dxyp(j)
  1332. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*(tracers(i,j,k,index))/ vol
  1333. end do
  1334. end do
  1335. case('seddustCI')
  1336. sedindex=sindex(iducoi)
  1337. xmcomp=xmdust
  1338. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+ &
  1339. deposition(region)%sed(i,j,1,sedindex) / dxyp(j) * 1.E-03*xmcomp*-100000
  1340. case('depdust')
  1341. tempbud=0.0
  1342. xmcomp=xmdust
  1343. do m=1,n_indices
  1344. !exit if indices ==0
  1345. !since indices after 0 will all be also 0
  1346. if (indices(m)>0) then
  1347. if (allvars(j_var)%indices(m)>69)then
  1348. sedindex=-1
  1349. else
  1350. sedindex=sindex(allvars(j_var)%indices(m))
  1351. end if
  1352. if (sedindex>0)then
  1353. tempbud=tempbud+( &
  1354. sum(deposition(region)%sed(i,j,:,sedindex))) / dxyp(j) * 1.E-03*xmcomp
  1355. end if
  1356. end if
  1357. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud)
  1358. end do
  1359. case('md')
  1360. do k=1,lmr
  1361. ! tendency of atm_mass content of dust dry aerosol particles due to emission
  1362. ! coarse mode only 3d hmmm
  1363. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)-1!dtime*rw_mode(1,7)%d3(i,j,k)
  1364. end do
  1365. case('flashrate')
  1366. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*flashrate_lightning(1)%d23(i,j)/(dxyp(j)*1e-4) !km-2s-1 (flashrate_lightning in [s-1]
  1367. case('conccn')
  1368. do k=1,lmr
  1369. temp=0.0
  1370. dens = pres3d(i,j,k) / temper_dat(region)%data(i,j,k) * xmair * 1.E-3 / (m_dat(region)%data(i,j,k) * rgas)
  1371. do m=1,n_indices
  1372. index=allvars(j_var)%indices(m)
  1373. if (index==0) cycle
  1374. temp=tracers(i,j,k,index)*dens
  1375. end do
  1376. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*temp
  1377. end do
  1378. case('sconcss')
  1379. temp=0.0
  1380. k=1 !Surface
  1381. dens = pres3d(i,j,k) / temper_dat(region)%data(i,j,k) * xmair * 1.E-3 / (m_dat(region)%data(i,j,k) * rgas)
  1382. do m=1,n_indices
  1383. index=allvars(j_var)%indices(m)
  1384. if (index==0) cycle
  1385. temp=tracers(i,j,k,index)*dens
  1386. end do
  1387. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*temp
  1388. case DEFAULT !('default')
  1389. write(gol,'("emon accumulate missing: ",a)') trim(allvars(j_var)%vname); call goPr
  1390. end select
  1391. end do
  1392. end do
  1393. !end if
  1394. else if (trim(allvars(j_var)%class)=='dry') then
  1395. !Sedimented indices in deposition%sed
  1396. !do i_sed=1,nsed
  1397. !gridpoints
  1398. do j = j1,j2
  1399. do i=i1,i2
  1400. select case ( trim(allvars(j_var)%vname))
  1401. case('dryoa')
  1402. dry_index=1
  1403. xmcomp=xmpom
  1404. case('drybc')
  1405. dry_index=2
  1406. xmcomp=xmbc
  1407. case ('dryso2')
  1408. dry_index=3
  1409. xmcomp=xmso2
  1410. case('dryso4')
  1411. dry_index=4
  1412. xmcomp=xmso4
  1413. case('drydust')
  1414. dry_index=5
  1415. xmcomp=xmdust
  1416. case('drydms')
  1417. dry_index=6
  1418. xmcomp=xmdms
  1419. case('dryss')
  1420. dry_index=7
  1421. xmcomp=xmnacl
  1422. case('drysoa')
  1423. dry_index=8
  1424. xmcomp=xmpom!soa
  1425. case('drynh3')
  1426. dry_index=9
  1427. xmcomp=xmnh3
  1428. case('drynh4')
  1429. dry_index=10
  1430. xmcomp=xmnh4
  1431. case('drynoy')
  1432. dry_index=11
  1433. xmcomp=1
  1434. case('dryo3')
  1435. dry_index=12
  1436. xmcomp=xmo3
  1437. case('dryno3')
  1438. xmcomp=xmno3
  1439. case('dryno2')
  1440. xmcomp=xmno2
  1441. case('dryno')
  1442. xmcomp=xmno
  1443. case DEFAULT !('default')
  1444. write(gol,'("dry xm-var missing: ",a)') trim(allvars(j_var)%vname); call goPr
  1445. end select
  1446. tempbud=0.0
  1447. !if (xx='dryoa') then
  1448. !end if
  1449. do m=1,n_indices
  1450. !exit if indices ==0
  1451. !since indices after 0 will all be also 0
  1452. if (indices(m)<=0) then
  1453. cycle
  1454. else
  1455. if (indices(m)>69) then
  1456. sedindex=-1
  1457. else
  1458. sedindex=sindex(allvars(j_var)%indices(m))
  1459. end if
  1460. !only M7 aerosol tracers (and msa/nh4/no3) are sedimented and deposited
  1461. if ( trim(allvars(j_var)%vname)=='drynoy')then
  1462. select case(allvars(j_var)%indices(m))
  1463. case(ino,ino2,ino3,ihno3,ino3_a,ihno4,ihono,ich3o2no2,ipan,iorgntr)
  1464. xmcomp=xmn
  1465. case(in2o5)
  1466. xmcomp=xmn*2.0
  1467. end select
  1468. end if
  1469. if (sedindex>0)then
  1470. tempbud=tempbud+(buddry_dat(region)%dry(i,j,indices(m)) +&
  1471. sum(deposition(region)%sed(i,j,:,sedindex))) / dxyp(j) * 1.E-03*xmcomp !kg m-2s-1 (s-1 at the time of writing)
  1472. !for others only deposition applies
  1473. else
  1474. tempbud=tempbud+buddry_dat(region)%dry(i,j,allvars(j_var)%indices(m)) / dxyp(j) * 1.E-03*xmcomp !kg m-2s-1 (s-1 at the time of writing)
  1475. end if
  1476. end if
  1477. end do
  1478. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-drydepos(region)%f2dslast(i,j,dry_index))
  1479. !drydepos(region)%f2dslast(i,j,dry_index)=tempbud
  1480. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  1481. allvars(j_var)%budgetdata(i,j,1)=tempbud
  1482. end do
  1483. end do
  1484. !end if
  1485. else if (trim(allvars(j_var)%class)=='wet') then
  1486. !gridpoints
  1487. do j = j1,j2
  1488. do i=i1,i2
  1489. select case ( trim(allvars(j_var)%vname))
  1490. case('wetoa')
  1491. wet_index=1
  1492. xmcomp=xmpom
  1493. case('wetbc')
  1494. wet_index=2
  1495. xmcomp=xmbc
  1496. case ('wetso2')
  1497. wet_index=3
  1498. xmcomp=xmso2
  1499. case('wetso4')
  1500. wet_index=4
  1501. xmcomp=xmso4
  1502. case('wetdust')
  1503. wet_index=5
  1504. xmcomp=xmdust
  1505. case('wetnoy')
  1506. !wet_index=6 !DMS
  1507. wet_index=13
  1508. xmcomp=1
  1509. case('wetss')
  1510. wet_index=7
  1511. xmcomp=xmnacl
  1512. case('wetsoa')
  1513. wet_index=8
  1514. xmcomp=xmpom!soa
  1515. case('wetnh3')
  1516. wet_index=9
  1517. xmcomp=xmnh3
  1518. case('wetnh4')
  1519. wet_index=10
  1520. xmcomp=xmnh4
  1521. case DEFAULT !('default')
  1522. write(gol,'("wetdep xm-var missing: ",a)') trim(allvars(j_var)%vname); call goPr
  1523. end select
  1524. tempbud=0.0
  1525. if ( trim(allvars(j_var)%vname)=='wetnoy')then
  1526. do m=1,n_indices
  1527. select case(allvars(j_var)%indices(m))
  1528. case(ino,ino2,ino3,ihno3,ino3_a,ihno4,ihono,ich3o2no2,ipan,iorgntr)
  1529. xmcomp=xmn
  1530. case(in2o5)
  1531. xmcomp=xmn*2.0
  1532. end select
  1533. if(allvars(j_var)%indices(m)>0 .and. allvars(j_var)%indices(m)<=ntracet)then
  1534. tempbud=tempbud+(sum(wetdep(region)%lsp(i,j,:,indices(m))) + sum(wetdep(region)%cp(i,j,:,indices(m)))) / dxyp(j) * 1.E-03*xmcomp
  1535. end if
  1536. end do
  1537. !write(gol,'("wet: ",a,i3,2E30.7e5)') trim(allvars(j_var)%vname),indices(m),sum(wetdep(region)%lsp(i,j,:,indices(m)))/ dxyp(j) * 1.E-03*xmcomp, sum(wetdep(region)%cp(i,j,:,indices(m))) / dxyp(j) * 1.E-03*xmcomp; call goPr
  1538. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1)) !kg m-2s-1 (s-1 at the time of writing)
  1539. allvars(j_var)%budgetdata(i,j,1)=tempbud
  1540. else
  1541. do m=1,n_indices
  1542. !exit if indices ==0
  1543. !since indices after 0 will all be also 0, and wetdep not defined for non-transported vars
  1544. if (indices(m)<=0.or.indices(m)>ntracet) then
  1545. cycle
  1546. else
  1547. if ( trim(allvars(j_var)%vname)=='wetnoy')then
  1548. select case(indices(m))
  1549. case(ino,ino2,ino3,ihno3,ino3_a,ihno4,ihono,ich3o2no2,ipan,iorgntr)
  1550. xmcomp=xmn
  1551. case(in2o5)
  1552. xmcomp=xmn*2.0
  1553. end select ! go through gridpoints
  1554. end if
  1555. tempbud=tempbud+(sum(wetdep(region)%lsp(i,j,:,indices(m))) + sum(wetdep(region)%cp(i,j,:,indices(m)))) / dxyp(j) * 1.E-03*xmcomp
  1556. end if
  1557. end do
  1558. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1)) !kg m-2s-1 (s-1 at the time of writing)
  1559. allvars(j_var)%budgetdata(i,j,1)=tempbud
  1560. end if
  1561. end do
  1562. end do
  1563. !end if
  1564. else if (trim(allvars(j_var)%class)=='che') then
  1565. do m=1,n_indices
  1566. !exit if indices ==0
  1567. !since indices after 0 will all be also 0
  1568. if (indices(m)<=0) then
  1569. cycle
  1570. else
  1571. ! go through gridpoints
  1572. do j = j1,j2
  1573. do i=i1,i2
  1574. do k=1,lmr
  1575. ! add emitted mass from different size ranges (i_emi)
  1576. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime! / dxyp(j)) * 1.E-03
  1577. end do
  1578. end do
  1579. end do
  1580. end if
  1581. end do
  1582. !end if
  1583. else if (trim(allvars(j_var)%class)=='chep') then
  1584. ! go through gridpoints
  1585. do j = j1,j2
  1586. do i=i1,i2
  1587. do k=1,lmr
  1588. ! density for conversion of aerosol mass densities ( ---> 1/m3 )
  1589. ! (conversion factor 1.E-03 is for g --> kg)
  1590. !volume(i1:ie,j,1:lmr) = (gph_dat(region)%data(i1:ie,j,2:lmr+1)-gph_dat(region)%data(i1:ie,j,1:lmr)) * dxyp(j)
  1591. vol = (gph_dat(region)%data(i,j,k+1)-gph_dat(region)%data(i,j,k)) * dxyp(j)
  1592. ! dtime not needed as time is already included in calculation of prod-field
  1593. ! gas-phase so4 production
  1594. if (trim(allvars(j_var)%vname)=='chegpso4')then
  1595. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+AC_diag_prod(region)%prod(i,j,k,iprod_gasso4)/ dxyp(j)
  1596. !liquid so4 production
  1597. else if (trim(allvars(j_var)%vname)=='cheaqpso4')then
  1598. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+AC_diag_prod(region)%prod(i,j,k,iprod_aqso4)/ dxyp(j)
  1599. else if (trim(allvars(j_var)%vname)=='lossch4')then
  1600. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+AC_loss(region)%prod(i,j,k,iloss_ch4)/vol
  1601. else if (trim(allvars(j_var)%vname)=='lossco')then
  1602. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+AC_loss(region)%prod(i,j,k,iloss_co)/vol
  1603. else if (trim(allvars(j_var)%vname)=='o3loss')then
  1604. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+AC_O3_lp(region)%prod(i,j,k,1) / vol
  1605. else if (trim(allvars(j_var)%vname)=='o3prod')then
  1606. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+AC_O3_lp(region)%prod(i,j,k,2) /vol
  1607. end if
  1608. end do
  1609. !if (trim(allvars(j_var)%vname)=='chepsoa')then
  1610. ! !All soa (svoc+elvoc)
  1611. ! allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+sum(AC_diag_prod(region)%prod(i,j,:,iprod_soa3dmon))/ dxyp(j)
  1612. !end if
  1613. end do
  1614. end do
  1615. if (trim(allvars(j_var)%vname)=='chepsoa')then
  1616. do j =j1,j2
  1617. do i =i1,i2
  1618. !All soa (svoc+elvoc)
  1619. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+sum(AC_diag_prod(region)%prod(i,j,:,iprod_soa3dmon))/ dxyp(j)
  1620. end do
  1621. end do
  1622. end if
  1623. !end if
  1624. else if (trim(allvars(j_var)%class)=='emi') then
  1625. !Data can be found in emis3d in emission_pom.f90, only when declaring emissions
  1626. ! which requires to write from there.
  1627. ! or in pom_emis_2/3d(region,sectors), available all the time.
  1628. !Could also use mode based index holder: nmode_end_XXX(nmod), where XXX=[so4,bc,pom,ss,dust]
  1629. !Sedimented indices in deposition%sed
  1630. do j = j1,j2
  1631. do i=i1,i2
  1632. ! add emitted mass from different size ranges (i_emi)
  1633. select case ( trim(allvars(j_var)%vname))
  1634. case('emioa')
  1635. emi_index=1
  1636. xmcomp=xmpom
  1637. case('emibc')
  1638. emi_index=2
  1639. xmcomp=xmbc
  1640. case ('emiso2')
  1641. emi_index=3
  1642. xmcomp=xmso2
  1643. case('emiso4')
  1644. emi_index=4
  1645. xmcomp=xmso4
  1646. case('emidust')
  1647. emi_index=5
  1648. xmcomp=xmdust
  1649. case('emidms')
  1650. emi_index=6
  1651. xmcomp=xmdms
  1652. case('emiss')
  1653. emi_index=7
  1654. xmcomp=xmnacl
  1655. case('emiisop')
  1656. emi_index=8
  1657. xmcomp=xmisop
  1658. case('emivoc')
  1659. emi_index=9
  1660. xmcomp=1!voc
  1661. case('eminh3')
  1662. emi_index=10
  1663. xmcomp=xmnh3
  1664. case('eminh4')
  1665. emi_index=11
  1666. xmcomp=xmnh4
  1667. case('emico')
  1668. emi_index=12
  1669. xmcomp=xmco
  1670. case('emibvoc')
  1671. emi_index=13
  1672. xmcomp=xmterp
  1673. case('eminox')
  1674. !emi_index=13
  1675. xmcomp=xmn
  1676. case('emipoa')
  1677. emi_index=1
  1678. xmcomp=xmpom
  1679. case DEFAULT
  1680. write(gol,'("emi xm-var missing: ",a)') trim(allvars(j_var)%vname); call goPr
  1681. end select
  1682. tempbud=0.0
  1683. if (trim(allvars(j_var)%vname)=='emivoc')then
  1684. do m=1,ncb5
  1685. select case(nmhc(m))
  1686. case(ipar,ich2o,ich3oh,ihcooh)
  1687. xmcomp=xmc
  1688. case(ieth,iole,iald2,imcooh,ic2h6,iethoh)
  1689. xmcomp=xmc*2.0
  1690. case(imgly,ic3h8,ic3h6,iacet)
  1691. xmcomp=xmc*3.0
  1692. end select
  1693. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,nmhc(m))) / dxyp(j) * 1.E-03*xmcomp!kg(C)m-2s-1
  1694. end do
  1695. do m=1,2
  1696. if (m==1)then
  1697. gasind=iterp
  1698. xmcomp=xmc*5*2
  1699. else
  1700. gasind=iisop
  1701. xmcomp=xmc*5.0
  1702. end if
  1703. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,gasind)) / dxyp(j) * 1.E-03*xmcomp!kg(C)m-2s-1
  1704. end do
  1705. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-emission(region)%f2dslast(i,j,emi_index))
  1706. !emission(region)%f2dslast(i,j,emi_index)=tempbud
  1707. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  1708. allvars(j_var)%budgetdata(i,j,1)=tempbud
  1709. else if (trim(allvars(j_var)%vname)=='emibvoc')then
  1710. tempbud=0.0
  1711. do m=1,2!ncb5
  1712. if (m==1)then
  1713. gasind=iterp
  1714. xmcomp=2*5*xmc!xmterp=2*cxmisop and as C: 2*5*xmc
  1715. else
  1716. gasind=iisop
  1717. xmcomp=5*xmc!xmisop as mass oc C
  1718. end if
  1719. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,gasind)) / dxyp(j) * 1.E-03*xmcomp
  1720. end do
  1721. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-emission(region)%f2dslast(i,j,emi_index))
  1722. !emission(region)%f2dslast(i,j,emi_index)=tempbud
  1723. allvars(j_var)%data2D(i,j)= 0.0!allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  1724. allvars(j_var)%budgetdata(i,j,1)=tempbud
  1725. else if (trim(allvars(j_var)%vname)=='eminox') then
  1726. tempbud=0.0
  1727. indices=allvars(j_var)%indices
  1728. do m=1,n_indices
  1729. if (indices(m)<=0)then
  1730. cycle
  1731. else
  1732. xmcomp=xmn
  1733. !write(gol,'("eminox: ",voca,i3,E20.7e1)')trim(allvars(j_var)%vname), indices(m),sum(budemi_dat(region)%emi(i,j,:,indices(m))) / dxyp(j) * 1.E-03*xmcomp; call goPr
  1734. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,indices(m))) / dxyp(j) * 1.E-03*xmcomp !kg(N) m-2s-1 (s-1 at the time of writing)
  1735. end if
  1736. end do
  1737. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  1738. allvars(j_var)%budgetdata(i,j,1)=tempbud
  1739. else
  1740. tempbud=0.0
  1741. ! add soa for emioa (emission + production)
  1742. do m=1,n_indices
  1743. !exit if indices ==0
  1744. !since indices after 0 will all be also 0
  1745. if (indices(m)<=0) then
  1746. cycle
  1747. else
  1748. ! go through gridpoints
  1749. tempbud = tempbud + sum(budemi_dat(region)%emi(i,j,:,indices(m))) / dxyp(j) * 1.E-03*xmcomp
  1750. allvars(j_var)%data2D(i,j) = allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  1751. allvars(j_var)%budgetdata(i,j,1)=tempbud
  1752. end if
  1753. end do
  1754. end if
  1755. ! add soa production to oa emission after poa is calculated.
  1756. if (allvars(j_var)%vname == 'emioa' .and. trim(allvars(j_var)%freq)=='mon') then
  1757. allvars(j_var)%data2D(i,j) = allvars(j_var)%data2D(i,j)+sum(AC_diag_prod(region)%prod(i,j,:,3))/ dxyp(j)
  1758. end if
  1759. end do
  1760. end do
  1761. !end if
  1762. ! CRESCENDO extensions !
  1763. else if (trim(allvars(j_var)%class)=='crescendo')then
  1764. if (trim(allvars(j_var)%vname)=='od5503ddust')then
  1765. cycle
  1766. else if (trim(allvars(j_var)%vname)=='od550dust')then
  1767. cycle
  1768. else if (trim(allvars(j_var)%vname)=='od550aer')then
  1769. cycle
  1770. else if (trim(allvars(j_var)%vname)=='ec550aer')then
  1771. cycle
  1772. else if (trim(allvars(j_var)%vname)=='od440aer')then
  1773. cycle
  1774. else if (trim(allvars(j_var)%vname)=='od440dust')then
  1775. cycle
  1776. else if (trim(allvars(j_var)%vname)=='od870aer')then
  1777. cycle
  1778. else if (trim(allvars(j_var)%vname)=='dmsos')then
  1779. cycle
  1780. END if
  1781. index=allvars(j_var)%indices(1)
  1782. indices=allvars(j_var)%indices(:)
  1783. if (allvars(j_var)%dims==3)then
  1784. do k=1,lmr
  1785. do j=j1,j2
  1786. do i=i1,i2
  1787. if (trim(allvars(j_var)%vname)=='ndtot')then
  1788. dens = pres3d(i,j,k) / temper_dat(region)%data(i,j,k) * xmair * 1.E-3 / (m_dat(region)%data(i,j,k) * rgas)
  1789. do m=1,7
  1790. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*(tracers(i,j,k,indices(m)))*dens
  1791. end do
  1792. else if (trim(allvars(j_var)%vname)=='emilnox')then
  1793. ! eminoc_lightning is /month so dtime/sec_month gives us per this step
  1794. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime/sec_month* eminox_lightning(region)%d3(i,j,k) / dxyp(j)
  1795. else if (trim(allvars(j_var)%vname)=='mmraerh2o_1')then
  1796. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*(h2o_mode(region,1)%d3(i,j,k))/m_dat(region)%data(i,j,k)
  1797. else if (trim(allvars(j_var)%vname)=='mmraerh2o_2')then
  1798. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*(h2o_mode(region,2)%d3(i,j,k))/m_dat(region)%data(i,j,k)
  1799. else if (trim(allvars(j_var)%vname)=='mmraerh2o_3')then
  1800. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*(h2o_mode(region,3)%d3(i,j,k))/m_dat(region)%data(i,j,k)
  1801. else if (trim(allvars(j_var)%vname)=='mmraerh2o_4')then
  1802. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*(h2o_mode(region,4)%d3(i,j,k))/m_dat(region)%data(i,j,k)
  1803. else if (trim(allvars(j_var)%vname)=='chepsoa3d')then
  1804. !All soa (svoc+elvoc)
  1805. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+AC_diag_prod(region)%prod(i,j,k,iprod_soa3dmon)/ dxyp(j)
  1806. !number concentrations (ndtot, sfndtot and sfnd100 handled separately)
  1807. else if (trim(allvars(j_var)%unit)==units(im3unit).and. .not. (trim(allvars(j_var)%vname)=='sfndtot' .or. trim(allvars(j_var)%vname)=='sfnd100' .or. trim(allvars(j_var)%vname)=='ndtot' ) ) then
  1808. dens = pres3d(i,j,k) / temper_dat(region)%data(i,j,k) * xmair * 1.E-3 / (m_dat(region)%data(i,j,k) * rgas)
  1809. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,index)*dens
  1810. else if (trim(allvars(j_var)%unit)==units(im3unit)) then
  1811. !nd? output processed here
  1812. dens = pres3d(i,j,k) / temper_dat(region)%data(i,j,k) * xmair * 1.E-3 / (m_dat(region)%data(i,j,k) * rgas)
  1813. !1e-6 for m3->cm-3
  1814. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,index)*dens
  1815. else if (index>0 .and. index<=ntracet) then
  1816. if (trim(allvars(j_var)%unit)==units(ivmrunit)) then
  1817. xmcomp=allvars(j_var)%xmgas
  1818. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,index)*xmair/xmcomp/m_dat(region)%data(i,j,k) !kmole kmole-1
  1819. else if (trim(allvars(j_var)%unit)==units(immrunit)) then
  1820. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,index)/m_dat(region)%data(i,j,k)!kg kg-1
  1821. end if
  1822. else if (index>ntracet)then ! than non transported (tracers_c=> chem_dat(region)%rm)
  1823. if (trim(allvars(j_var)%unit)==units(ivmrunit)) then
  1824. xmcomp=allvars(j_var)%xmgas
  1825. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers_c(i,j,k,index)*xmair/xmcomp/m_dat(region)%data(i,j,k)
  1826. else if (trim(allvars(j_var)%unit)==units(immrunit)) then
  1827. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers_c(i,j,k,index)/m_dat(region)%data(i,j,k)!kg kg-1
  1828. else
  1829. write(gol,'("user_output_aerchemmip: no case for output ",a)') trim(allvars(j_var)%vname) ; call goErr
  1830. TRACEBACK
  1831. status=1; return
  1832. end if
  1833. else
  1834. write(gol,*) 'user_output_aerchemmip: missing accumulation for CRESCENDO 2D variable ',allvars(j_var)%vname ; call goErr
  1835. TRACEBACK
  1836. status=1; return
  1837. end if
  1838. end do
  1839. end do
  1840. end do
  1841. else !2D vars
  1842. do j=j1,j2
  1843. do i=i1,i2
  1844. tempbud=0.0
  1845. if (trim(allvars(j_var)%vname)=='sfmmrss')then
  1846. tempbud=0.0
  1847. do m=1,size(allvars(j_var)%indices)
  1848. index=allvars(j_var)%indices(m)
  1849. if (index>0)then
  1850. tempbud=tempbud+tracers(i,j,1,index)/m_dat(region)%data(i,j,1)!kg kg-1
  1851. end if
  1852. end do
  1853. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!*den
  1854. allvars(j_var)%data2D(i,j)= tempbud
  1855. else if (trim(allvars(j_var)%vname)=='co2mass')then
  1856. !NOTAVAILABLE
  1857. do k=1,lmr
  1858. !mass of CO2, sum over levels
  1859. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers_c(i,j,k,iaco2))!/m_dat(region)%data(i,j,k)
  1860. end do
  1861. else if (trim(allvars(j_var)%vname)=='chepsoa2d')then
  1862. !All soa (svoc+elvoc)
  1863. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+sum(AC_diag_prod(region)%prod(i,j,:,iprod_soa2dhour))/ dxyp(j)
  1864. allvars(j_var)%data2D(i,j)= sum(AC_diag_prod(region)%prod(i,j,:,iprod_soa2dhour))/ dxyp(j)/dtime !
  1865. !!! FOLLOWING CRESCENDO VARS: Instantaneous, no accumulation
  1866. else if (trim(allvars(j_var)%vname)=='sfmmrso4')then
  1867. !!! Instantaneous, no accumulation
  1868. tempbud=0.0
  1869. do m=1,size(allvars(j_var)%indices)
  1870. index=allvars(j_var)%indices(m)
  1871. if (index>0)then
  1872. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!*den
  1873. tempbud=tempbud+(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!kg kg-1
  1874. end if
  1875. end do
  1876. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!*den
  1877. allvars(j_var)%data2D(i,j)= tempbud
  1878. else if (trim(allvars(j_var)%vname)=='sfmmrbc')then
  1879. !!! Instantaneous, no accumulation
  1880. tempbud=0.0
  1881. do m=1,size(allvars(j_var)%indices)
  1882. index=allvars(j_var)%indices(m)
  1883. if (index>0)then
  1884. tempbud=tempbud+(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!kg kg-1
  1885. end if
  1886. end do
  1887. allvars(j_var)%data2D(i,j)=tempbud
  1888. else if (trim(allvars(j_var)%vname)=='sfmmrsoa')then
  1889. !!! Instantaneous, no accumulation
  1890. tempbud=0.0
  1891. do m=1,size(allvars(j_var)%indices)
  1892. index=allvars(j_var)%indices(m)
  1893. if (index>0)then
  1894. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!*den
  1895. tempbud=tempbud+(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!kg kg-1
  1896. end if
  1897. end do
  1898. allvars(j_var)%data2D(i,j)= tempbud
  1899. else if (trim(allvars(j_var)%vname)=='sfmmroa')then
  1900. !!! Instantaneous, no accumulation
  1901. tempbud=0.0
  1902. do m=1,size(allvars(j_var)%indices)
  1903. index=allvars(j_var)%indices(m)
  1904. if (index>0)then
  1905. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!*den
  1906. tempbud=tempbud+(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!kg kg-1
  1907. end if
  1908. end do
  1909. allvars(j_var)%data2D(i,j)= tempbud
  1910. else if (trim(allvars(j_var)%vname)=='sfisop')then
  1911. !!! Instantaneous, no accumulation
  1912. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,1,iisop)*xmair/xmisop/m_dat(region)%data(i,j,1)
  1913. allvars(j_var)%data2D(i,j)=tracers(i,j,1,iisop)*xmair/xmisop/m_dat(region)%data(i,j,1) !kilomole kilomole-1
  1914. else if (trim(allvars(j_var)%vname)=='sfdms')then
  1915. !!! Instantaneous, no accumulation
  1916. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,1,idms)*xmair/xmdms/m_dat(region)%data(i,j,1)
  1917. allvars(j_var)%data2D(i,j)= tracers(i,j,1,idms)*xmair/xmdms/m_dat(region)%data(i,j,1) !kmole kmole-1
  1918. else if (trim(allvars(j_var)%vname)=='sfmono')then
  1919. !!! Instantaneous, no accumulation
  1920. !tracers_c(i,j,k,index)*xmair/xmgas/m_dat(region)%data(i,j,k)
  1921. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,1,iterp)*xmair/xmterp/m_dat(region)%data(i,j,1)
  1922. allvars(j_var)%data2D(i,j)= tracers(i,j,1,iterp)*xmair/xmterp/m_dat(region)%data(i,j,1) !kmole kmole-1
  1923. !!! no accumulation
  1924. else if (trim(allvars(j_var)%vname)=='sfmmrdustabv1')then
  1925. !!! Instantaneous, no accumulation
  1926. allvars(j_var)%data2D(i,j)= (&
  1927. (1.0-mode_fraction(rw_mode(1,3)%d3(i,j,1),1000e-9,3))*tracers(i,j,1,iduacs)+&
  1928. (1.0-mode_fraction(rw_mode(1,4)%d3(i,j,1),1000e-9,4))*tracers(i,j,1,iducos)+&
  1929. (1.0-mode_fraction(rw_mode(1,6)%d3(i,j,1),1000e-9,6))*tracers(i,j,1,iduaci)+&
  1930. (1.0-mode_fraction(rw_mode(1,7)%d3(i,j,1),1000e-9,7))*tracers(i,j,1,iducoi))&
  1931. /m_dat(region)%data(i,j,1)!kg kg-1
  1932. else if (trim(allvars(j_var)%vname)=='sfmmrdustabv10')then
  1933. !!! Instantaneous, no accumulation
  1934. allvars(j_var)%data2D(i,j)=(&
  1935. (1.0-mode_fraction(rw_mode(1,3)%d3(i,j,1),10000e-9,3))*tracers(i,j,1,iduacs)+&
  1936. (1.0-mode_fraction(rw_mode(1,4)%d3(i,j,1),10000e-9,4))*tracers(i,j,1,iducos)+&
  1937. (1.0-mode_fraction(rw_mode(1,6)%d3(i,j,1),10000e-9,6))*tracers(i,j,1,iduaci)+&
  1938. (1.0-mode_fraction(rw_mode(1,7)%d3(i,j,1),10000e-9,7))*tracers(i,j,1,iducoi))&
  1939. /m_dat(region)%data(i,j,1)!kg kg-1
  1940. else if (trim(allvars(j_var)%vname)=='sfmmrdustbel1')then
  1941. !!! Instantaneous, no accumulation
  1942. allvars(j_var)%data2D(i,j)= (&
  1943. (mode_fraction(rw_mode(1,3)%d3(i,j,1),1000e-9,3))*tracers(i,j,1,iduacs)+&
  1944. (mode_fraction(rw_mode(1,4)%d3(i,j,1),1000e-9,4))*tracers(i,j,1,iducos)+&
  1945. (mode_fraction(rw_mode(1,6)%d3(i,j,1),1000e-9,6))*tracers(i,j,1,iduaci)+&
  1946. (mode_fraction(rw_mode(1,7)%d3(i,j,1),1000e-9,7))*tracers(i,j,1,iducoi))&
  1947. /m_dat(region)%data(i,j,1)!kg kg-1
  1948. else if (trim(allvars(j_var)%vname)=='uas')then
  1949. ! distance of single gridbox
  1950. yres = dy/yref(1)
  1951. xres = dx/xref(1)
  1952. lat = ybeg(1) + 0.5 * yres + yres * (j-1)
  1953. dxx = ae * xres * gtor * cos(lat*gtor)
  1954. uwind=dxx*(pu_dat(1)%data(i,j,1) + pu_dat(1)%data(i-1,j,1))*0.5 / m_dat(1)%data(i,j,1)
  1955. allvars(j_var)%data2D(i,j)= uwind
  1956. else if (trim(allvars(j_var)%vname)=='vas')then
  1957. yres = dy/yref(1)
  1958. dyy = ae * yres * gtor
  1959. vwind= dyy *(pv_dat(1)%data(i,j,1) + pv_dat(1)%data(i,j+1,1))*0.5 / m_dat(1)%data(i,j,1)
  1960. allvars(j_var)%data2D(i,j)= +vwind
  1961. !!!6hr output ending here
  1962. else if (trim(allvars(j_var)%vname)=='ps' .and. trim(allvars(j_var)%freq) =='1hr')then
  1963. allvars(j_var)%data2D(i,j)=sp_dat(1)%data(i,j,1)!Pa
  1964. else if (trim(allvars(j_var)%vname)=='sfno'.and. trim(allvars(j_var)%freq) =='1hr')then
  1965. allvars(j_var)%data2D(i,j)=tracers_c(i,j,1,ino)*xmair/xmno/m_dat(region)%data(i,j,1)!mole mole-1
  1966. else if (trim(allvars(j_var)%vname)=='sfnh3'.and. trim(allvars(j_var)%freq) =='1hr')then
  1967. allvars(j_var)%data2D(i,j)= tracers(i,j,1,inh3)*xmair/xmnh3/m_dat(region)%data(i,j,1)!mole mole-1
  1968. else if (trim(allvars(j_var)%vname)=='sfhno3'.and. trim(allvars(j_var)%freq) =='1hr')then
  1969. allvars(j_var)%data2D(i,j)= tracers(i,j,1,ihno3)*xmair/xmhno3/m_dat(region)%data(i,j,1)!mole mole-1
  1970. else if (trim(allvars(j_var)%vname)=='tas'.and. trim(allvars(j_var)%freq) =='1hr')then
  1971. allvars(j_var)%data2D(i,j)= temper_dat(1)%data(i,j,1)!K
  1972. else if (trim(allvars(j_var)%vname)=='sfo3'.and. trim(allvars(j_var)%freq) =='1hr')then
  1973. allvars(j_var)%data2D(i,j)= tracers(i,j,1,io3)*xmair/xmo3/m_dat(region)%data(i,j,1)!mole mole-1
  1974. !!$ else if (trim(allvars(j_var)%vname)=='sfpm25'.and. trim(allvars(j_var)%freq) =='1hr')then
  1975. !!$ pm_sizelimit=2.5!micrometers
  1976. !!$ call PMx_Integrate_0d(region,i,j,1,pm_sizelimit,temp,status)!kgm-3
  1977. !!$ allvars(j_var)%data2D(i,j)= temp/dens/m_dat(region)%data(i,j,1)!kg kg-1
  1978. else if (trim(allvars(j_var)%vname)=='sfno2'.and. trim(allvars(j_var)%freq) =='1hr')then
  1979. allvars(j_var)%data2D(i,j)=tracers_c(i,j,1,ino2)*xmair/xmno2/m_dat(region)%data(i,j,1)
  1980. else if (trim(allvars(j_var)%vname)=='sfndtot'.and. trim(allvars(j_var)%freq) =='6hr')then
  1981. tempbud=0.0
  1982. dens = pres3d(i,j,1) / temper_dat(region)%data(i,j,1) * xmair * 1.E-3 / (m_dat(region)%data(i,j,1) * rgas)
  1983. do m=1,7
  1984. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,indices(m)))*dens
  1985. tempbud=tempbud+(tracers(i,j,1,indices(m)))*dens
  1986. end do
  1987. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,indices(m)))*dens
  1988. allvars(j_var)%data2D(i,j)=tempbud
  1989. else if (trim(allvars(j_var)%vname)=='sfnd100'.and. trim(allvars(j_var)%freq) =='6hr')then
  1990. tempbud=0.0
  1991. dens = pres3d(i,j,1) / temper_dat(region)%data(i,j,1) * xmair * 1.E-3 / (m_dat(region)%data(i,j,1) * rgas)
  1992. do m=1,7
  1993. tempbud=tempbud+(1.0-mode_fraction(rw_mode(1,m)%d3(i,j,1),100e-9,m))*(tracers(i,j,1,indices(m)))*dens
  1994. end do
  1995. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(temp)
  1996. allvars(j_var)%data2D(i,j)= tempbud
  1997. !! daily ouptu
  1998. else if (trim(allvars(j_var)%vname)=='sfmmrdust')then
  1999. tempbud=0.0
  2000. do m=1,size(allvars(j_var)%indices)
  2001. index=allvars(j_var)%indices(m)
  2002. if (index>0)then
  2003. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!kg kg-1
  2004. !tempbud=tempbud+(tracers(i,j,1,index))/m_dat(region)%data(i,j,1)!*den
  2005. end if
  2006. end do
  2007. else if (trim(allvars(j_var)%vname)=='depdustabv1')then
  2008. tempbud=0.0
  2009. xmcomp=xmdust
  2010. !modes_dust=(/3,4,6,7/)
  2011. do m=1,size(allvars(j_var)%indices)
  2012. !exit if indices ==0
  2013. !since indices after 0 will all be also 0
  2014. if (allvars(j_var)%indices(m)>0) then
  2015. if (allvars(j_var)%indices(m)>69)then
  2016. sedindex=-1
  2017. else
  2018. sedindex=sindex(allvars(j_var)%indices(m))
  2019. end if
  2020. if (sedindex>0)then
  2021. do k=1,lmr
  2022. tempbud=tempbud+( &
  2023. (deposition(region)%sed(i,j,k,sedindex)*(1.0-mode_fraction(rw_mode(1,modes_dust(m))%d3(i,j,k),1000e-9,modes_dust(m))))) / dxyp(j) * 1.E-03*xmcomp
  2024. end do
  2025. end if
  2026. end if
  2027. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud)
  2028. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2029. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2030. end do
  2031. else if (trim(allvars(j_var)%vname)=='depdustabv10')then
  2032. tempbud=0.0
  2033. xmcomp=xmdust
  2034. !modes_dust=(/3,4,6,7/)
  2035. do m=1,size(allvars(j_var)%indices)
  2036. !exit if indices ==0
  2037. !since indices after 0 will all be also 0
  2038. if (allvars(j_var)%indices(m)>0) then
  2039. if (allvars(j_var)%indices(m)>69)then
  2040. sedindex=-1
  2041. else
  2042. sedindex=sindex(allvars(j_var)%indices(m))
  2043. end if
  2044. if (sedindex>0)then
  2045. do k=1,lmr
  2046. tempbud=tempbud+( &
  2047. (deposition(region)%sed(i,j,k,sedindex)*(1.0-mode_fraction(rw_mode(1,modes_dust(m))%d3(i,j,k),10000e-9,modes_dust(m))))) / dxyp(j) * 1.E-03*xmcomp
  2048. end do
  2049. end if
  2050. end if
  2051. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud)
  2052. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2053. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2054. end do
  2055. else if (trim(allvars(j_var)%vname)=='depdustbel1')then
  2056. tempbud=0.0
  2057. xmcomp=xmdust
  2058. modes_dust=(/3,4,6,7/)
  2059. do m=1,size(allvars(j_var)%indices)
  2060. !exit if indices ==0
  2061. !since indices after 0 will all be also 0
  2062. if (allvars(j_var)%indices(m)>0) then
  2063. if (allvars(j_var)%indices(m)>69)then
  2064. sedindex=-1
  2065. else
  2066. sedindex=sindex(allvars(j_var)%indices(m))
  2067. end if
  2068. if (sedindex>0)then
  2069. do k=1,lmr
  2070. tempbud=tempbud+( &
  2071. (deposition(region)%sed(i,j,k,sedindex)*(mode_fraction(rw_mode(1,modes_dust(m))%d3(i,j,k),1000e-9,modes_dust(m))))) / dxyp(j) * 1.E-03*xmcomp
  2072. end do
  2073. end if
  2074. end if
  2075. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud)
  2076. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2077. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2078. end do
  2079. else if (trim(allvars(j_var)%vname)=='sfcWind')then
  2080. yres = dy/yref(1)
  2081. xres = dx/xref(1)
  2082. lat = ybeg(1) + 0.5 * yres + yres * (j-1)
  2083. dxx = ae * xres * gtor * cos(lat*gtor)
  2084. dyy = ae * yres * gtor
  2085. vwind= dyy *(pv_dat(1)%data(i,j,1) + pv_dat(1)%data(i,j+1,1))*0.5 / m_dat(1)%data(i,j,1)
  2086. uwind=dxx*(pu_dat(1)%data(i,j,1) + pu_dat(1)%data(i-1,j,1))*0.5 / m_dat(1)%data(i,j,1)
  2087. meanwind=(uwind**2+vwind**2)**(1./2.)
  2088. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*meanwind
  2089. else if (trim(allvars(j_var)%vname)=='sfndtot')then
  2090. tempbud=0.0
  2091. dens = pres3d(i,j,1) / temper_dat(region)%data(i,j,1) * xmair * 1.E-3 / (m_dat(region)%data(i,j,1) * rgas)
  2092. do m=1,7
  2093. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,indices(m)))*dens
  2094. tempbud=tempbud+(tracers(i,j,1,indices(m)))*dens
  2095. end do
  2096. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tracers(i,j,1,indices(m)))*dens
  2097. allvars(j_var)%data2D(i,j)=tempbud
  2098. else if (trim(allvars(j_var)%vname)=='sfnd100')then
  2099. tempbud=0.0
  2100. dens = pres3d(i,j,1) / temper_dat(region)%data(i,j,1) * xmair * 1.E-3 / (m_dat(region)%data(i,j,1) * rgas)
  2101. do m=1,7
  2102. tempbud=tempbud+(1.0-mode_fraction(rw_mode(1,m)%d3(i,j,1),100e-9,m))*(tracers(i,j,1,indices(m)))*dens
  2103. end do
  2104. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(temp)
  2105. allvars(j_var)%data2D(i,j)= tempbud
  2106. else if (trim(allvars(j_var)%vname)=='sfsh')then
  2107. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*humid_dat(1)%data(i,j,1)
  2108. else if (trim(allvars(j_var)%vname)=='sfmmraerh2o_1')then
  2109. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*(h2o_mode(region,1)%d3(i,j,1))/m_dat(region)%data(i,j,1)!kg kg-1
  2110. else if (trim(allvars(j_var)%vname)=='sfmmraerh2o_2')then
  2111. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*(h2o_mode(region,2)%d3(i,j,1))/m_dat(region)%data(i,j,1)!kg kg-1
  2112. else if (trim(allvars(j_var)%vname)=='sfmmraerh2o_3')then
  2113. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*(h2o_mode(region,3)%d3(i,j,1))/m_dat(region)%data(i,j,1)!kg kg-1
  2114. else if (trim(allvars(j_var)%vname)=='sfmmraerh2o_4')then
  2115. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*(h2o_mode(region,4)%d3(i,j,1))/m_dat(region)%data(i,j,1)!kg kg-1
  2116. else if (trim(allvars(j_var)%vname)=='tas')then
  2117. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*temper_dat(1)%data(i,j,1)!K
  2118. else if (trim(allvars(j_var)%vname)=='sfo3')then
  2119. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,1,io3)*xmair/xmo3/m_dat(region)%data(i,j,1)!mole mole-1
  2120. !!$ else if (trim(allvars(j_var)%vname)=='sfpm25')then
  2121. !!$ pm_sizelimit=2.5!micrometers
  2122. !!$ call PMx_Integrate_0d(region,i,j,1,pm_sizelimit,temp,status)!kg
  2123. !!$ allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j) + dtime*temp/m_dat(region)%data(i,j,1)/dens!kg kg-1
  2124. else if (trim(allvars(j_var)%vname)=='sfno2')then
  2125. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j) + dtime*tracers_c(i,j,1,ino2)*xmair/xmno2/m_dat(region)%data(i,j,1)
  2126. else if (trim(allvars(j_var)%vname)=='wetdms' .or.&
  2127. trim(allvars(j_var)%vname)=='wetno3' .or.&
  2128. trim(allvars(j_var)%vname)=='wetnh4' .or.&
  2129. trim(allvars(j_var)%vname)=='wethno3' .or.&
  2130. trim(allvars(j_var)%vname)=='wetdust' ) then
  2131. ! Wet index not used for CRESCENDO vars
  2132. ! Changed to own budget variable to fix budget calculation on the
  2133. ! variable holder in allvars(jvar). This way you can use the same var
  2134. ! in more than one time means (hr, daily, monthly)
  2135. select case ( trim(allvars(j_var)%vname))
  2136. case('wetdms')
  2137. !wet_index=6
  2138. xmcomp=xmdms
  2139. case('wetno3')
  2140. !wet_index=11
  2141. xmcomp=xmno3
  2142. case('wethno3')
  2143. !wet_index=12
  2144. xmcomp=xmhno3
  2145. case('wetnh4')
  2146. !wet_index=10
  2147. xmcomp=xmnh4
  2148. case('wetdust')
  2149. !wet_index=5
  2150. xmcomp=xmdust
  2151. case DEFAULT
  2152. write(gol,'("CRESCENDO wetdep xm-var missing: ",a)') trim(allvars(j_var)%vname); call goPr
  2153. end select
  2154. tempbud=0.0
  2155. do m=1,n_indices
  2156. !exit if indices ==0
  2157. !since indices after 0 will all be also 0
  2158. if (allvars(j_var)%indices(m)<70)then
  2159. if (allvars(j_var)%indices(m)<=0) then
  2160. cycle
  2161. else
  2162. ! go through gridpoints
  2163. tempbud=tempbud+(sum(wetdep(region)%lsp(i,j,:,indices(m))) + sum(wetdep(region)%cp(i,j,:,indices(m)))) / dxyp(j) * 1.E-03*xmcomp !kg m-2s-1 (s-1 at the time of writing)
  2164. end if
  2165. end if
  2166. end do
  2167. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-wetdepos(region)%f2dslast(i,j,wet_index))
  2168. !wetdepos(region)%f2dslast(i,j,wet_index)=tempbud
  2169. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2170. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2171. else if (trim(allvars(j_var)%vname)=='seddust')then
  2172. tempbud=0.0
  2173. xmcomp=xmdust
  2174. do m=1,n_indices
  2175. !exit if indices ==0
  2176. !since indices after 0 will all be also 0
  2177. if (indices(m)<=0) then
  2178. cycle
  2179. else
  2180. if (allvars(j_var)%indices(m)>69)then
  2181. sedindex=-1
  2182. else
  2183. sedindex=sindex(allvars(j_var)%indices(m))
  2184. end if
  2185. if (sedindex>0)then
  2186. tempbud=tempbud+( &
  2187. sum(deposition(region)%sed(i,j,:,sedindex))) / dxyp(j) * 1.E-03*xmcomp !kg m-2s-1 (s-1 at the time of writing)
  2188. end if
  2189. end if
  2190. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud)
  2191. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2192. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2193. end do
  2194. else if (trim(allvars(j_var)%vname)=='drydms' .or.&
  2195. trim(allvars(j_var)%vname)=='dryno3' .or.&
  2196. trim(allvars(j_var)%vname)=='drynh4' .or.&
  2197. trim(allvars(j_var)%vname)=='dryhno3' .or.&
  2198. trim(allvars(j_var)%vname)=='dryno2' .or.&
  2199. trim(allvars(j_var)%vname)=='dryno' .or.&
  2200. trim(allvars(j_var)%vname)=='drypan' .or.&
  2201. trim(allvars(j_var)%vname)=='drydust' &
  2202. ) then
  2203. ! Dry index not used for CRESCENDO vars
  2204. ! Changed to own budget variable to fix budget calculation on the
  2205. ! variable holder in allvars(jvar). This way you can use the same var
  2206. ! in more than one time means (hr, daily, monthly)
  2207. select case ( trim(allvars(j_var)%vname))
  2208. case('drynh4')
  2209. !dry_index=10
  2210. xmcomp=xmnh4
  2211. case('dryno3')
  2212. !dry_index=13
  2213. xmcomp=xmno3
  2214. case('drydms')
  2215. !dry_index=6
  2216. xmcomp=xmdms
  2217. case('dryhno3')
  2218. !dry_index=14
  2219. xmcomp=xmhno3
  2220. case('dryno2')
  2221. !dry_index=15
  2222. xmcomp=xmno2
  2223. case('dryno')
  2224. !dry_index=16
  2225. xmcomp=xmno
  2226. case('drypan')
  2227. !dry_index=17
  2228. xmcomp=xmpan
  2229. case('drydust')
  2230. !dry_index=5
  2231. xmcomp=xmdust
  2232. case DEFAULT
  2233. write(gol,'("CRESCENDO drydep xm-var missing: ",a)') trim(allvars(j_var)%vname); call goPr
  2234. end select
  2235. tempbud=0.0
  2236. do m=1,n_indices
  2237. !exit if indices ==0
  2238. !since indices after 0 will all be also 0
  2239. if (indices(m)<=0) then
  2240. cycle
  2241. else
  2242. if (allvars(j_var)%indices(m)>69)then
  2243. sedindex=-1
  2244. else
  2245. sedindex=sindex(allvars(j_var)%indices(m))
  2246. end if
  2247. !only M7 aerosol tracers (and msa/nh4/no3) are sedimented and deposited
  2248. if (sedindex>0)then
  2249. tempbud=tempbud+(buddry_dat(region)%dry(i,j,indices(m)) +&
  2250. sum(deposition(region)%sed(i,j,:,sedindex))) / dxyp(j) * 1.E-03*xmcomp !kg m-2s-1 (s-1 at the time of writing)
  2251. else
  2252. tempbud=tempbud+buddry_dat(region)%dry(i,j,indices(m)) / dxyp(j) * 1.E-03*xmcomp !kg m-2s-1 (s-1 at the time of writing)
  2253. end if
  2254. end if
  2255. end do
  2256. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-drydepos(region)%f2dslast(i,j,dry_index))
  2257. !drydepos(region)%f2dslast(i,j,dry_index)=tempbud
  2258. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2259. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2260. else if (trim(allvars(j_var)%vname)=='emioa')then
  2261. emi_index=1
  2262. xmcomp=xmpom
  2263. tempbud=0.0
  2264. do m=1,n_indices
  2265. !exit if indices ==0
  2266. !since indices after 0 will all be also 0
  2267. if (indices(m)<=0) then
  2268. cycle
  2269. else
  2270. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,indices(m))) / dxyp(j) * 1.E-03*xmcomp !kg m-2s-1 (s-1 at the time of writing)
  2271. !OLDWAY which is not in use for CRESCENDO vars:
  2272. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-emission(region)%f2dslast(i,j,emi_index))
  2273. !emission(region)%f2dslast(i,j,emi_index)=tempbud
  2274. end if
  2275. end do
  2276. ! emioa is requested as emi+chepsoa so add soa production
  2277. !if (trim(allvars(j_var)%freq)=='mon')then
  2278. ! tempbud= tempbud + AC_diag_prod(region)%prod(i,j,k,3)/ dxyp(j) !kg m-2s-1 (s-1 at the time of writing)
  2279. !else if (trim(allvars(j_var)%freq)=='6hr')then
  2280. ! tempbud= tempbud + AC_diag_prod(region)%prod(i,j,k,4)/ dxyp(j) !kg m-2s-1 (s-1 at the time of writing)
  2281. !else
  2282. ! write(gol,'("Uknown output frequency for production of soa in calculation of : ",a)')trim(allvars(j_var)%freq); call goErr
  2283. ! TRACEBACK
  2284. ! status=1; return
  2285. !end if
  2286. if (trim(allvars(j_var)%freq)=='6hr'.or.trim(allvars(j_var)%freq)=='1hr')then
  2287. allvars(j_var)%data2D(i,j)= (tempbud-allvars(j_var)%budgetdata(i,j,1))/dtime!timerange for instantaneous data is half of dynamical timestep /dtime
  2288. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2289. else if (trim(allvars(j_var)%freq)=='mon'.or.trim(allvars(j_var)%freq)=='day')then
  2290. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+tempbud-allvars(j_var)%budgetdata(i,j,1)
  2291. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2292. else
  2293. write(gol,'("Uknown output frequency: ",a)')trim(allvars(j_var)%vname); call goErr
  2294. TRACEBACK
  2295. status=1; return
  2296. end if
  2297. else if (trim(allvars(j_var)%vname)=='emiisop')then
  2298. tempbud=0.0
  2299. gasind=iisop
  2300. xmcomp=xmisop
  2301. emi_index=8
  2302. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,gasind)) / dxyp(j) * 1.E-03*xmcomp !kg m-2s-1 (s-1 at the time of writing)
  2303. if (trim(allvars(j_var)%freq)=='6hr'.or.trim(allvars(j_var)%freq)=='1hr')then
  2304. allvars(j_var)%data2D(i,j)= (tempbud-allvars(j_var)%budgetdata(i,j,1))/dtime!timerange for instantaneous data is half of dynamical timestep /dtime! instantaneous values -> /dtime
  2305. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2306. allvars(j_var)%budgetdata(i,j,1)=tempbud !kg m-2s-1 (s-1 at the time of writing)
  2307. else if (trim(allvars(j_var)%freq)=='mon'.or.trim(allvars(j_var)%freq)=='day')then
  2308. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j) + (tempbud-allvars(j_var)%budgetdata(i,j,1))
  2309. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2310. allvars(j_var)%budgetdata(i,j,1)=tempbud !kg m-2s-1 (s-1 at the time of writing)
  2311. else
  2312. write(gol,'("Uknown output frequency: ",a)')trim(allvars(j_var)%vname); call goErr
  2313. TRACEBACK
  2314. status=1; return
  2315. end if
  2316. !allvars(j_var)%data2D(i,j)= tempbud-allvars(j_var)%budgetdata(i,j,1)
  2317. !allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(tempbud-allvars(j_var)%budgetdata(i,j,1))
  2318. !allvars(j_var)%budgetdata(i,j,1)=tempbud
  2319. else if (trim(allvars(j_var)%vname)=='emimono')then
  2320. tempbud=0.0
  2321. gasind=iterp
  2322. xmcomp=xmterp
  2323. emi_index=13
  2324. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,gasind)) / dxyp(j) * 1.E-03*xmcomp
  2325. if (trim(allvars(j_var)%freq)=='6hr'.or.trim(allvars(j_var)%freq)=='1hr')then
  2326. !Instantaneous values requested
  2327. allvars(j_var)%data2D(i,j)= (tempbud-allvars(j_var)%budgetdata(i,j,1))/dtime!timerange for instantaneous data is half of dynamical timestep /dtime! instantaneous values -> /dtime : kgm-2s-1
  2328. allvars(j_var)%budgetdata(i,j,1)=tempbud !kg m-2s-1 (s-1 at the time of writing)
  2329. else if (trim(allvars(j_var)%freq)=='mon'.or.trim(allvars(j_var)%freq)=='day')then
  2330. !mean values
  2331. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j) + (tempbud-allvars(j_var)%budgetdata(i,j,1))
  2332. allvars(j_var)%budgetdata(i,j,1)=tempbud !kg m-2s-1 (s-1 at the time of writing)
  2333. else
  2334. write(gol,'("Uknown output frequency: ",a)')trim(allvars(j_var)%vname); call goErr
  2335. TRACEBACK
  2336. status=1; return
  2337. end if
  2338. else if (trim(allvars(j_var)%vname)=='emidms')then
  2339. tempbud=0.0
  2340. gasind=idms
  2341. emi_index=6
  2342. xmcomp=xmdms
  2343. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,gasind)) / dxyp(j) * 1.E-03*xmcomp
  2344. if (trim(allvars(j_var)%freq)=='6hr')then
  2345. allvars(j_var)%data2D(i,j)= (tempbud-allvars(j_var)%budgetdata(i,j,1))/dtime!timerange for instantaneous data is half of dynamical timestep /dtime
  2346. allvars(j_var)%budgetdata(i,j,1)=tempbud !kg m-2s-1 (s-1 at the time of writing)
  2347. else
  2348. write(gol,'("CRESCENDO output frequency not implemented: ",a)')trim(allvars(j_var)%vname); call goErr
  2349. TRACEBACK
  2350. status=1; return
  2351. end if
  2352. else if (trim(allvars(j_var)%vname)=='emiss')then
  2353. emi_index=7
  2354. xmcomp=xmnacl
  2355. do m=1,n_indices
  2356. !exit if indices ==0
  2357. !since indices after 0 will all be also 0
  2358. if (indices(m)<=0) then
  2359. cycle
  2360. else
  2361. ! go through gridpoints
  2362. tempbud=tempbud+ sum(budemi_dat(region)%emi(i,j,:,indices(m))) / dxyp(j) * 1.E-03*xmcomp
  2363. end if
  2364. end do
  2365. if (trim(allvars(j_var)%freq)=='6hr')then
  2366. allvars(j_var)%data2D(i,j)= (tempbud-allvars(j_var)%budgetdata(i,j,1))/dtime!timerange for instantaneous data is half of dynamical timestep /dtime !kg m-2s-1 (s-1 at the time of writing)
  2367. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2368. else if (trim(allvars(j_var)%freq)=='mon'.or.trim(allvars(j_var)%freq)=='day')then
  2369. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j) + (tempbud-allvars(j_var)%budgetdata(i,j,1))*dtime
  2370. allvars(j_var)%budgetdata(i,j,1)=tempbud
  2371. end if
  2372. else if (trim(allvars(j_var)%unit)=='cm-3') then
  2373. dens = pres3d(i,j,1) / temper_dat(region)%data(i,j,1) * xmair * 1.E-3 / (m_dat(region)%data(i,j,1) * rgas)
  2374. !1e-6 for m3->cm-3
  2375. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,1,index)*dens*1e-6
  2376. else if (index>0 .and. index<=ntracet) then
  2377. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,1,index)/m_dat(region)%data(i,j,1)!kg kg-1
  2378. else if (index>ntracet) then ! than non transported (tracers_c=> chem_dat(region)%rm)
  2379. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers_c(i,j,1,index)/m_dat(region)%data(i,j,1)!kg kg-1
  2380. else
  2381. write(gol,*) 'user_output_aerchemmip: missing accumulation for CRESCENDO 3D variable ',allvars(j_var)%vname ; call goErr
  2382. TRACEBACK
  2383. status=1; return
  2384. end if
  2385. end do
  2386. end do
  2387. end if
  2388. !end if
  2389. else if (trim(allvars(j_var)%class)=='mmr')then
  2390. do k=1,lmr
  2391. do j=j1,j2
  2392. do i=i1,i2
  2393. !dens = pres3d(i,j,k) / temper_dat(region)%data(i,j,k) * xmair * 1.E-3 / (m_dat(region)%data(i,j,k) * rgas)
  2394. !do all mode-specific tracers for given compound
  2395. dens = pres3d(i,j,k) / temper_dat(region)%data(i,j,k) * xmair * 1.E-3 / (m_dat(region)%data(i,j,k) * rgas)
  2396. do imode=1,size(allvars(j_var)%indices)
  2397. index=allvars(j_var)%indices(imode)
  2398. ! first variables that that are not tracers (transported or non-transported)
  2399. if (index<=0) then
  2400. if (trim(allvars(j_var)%vname)=='mmrpm2p5')then
  2401. pm_sizelimit=2.5!micrometers
  2402. !call PMx_Integrate_3d(region,pm_sizelimit,temp_pm,status)
  2403. CALL pmx_integrate_0d( region, i, j, k, pm_sizelimit, temp, status ) !returns kg/m3
  2404. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*temp/dens/m_dat(region)%data(i,j,k) !kg(pm)/m3 /(1/m3) /kg(air)->kg(pm)/kg(air)
  2405. else if (trim(allvars(j_var)%vname)=='mmrpm1')then
  2406. pm_sizelimit=1.0!micrometers
  2407. !call PMx_Integrate_3d(region,pm_sizelimit,temp_pm,status)
  2408. CALL pmx_integrate_0d( region, i, j, k, pm_sizelimit, temp, status ) !returns kg/m3
  2409. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*temp/dens/m_dat(region)%data(i,j,k)!kg kg-1
  2410. else if (trim(allvars(j_var)%vname)=='mmrpm10')then
  2411. pm_sizelimit=10.0!micrometers
  2412. !call PMx_Integrate_3d(region,pm_sizelimit,temp_pm,status)
  2413. CALL pmx_integrate_0d( region, i, j, k, pm_sizelimit, temp, status ) !returns kg/m3
  2414. !kg/m3/m-3/kg
  2415. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*temp/dens/m_dat(region)%data(i,j,k)!kg kg-1
  2416. else if (trim(allvars(j_var)%vname)=='mmraerh2o')then
  2417. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*(h2o_mode(region,1)%d3(i,j,k)+h2o_mode(region,2)%d3(i,j,k)+h2o_mode(region,3)%d3(i,j,k)+h2o_mode(region,4)%d3(i,j,k))/m_dat(region)%data(i,j,k)!kg kg-1
  2418. end if
  2419. !exit
  2420. else
  2421. !Transported variables are stored in different array (tracers=> mass_dat(region)%rm)
  2422. if (index<=ntracet) then
  2423. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,index)/m_dat(region)%data(i,j,k)!kg kg-1
  2424. else ! than non transported (tracers_c=> chem_dat(region)%rm)
  2425. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers_c(i,j,k,index)/m_dat(region)%data(i,j,k)!kg kg-1
  2426. end if
  2427. end if
  2428. end do
  2429. end do
  2430. end do
  2431. end do
  2432. !end if
  2433. else if (trim(allvars(j_var)%class)=='gas')then
  2434. do k=1,lmr
  2435. do j=j1,j2
  2436. do i=i1,i2
  2437. index=allvars(j_var)%indices(1)
  2438. if (index<=0) then
  2439. cycle
  2440. else if (trim(allvars(j_var)%vname)=='h2o') then
  2441. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*humid_dat(1)%data(i,j,k)/xmh2o*xmair !mole mole-1
  2442. !tracers_c(i,j,k,index)*xmair/xmgas/m_dat(region)%data(i,j,k)
  2443. else if (trim(allvars(j_var)%vname)=='voc')then
  2444. ! ACTUALLY not requested
  2445. do m=1,ncb5
  2446. gasind=nmhc(m)
  2447. xmgas=xmcb5(m)
  2448. select case(nmhc(m))
  2449. case(ipar,ich2o,ich3oh,ihcooh)
  2450. xmcomp=xmc
  2451. case(ieth,iole,iald2,imcooh,ic2h6,iethoh)
  2452. xmcomp=xmc*2.0
  2453. case(imgly,ic3h8,ic3h6,iacet)
  2454. xmcomp=xmc*3.0
  2455. end select
  2456. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,gasind)*xmair/xmcomp/m_dat(region)%data(i,j,k) !kmole kmole-1
  2457. end do
  2458. do m=1,2
  2459. if (m==1)then
  2460. gasind=iterp
  2461. xmcomp=xmc*5*2
  2462. else
  2463. gasind=iisop
  2464. xmcomp=xmc*5.0
  2465. end if
  2466. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,gasind)*xmair/xmcomp/m_dat(region)%data(i,j,k) !kmole kmole-1
  2467. end do
  2468. else
  2469. xmgas=allvars(j_var)%xmgas
  2470. if (index >= ntracet) then
  2471. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers_c(i,j,k,index)*xmair/xmgas/m_dat(region)%data(i,j,k) !kmole kmole-1
  2472. else
  2473. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,index)*xmair/xmgas/m_dat(region)%data(i,j,k) !kmole kmole-1
  2474. end if
  2475. end if
  2476. end do
  2477. end do
  2478. end do
  2479. !end if
  2480. else if (trim(allvars(j_var)%class)=='ps6h')then
  2481. do i=i1,i2
  2482. do j=j1,j2
  2483. if (trim(allvars(j_var)%vname)=='ps')then
  2484. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)!Pa
  2485. end if
  2486. end do
  2487. end do
  2488. !end if
  2489. ! 1 hourly surface variables
  2490. else if (trim(allvars(j_var)%class)=='sf1h')then
  2491. do i=i1,i2
  2492. do j=j1,j2
  2493. if (trim(allvars(j_var)%vname)=='ps')then
  2494. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)!Pa
  2495. else if (trim(allvars(j_var)%vname)=='sfno2')then
  2496. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*tracers_c(i,j,1,ino2)*xmair/xmno2/m_dat(region)%data(i,j,1)*dtime !kmole kmole-1
  2497. else if (trim(allvars(j_var)%vname)=='sfo3')then
  2498. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,1,io3)*xmair/xmo3/m_dat(region)%data(i,j,1) !kmole kmole-1
  2499. else if (trim(allvars(j_var)%vname)=='sfpm25')then
  2500. pm_sizelimit=2.5!micrometers
  2501. dens = pres3d(i,j,1) / temper_dat(region)%data(i,j,1) * xmair * 1.E-3 / (m_dat(region)%data(i,j,1) * rgas)
  2502. call PMx_Integrate_0d(region,i,j,1,pm_sizelimit,temp,status)
  2503. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*temp/m_dat(region)%data(i,j,1)/dens!kg kg-1
  2504. !allvars(j_var)%data2D(i,j)=temp/m_dat(region)%data(i,j,1)/dens*dtime!kg kg-1
  2505. else if (trim(allvars(j_var)%vname)=='tas')then
  2506. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*temper_dat(1)%data(i,j,1)!K
  2507. end if
  2508. end do
  2509. end do
  2510. !end if
  2511. ! surface daily variables
  2512. else if (trim(allvars(j_var)%class)=='sf1d')then
  2513. do i=i1,i2
  2514. do j=j1,j2
  2515. if (trim(allvars(j_var)%vname)=='ps')then
  2516. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)!Pa
  2517. else if (trim(allvars(j_var)%vname)=='toz')then
  2518. ! conversion (in order of execution):
  2519. !kg->g (1e3), g->molec (xmo3), m2->cm2(1e-4) , molec-> molec/m2(dxyp) , molec/cm2->dobson (DOBS)
  2520. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*sum(tracers(i,j,:,io3)*1e3/xmo3*Avog*1e-4/dxyp(j)/Dobs) !GU
  2521. else if (trim(allvars(j_var)%vname)=='sfo3max')then
  2522. sfo3_molmol = tracers(i,j,1,io3)*xmair/xmo3/m_dat(region)%data(i,j,1)
  2523. if ( sfo3_molmol > allvars(j_var)%data2D(i,j)) then
  2524. allvars(j_var)%data2D(i,j) = sfo3_molmol !kmole kmole-1
  2525. end if
  2526. else if (trim(allvars(j_var)%vname)=='maxpblz')then
  2527. if (conv_dat(1)%blh(i,j)> allvars(j_var)%data2D(i,j)) then
  2528. allvars(j_var)%data2D(i,j)= conv_dat(1)%blh(i,j)!m
  2529. end if
  2530. else if (trim(allvars(j_var)%vname)=='minpblz')then
  2531. if (conv_dat(1)%blh(i,j)< allvars(j_var)%data2D(i,j)) then
  2532. allvars(j_var)%data2D(i,j)= conv_dat(1)%blh(i,j)!m
  2533. end if
  2534. else if (trim(allvars(j_var)%vname)=='tas')then
  2535. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*temper_dat(1)%data(i,j,1)!K
  2536. else if (trim(allvars(j_var)%vname)=='tasmin')then
  2537. if (temper_dat(1)%data(i,j,1)< allvars(j_var)%data2D(i,j)) then
  2538. allvars(j_var)%data2D(i,j)= temper_dat(1)%data(i,j,1)!K
  2539. end if
  2540. else if (trim(allvars(j_var)%vname)=='tasmax')then
  2541. if (temper_dat(1)%data(i,j,1)> allvars(j_var)%data2D(i,j)) then
  2542. allvars(j_var)%data2D(i,j)= temper_dat(1)%data(i,j,1)!K
  2543. end if
  2544. else if (trim(allvars(j_var)%vname)=='pr')then
  2545. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*(lsp_dat(1)%data(i,j,1)+ cp_dat(1)%data(i,j,1))/rol!kgm-2s-1
  2546. end if
  2547. end do
  2548. end do
  2549. !end if
  2550. else if (trim(allvars(j_var)%class)=='zonal')then
  2551. ! zonal mean needs to be done afterwards...
  2552. ! So just save the variables as 3D
  2553. do i=i1,i2
  2554. do j=j1,j2
  2555. do k=1,lmr
  2556. if (trim(allvars(j_var)%vname)=='ch4')then
  2557. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,ich4)/m_dat(region)%data(i,j,k)*xmair/xmch4!mol mol-1
  2558. else if (trim(allvars(j_var)%vname)=='hno3')then
  2559. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,ihno3)/m_dat(region)%data(i,j,k)*xmair/xmhno3!mol mol-1
  2560. else if (trim(allvars(j_var)%vname)=='o3')then
  2561. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,io3)/m_dat(region)%data(i,j,k)*xmair/xmo3!mol mol-1
  2562. else if (trim(allvars(j_var)%vname)=='ta')then
  2563. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*temper_dat(1)%data(i,j,k)!K
  2564. else if (trim(allvars(j_var)%vname)=='h2o')then
  2565. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+0.0!dtime*humid_dat(1)%data(i,j,k)/xmh2o*xmair!mol mol-1
  2566. else if (trim(allvars(j_var)%vname)=='zg')then
  2567. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*gph_dat(1)%data(i,j,k)!m
  2568. else if (trim(allvars(j_var)%vname)=='ho2')then
  2569. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*tracers_c(i,j,k,iho2)/m_dat(region)%data(i,j,k)*xmair/xmho2!mol mol-1
  2570. else if (trim(allvars(j_var)%vname)=='oh')then
  2571. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*tracers_c(i,j,k,ioh)/m_dat(region)%data(i,j,k)*xmair/xmoh!mol mol-1
  2572. else if (trim(allvars(j_var)%vname)=='noy')then
  2573. do icomp=1,size( allvars(j_var)%indices(:))
  2574. index= allvars(j_var)%indices(icomp)
  2575. xmcomp=ra(index)
  2576. if (allvars(j_var)%indices(icomp)>0) then
  2577. !write(gol,'(": ",a,i3,E20.7e2)') trim(allvars(j_var)%vname),index,tracers(i,j,k,index)/m_dat(region)%data(i,j,k)*xmair/xmcomp; call goPr
  2578. if (allvars(j_var)%indices(icomp)<70) then
  2579. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*tracers(i,j,k,index)/m_dat(region)%data(i,j,k)*xmair/xmcomp!???
  2580. else
  2581. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*tracers_c(i,j,k,index)/m_dat(region)%data(i,j,k)*xmair/xmcomp!???
  2582. end if
  2583. end if
  2584. end do
  2585. end if
  2586. end do
  2587. end do
  2588. end do
  2589. else
  2590. ! optics and fixed are not accumulated here
  2591. ! optics in optics_calc
  2592. ! fixed not at all
  2593. if (trim(allvars(j_var)%class)/='optics' .and. trim(allvars(j_var)%class)/='fixed') then
  2594. write(gol,*) 'output_aerhemmip_accumulate: output class not found!!!',trim(allvars(j_var)%vname),trim(allvars(j_var)%class)
  2595. !call goPr
  2596. call goErr
  2597. status=1
  2598. return
  2599. end if
  2600. end if
  2601. end do
  2602. end if
  2603. ! zero accumulated budget variables for the amount between output steps
  2604. AC_diag_prod(region)%prod(i1:i2,j1:j2,:,1)=0.0
  2605. AC_diag_prod(region)%prod(i1:i2,j1:j2,:,2)=0.0
  2606. AC_diag_prod(region)%prod(i1:i2,j1:j2,:,3)=0.0
  2607. AC_diag_prod(region)%prod(i1:i2,j1:j2,:,4)=0.0
  2608. AC_loss(region)%prod(i1:i2,j1:j2,:,1:2)=0.0
  2609. AC_O3_lp(region)%prod(i1:i2,j1:j2,:,1:2)=0.0
  2610. deallocate(gphx)
  2611. deallocate(tx)
  2612. deallocate(temp_pm)
  2613. deallocate(pres3d)
  2614. deallocate(pres3dh)
  2615. call GO_Timer_Start( itim_accu_opt, status )
  2616. call calculate_optics(1,dhour,l_do_ec550aer_only,status)
  2617. call GO_Timer_End( itim_accu_opt, status )
  2618. call GO_Timer_End( itim_accu, status )
  2619. ! IF_NOTOK_RETURN(status=1)
  2620. call goLabel()
  2621. !status = 1
  2622. end subroutine accumulate_data
  2623. subroutine output_aerchemmip_done(status)
  2624. use partools, only: isRoot,myid
  2625. implicit none
  2626. integer :: status
  2627. character(len=*), parameter :: rname = mname//'/output_aerchemmip_done'
  2628. integer :: j_var, region
  2629. call goLabel(rname)
  2630. region = 1
  2631. if (isroot) then
  2632. do j_var=1,n_vars
  2633. call MDF_Close( allvars(j_var)%fileunit, status )
  2634. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  2635. end do
  2636. end if
  2637. deallocate(wdep_out )
  2638. deallocate(drydepos(region)%f2dslast)
  2639. deallocate(wetdepos(region)%f2dslast)
  2640. deallocate(emission(region)%f2dslast)
  2641. deallocate(dimension_data%lon)
  2642. deallocate(dimension_data%lat)
  2643. deallocate(dimension_data%lev)
  2644. do j_var=1,n_vars
  2645. deallocate(allvars(j_var)%data2D)
  2646. deallocate(allvars(j_var)%data3D)
  2647. end do
  2648. deallocate(allvars)
  2649. deallocate(fixedvars)
  2650. call goLabel()
  2651. status = 0
  2652. end subroutine output_aerchemmip_done
  2653. !subroutine add_variable(itm5,shortname,longname,unit,positive,standardname,varid,fileunit,filename,data_dims,status,class,table,pxmgas)
  2654. subroutine add_variable(itm5,shortname,longname,unit,data_dims,status,class,table,pxmgas)
  2655. use chem_param, only: mode_end_so4,mode_end_pom,mode_end_bc,mode_end_ss,mode_end_dust
  2656. use global_data, only: outdir
  2657. use datetime, only: tau2date, date2tau
  2658. use dims, only: itau,itaue,itaut
  2659. implicit none
  2660. integer:: itm5
  2661. character(len=*),intent(in)::shortname
  2662. character(len=*),intent(in)::longname
  2663. character(len=*)::unit
  2664. character(len=30)::standardname
  2665. character(len=*)::table
  2666. character(len=*),optional::class
  2667. real,optional::pxmgas
  2668. integer:: data_dims
  2669. integer,intent(out)::status
  2670. !LOCAL
  2671. character(len=4)::positive=''
  2672. integer:: fileunit=-1 !defined only when creating a file
  2673. integer:: varid=-1! defined when opening ncfile
  2674. !character(len=120)::filename
  2675. character(len=30)::table_id
  2676. !character(len=30)::source_id
  2677. !character(len=30)::experiment_id
  2678. character(len=30)::member_id
  2679. !character(len=30)::grid_label
  2680. character(len=30)::time_range
  2681. character(len=200)::filename1
  2682. character(len=10)::freq
  2683. real,dimension(:,:),pointer::data2D
  2684. ! real,dimension(:,:),pointer::dataZonal
  2685. real,dimension(:,:,:),pointer::data3D
  2686. real,dimension(:,:,:),pointer::budget
  2687. character(len=*), parameter :: rname = mname//'/output_aerchemmip_add_variable'
  2688. integer ::i1,i2,j1,j2,jmr,imr,lmr
  2689. integer, dimension(6) :: idater, idateend, idatett
  2690. integer :: endmonth, endday
  2691. character(len=30) :: idates
  2692. call tau2date(itau,idater)
  2693. ! define frequency from table
  2694. if (trim(table)=='AERhr')then
  2695. !table id depends on variable
  2696. table_id=table
  2697. freq='1hr'
  2698. else if (trim(table)=='AER6hr')then
  2699. !table id depends on variable
  2700. table_id=table
  2701. freq='6hr'
  2702. else if( trim(table)=='AERmon'.or.trim(table)=='AERmonZ'.or.trim(table)=='Emon')then
  2703. !table id depends on variable
  2704. table_id=table
  2705. freq='mon'
  2706. else if(trim(table)=='AERday')then
  2707. !table id depends on variable
  2708. table_id=table
  2709. freq='day'
  2710. else if(trim(table)=='AERfx')then
  2711. !table id depends on variable
  2712. table_id=table
  2713. freq='na'
  2714. else
  2715. freq='freq-nondefined'
  2716. table_id='table-nondefined'
  2717. end if
  2718. ! CREATE date string for output
  2719. !
  2720. ! ATM assumed that the output is initilised at the beginninh of year
  2721. endmonth=12
  2722. endday=31
  2723. !
  2724. if (freq=='mon')then
  2725. ! By default AERCHEMMIP runs are done by 1-year chunks -> idater(2) - idater(2)+11
  2726. write(idates, '(i4,i2.2,a,i4,i2.2)') idater(1), idater(2),'-', idater(1),endmonth
  2727. else if(freq=='day')then
  2728. !time range form Jan-1 ->Dec-31x
  2729. write(idates, '(i4,2i2.2,a,i4,2i2.2)') idater(1), idater(2), idater(3),'-', idater(1), endmonth, endday
  2730. else if(freq=='1hr')then
  2731. write(idates, '(i4,2i2.2,2a2,a,i4,2i2.2,2a2)') idater(1), idater(2), idater(3),'00','00','-', idater(1), endmonth, endday, '23', '59'
  2732. else if (freq=='6hr')then
  2733. write(idates, '(i4,2i2.2,2a2,a,i4,2i2.2,2a2)') idater(1), idater(2), idater(3),'00','00','-', idater(1), endmonth, endday,'18','00'
  2734. end if
  2735. !statf(region)%fname = trim(outdir)//'/'//&
  2736. ! trim(f_dataid) //'_'//&
  2737. ! trim(f_model) //'_'//&
  2738. ! trim(aerocom_exper) //'_'//&
  2739. ! trim(f_dimstat)//'_'//&
  2740. ! trim(idates) //'_'//&
  2741. ! trim(aerocom_freq) //'.nc'
  2742. call goLabel(rname)
  2743. call GO_Timer_Start( itim_addvar, status )
  2744. IF_NOTOK_RETURN(status=1)
  2745. !outdir='output'
  2746. ! temporary
  2747. standardname=longname
  2748. ! source_id constant
  2749. !source_id='EC-EARTH-AerChem'
  2750. ! experiment depends on run
  2751. !experiment_id='exp_dynamic'
  2752. member_id='r'//trim(realization_i)//'i'//trim(initialization_i)//'p'//trim(physics_i)//'f'//trim(forcing_i)
  2753. !grid_label='3x2_degrees'
  2754. ! time range has divider in place since it can be omitted alltogether with non-time dependendent variables
  2755. if (trim(table)=='AERfx')then
  2756. time_range=''
  2757. else
  2758. time_range='_'//trim(idates)
  2759. end if
  2760. ! for fixed variables time range should not be written
  2761. n_vars=n_vars+1
  2762. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  2763. ! define sizes for arrays
  2764. imr=i2-i1+1
  2765. jmr=j2-j1+1
  2766. lmr = levi%nlev
  2767. if (trim(shortname)=='phalf') then
  2768. allocate(budget(i1:i2,j1:j2,1:lmr+1))
  2769. else
  2770. allocate(budget(i1:i2,j1:j2,1:lmr))
  2771. end if
  2772. budget(:,:,:)=0.0
  2773. ! 2D variables
  2774. if (data_dims==2) then
  2775. !Allocate holders for data
  2776. allocate(allvars(n_vars)%data2D(i1:i2,j1:j2))
  2777. allocate(allvars(n_vars)%data3D(1,1,1))
  2778. ! allocate local variables
  2779. allocate(data2D(i1:i2,j1:j2))
  2780. allocate(data3D(1,1,1))
  2781. ! zero local data holders
  2782. data2D(:,:)=0.0
  2783. ! dataZonal(:,:)=0.0
  2784. data3D(:,:,:)=0.0
  2785. !init variable
  2786. ! set default for minimum variables to high value
  2787. if (shortname=='minpblz' .or. shortname=='tasmin')then
  2788. data2D(:,:)=1000000.0
  2789. end if
  2790. !create filename
  2791. if (trim(class)=='crescendo')then
  2792. ! filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(table_id)//'_'//trim(source_id)//'_'//trim(experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//'_'//trim(time_range)//trim('.nc')
  2793. filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(class)//'_'//trim(table_id)//'_'//trim(source_id)//'_'//trim(experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//trim(time_range)//trim('.nc')
  2794. else
  2795. filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(table_id)//'_'//trim(source_id)//'_'//trim(experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//trim(time_range)//trim('.nc')
  2796. end if
  2797. allvars(n_vars)=varfile(itm5,shortname,longname,unit,positive,standardname,data2D,data3D,budget,-1,-1,&
  2798. filename1,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,data_dims,freq,class,(/0,0,0,0,0,0,0,0,0,0,0/),pxmgas,table_id)
  2799. !! LEFT HERE on purpose to see what variables go where in above statement
  2800. !!$ allvars(n_vars)%itm5=itm5
  2801. !!$ allvars(n_vars)%vname=shortname
  2802. !!$ allvars(n_vars)%lname=longname
  2803. !!$ allvars(n_vars)%unit=unit
  2804. !!$ allvars(n_vars)%positive=positive
  2805. !!$ allvars(n_vars)%standard_name=standardname
  2806. !!$ allvars(n_vars)%data2D=data2D
  2807. !!$ allvars(n_vars)%data3D=data3D
  2808. !!$ allvars(n_vars)%budgetdata=data3D
  2809. !!$ allvars(n_vars)varid=-1
  2810. !!$ allvars(n_vars)%filenunit=-1
  2811. !!$ allvars(n_vars)%filename=filename1
  2812. !!$ allvars(n_vars)%dimensions=2
  2813. !!$ allvars(n_vars)%lon_varid=-1
  2814. !!$ allvars(n_vars)%lat_varid=-1
  2815. !!$ allvars(n_vars)%lev_varid=-1
  2816. !!$ allvars(n_vars)%time_varid=-1
  2817. !!$ allvars(n_vars)%bounds_varid=-1
  2818. !!$ allvars(n_vars)%dims=dims
  2819. !!$ allvars(n_vars)%class=class
  2820. !!$ allvars(n_vars)%indices=(/0,0,0,0,0,0,0/))
  2821. !!$ allvars(n_vars)%xmgas=molarweight
  2822. !!$ allvars(n_vars)%table_id=
  2823. ! 3D variables
  2824. else if (data_dims==3) then
  2825. ! allocate holders for data
  2826. allocate(allvars(n_vars)%data2D(1,1))
  2827. if (trim(shortname)=='phalf') then
  2828. allocate(allvars(n_vars)%data3D(i1:i2,j1:j2,1:lmr+1))
  2829. allocate(data3D(i1:i2,j1:j2,1:lmr+1))
  2830. else
  2831. allocate(allvars(n_vars)%data3D(i1:i2,j1:j2,1:lmr))
  2832. allocate(data3D(i1:i2,j1:j2,1:lmr))
  2833. end if
  2834. ! allocate local variables
  2835. ! maybe remove these
  2836. allocate(data2D(1,1))
  2837. !allocate(data3D(i1:i2,j1:j2,1:lmr))
  2838. ! zero local data holders
  2839. data2D(:,:)=0.0
  2840. data3D(:,:,:)=0.0
  2841. !init variable
  2842. if (trim(class)=='crescendo')then
  2843. ! filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(table_id)//'_'//trim(source_id)//'_'//trim(experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//'_'//trim(time_range)//trim('.nc')
  2844. filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(class)//'_'//trim(table_id)//'_'//trim(source_id)//'_'//trim(experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//trim(time_range)//trim('.nc')
  2845. else
  2846. filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(table_id)//'_'//trim(source_id)//'_'//trim(experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//trim(time_range)//trim('.nc')
  2847. end if
  2848. allvars(n_vars)=varfile(itm5,shortname,longname,unit,positive,standardname,data2D,data3D,budget,-1,-1,&
  2849. filename1,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,data_dims,freq,class,(/0,0,0,0,0,0,0,0,0,0,0/),pxmgas,table)
  2850. end if
  2851. ! add chemical info also: (vars beginning with emi,wet,dry)
  2852. select case (trim(shortname(4:)))
  2853. case ('so4')
  2854. allvars(n_vars)%indices(1:7)=(/iso4nus,iso4ais,iso4acs,iso4cos,0,0,0/)!mode_end_so4
  2855. case ('so2')
  2856. allvars(n_vars)%indices(1)=iso2
  2857. case ('oa','emioa')
  2858. !allvars(n_vars)%indices(1:7)=(/ipomais,ipomacs,ipomcos,ipomaii,0,0,0/)!mode_end_pom
  2859. allvars(n_vars)%indices(1:9)=(/ipomais,ipomacs,ipomcos,ipomaii,isoanus,isoaais,isoaacs,isoacos,isoaaii/)!mode_end_pom
  2860. case ('poa','emipoa')
  2861. allvars(n_vars)%indices(1:4)=(/ipomais,ipomacs,ipomcos,ipomaii/)!mode_end_pom
  2862. case ('soa')
  2863. allvars(n_vars)%indices(1:7)=(/isoanus,isoaais,isoaacs,isoacos,isoaaii,0,0/)!mode_end_pom
  2864. case ('bc')
  2865. allvars(n_vars)%indices(1:7)=(/ibcaii,ibcais,ibcacs,ibccos,0,0,0/)!mode_end_bc
  2866. case ('ss','emiss')
  2867. allvars(n_vars)%indices(1:7)=(/issacs,isscos,0,0,0,0,0/)!mode_end_ss
  2868. case ('dust')
  2869. allvars(n_vars)%indices(1:7)=(/iduacs,iducos,iduaci,iducoi,0,0,0/)!mode_end_dust
  2870. case('nox')
  2871. !allvars(n_vars)%indices(1:2)=(/ino,ino2/)
  2872. allvars(n_vars)%indices(1)=inox
  2873. case('voc')
  2874. allvars(n_vars)%indices(1)=1!(/ipar,ieth,iole,iald2,imgly,0,0/)
  2875. case('bvoc')
  2876. allvars(n_vars)%indices(1:2)=(/iterp,iisop/)!ibvoc
  2877. case('nh3','sfnh3')
  2878. allvars(n_vars)%indices(1)=inh3
  2879. case('nh4')
  2880. allvars(n_vars)%indices(1)=inh4
  2881. case('noy')
  2882. allvars(n_vars)%indices(1:11)=(/ ino, iNO2, ino3, iHNO3, iNO3_a, ihno4, in2o5, iPAN, iOrgNtr, ihono, ich3o2no2/)
  2883. !allvars(n_vars)%indices(1)=ino2!(/ ino, iNO2, ino3, iHNO3, iNO3_a, ihno4, in2o5, iPAN, iOrgNtr, ihono, ich3o2no2/)
  2884. case('no3')
  2885. allvars(n_vars)%indices(1)=ino3_a
  2886. case('pm1')
  2887. allvars(n_vars)%indices(1)=-1
  2888. case('pm2p5','sfpm25')
  2889. allvars(n_vars)%indices(1)=-1
  2890. case('pm10')
  2891. allvars(n_vars)%indices(1)=-1
  2892. case('o3')
  2893. allvars(n_vars)%indices(1)=io3
  2894. case('co')
  2895. allvars(n_vars)%indices(1)=ico
  2896. case('dms')
  2897. allvars(n_vars)%indices(1)=idms
  2898. case('isop')
  2899. allvars(n_vars)%indices(1)=iisop
  2900. !case('terp')
  2901. ! allvars(n_vars)%indices(1)=iterp
  2902. end select
  2903. select case (trim(shortname))
  2904. case('noy')
  2905. allvars(n_vars)%indices(1:11)=(/ iNO, ino2, ino3, iHNO3, iNO3_a, ihno4, in2o5, iPAN, iOrgNtr, ihono, ich3o2no2/)
  2906. !allvars(n_vars)%indices(1)=ino2!(/ iNO, ino3, iHNO3, iNO3_a, ihno4, in2o5, iPAN, iOrgNtr, ihono, ich3o2no2/)
  2907. case('areacella')
  2908. allvars(n_vars)%indices(:)=0
  2909. areacella=n_vars
  2910. case('c2h2')
  2911. allvars(n_vars)%indices(1)=-1
  2912. case('c2h6')
  2913. allvars(n_vars)%indices(1)=ic2h6
  2914. case('c3h6')
  2915. allvars(n_vars)%indices(1)=ic3h6
  2916. case('c3h8')
  2917. allvars(n_vars)%indices(1)=ic3h8
  2918. case('ch3coch3')
  2919. allvars(n_vars)%indices(1)=iacet!ich3coch3
  2920. case('ch4')
  2921. allvars(n_vars)%indices(1)=ich4
  2922. case('co')
  2923. allvars(n_vars)%indices(1)=ico
  2924. case('so2')
  2925. allvars(n_vars)%indices(1)=iso2
  2926. case('co2')
  2927. allvars(n_vars)%indices(1)=-1
  2928. case('dms')
  2929. allvars(n_vars)%indices(1)=idms
  2930. case('h2o')
  2931. allvars(n_vars)%indices(1)=-1!ih2o
  2932. case('hcho')
  2933. allvars(n_vars)%indices(1)=ich2o
  2934. case('hcl')
  2935. allvars(n_vars)%indices(1)=-1!ihcl
  2936. case('hno3','sfmmrhno3')
  2937. allvars(n_vars)%indices(1)=ihno3
  2938. case('isop')
  2939. allvars(n_vars)%indices(1)=iisop
  2940. case('n2o')
  2941. allvars(n_vars)%indices(1)=-1!in2o
  2942. case('no', 'sfno')
  2943. allvars(n_vars)%indices(1)=ino
  2944. case('no2','sfno2')
  2945. allvars(n_vars)%indices(1)=ino2
  2946. case('o3','sfo3')
  2947. allvars(n_vars)%indices(1)=io3
  2948. case('o3ste')
  2949. allvars(n_vars)%indices(1)=io3s
  2950. case('oh')
  2951. allvars(n_vars)%indices(1)=ioh
  2952. case('pan')
  2953. allvars(n_vars)%indices(1)=ipan
  2954. !CRESCENDO variables
  2955. case('nh3','sfmmrnh3','sfnh3')
  2956. allvars(n_vars)%indices(1)=inh3
  2957. case('nh4','sfmmrnh4')
  2958. allvars(n_vars)%indices(1)=inh4
  2959. case('sfmmrno3')
  2960. allvars(n_vars)%indices(1)=ino3_a
  2961. case('pm1')
  2962. allvars(n_vars)%indices(1)=-1
  2963. case('pm2p5','sfpm25')
  2964. allvars(n_vars)%indices(1)=-1
  2965. case ('mmraerh2o_1','mmraerh2o_2','mmraerh2o_3','mmraerh2o_4','mmraerh2o')
  2966. allvars(n_vars)%indices(1)=-1
  2967. case ('sfmmrso4')
  2968. allvars(n_vars)%indices(1:4)=(/iso4nus,iso4ais,iso4acs,iso4cos/)
  2969. case ('sfmmrsoa')
  2970. allvars(n_vars)%indices(1:5)=(/isoanus,isoaais,isoaacs,isoacos,isoaaii/)
  2971. case ('sfmmroa')
  2972. allvars(n_vars)%indices(1:4)=(/ipomais,ipomacs,ipomcos,ipomaii/)
  2973. case ('sfmmrbc')
  2974. allvars(n_vars)%indices(1:4)=(/ibcais,ibcacs,ibccos,ibcaii/)
  2975. case ('sfmmrdustbel1','sfmmrdustabv1','sfmmrdustabv10','seddust','sfmmrdust')
  2976. allvars(n_vars)%indices(1:4)=(/iduacs,iducos,iduaci,iducoi/)
  2977. case ('sfmmrss')
  2978. allvars(n_vars)%indices(1:2)=(/issacs,isscos/)
  2979. case ('mmrsu1','sfmmrsu1')
  2980. allvars(n_vars)%indices(1)=iso4nus
  2981. case ('mmrsu2','sfmmrsu2')
  2982. allvars(n_vars)%indices(1)=iso4ais
  2983. case ('mmrsu3','sfmmrsu3')
  2984. allvars(n_vars)%indices(1)=iso4acs
  2985. case ('mmrsu4','sfmmrsu4')
  2986. allvars(n_vars)%indices(1)=iso4cos
  2987. case ('mmrsoa1','sfmmrsoa1')
  2988. allvars(n_vars)%indices(1)=isoanus
  2989. case ('mmrsoa2','sfmmrsoa2')
  2990. allvars(n_vars)%indices(1)=isoaais
  2991. case ('mmrsoa3','sfmmrsoa3')
  2992. allvars(n_vars)%indices(1)=isoaacs
  2993. case ('mmrsoa4','sfmmrsoa4')
  2994. allvars(n_vars)%indices(1)=isoacos
  2995. case ('mmrsoa5','sfmmrsoa5')
  2996. allvars(n_vars)%indices(1)=isoaaii
  2997. case ('mmroa2','sfmmroa2')
  2998. allvars(n_vars)%indices(1)=ipomais
  2999. case ('mmroa3','sfmmroa3')
  3000. allvars(n_vars)%indices(1)=ipomacs
  3001. case ('mmroa4','sfmmroa4')
  3002. allvars(n_vars)%indices(1)=ipomcos
  3003. case ('mmroa5','sfmmroa5')
  3004. allvars(n_vars)%indices(1)=ipomaii
  3005. case ('mmrbc2','sfmmrbc2')
  3006. allvars(n_vars)%indices(1)=ibcais
  3007. case ('mmrbc3','sfmmrbc3')
  3008. allvars(n_vars)%indices(1)=ibcacs
  3009. case ('mmrbc4','sfmmrbc4')
  3010. allvars(n_vars)%indices(1)=ibccos
  3011. case ('mmrbc5','sfmmrbc5')
  3012. allvars(n_vars)%indices(1)=ibcaii
  3013. case ('mmrss3','sfmmrss3')
  3014. allvars(n_vars)%indices(1)=issacs
  3015. case ('mmrss4','sfmmrss4')
  3016. allvars(n_vars)%indices(1)=isscos
  3017. case ('mmrdu3','sfmmrdu3')
  3018. allvars(n_vars)%indices(1)=iduacs
  3019. case ('mmrdu4','sfmmrdu4')
  3020. allvars(n_vars)%indices(1)=iducos
  3021. case ('mmrdu6','sfmmrdu6')
  3022. allvars(n_vars)%indices(1)=iduaci
  3023. case ('mmrdu7','sfmmrdu7')
  3024. allvars(n_vars)%indices(1)=iducoi
  3025. case ('sfndtot','sfnd100','ndtot')
  3026. allvars(n_vars)%indices(1:7)=(/inus_n,iais_n,iacs_n,icos_n,iaii_n,iaci_n,icoi_n/)
  3027. case ('nd1','sfnd1','sfnd1_tst')
  3028. allvars(n_vars)%indices(1)=inus_n
  3029. case ('nd2','sfnd2')
  3030. allvars(n_vars)%indices(1)=iais_n
  3031. case ('nd3','sfnd3')
  3032. allvars(n_vars)%indices(1)=iacs_n
  3033. case ('nd4','sfnd4')
  3034. allvars(n_vars)%indices(1)=icos_n
  3035. case ('nd5','sfnd5')
  3036. allvars(n_vars)%indices(1)=iaii_n
  3037. case ('nd6','sfnd6')
  3038. allvars(n_vars)%indices(1)=iaci_n
  3039. case ('nd7','sfnd7')
  3040. allvars(n_vars)%indices(1)=icoi_n
  3041. ! case('sfmmrnh3')
  3042. ! allvars(n_vars)%indices(1)=inh3
  3043. ! case('sfmmrnh4')
  3044. ! allvars(n_vars)%indices(1)=inh4
  3045. case('drydms')
  3046. allvars(n_vars)%indices(1)=idms
  3047. case('wetdms')
  3048. allvars(n_vars)%indices(1)=idms
  3049. case('dryno3')
  3050. allvars(n_vars)%indices(1)=ino3_a
  3051. case('wetno3')
  3052. allvars(n_vars)%indices(1)=ino3_a
  3053. case('dryhno3')
  3054. allvars(n_vars)%indices(1)=ihno3
  3055. case('wethno3')
  3056. allvars(n_vars)%indices(1)=ihno3
  3057. case('dryno2')
  3058. allvars(n_vars)%indices(1)=ino2
  3059. case('dryno')
  3060. allvars(n_vars)%indices(1)=ino
  3061. case('drypan')
  3062. allvars(n_vars)%indices(1)=ipan
  3063. case('sfo3max')
  3064. allvars(n_vars)%indices(1)=io3
  3065. case('mono')
  3066. allvars(n_vars)%indices(1)=iterp
  3067. case('co2mass')
  3068. allvars(n_vars)%indices(1)=-1! not available
  3069. case('chepsoa','chepsoa3d','chepsoa2d')
  3070. allvars(n_vars)%indices(1)=-1
  3071. case('flashrate')
  3072. allvars(n_vars)%indices(1)=-1
  3073. case('md')
  3074. allvars(n_vars)%indices(1)=-1
  3075. case('sedustCI')
  3076. allvars(n_vars)%indices(1)=iducoi
  3077. case('depdust')
  3078. allvars(n_vars)%indices(1:4)=(/iduacs,iducos,iduaci,iducoi/)
  3079. case('concdust')
  3080. allvars(n_vars)%indices(1:4)=(/iduacs,iducos,iduaci,iducoi/)
  3081. case('conccn')
  3082. allvars(n_vars)%indices(1:7)=(/inus_n,iais_n,iacs_n,icos_n,iaii_n,iaci_n,icoi_n/)
  3083. case('sconcss')
  3084. allvars(n_vars)%indices(1:2)=(/issacs,isscos/)
  3085. case('loaddust')
  3086. allvars(n_vars)%indices(1:4)=(/iduacs,iducos,iduaci,iducoi/)
  3087. case('lossch4')
  3088. allvars(n_vars)%indices(1)=ich4
  3089. case('lossco')
  3090. allvars(n_vars)%indices(1)=ico
  3091. end select
  3092. if (class=='crescendo') then
  3093. select case (trim(shortname))
  3094. case('od440dust')
  3095. allvars(n_vars)%indices(1)=-1
  3096. if (freq=='day' .and. data_dims==2)then
  3097. od440dustday=n_vars
  3098. end if
  3099. case('od440aer')
  3100. allvars(n_vars)%indices(1)=-1
  3101. if (freq=='1hr') then
  3102. od440aerhr=n_vars
  3103. else if (freq=='day') then
  3104. od440aerdaily=n_vars
  3105. else if (freq=='mon') then
  3106. od440aermonthly=n_vars
  3107. end if
  3108. case('od550aer')
  3109. allvars(n_vars)%indices(1)=-1
  3110. if (freq=='1hr')then
  3111. od550aerhr=n_vars
  3112. end if
  3113. case('od550dust')
  3114. if (freq=='day' .and. data_dims==2)then
  3115. od550dust2dday=n_vars
  3116. end if
  3117. case('od5503ddust')
  3118. if (freq=='day' .and. data_dims==3)then
  3119. od550dust3dday=n_vars
  3120. end if
  3121. case('ec550aer')
  3122. allvars(n_vars)%indices(1)=-1
  3123. ec550aermon=n_vars
  3124. end select
  3125. end if
  3126. if (class=='sf1d') then
  3127. select case (trim(shortname))
  3128. case('od550aer')
  3129. allvars(n_vars)%indices(1)=-1
  3130. od550aerdaily=n_vars
  3131. case('sfo3max')
  3132. allvars(n_vars)%indices(1)=io3
  3133. end select
  3134. end if
  3135. if(class=='optics') then
  3136. select case (trim(shortname))
  3137. case('ec550aer')
  3138. allvars(n_vars)%indices(1)=-1
  3139. ec550aer=n_vars
  3140. case('od550aer')
  3141. allvars(n_vars)%indices(1)=-1
  3142. od550aer=n_vars
  3143. case('od550so4')
  3144. allvars(n_vars)%indices(1)=-1
  3145. od550so4=n_vars
  3146. case('od550bc')
  3147. allvars(n_vars)%indices(1)=-1
  3148. od550bc=n_vars
  3149. case('od550oa')
  3150. allvars(n_vars)%indices(1)=-1
  3151. od550oa=n_vars
  3152. case('od550soa')
  3153. allvars(n_vars)%indices(1)=-1
  3154. od550soa=n_vars
  3155. case('od550ss')
  3156. allvars(n_vars)%indices(1)=-1
  3157. od550ss=n_vars
  3158. case('od550dust')
  3159. allvars(n_vars)%indices(1)=-1
  3160. od550dust=n_vars
  3161. case('od550no3')
  3162. allvars(n_vars)%indices(1)=-1
  3163. od550no3=n_vars
  3164. case('od550aerh2o')
  3165. allvars(n_vars)%indices(1)=-1
  3166. od550aerh2o=n_vars
  3167. case('od550lt1aer')
  3168. allvars(n_vars)%indices(1)=-1
  3169. od550lt1aer=n_vars
  3170. case('abs550aer')
  3171. allvars(n_vars)%indices(1)=-1
  3172. abs550aer=n_vars
  3173. case('od440aer')
  3174. allvars(n_vars)%indices(1)=-1
  3175. if (freq=='mon') then
  3176. od440aer=n_vars
  3177. !else if (freq=='day') then
  3178. ! od440aerdaily=n_vars
  3179. end if
  3180. case('od350aer')
  3181. allvars(n_vars)%indices(1)=-1
  3182. od350aer=n_vars
  3183. case('od870aer')
  3184. allvars(n_vars)%indices(1)=-1
  3185. od870aer=n_vars
  3186. end select
  3187. end if
  3188. call goLabel()
  3189. status = 0
  3190. call GO_Timer_End( itim_addvar, status )
  3191. IF_NOTOK_RETURN(status=1)
  3192. end subroutine add_variable
  3193. subroutine write_attributes(status,j_var)
  3194. implicit none
  3195. integer :: j_var
  3196. integer,intent(out)::status
  3197. character(len=*), parameter :: rname = mname//'/output_aerchemmip_writeattr'
  3198. call goLabel(rname)
  3199. call GO_Timer_Start( itim_attr, status )
  3200. IF_NOTOK_RETURN(status=1)
  3201. call MDF_Put_Att( allvars(j_var)%fileunit, MDF_GLOBAL, 'title', 'Model output for Aerchemmip', status )
  3202. IF_NOTOK_MDF(fid= allvars(j_var)%fileunit)
  3203. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'units', 'degrees_east', status)
  3204. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3205. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'axis', 'X', status)
  3206. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3207. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'long_name', 'longitude', status)
  3208. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3209. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'standard_name', 'longitude', status)
  3210. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3211. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'units', 'degrees_north', status)
  3212. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3213. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'axis', 'Y', status)
  3214. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3215. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'long_name', 'latitude', status)
  3216. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3217. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'standard_name', 'latitude', status)
  3218. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3219. ! allvars(j_var)%lev_varid
  3220. if (allvars(j_var)%dims==3) then
  3221. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'units', 'level', status)
  3222. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3223. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'axis', 'Z', status)
  3224. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3225. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'long_name', 'hybrid model level at layer midpoints', status)
  3226. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3227. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'standard_name', 'hybrid_model_level', status)
  3228. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3229. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'formula', 'a+b*ps', status)
  3230. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3231. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'positive', 'up', status)
  3232. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3233. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyam_varid , 'long_name', 'hybrid A coefficient at layer midpoints', status)
  3234. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3235. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyam_varid , 'units', 'Pa', status)
  3236. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3237. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybm_varid , 'long_name', 'hybrid B coefficient at layer midpoints', status)
  3238. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3239. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybm_varid , 'units', '1', status)
  3240. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3241. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyai_varid , 'long_name', 'hybrid A coefficient at layer interfaces', status)
  3242. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3243. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyai_varid , 'units', 'Pa', status)
  3244. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3245. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybi_varid , 'long_name', 'hybrid B coefficient at layer interfaces', status)
  3246. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3247. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybi_varid , 'units', '1', status)
  3248. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3249. END if
  3250. if (allvars(j_var)%table_id/='AERfx')then
  3251. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'units', 'days since 1750-01-01 00:00:00', status)
  3252. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3253. ! call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'axis', 'X', status)
  3254. ! IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3255. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'calendar', 'gregorian', status)
  3256. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3257. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'long_name', 'time', status)
  3258. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3259. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'axis', 'T', status)
  3260. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3261. !time bounds
  3262. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'bounds', 'time_bounds', status)
  3263. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3264. end if
  3265. !experiment=
  3266. !CMIP6 global attributes:
  3267. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'Conventions', 'CF-1.7 CMIP-6.0 UGRID-0.9', status)
  3268. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'activity_id', 'AerChemMIP', status)
  3269. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'branch_method','', status)
  3270. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'creation_date','', status)
  3271. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'data_specs_version','1.0.0', status)
  3272. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'experiment',trim(experiment), status)
  3273. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'experiment_id',trim(experiment_id), status)
  3274. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'forcing_index',trim(forcing_i), status)
  3275. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'frequency',trim(allvars(j_var)%freq), status)
  3276. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'further_info_url','MISSING', status)
  3277. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'grid','native '//trim(grid)//' degree grid', status)!module variables
  3278. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'grid_label',trim(grid_label), status)!module variables
  3279. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'initialization_index',trim(initialization_i), status)
  3280. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'institution','KNMI, The Netherlands; SMHI, Sweden; DMI, Denmark; &
  3281. &AEMET, Spain; Met Eireann, Ireland; CNR-ISAC, Italy; Instituto de Meteorologia, Portugal; FMI, Finland; BSC, Spain; &
  3282. &Centro de Geofisica, University of Lisbon, Portugal; ENEA, Italy; Geomar, Germany; Geophysical Institute, University of Bergen, Norway; &
  3283. &ICHEC, Ireland; ICTP, Italy; IMAU, The Netherlands; IRV, Sweden; Lund University, Sweden; &
  3284. &Meteorologiska Institutionen, Stockholms University, Sweden; Niels Bohr Institute, University of Copenhagen, Denmark; &
  3285. &NTNU, Norway; SARA, The Netherlands; Unite ASTR, Belgium; Universiteit Utrecht, The Netherlands; &
  3286. &Universiteit Wageningen, The Netherlands; University College Dublin, Ireland; Vrije Universiteit Amsterdam, the Netherlands; &
  3287. &University of Helsinki, Finland; KIT, Karlsruhe, Germany; USC, University of Santiago de Compostela, Spain; &
  3288. &Uppsala Universitet, Sweden; NLeSC, Netherlands eScience Center, The Netherlands', status)
  3289. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'institution_id','EC-Earth-Consortium', status)
  3290. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'license','NEEDS DEFINING', status)
  3291. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'mip_era','CMIP6', status)
  3292. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'nominal_resolution','250 km', status)!dmax
  3293. !dmax=r*phi/2*(1+((phi**2+lamb**2)/(phi*lamb))*np.arctan(lamb/phi))=348 r=6371, phi=2(lat), lamb=3(long)
  3294. !CMIP6 global attributes: 100 < dmax < 350 -> nominal resolution 250 km
  3295. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'physics_index',trim(physics_i), status)
  3296. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'product','output', status)!only choice
  3297. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'realization_index',trim(realization_i), status)!1 for primary or single realization
  3298. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'realm',trim(realm), status)! depends on run, some are AGCM
  3299. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source',trim(source), status)!
  3300. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source_id',trim(source_id), status)
  3301. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source_type',trim(source_type), status)
  3302. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'sub_experiment','', status)
  3303. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'sub_experiment_id','', status)
  3304. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'table_id',trim(allvars(j_var)%table_id), status)
  3305. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'tracking_id','', status)
  3306. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variable_id',trim(allvars(j_var)%vname), status)
  3307. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variant_label','', status)
  3308. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variant_label','', status)
  3309. call GO_Timer_End( itim_attr, status )
  3310. IF_NOTOK_RETURN(status=1)
  3311. call goLabel()
  3312. status = 0
  3313. end subroutine write_attributes
  3314. subroutine write_dimensions(status,j_var)
  3315. use dims, only : iyear0 !current year
  3316. use go_date, only : days_in_year,newDate
  3317. use partools , only : isRoot,myid
  3318. implicit none
  3319. integer :: j_var
  3320. integer,intent(out)::status
  3321. integer :: i1,i2,j1,j2,imr,jmr,lmr
  3322. integer :: lon_varid,lonid,lon_dimid
  3323. integer :: lat_varid,latid,lat_dimid
  3324. integer :: lev_varid,levid,lev_dimid
  3325. integer :: hym_varid,hym_dimid
  3326. integer :: hyi_varid,hyi_dimid
  3327. integer :: time_varid,timeid,time_dimid,bounds_dimid,bounds_varid,boudid
  3328. ! most of data is monthly mean, but change to dynamic number of output steps needed
  3329. integer :: nout_steps!=12
  3330. integer :: nhym
  3331. integer :: nhyi
  3332. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write_dim'
  3333. call goLabel(rname)
  3334. ! define dimensions
  3335. !call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3336. imr=dimension_data%nlon
  3337. jmr=dimension_data%nlat
  3338. lmr=dimension_data%nlev
  3339. nhym=lmr
  3340. nhyi=lmr+1
  3341. ! With parallel netcdf whole netcdf must be reserved at the time of initialisation
  3342. ! therefore we need to know the number of output steps per file.
  3343. ! Define number of output steps in a file depending on the output frequency
  3344. ! use newdate to create TDate structure, and use that in days_in_year
  3345. if (allvars(j_var)%table_id=='AERhr')then
  3346. nout_steps=24*days_in_year(newdate(iyear0))
  3347. else if (allvars(j_var)%table_id=='AER6hr')then
  3348. nout_steps=4*days_in_year(newdate(iyear0))
  3349. else if (allvars(j_var)%table_id=='AERday')then
  3350. nout_steps=days_in_year(newdate(iyear0))
  3351. else if (allvars(j_var)%table_id=='AERmon'.or. (allvars(j_var)%table_id=='AERmonZ'))then
  3352. nout_steps=12
  3353. end if
  3354. if (isroot) then
  3355. !DEFINE DIMENSIONS
  3356. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lon', imr,lon_dimid, status )
  3357. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3358. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lat', jmr, lat_dimid, status )
  3359. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3360. if (allvars(j_var)%dims==3) then
  3361. if (trim(allvars(j_var)%vname)=='phalf') then
  3362. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lev', lmr+1, lev_dimid, status )
  3363. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3364. else
  3365. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lev', lmr, lev_dimid, status )
  3366. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3367. end if
  3368. end if
  3369. if (allvars(j_var)%table_id/='AERfx')then
  3370. !call MDF_Def_Dim( allvars(j_var)%fileunit, 'time', nout_steps, time_dimid, status )
  3371. call MDF_Def_Dim( allvars(j_var)%fileunit, 'time', MDF_UNLIMITED, time_dimid, status )
  3372. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3373. call MDF_Def_Dim( allvars(j_var)%fileunit, 'bounds', 2, bounds_dimid, status )
  3374. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3375. end if
  3376. if (allvars(j_var)%dims==3) then
  3377. call MDF_Def_Dim( allvars(j_var)%fileunit, 'nhym', nhym, hym_dimid, status )
  3378. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3379. call MDF_Def_Dim( allvars(j_var)%fileunit, 'nhyi', nhyi, hyi_dimid, status )
  3380. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3381. end if
  3382. ! define dimension variables
  3383. ! longitude
  3384. call MDF_Def_Var( allvars(j_var)%fileunit, 'lon', MDF_DOUBLE, &
  3385. (/ lon_dimid/), allvars(j_var)%lon_varid, status )
  3386. ! define latitude variable
  3387. call MDF_Def_Var( allvars(j_var)%fileunit, 'lat', MDF_DOUBLE, &
  3388. (/ lat_dimid/), allvars(j_var)%lat_varid, status )
  3389. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3390. ! level
  3391. if (allvars(j_var)%dims==3) then
  3392. call MDF_Def_Var( allvars(j_var)%fileunit, 'lev', MDF_DOUBLE, &
  3393. (/ lev_dimid/), allvars(j_var)%lev_varid, status )
  3394. end if
  3395. if (allvars(j_var)%table_id/='AERfx')then
  3396. call MDF_Def_Var( allvars(j_var)%fileunit, 'time', MDF_DOUBLE, &
  3397. (/ time_dimid/), allvars(j_var)%time_varid, status )
  3398. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3399. call MDF_Def_Var( allvars(j_var)%fileunit, 'time_bounds', MDF_DOUBLE, &
  3400. (/ bounds_dimid,time_dimid/), allvars(j_var)%bounds_varid, status )
  3401. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3402. end if
  3403. if (allvars(j_var)%dims==3) then
  3404. ! define hybm variable
  3405. call MDF_Def_Var( allvars(j_var)%fileunit, 'hybm', MDF_DOUBLE, &
  3406. (/ hym_dimid/), allvars(j_var)%hybm_varid, status )
  3407. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3408. ! define hyam variable
  3409. call MDF_Def_Var( allvars(j_var)%fileunit, 'hyam', MDF_DOUBLE, &
  3410. (/ hym_dimid/), allvars(j_var)%hyam_varid, status )
  3411. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3412. ! define hybi variable
  3413. call MDF_Def_Var( allvars(j_var)%fileunit, 'hybi', MDF_DOUBLE, &
  3414. (/ hyi_dimid/), allvars(j_var)%hybi_varid, status )
  3415. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3416. ! define hyai variable
  3417. call MDF_Def_Var( allvars(j_var)%fileunit, 'hyai', MDF_DOUBLE, &
  3418. (/ hyi_dimid/), allvars(j_var)%hyai_varid, status )
  3419. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3420. end if
  3421. ! * Write out dimension variable values
  3422. ! Write out hybm
  3423. if (allvars(j_var)%dims==3) then
  3424. ! midpoints
  3425. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hybm_varid,levi%fb, status)
  3426. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3427. ! Write out hyam
  3428. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hyam_varid,levi%fa, status)
  3429. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3430. ! interfaces
  3431. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hybi_varid,levi%b, status)
  3432. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3433. ! Write out hyai
  3434. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hyai_varid,levi%a, status)
  3435. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3436. end if
  3437. ! Write out the longitudes
  3438. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%lon_varid, dimension_data%lon, status)
  3439. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3440. !write out the latitude to variable
  3441. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%lat_varid, dimension_data%lat, status)
  3442. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3443. if (allvars(j_var)%dims==3) then
  3444. if (trim(allvars(j_var)%vname)=='phalf') then
  3445. ! Write out the levels
  3446. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%lev_varid, (/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35/), status)
  3447. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3448. else
  3449. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%lev_varid, (/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34/), status)
  3450. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3451. end if
  3452. end if
  3453. ! Time will be written during output write -steps
  3454. end if
  3455. call goLabel()
  3456. status = 0
  3457. end subroutine write_dimensions
  3458. subroutine write_var(status,j_var)
  3459. implicit none
  3460. integer :: j_var
  3461. integer,intent(out)::status
  3462. integer :: i1,i2,j1,j2,imr,jmr,lmr
  3463. integer :: lon_varid,lonid
  3464. integer :: lat_varid,latid
  3465. integer :: lev_varid,levid
  3466. integer :: time_varid,timeid
  3467. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write_dim'
  3468. call goLabel(rname)
  3469. ! define dimensions
  3470. !call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3471. imr=dimension_data%nlon
  3472. jmr=dimension_data%nlat
  3473. lmr=dimension_data%nlev
  3474. ! define dimension variables
  3475. ! longitude
  3476. if (allvars(j_var)%dims==2.and.allvars(j_var)%table_id/='AERfx') then
  3477. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  3478. (/allvars(j_var)%lon_varid, allvars(j_var)%lat_varid, allvars(j_var)%time_varid/), allvars(j_var)%varid, status )
  3479. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3480. else if (allvars(j_var)%dims==2.and.allvars(j_var)%table_id=='AERfx') then
  3481. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  3482. (/allvars(j_var)%lon_varid, allvars(j_var)%lat_varid/), allvars(j_var)%varid, status )
  3483. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3484. else
  3485. !(allvars(j_var)%dims==3)
  3486. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  3487. (/allvars(j_var)%lon_varid, allvars(j_var)%lat_varid, allvars(j_var)%lev_varid,allvars(j_var)%time_varid/), allvars(j_var)%varid, status )
  3488. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3489. end if
  3490. ! Write out the longitudes
  3491. call MDF_Put_Att( allvars(j_var)%fileunit, allvars(j_var)%varid, 'long_name', trim(allvars(j_var)%lname), status )
  3492. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3493. call MDF_Put_Att(allvars(j_var)%fileunit,allvars(j_var)%varid, 'standard_name', trim(allvars(j_var)%standard_name), status )
  3494. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3495. call MDF_Put_Att(allvars(j_var)%fileunit , allvars(j_var)%varid, 'units', trim(allvars(j_var)%unit), status )
  3496. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3497. call MDF_EndDef( allvars(j_var)%fileunit, status )
  3498. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3499. call goLabel()
  3500. status = 0
  3501. end subroutine write_var
  3502. subroutine calculate_optics( region, dhour, l_do_ec550aer_only,status)
  3503. use optics, only : optics_aop_get
  3504. use MeteoData, only : gph_dat,temper_dat
  3505. USE toolbox, only : ltropo_ifs, lvlpress
  3506. use dims, only : lm
  3507. implicit none
  3508. integer :: i, j, k, imr, jmr, lmr, lwl, dtime
  3509. integer :: i1, i2, j1, j2,ivar
  3510. integer :: ie, je ! indices for subdomain extended with halo cells
  3511. integer, parameter :: l_halo=1
  3512. logical :: polar
  3513. integer :: istat, imode
  3514. real :: dens, load_tmp
  3515. Real, Dimension(:,:,:), Allocatable :: aop_output_ext ! extinctions
  3516. Real, Dimension(:,:), Allocatable :: aop_output_a ! single scattering albedo
  3517. Real, Dimension(:,:), Allocatable :: aop_output_g ! assymetry factor
  3518. Real, Dimension(:,:,:), Allocatable :: aop_output_add ! additional parameters
  3519. real, dimension(:,:,:,:,:), allocatable :: opt_ext
  3520. real, dimension(:,:,:,:), allocatable :: opt_a
  3521. real, dimension(:,:,:,:), allocatable :: opt_g
  3522. real, dimension(:,:,:,:,:), allocatable :: opt_add
  3523. real, dimension(:,:,:), allocatable :: volume
  3524. real, dimension(:,:), allocatable :: temp2d
  3525. real, dimension(:,:), allocatable :: tempdust2dday
  3526. real, dimension(:,:), allocatable :: tempdust2d440day
  3527. integer :: ncontr, lvec, lct, l, indoffset, nwl
  3528. integer :: nadd, nadd_max, indoffset_stat, indabs
  3529. integer :: iadd
  3530. integer :: region,dhour,status
  3531. real :: no3fac, wght, dwght, tabs
  3532. real,dimension(:),allocatable :: tx
  3533. integer :: itropo
  3534. real, dimension(:,:,:), pointer :: gph ! height (incl. oro)
  3535. real,dimension(:,:,:), pointer :: t ! temperature (K)
  3536. logical :: l_do_ec550aer_only
  3537. character(len=*), parameter :: rname = mname//'/output_aerchemmip_optics'
  3538. call goLabel(rname)
  3539. ! grid size
  3540. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2, hasNorthPole=polar )
  3541. imr = i2-i1+1
  3542. jmr = j2-j1+1
  3543. lmr = levi%nlev
  3544. allocate(tx(lm(region)))
  3545. t => temper_dat (region)%data
  3546. gph => gph_dat (region)%data
  3547. ! ---------------------
  3548. ! DO OPTICS IN PARALLEL
  3549. ! ---------------------
  3550. ! steps needed for that:
  3551. ! 1) according to the parallelisation there is different container sizes for
  3552. ! the results of the optics; these have to be allocated correctly
  3553. ! (aop_output_ext/a/g/add)
  3554. ! 2) the optics code is called (init/calculate_aop/done), see documentation
  3555. ! in the optics module
  3556. ! 3) the distributed fields (levels/tracers) are reshaped to global fields
  3557. ! (opt_ext/a/g/add), according to parallelisation
  3558. ! 4) fields are communicated such that the result contains the right
  3559. ! total extinctions, albedos, asymmetry factors etc.
  3560. ! 5) post-calculations (AOD etc.) are done and results are written
  3561. ! to mixf%../statf% containers as well as to the AOD dump files
  3562. ! 6) done...
  3563. ! ------------ REMARKS
  3564. ! IMPOSSIBLE / TOO EXPENSIVE (from the AEROCOM list of parameters for QUICKLOOK)
  3565. ! - gf @ 90% RH
  3566. ! - "AOD@550nm SOA", "AOD@550nm BB"
  3567. ! ---------------------------------
  3568. ! fill current M7 state into an appropriate container
  3569. ! and allocate output fields (ext,a,g)
  3570. ! ------------------------------------
  3571. ! ----- A T T E N T I O N ---------
  3572. ! in case for a 'split', we need a field big enough to contain
  3573. ! various contributions
  3574. ! (to be synchronously changed with optics_aop_calculate!!)
  3575. ! ncontr is here number of contributors
  3576. ! Total, SO4, BC, OC, SS, DU, NO3, Water, Fine, Fine Dust, Fine SS
  3577. ! Total(water), Total(nowater)
  3578. !ncontr = 10
  3579. ncontr = 12
  3580. ! Total, SO4, BC, OC,SOA, SS, DU, NO3, Water, lt1aer
  3581. dtime=dhour*3600
  3582. !TB Following additional fields are nnecessary but call to optics needs it...
  3583. ! Additional fields for surface dry aerosol
  3584. ! to be used for validation against in-situ data:
  3585. ! extinction, absorption, asymmetry factor
  3586. ! fine-mode contribution to extinction, absorption
  3587. nadd = 5
  3588. lvec = imr*jmr*lmr
  3589. ! allocate output fields for optics_calculate_aop
  3590. allocate( aop_output_ext(lvec, size(wdep_out), ncontr ) ) ! extinction
  3591. allocate( aop_output_a (lvec, size(wdep_out) ) ) ! single scattering albedo
  3592. allocate( aop_output_g (lvec, size(wdep_out) ) ) ! asymmetry factor
  3593. allocate( aop_output_add(lvec, size(wdep_out), nadd ) ) ! extinction/absorption due to dry aerosol at surface
  3594. call optics_aop_get(lvec, region, size(wdep_out),wdep_out, ncontr, .false., aop_output_ext, aop_output_a, aop_output_g, &
  3595. status, aop_output_add )
  3596. IF_NOTOK_RETURN(status=1)
  3597. ! allocate here result arrays for ext, abs, ssa, asymmetry parameter, additional parameters (PM10)
  3598. ! ncontr is number of contributors for 'split'
  3599. allocate( opt_ext( i1:i2, j1:j2, lmr, size(wdep_out), ncontr ) ) ; opt_ext = 0.0
  3600. allocate( opt_a ( i1:i2, j1:j2, lmr, size(wdep_out) ) ) ; opt_a = 0.0
  3601. allocate( opt_g ( i1:i2, j1:j2, lmr, size(wdep_out) ) ) ; opt_g = 0.0
  3602. allocate( opt_add( i1:i2, j1:j2, lmr, size(wdep_out), nadd ) ) ; opt_add = 0.0
  3603. ! ---------------------------------
  3604. ! unpack results from calculate_aop
  3605. ! ---------------------------------
  3606. do lwl = 1, size(wdep_out)
  3607. if( wdep_out(lwl)%split ) then
  3608. ! fill the array for the extinction coefficients of contributors
  3609. do lct = 1, ncontr
  3610. opt_ext(:,:,:,lwl,lct) = reshape( aop_output_ext(:,lwl,lct), (/imr,jmr,lmr/) )
  3611. end do
  3612. else
  3613. ! fill only total extinction coefficients
  3614. opt_ext(:,:,:,lwl,1) = reshape( aop_output_ext(:,lwl,1), (/imr,jmr,lmr/) )
  3615. endif
  3616. opt_a(:,:,:,lwl) = reshape( aop_output_a(:,lwl),(/imr,jmr,lmr/) )
  3617. opt_g(:,:,:,lwl) = reshape( aop_output_g(:,lwl),(/imr,jmr,lmr/) )
  3618. end do ! lwl
  3619. ! free temporary arrays for results from calculate_aop
  3620. deallocate( aop_output_ext )
  3621. deallocate( aop_output_a )
  3622. deallocate( aop_output_g )
  3623. deallocate( aop_output_add )
  3624. ! the following sections assume that for 550nm there is splitted information
  3625. ! available and that there is *NO* split for other wavelengths!
  3626. if( count( (wdep_out(:)%wl == 0.550) .and. wdep_out(:)%split ) /= 1 ) then
  3627. write(gol,*) 'user_output_aerocom: wrong setup with splitted AOD information.'; call goErr
  3628. TRACEBACK
  3629. status=1; return
  3630. end if
  3631. ! -------------------------------------
  3632. ! here additional calculations and
  3633. ! file writing begin
  3634. ! -------------------------------------
  3635. ! cycle over wavelengths
  3636. do lwl = 1, size(wdep_out)
  3637. if (.not. l_do_ec550aer_only)then
  3638. ! if split and if wavelength=550nm
  3639. if( wdep_out(lwl)%split ) then
  3640. if (wdep_out(lwl)%wl == 0.550) then
  3641. ! for 550nm:
  3642. ! 1) AODs
  3643. ! fill for contributors (total, SO4, BC, POM, SS, DU, NO3, H2O, fine, fine dust, fine SS)
  3644. ! 2) Absorption for 550nm (45)
  3645. ! Extinction is here the sum of scattering and absorption and
  3646. ! the scattering part is given by the albedo (SSA). Thus the
  3647. ! remainder is absorption: Abs = Ext * (1 - SSA)
  3648. indoffset = od550aer
  3649. allocate(temp2d(i1:i2,j1:j2))
  3650. allocate(tempdust2dday(i1:i2,j1:j2))
  3651. do lct = 1, ncontr
  3652. temp2d = 0.0
  3653. tempdust2dday=0.0
  3654. do j = j1, j2
  3655. do i = i1, i2
  3656. ! multiply with height elements and sum up
  3657. tabs = 0.0
  3658. ! AOD output will only be for troposphere in data request
  3659. tx(:)=t(i,j,:)
  3660. itropo = ltropo_ifs(region,i,j,tx,lm(region))
  3661. do l = 1, itropo!lmr
  3662. temp2d(i,j) = temp2d(i,j) + opt_ext(i,j,l,lwl,lct) * &
  3663. (gph_dat(region)%data(i,j,l+1) - &
  3664. gph_dat(region)%data(i,j,l ))
  3665. if( lct == 1 ) then ! TOTAL AOD
  3666. ! Absorption: do this only once for the totals
  3667. tabs = tabs + opt_ext(i,j,l,lwl,lct) * (1.0 - opt_a(i,j,l,lwl)) * &
  3668. (gph_dat(region)%data(i,j,l+1) - gph_dat(region)%data(i,j,l))
  3669. else if (lct==4) then ! OAAOD
  3670. ! add SOA aod (5)to POM aod (4) (AerChemMIP expects total oa in aod550oa)
  3671. temp2d(i,j) = temp2d(i,j) + opt_ext(i,j,l,lwl,5) * &
  3672. (gph_dat(region)%data(i,j,l+1) - &
  3673. gph_dat(region)%data(i,j,l ))
  3674. else if (lct==7) then ! DUSTAOD
  3675. if ( wdep_out(lwl)%wl == 0.550) then
  3676. if (crescendo_out) allvars(od550dust3dday)%data3D(i,j,l)= opt_ext(i,j,l,lwl,lct) * &
  3677. (gph_dat(region)%data(i,j,l+1) - &
  3678. gph_dat(region)%data(i,j,l ))
  3679. tempdust2dday(i,j)=tempdust2dday(i,j)+ opt_ext(i,j,l,lwl,lct) * &
  3680. (gph_dat(region)%data(i,j,l+1) - &
  3681. gph_dat(region)%data(i,j,l ))
  3682. else
  3683. tempdust2dday(i,j)=tempdust2dday(i,j)+ opt_ext(i,j,l,lwl,lct) * &
  3684. (gph_dat(region)%data(i,j,l+1) - &
  3685. gph_dat(region)%data(i,j,l ))
  3686. end if
  3687. end if
  3688. end do
  3689. ! Absorption: do this only once for the totals
  3690. if( lct == 1 ) then
  3691. allvars(abs550aer)%data2D(i,j)=allvars(abs550aer)%data2D(i,j) + tabs*dtime
  3692. !extra output for total od550aer (ncontr==1)
  3693. allvars(od550aerdaily)%data2D(i,j)=allvars(od550aerdaily)%data2D(i,j) + temp2d(i,j)*dtime
  3694. if (crescendo_out)then
  3695. allvars(od550aerhr)%data2D(i,j)= dtime*temp2d(i,j)
  3696. end if
  3697. allvars(od550aer)%data2D(i,j)=allvars(od550aer)%data2D(i,j) + temp2d(i,j)*dtime
  3698. else if (lct<11)Then !AOD by compounds
  3699. allvars(indoffset+lct-1)%data2D(i,j)=allvars(indoffset+lct-1)%data2D(i,j) + temp2d(i,j)*dtime
  3700. if (crescendo_out .and. lct==7 .and. wdep_out(lwl)%wl == 0.550) then !DUSTAOD for 550nm
  3701. allvars(od550dust2dday)%data2D(i,j)=allvars(od550dust2dday)%data2D(i,j) + tempdust2dday(i,j)*dtime
  3702. end if
  3703. end if
  3704. end do
  3705. end do
  3706. end do
  3707. deallocate( temp2d )
  3708. deallocate( tempdust2dday)
  3709. !if 440 has splits do this
  3710. else if (wdep_out(lwl)%wl == 0.440 ) then
  3711. indoffset = od440aer
  3712. !not needed for AERCHEMMIP
  3713. indabs = -1
  3714. !abs440aer
  3715. ! fill AODs
  3716. allocate(tempdust2d440day(i1:i2,j1:j2))
  3717. allocate(temp2d(i1:i2,j1:j2))
  3718. tempdust2d440day=0.0
  3719. temp2d = 0.0
  3720. tempdust2d440day=0.0
  3721. do j = j1, j2
  3722. do i = i1, i2
  3723. ! AOD output will only be for troposphere in data request
  3724. tx(:)=t(i,j,:)
  3725. itropo = ltropo_ifs(region,i,j,tx,lm(region))
  3726. ! multiply with height elements and sum up
  3727. tabs = 0.0
  3728. do l = 1, itropo!lmr
  3729. ! od440aer
  3730. lct=1 ! total aod
  3731. temp2d(i,j) = temp2d(i,j) + opt_ext(i,j,l,lwl,lct) * &
  3732. (gph_dat(region)%data(i,j,l+1) - &
  3733. gph_dat(region)%data(i,j,l ))
  3734. tabs = tabs + opt_ext(i,j,l,lwl,lct) * (1.0 - opt_a(i,j,l,lwl)) * &
  3735. (gph_dat(region)%data(i,j,l+1) - gph_dat(region)%data(i,j,l))
  3736. !OD440DUST
  3737. lct=7
  3738. tempdust2d440day(i,j)=tempdust2d440day(i,j)+ opt_ext(i,j,l,lwl,lct) * &
  3739. (gph_dat(region)%data(i,j,l+1) - &
  3740. gph_dat(region)%data(i,j,l ))
  3741. end do
  3742. if (indabs>0) then
  3743. allvars(indabs)%data2D(i,j)=allvars(indabs)%data2D(i,j) + tabs*dtime
  3744. end if
  3745. end do
  3746. end do
  3747. allvars(od440aer)%data2D=allvars(od440aer)%data2D + temp2d*dtime
  3748. if (crescendo_out)then
  3749. allvars(od440dustday)%data2D=allvars(od440dustday)%data2D + tempdust2d440day*dtime
  3750. allvars(od440aerdaily)%data2D=allvars(od440aerdaily)%data2D + temp2d*dtime
  3751. allvars(od440aerhr)%data2D=temp2d*dtime
  3752. end if
  3753. deallocate( tempdust2d440day)
  3754. deallocate( temp2d )
  3755. end if
  3756. else !NON SPLITS
  3757. ! for 440/870/350 nm:
  3758. ! 1) fill total AOD and AAOD and write to containers
  3759. ! 2) dump AOD fields
  3760. if ( wdep_out(lwl)%wl == 0.870 ) then
  3761. indoffset = od870aer
  3762. !not needed for AERCHEMMIP
  3763. indabs = -1
  3764. !abs870aer
  3765. elseif ( wdep_out(lwl)%wl == 0.440 ) then
  3766. indoffset = -1 !od440aer
  3767. !not needed for AERCHEMMIP
  3768. indabs = -1
  3769. !abs350aer
  3770. elseif ( wdep_out(lwl)%wl == 0.350 ) then
  3771. indoffset = od350aer
  3772. !not needed for AERCHEMMIP
  3773. indabs = -1
  3774. !abs350aer
  3775. else
  3776. write(gol,*) 'user_output_aerchemmip: wrong wavelength given for aerocom diagnostics' ; call goErr
  3777. TRACEBACK
  3778. status=1; return
  3779. end if
  3780. ! fill AODs, total only
  3781. allocate(temp2d(i1:i2,j1:j2))
  3782. temp2d = 0.0
  3783. do j = j1, j2
  3784. do i = i1, i2
  3785. ! multiply with height elements and sum up
  3786. tabs = 0.0
  3787. do l = 1, lmr
  3788. temp2d(i,j) = temp2d(i,j) + opt_ext(i,j,l,lwl,1) * &
  3789. (gph_dat(region)%data(i,j,l+1) - &
  3790. gph_dat(region)%data(i,j,l ))
  3791. tabs = tabs + opt_ext(i,j,l,lwl,1) * (1.0 - opt_a(i,j,l,lwl)) * &
  3792. (gph_dat(region)%data(i,j,l+1) - gph_dat(region)%data(i,j,l))
  3793. end do
  3794. if (indabs>0) then
  3795. allvars(indabs)%data2D(i,j)=allvars(indabs)%data2D(i,j) + tabs*dtime
  3796. end if
  3797. end do
  3798. end do
  3799. if ((indoffset)==od870aer) then
  3800. allvars(od870aer)%data2D=allvars(od870aer)%data2D + temp2d*dtime
  3801. end if
  3802. deallocate(temp2d)
  3803. endif
  3804. end if
  3805. ! Extinction in 3D
  3806. if ( wdep_out(lwl)%wl == 0.550 ) then
  3807. allvars(ec550aer)%data3D= opt_ext(:,:,:,lwl,1)
  3808. if (crescendo_out) allvars(ec550aermon)%data3D=allvars(ec550aermon)%data3D + opt_ext(:,:,:,lwl,1)*dtime
  3809. endif
  3810. end do
  3811. deallocate( opt_ext, opt_a, opt_g, opt_add )
  3812. deallocate( tx )
  3813. call goLabel() ; status = 0
  3814. end subroutine calculate_optics
  3815. real function mode_fraction(r,limit,imode) result(modfrac)
  3816. Use mo_aero_m7, only : nmod, cmedr2mmedr, sigma
  3817. implicit none
  3818. !real :: var
  3819. real :: r
  3820. real :: z
  3821. real :: limit
  3822. ! real :: sigma
  3823. real :: hr2=0.5*sqrt(2.0)
  3824. integer::imode
  3825. z=0.0
  3826. if( r<100*tiny(1.0))then
  3827. modfrac=1.0
  3828. else
  3829. z=(log(limit)-log(r*cmedr2mmedr(imode)))/log(sigma(imode))
  3830. modfrac=0.5+0.5*erf(z*hr2)
  3831. end if
  3832. end function mode_fraction
  3833. end MODULE USER_OUTPUT_AERCHEMMIP