user_output_aerchemmip.F90 204 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372
  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. character(len=*), parameter :: mname = 'user_output_aerchemmip'
  77. ! max indices, at maximum 7, one for each mode
  78. integer,parameter :: n_indices=11
  79. type varfile
  80. integer :: itm5 !
  81. character(len=16) :: vname !
  82. character(len=64) :: lname !
  83. character(len=11) :: unit !
  84. character(len=10) :: positive !
  85. character(len=130) :: standard_name !
  86. ! real,dimension (:,:),pointer :: dataZonal !
  87. real,dimension (:,:),pointer :: data2D !
  88. real,dimension (:,:,:),pointer :: data3D !
  89. real,dimension (:,:,:),pointer :: budgetdata !
  90. integer :: varid !
  91. integer :: fileunit ! file unit number
  92. character(len=200) :: filename !
  93. integer :: dimensions !
  94. integer :: lon_varid !
  95. integer :: lat_varid !
  96. integer :: lev_varid !
  97. integer :: time_varid
  98. integer :: hyam_varid
  99. integer :: hybm_varid
  100. integer :: hyai_varid
  101. integer :: hybi_varid
  102. integer :: bounds_varid
  103. integer :: dims
  104. character(len=10) :: freq
  105. character(len=9) :: class ! which class of variable :emi, ddep, wdep,conc,aod,met,crescendo
  106. integer,dimension(n_indices) :: indices
  107. real :: xmgas
  108. character(len=20) :: table_id
  109. end type varfile
  110. type dimdata
  111. integer :: nlon ! size of x dimension of requested field
  112. integer :: nlat ! size of y dimension of requested field
  113. integer :: nlev ! size of z dimension of requested field
  114. real,dimension(:),pointer :: lon ! x dimension of requested field
  115. real,dimension(:),pointer :: lat ! y dimension of requested field
  116. real,dimension(:),pointer :: lev ! z dimension of requested field
  117. integer :: lonid ! x dimension id in nc
  118. integer :: latid ! y dimension id in nc
  119. integer :: levid ! z dimension id in nc
  120. integer :: timeid ! time dimension id in nc
  121. integer :: time_varid
  122. end type dimdata
  123. type(dimdata)::dimension_data
  124. type budgetstore
  125. real, dimension(:,:,:), allocatable :: f2dslast
  126. integer :: lasttime
  127. end type budgetstore
  128. type(budgetstore), dimension(nregions), save :: drydepos, wetdepos, emission
  129. ! type experimentdata
  130. ! character(len=16) ::
  131. ! end type experimentdata
  132. ! wavelength information
  133. type(wavelendep), dimension(:), allocatable :: wdep_out
  134. !!!!
  135. integer::test_fileunit
  136. !!!!
  137. integer :: n_vars=0
  138. type(varfile), dimension(:), allocatable :: allvars
  139. type(varfile), dimension(:), allocatable :: fixedvars
  140. integer :: n_var_max=300
  141. integer :: n_fixed=3
  142. integer, public :: n_days_in_month
  143. character(len=20), public :: aerchemmip_exper ! AeroCom experiment name
  144. integer, save :: od550aer, &
  145. ec550aer,&
  146. ec550aermon,&
  147. od550aerdaily, &
  148. od550so4, &
  149. od550bc, &
  150. od550oa,&
  151. od550soa,&
  152. od550ss,&
  153. od550dust,&
  154. od440dustday,&
  155. od550dust2dday,&
  156. od550dust3dday,&
  157. od550no3,&
  158. od550aerh2o,&
  159. od550lt1aer,&
  160. abs550aer,&
  161. od440aer,&
  162. od350aer,&
  163. od870aer,&
  164. od440aerhr,&
  165. od440aermonthly,&
  166. od440aerdaily,&
  167. od550aerhr,&
  168. areacella,&
  169. sftlf,&
  170. orog
  171. integer :: fid ! file id for IF_NOTOK_MDF macro
  172. integer :: access_mode
  173. integer :: accumulation_mon,accumulation_day,accumulation_hr,accumulation_6hr
  174. integer :: timeidx_mon,timeidx_hr,timeidx_day,timeidx_6hr
  175. logical,public::crescendo_out=.false.
  176. integer,parameter::iemiunit=1
  177. integer,parameter::iddepunit=1 !same dimensions as emi
  178. integer,parameter::iwdepunit=1 !same dimensions as emi
  179. integer,parameter::iprod3dunit=2
  180. integer,parameter::immrunit=3
  181. integer,parameter::idimensionlessunit=4
  182. integer,parameter::iheightunit=5
  183. integer,parameter::itempunit=6
  184. integer,parameter::io3unit=7
  185. integer,parameter::ipresunit=8
  186. integer,parameter::ivmrunit=9
  187. integer,parameter::irateunit=10
  188. integer,parameter::iloadunit=11
  189. integer,parameter::iextunit=12
  190. integer,parameter::iccunit=13
  191. integer,parameter::im3unit=14
  192. integer,parameter::imassunit=15
  193. 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',&
  194. 's-1','kg m-2','m-1','cm-3','m-3','kg'/)
  195. !CRESCENDO
  196. !3D
  197. Character(len=11),dimension(40),parameter :: crescendo3D= (/'nd1', 'nd2', 'nd3', 'nd4', 'nd5', 'nd6', 'nd7', &
  198. 'mmrsu1', 'mmrsu2', 'mmrsu3', 'mmrsu4', 'mmrsoa1', 'mmrsoa2', 'mmrsoa3', 'mmrsoa4', 'mmrsoa5', 'mmroa2', &
  199. 'mmroa3', 'mmroa4', 'mmroa5', 'mmrbc2', 'mmrbc3', 'mmrbc4', 'mmrbc5', 'mmrss3', 'mmrss4', 'mmrdu3', 'mmrdu4', &
  200. 'mmrdu6', 'mmrdu7', 'mmraerh2o_1', 'mmraerh2o_2', 'mmraerh2o_3', 'mmraerh2o_4', 'mono', 'nh3', 'ndtot', &
  201. 'ec550aer', 'chepsoa3d','emilnox'/)
  202. Character(len=11),dimension(40),parameter :: crescendo3Dunit=(/units(im3unit), units(im3unit), units(im3unit), &
  203. units(im3unit), units(im3unit), units(im3unit), units(im3unit), units(immrunit), units(immrunit), units(immrunit), &
  204. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit),&
  205. units(immrunit), units(immrunit), units(immrunit), units(immrunit), 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(ivmrunit), units(ivmrunit), units(im3unit), units(iextunit), &
  208. units(iemiunit),units(iemiunit)/)
  209. Character(len=11),dimension(2),parameter :: crescendo3Dday=(/'co', 'od5503ddust'/)
  210. Character(len=11),dimension(2),parameter :: crescendo3Ddayunit=(/units(ivmrunit),units(idimensionlessunit)/)
  211. !2D
  212. !mon
  213. Character(len=8),dimension(14),parameter :: crescendo2Dmon=(/'drydms', 'wetdms', 'wetno3', 'dryhno3', 'wethno3', &
  214. 'dryno2', 'dryno', 'drypan', 'emimono', 'dmsos', 'seddust', 'uas', 'vas', 'sfcWind'/)
  215. Character(len=11),dimension(14),parameter :: crescendo2Dmonunit=(/units(iddepunit), units(iddepunit), units(iddepunit), &
  216. units(iddepunit), units(iddepunit), units(iddepunit), units(iddepunit), units(iddepunit), units(iddepunit), &
  217. 'kg m-3',units(iddepunit),'m s-1', 'm s-1', 'm s-1'/)
  218. ! 2d
  219. ! 6hr
  220. Character(len=16),dimension(19),parameter :: crescendo2D6hr=(/'sfmmrso4', 'sfmmrss', 'sfmmroa', 'sfmmrsoa', 'sfmmrbc', &
  221. 'sfmmrdustabv1', 'sfmmrdustabv10', 'sfmmrdustbel1', 'sfdms', 'sfisop', 'sfmono', 'emidms', 'emiss', 'emioa', &
  222. 'emiisop', 'emimono', 'sfndtot', 'sfnd100', 'chepsoa2d'/)
  223. Character(len=11),dimension(19),parameter :: crescendo2D6hrunit=(/units(immrunit), units(immrunit), units(immrunit),&
  224. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(ivmrunit), &
  225. units(ivmrunit), units(ivmrunit), units(iemiunit), units(iemiunit), units(iemiunit), units(iemiunit), &
  226. units(iemiunit), units(im3unit), units(im3unit),'kgm-2s-1'/)
  227. !2d
  228. !day
  229. Character(len=16),dimension(52),parameter :: crescendo2Dday=(/'sfnd1', 'sfnd2', 'sfnd3', 'sfnd4', 'sfnd5', 'sfnd6', &
  230. 'sfnd7', 'sfmmrsu1', 'sfmmrsu2', 'sfmmrsu3', 'sfmmrsu4', 'sfmmrsoa1', 'sfmmrsoa2', 'sfmmrsoa3', 'sfmmrsoa4', &
  231. 'sfmmrsoa5', 'sfmmroa2', 'sfmmroa3', 'sfmmroa4', 'sfmmroa5', 'sfmmrbc2', 'sfmmrbc3', 'sfmmrbc4', 'sfmmrbc5', &
  232. 'sfmmrss3', 'sfmmrss4', 'sfmmrdu3', 'sfmmrdu4', 'sfmmrdu6', 'sfmmrdu7', 'sfmmraerh2o_1', 'sfmmraerh2o_2', &
  233. 'sfmmraerh2o_3', 'sfmmraerh2o_4', 'sfmmrno3', 'sfmmrnh4', 'sfmmrnh3', 'sfsh', 'od440aer', 'od440dust', &
  234. 'od550dust', 'depdustbel1', 'depdustabv1', 'depdustabv10', 'sfmmrdust', 'drynh4', 'wetnh4', 'dryno3', &
  235. 'wetno3', 'dryhno3','drydust','wetdust'/)
  236. Character(len=11),dimension(52),parameter :: crescendo2Ddayunit=(/units(im3unit), units(im3unit), units(im3unit), &
  237. units(im3unit), units(im3unit), units(im3unit), units(im3unit), units(immrunit), units(immrunit), units(immrunit), &
  238. units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit), units(immrunit),&
  239. units(immrunit), units(immrunit), units(immrunit), units(immrunit), 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),&
  242. units(idimensionlessunit), units(idimensionlessunit), units(idimensionlessunit), units(idimensionlessunit), units(iddepunit),&
  243. units(iddepunit), units(iddepunit), units(immrunit), units(iddepunit), units(iddepunit), units(iddepunit), units(iddepunit), &
  244. units(iddepunit), units(iddepunit), units(iddepunit)/)
  245. !2d
  246. !hr
  247. Character(len=9), dimension(5), parameter :: crescendo2Dhr=(/'od550aer', 'od440aer', 'sfno', 'sfnh3', 'sfhno3'/)
  248. Character(len=11), dimension(5), parameter :: crescendo2Dhrunit=(/units(idimensionlessunit), units(idimensionlessunit), &
  249. units(ivmrunit), units(ivmrunit), units(ivmrunit)/)
  250. !Character(len=11),dimension(6,2),parameter :: crescendo2Dtest=reshape(&
  251. ! (/'od550aer', 'od440aer', 'sfno' ,'sfnh3' ,'sfhno3' ,'chepsoa2d' ,&
  252. ! '1' ,'1' ,units(ivmrunit), units(ivmrunit), units(ivmrunit),'kgm-2s-1'/),(/6,2/))
  253. !METEO
  254. !3D
  255. Character(len=7),dimension(11),parameter :: meteo3D=(/'ta', 'pfull', 'phalf', 'hus', 'zg', 'airmass', 'emilnox', &
  256. 'jno2', 'ua', 'va', 'wa'/)
  257. Character(len=11),dimension(11),parameter :: meteo3Dunit=(/units(itempunit), units(ipresunit), units(ipresunit), &
  258. units(idimensionlessunit), units(iheightunit), units(iloadunit), 'mol s-1', units(irateunit),'ms-1', 'ms-1', 'ms-1'/)
  259. !2D
  260. Character(len=7),dimension(9),parameter :: meteo2D=(/'ps', 'ptp', 'tatp', 'ztp', 'bldep', 'pr', 'tropoz', 'toz', 'albsrfc'/)
  261. Character(len=11),dimension(9),parameter :: meteo2Dunit=(/units(ipresunit), units(ipresunit), units(itempunit), &
  262. units(iheightunit), units(iheightunit), units(iemiunit), units(io3unit), units(io3unit), units(idimensionlessunit)/)
  263. !OPTICS
  264. Character(len=11),dimension(13),parameter :: opticscomp=(/'od550aer', 'od550so4', 'od550bc', 'od550oa', 'od550soa',&
  265. 'od550ss', 'od550dust', 'od550no3', 'od550aerh2o', 'od550lt1aer', 'od440aer', 'od870aer', 'abs550aer'/)!
  266. !AEROSOL compounds
  267. Character(len=3),dimension(6),parameter :: comp=(/'BC', 'POM', 'SO4', 'DU', 'SS', 'SOA'/)!SOA
  268. !CHEMICAL
  269. Character(len=6),dimension(2),parameter :: checomp=(/'aqpso4', 'gpso4'/)
  270. Character(len=6),dimension(1),parameter :: chepcomp=(/'soa'/)
  271. Character(len=7),dimension(4),parameter :: o3chepcomp=(/'o3loss', 'o3prod','lossch4','lossco'/)
  272. !Emon
  273. Character(len=9),dimension(8),parameter :: emonout=(/'flashrate', 'depdust','seddustCI','md','loaddust','concdust','conccn','sconcss'/)
  274. 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'/)
  275. !BUDGET (EMI+REMOVAL)
  276. Character(len=4),dimension(14),parameter :: emicomp=(/'bvoc', 'co', 'dms', 'isop', 'nox', 'nh3', 'oa', 'so2', 'bc', &
  277. 'so4', 'dust', 'ss', 'voc','poa'/)
  278. Character(len=4),dimension(12),parameter :: ddepcomp=(/'nh3', 'noy', 'o3', 'oa', 'so2', 'bc', 'so4', 'dust', 'ss', &
  279. 'soa', 'nh4', 'no3'/)
  280. Character(len=4),dimension(10),parameter :: wdepcomp=(/'bc', 'dust', 'nh3', 'nh4', 'noy', 'oa', 'so2', 'so4', 'ss', 'soa'/)
  281. !MIXING ratios
  282. Character(len=6),dimension(13),parameter :: aerommrcomp=(/'bc', 'dust', 'nh3', 'nh4', 'no3', 'oa', 'so4', 'ss', 'pm1', &
  283. 'pm2p5', 'pm10', 'aerh2o', 'soa'/)
  284. Character(len=8),dimension(20),parameter :: gascomp=(/'c2h6', 'c3h6', 'c3h8', 'ch3coch3', 'ch4', 'co', 'co2', 'dms', &
  285. 'h2o', 'hno3', 'isop', 'no', 'no2', 'o3', 'oh', 'pan', 'so2', 'voc', 'hcho', 'o3ste'/)
  286. !Molecular weights
  287. real,dimension(20),parameter :: xmgascomp=(/xmc2h6, xmc3h6, xmc3h8, xmacet, xmch4, xmco, -1.0, xmdms, xmh2o, xmhno3, &
  288. xmisop, xmno, xmno2, xmo3, xmoh, xmpan, xmso2, 1.0, xmch2o,xmo3/)!VOC=1,
  289. !hcho=ch2o in TM5, but output for hcho is needed.
  290. !SPECIAL
  291. !HOURLY
  292. character(len=8),dimension(1),parameter:: ps6hr=(/'ps'/)
  293. character(len=11),dimension(1),parameter:: ps6hrunit=(/units(ipresunit)/)
  294. character(len=8),dimension(6),parameter:: hourly_var=(/'ps', 'sfno2', 'sfo3', 'sfpm25', 'tas', 'ec550aer'/)
  295. character(len=11),dimension(6),parameter:: hourly_varunit=(/units(ipresunit), units(ivmrunit), units(ivmrunit), &
  296. units(immrunit), units(itempunit), units(iextunit)/)
  297. !DAILY
  298. character(len=8),dimension(10),parameter:: daily_var=(/'od550aer', 'toz', 'maxpblz', 'minpblz', 'tasmin', 'tasmax', &
  299. 'pr', 'sfo3max', 'tas','ps'/)
  300. character(len=11),dimension(10),parameter:: daily_varunit=(/units(idimensionlessunit), units(io3unit), &
  301. units(iheightunit), units(iheightunit), units(itempunit), units(itempunit), units(iemiunit), units(ivmrunit), units(itempunit),units(ipresunit)/)
  302. !ZONAL
  303. character(len=6),dimension(8),parameter:: zonal_var=(/'ch4', 'hno3', 'ho2', 'noy', 'ta', 'zg', 'o3', 'oh'/)
  304. character(len=11),dimension(8),parameter:: zonal_varunit=(/units(ivmrunit), units(ivmrunit), units(ivmrunit), &
  305. units(ivmrunit), units(itempunit), units(iheightunit), units(ivmrunit), units(ivmrunit)/)
  306. integer,dimension(8),parameter:: zonal_idx=(/ich4,ihno3,iho2,-1,-1,-1,io3,ioh/)
  307. !AERCHEMMIP global attributes that might change with run or something else
  308. character(len=3),parameter::grid='3x2'!'250 km'
  309. character(len=3),parameter::grid_label='gn'!'gnz' for zonal means
  310. character(len=300),parameter::source='EC-Earth3-AerChem (2017): atmosphere: IFS cy36r4 (TL255, linearly &
  311. &reduced Gaussian grid equivalent to 512 x 256, 91 levels, top level: 0.01 hPa);atmospheric_chemistry: &
  312. &TM5 (3 deg. (long.) x 2 deg. (lat.), 34 levels, top level: 0.1 hPa; aerosol: TM5'
  313. character(len=17),parameter::source_id='EC-Earth3-AerChem'
  314. character(len=20),public ::source_type!='AOGCM CHEM AER' !or 'AGCM CHEM AER' for amip-runs
  315. character(len=60),public ::realm
  316. character(len=60),public::experiment_id
  317. character(len=60),public::experiment
  318. character(len=1),public::realization_i='1'
  319. character(len=1),public::physics_i='1'
  320. character(len=1),public::forcing_i='1'
  321. character(len=1),public::initialization_i='1'
  322. integer, public:: aerchemmip_dhour
  323. ! Timers
  324. integer :: itim_init, itim_addvar, itim_write, itim_accu, itim_attr, itim_accu_opt, itim_write_hour, itim_write_day, &
  325. itim_write_mon, itim_write_gather
  326. contains
  327. subroutine output_aerchemmip_init(status)
  328. ! Open files
  329. ! allocate dataholders
  330. use dims, only : newsrun,itau,mlen
  331. use global_data, only : outdir
  332. use datetime, only : tau2date, date2tau
  333. use partools, only : MPI_INFO_NULL, localComm
  334. use optics, only : Optics_Init
  335. use sedimentation, only : ised,nsed
  336. use partools , only : isRoot,myid
  337. use global_data, only : region_dat
  338. use tm5_distgrid, only : gather
  339. use meteodata , only : lsmask_dat,oro_dat
  340. use Binas , only : grav
  341. implicit none
  342. !OUTPUT parameters
  343. integer, intent(out) :: status
  344. !LOCAL parameters
  345. integer :: region !iterator for regions
  346. integer :: nlon_region
  347. integer :: nlat_region
  348. integer :: nlev_region ! also global
  349. integer :: j_var
  350. !integer :: nlev_region ! also global
  351. !integer :: nlev_region ! also global
  352. integer :: itrac
  353. integer :: i_sed
  354. integer :: i,i1,i2,j1,j2,k,j,imr,jmr
  355. character(len=*), parameter :: rname = mname//'/output_aerchemmip_init'
  356. !FIXED VARS
  357. real, dimension(:),pointer :: dxyp
  358. real, allocatable :: arr2d(:,:)
  359. real ::xmcomp
  360. call goLabel(rname)
  361. ! define timers:
  362. call GO_Timer_Def( itim_init, 'output aerchemmip init', status )
  363. IF_NOTOK_RETURN(status=1)
  364. call GO_Timer_Def( itim_write, 'output aerchemmip write', status )
  365. IF_NOTOK_RETURN(status=1)
  366. call GO_Timer_Def( itim_write_gather, 'output aerchemmip write gather', status )
  367. IF_NOTOK_RETURN(status=1)
  368. call GO_Timer_Def( itim_write_day, 'output aerchemmip write day', status )
  369. IF_NOTOK_RETURN(status=1)
  370. call GO_Timer_Def( itim_write_hour, 'output aerchemmip write hour', status )
  371. IF_NOTOK_RETURN(status=1)
  372. call GO_Timer_Def( itim_write_mon, 'output aerchemmip write mon', status )
  373. IF_NOTOK_RETURN(status=1)
  374. call GO_Timer_Def( itim_accu, 'output aerchemmip accu', status )
  375. IF_NOTOK_RETURN(status=1)
  376. call GO_Timer_Def( itim_accu_opt, 'output aerchemmip accu _optics', status )
  377. IF_NOTOK_RETURN(status=1)
  378. call GO_Timer_Def( itim_attr, 'output aerchemmip attr', status )
  379. IF_NOTOK_RETURN(status=1)
  380. call GO_Timer_Def( itim_addvar, 'output aerchemmip addvar', status )
  381. IF_NOTOK_RETURN(status=1)
  382. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  383. if (newsrun) then
  384. !optics?
  385. ! ensure that required meteo is loaded:
  386. ! call Set( sp_dat(region), status, used=.true. )
  387. ! set wavelength information
  388. ! wl: wavelength in microns
  389. ! split: whether to split into contributions from
  390. ! M7 constituents (incl. water)
  391. !TB Have to keep insitu part, since optics-module usest it for comparisons.
  392. allocate( wdep_out( 3 ) )
  393. wdep_out(1)%wl = 0.550 ; wdep_out(1)%split = .true. ; wdep_out(1)%insitu = .false.
  394. wdep_out(2)%wl = 0.440 ; wdep_out(2)%split = .true. ; wdep_out(2)%insitu = .false.
  395. wdep_out(3)%wl = 0.870 ; wdep_out(3)%split = .false. ; wdep_out(3)%insitu = .false.
  396. !wdep_out(4)%wl = 0.350 ; wdep_out(4)%split = .false. ; wdep_out(4)%insitu = .false.
  397. ! get the optics code prepared
  398. call Optics_Init(size(wdep_out), wdep_out, status )
  399. IF_NOTOK_RETURN(status=1)
  400. accumulation_mon=0.0
  401. accumulation_hr=0.0
  402. accumulation_6hr=0.0
  403. accumulation_day=0.0
  404. region=1
  405. ! intermediate structures for budgets
  406. allocate(drydepos(region)%f2dslast(i1:i2,j1:j2,18))
  407. allocate(wetdepos(region)%f2dslast(i1:i2,j1:j2,13))
  408. allocate(emission(region)%f2dslast(i1:i2,j1:j2,13))
  409. !imr = i2-i1+1
  410. !jmr = j2-j1+1
  411. ! these here are the initial budgets (monthly): 0.0
  412. drydepos(region)%f2dslast = 0.0
  413. wetdepos(region)%f2dslast = 0.0
  414. emission(region)%f2dslast = 0.0
  415. imr = global_lli(1)%nlon
  416. jmr = global_lli(1)%nlat
  417. ! for areacella,orog,sftlf
  418. if (isRoot) then
  419. allocate( arr2d(imr,jmr) )
  420. else
  421. allocate( arr2d(1,1) )
  422. endif
  423. arr2d(:,:)=0.0
  424. ! for monthly output
  425. ! initialise with 31 for january
  426. n_days_in_month=31
  427. end if
  428. call GO_Timer_Start( itim_init, status )
  429. IF_NOTOK_RETURN(status=1)
  430. ! AERCHEMMIP only available for global-> region=1
  431. region=1
  432. !Initialise grid definitions
  433. nlon_region = global_lli(region)%nlon
  434. nlat_region = global_lli(region)%nlat
  435. nlev_region = levi%nlev
  436. dimension_data%nlon= nlon_region
  437. dimension_data%nlat= nlat_region
  438. dimension_data%nlev= nlev_region
  439. allocate(dimension_data%lon(nlon_region))
  440. allocate(dimension_data%lat(nlat_region))
  441. allocate(dimension_data%lev(nlev_region))
  442. dimension_data%lon=global_lli(region)%lon_deg
  443. dimension_data%lat=global_lli(region)%lat_deg
  444. ! initialise output timeidx used for keeping track which output steps is written
  445. timeidx_mon=1
  446. timeidx_day=1
  447. timeidx_hr=1
  448. timeidx_6hr=1
  449. ! allocate room for variables
  450. allocate(allvars(n_var_max))
  451. allocate(fixedvars(n_fixed))
  452. if (crescendo_out)then
  453. do i=1,size(crescendo3D)
  454. if (trim(crescendo3D(i))=='mono')then
  455. xmcomp=xmterp
  456. else if (trim(crescendo3D(i))=='nh3')then
  457. xmcomp=xmnh3
  458. else
  459. write(gol,*) 'CRESCENDO 3D monthly with negative molar mass'
  460. xmcomp=-1.0
  461. end if
  462. call add_variable(-1,trim(crescendo3D(i)),trim(crescendo3D(i)),crescendo3Dunit(i),3,status,'crescendo','AERmon',xmcomp)
  463. end do
  464. do i=1,size(crescendo3Dday)
  465. if (trim(crescendo3Dday(i))=='co')then
  466. xmcomp=xmco
  467. else
  468. write(gol,*) 'CRESCENDO 3D daily with negative molar mass'
  469. xmcomp=-1.0
  470. end if
  471. call add_variable(-1,trim(crescendo3Dday(i)),trim(crescendo3Dday(i)),crescendo3Ddayunit(i),3,status,'crescendo','AERday',xmcomp)
  472. end do
  473. do i=1,size(crescendo2D6hr)
  474. if (trim(crescendo2D6hr(i))=='sfdms')then
  475. xmcomp=xmdms
  476. else if (trim(crescendo2D6hr(i))=='sfisop')then
  477. xmcomp=xmisop
  478. else if (trim(crescendo2D6hr(i))=='sfmono')then
  479. xmcomp=xmterp
  480. else
  481. write(gol,*) 'CRESCENDO 2D 6hr with negative molar mass'
  482. write(gol,*) 'gascomp with negative molar mass'
  483. xmcomp=-1.0
  484. end if
  485. call add_variable(-1,trim(crescendo2D6hr(i)),trim(crescendo2D6hr(i)),crescendo2D6hrunit(i),2,status,'crescendo','AER6hr',xmcomp)
  486. end do
  487. do i=1,size(crescendo2Dmon)
  488. call add_variable(-1,trim(crescendo2Dmon(i)),trim(crescendo2Dmon(i)),crescendo2Dmonunit(i),2,status,'crescendo','AERmon',-1.0)
  489. end do
  490. do i=1,size(crescendo2Dhr)
  491. if (trim(crescendo2Dhr(i))=='sfno')then
  492. xmcomp=xmno
  493. else if (trim(crescendo2Dhr(i))=='sfnh3')then
  494. xmcomp=xmnh3
  495. else if (trim(crescendo2Dhr(i))=='sfhno3')then
  496. xmcomp=xmhno3
  497. else
  498. ! -1 so that missing molar mass will be noticed easily
  499. write(gol,*) 'CRESCENDO 2D hr with negative molar mass'
  500. xmcomp=-1.0
  501. end if
  502. call add_variable(-1,trim(crescendo2Dhr(i)),trim(crescendo2Dhr(i)),crescendo2Dhrunit(i),2,status,'crescendo','AERhr',xmcomp)
  503. end do
  504. do i=1,size(crescendo2Dday)
  505. call add_variable(-1,trim(crescendo2Dday(i)),trim(crescendo2Dday(i)),crescendo2Ddayunit(i),2,status,'crescendo','AERday',-1.0)
  506. !call add_variable(-1,trim(crescendo2Dday_new(i,1)),trim(crescendo2Dday_new(i,1)),crescendo2Dday_new(i,2),2,status,'crescendo','AERday',-1.0)
  507. end do
  508. end if
  509. do i=1,size(ps6hr)
  510. call add_variable(-1,trim(ps6hr(i)),trim(ps6hr(i)),ps6hrunit(i),2,status,'ps6h','AER6hr',-1.0)
  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. do i=1,size(hourly_var)
  574. if (trim(hourly_var(i))=='ec550aer')then
  575. call add_variable(-1,trim(hourly_var(i)),'optics '//trim(hourly_var(i)), units(iextunit),3,status,'optics','AER6hr',-1.0)
  576. else
  577. call add_variable(-1,trim(hourly_var(i)),trim(hourly_var(i)),hourly_varunit(i),2,status,'sf1h','AERhr',-1.0)
  578. end if
  579. end do
  580. ! add daily fields
  581. do i=1,size(daily_var)
  582. call add_variable(-1,trim(daily_var(i)),trim(daily_var(i)),daily_varunit(i),2,status,'sf1d','AERday',-1.0)
  583. end do
  584. ! add zonal fields, some fields are repeated (3d/zonal)
  585. do i=1,size(zonal_var)
  586. call add_variable(zonal_idx(i),trim(zonal_var(i)),trim(zonal_var(i)),zonal_varunit(i),3,status,'zonal','AERmonZ',-1.0)
  587. end do
  588. call add_variable(-1,'areacella','cell area','m2',2,status,'fixed','AERfx',-1.0)
  589. call add_variable(-1,'orog','surface_altitude','m',2,status,'fixed','AERfx',-1.0)
  590. call add_variable(-1,'sftlf','land_area_fraction','1',2,status,'fixed','AERfx',-1.0)
  591. !
  592. do j_var = 1, n_vars
  593. ! initialise a single file for each variables as per AERCHEMMIP specification
  594. ! overwrite existing files (clobber)
  595. if (isroot)call MDF_Create( allvars(j_var)%filename, MDF_NETCDF4, MDF_REPLACE, allvars(j_var)%fileunit, status )
  596. IF_NOTOK_RETURN(status=1)
  597. !For each file
  598. ! write grid dimension attributes
  599. if (isroot) call write_dimensions(status, j_var)
  600. IF_NOTOK_RETURN(status=1)
  601. ! write global attributes
  602. if (isroot) call write_attributes(status, j_var)
  603. IF_NOTOK_RETURN(status=1)
  604. !write dimension variables
  605. if (isroot) call write_var(status,j_var)
  606. IF_NOTOK_RETURN(status=1)
  607. if (allvars(j_var)%table_id=='AERfx')then
  608. if (trim(allvars(j_var)%vname)=='areacella')then
  609. ! Gridbox area
  610. dxyp => region_dat(1)%dxyp
  611. do j=j1,j2
  612. allvars(j_var)%data2D(i1:i2,j)=dxyp(j)
  613. end do
  614. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  615. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  616. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  617. else if (trim(allvars(j_var)%vname)=='orog')then
  618. ! Gridbox area
  619. allvars(j_var)%data2D(i1:i2,j1:j2) =oro_dat(region)%data(i1:i2,j1:j2,1)/grav
  620. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  621. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  622. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  623. else if (trim(allvars(j_var)%vname)=='sftlf')then
  624. ! Gridbox area
  625. allvars(j_var)%data2D(i1:i2,j1:j2)=lsmask_dat(1)%data(i1:i2,j1:j2,1)/100.
  626. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  627. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  628. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  629. end if
  630. end if
  631. end do
  632. deallocate(arr2d)
  633. call GO_Timer_End( itim_init, status )
  634. IF_NOTOK_RETURN(status=1)
  635. call goLabel()
  636. status = 0
  637. end subroutine output_aerchemmip_init
  638. subroutine output_aerchemmip_write(region,newhour,status)
  639. use MeteoData, only : temper_dat,sst_dat,albedo_dat,ci_dat,lsp_dat,cp_dat,ssr_dat,str_dat,&
  640. blh_dat,gph_dat,lwc_dat,iwc_dat,cco_dat,cc_dat,humid_dat, m_dat,phlb_dat,sp_dat !
  641. use global_data, only : conv_dat
  642. use GO, only : TDate, NewDate
  643. use go_date,only: days_in_month!
  644. use datetime, only : tau2date,date2tau,julday !
  645. use dims, only : itau,iyear0 !current time
  646. use ebischeme, only : AC_diag_prod,AC_O3_lp,AC_loss
  647. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  648. use partools , only : isRoot,myid
  649. ! use domain_decomp, only: gather
  650. implicit none
  651. logical,intent(in) ::newhour
  652. integer,intent(out)::status
  653. integer::region
  654. integer:: j_var
  655. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  656. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write'
  657. real, allocatable :: arr3d(:,:,:),arr3dh(:,:,:),arr2d(:,:)
  658. integer, dimension(6) :: curdate
  659. ! reference time:
  660. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  661. integer(kind=8) :: itauref ! reftime in seconds
  662. real :: reftime ! seconds from reference time
  663. real :: rangemon
  664. type(Tdate)::curdate_tdate
  665. call goLabel(rname)
  666. call GO_Timer_Start( itim_write_mon, status )
  667. IF_NOTOK_RETURN(status=1)
  668. if (region > 1) then
  669. write(gol,*) 'output_aerhemmip_write: region >1, only available in global mode!'
  670. call goErr
  671. status=1
  672. return
  673. end if
  674. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  675. ! entire region grid size
  676. imr = global_lli(1)%nlon
  677. jmr = global_lli(1)%nlat
  678. lmr = levi%nlev
  679. ! define the reference time in seconds (itauref)
  680. ! (for now in days since 1850-01-01 00:00, local variable)
  681. ! returns the difference to current time, beginning of new step
  682. !
  683. call date2tau( time_reftime6, itauref )
  684. ! calculate reftime as fractional days from itauref, hence division by 86400
  685. ! call date2tau( idater, itaucur )
  686. ! itau is the 1st day of new month at 00:00 so we need to fix the reftime back half a month (15th day)
  687. ! ((cursecond - reftimesecond) / seconds_in_day) - days_in_last_month + 15days
  688. !reftime = (itau - itauref -n_days_in_month*24*3600 + 15*24*3600) / 86400.
  689. reftime = (itau - itauref ) / 86400.
  690. !get current date in integers
  691. call tau2date(itau, curdate)
  692. ! create a TDATE date variable of the previous month (curdate(3)-1)
  693. curdate_tdate=newdate(curdate(1),curdate(2),curdate(3)-1,curdate(4),curdate(5),curdate(6),calender='greg')
  694. ! get days in month and save for next step
  695. n_days_in_month=days_in_month(curdate_tdate)
  696. ! change reftime to beginning of last month (the month data is from)
  697. reftime=reftime-n_days_in_month
  698. !length of the month-1s(in days) for the time_bounds
  699. rangemon=n_days_in_month !-(1.0/86400.0)
  700. ! allocate 3D and 4D global arrays for gathering data
  701. ! only root needs the full array, but it must be allocated in all tasks
  702. if (isRoot) then
  703. allocate( arr3d(imr,jmr,lmr) )
  704. allocate( arr3dh(imr,jmr,lmr+1) )
  705. allocate( arr2d(imr,jmr) )
  706. else
  707. allocate( arr3d(1,1,1) )
  708. allocate( arr3dh(1,1,1) )
  709. allocate( arr2d(1,1) )
  710. endif
  711. arr2d(:,:)=0.0
  712. arr3d(:,:,:)=0.0
  713. arr3dh(:,:,:)=0.0
  714. do j_var =1,n_vars
  715. ! hourly and daily variables are handled separately
  716. if (allvars(j_var)%table_id=='AERhr'.or.allvars(j_var)%table_id=='AER6hr'.or.&
  717. allvars(j_var)%table_id=='AERday'.or.allvars(j_var)%table_id=='AERfx')then
  718. cycle
  719. end if
  720. if (allvars(j_var)%dims==2)then !2D
  721. if (trim(allvars(j_var)%vname)/='minpblz'.and.trim(allvars(j_var)%vname)/='tasmin'.and. &
  722. trim(allvars(j_var)%vname)/='maxpblz'.and.trim(allvars(j_var)%vname)/='tasmax')then
  723. allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_mon)
  724. end if
  725. call GO_Timer_Start( itim_write_gather, status )
  726. IF_NOTOK_RETURN(status=1)
  727. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  728. call GO_Timer_End( itim_write_gather, status )
  729. IF_NOTOK_RETURN(status=1)
  730. IF_NOTOK_RETURN(status=1)
  731. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1,timeidx_mon/), &
  732. count=(/imr,jmr,1/) )
  733. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  734. ! Zero out the accumulated and written data for the next interval
  735. if (trim(allvars(j_var)%vname)=='minpblz' .or. trim(allvars(j_var)%vname)=='tasmin') then
  736. ! put high number so simple comparison is needed for finding minimum
  737. allvars(j_var)%data2D(i1:i2,j1:j2)=1e10
  738. else
  739. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  740. end if
  741. else !3D
  742. if (trim( allvars(j_var)%vname)=='phalf') then !lmr+1
  743. 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)
  744. call GO_Timer_Start( itim_write_gather, status )
  745. IF_NOTOK_RETURN(status=1)
  746. call gather( dgrid(1), allvars(j_var)%data3D , arr3dh(:,:,:), 0, status)
  747. IF_NOTOK_RETURN(status=1)
  748. call GO_Timer_End( itim_write_gather, status )
  749. IF_NOTOK_RETURN(status=1)
  750. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr3dh , status, start=(/1,1,1,timeidx_mon/), &
  751. count=(/imr,jmr,lmr+1,1/) )
  752. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  753. else
  754. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_mon)
  755. call GO_Timer_Start( itim_write_gather, status )
  756. IF_NOTOK_RETURN(status=1)
  757. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  758. IF_NOTOK_RETURN(status=1)
  759. call GO_Timer_End( itim_write_gather, status )
  760. IF_NOTOK_RETURN(status=1)
  761. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr3d , status, start=(/1,1,1,timeidx_mon/), &
  762. count=(/imr,jmr,lmr,1/) )
  763. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  764. end if
  765. ! Zero out the accumulated and written data for the next interval
  766. allvars(j_var)%data3D(i1:i2,j1:j2,:)=0.0
  767. end if
  768. !end if
  769. ! write the date for timestep
  770. 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/) )
  771. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  772. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%bounds_varid,(/ reftime,reftime+rangemon/) , status, &
  773. start=(/1,timeidx_mon/), count=(/2,1/) )
  774. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  775. end do
  776. deallocate( arr3d,arr3dh,arr2d)
  777. ! change time index
  778. timeidx_mon= timeidx_mon + 1
  779. ! accululated time to zero
  780. accumulation_mon=0
  781. ! zero out the chemical production (for mongthly output)
  782. !AC_diag_prod(region)%prod(i1:i2,j1:j2,:,1:3)=0.0
  783. ! zero out the chemical production
  784. !AC_O3_lp(region)%prod(i1:i2,j1:j2,:,1:2)=0.0
  785. ! zero out the chemical production
  786. !AC_loss(region)%prod(i1:i2,j1:j2,:,1:2)=0.0
  787. !status=1
  788. !return
  789. call GO_Timer_End( itim_write_mon, status )
  790. IF_NOTOK_RETURN(status=1)
  791. call goLabel()
  792. status = 0
  793. end subroutine output_aerchemmip_write
  794. subroutine output_aerchemmip_write_daily(region,newday,status)
  795. use MeteoData, only : temper_dat, sst_dat, albedo_dat, ci_dat, lsp_dat, cp_dat, ssr_dat, str_dat, &
  796. blh_dat, gph_dat, lwc_dat, iwc_dat, cco_dat, cc_dat, humid_dat, m_dat, phlb_dat, sp_dat !
  797. use meteodata , only : global_lli, levi
  798. use partools , only : isRoot,myid
  799. use GO, only : TDate, NewDate!
  800. use datetime, only : tau2date,date2tau,julday !
  801. use dims, only : itau,iyear0 !current time
  802. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  803. implicit none
  804. logical,intent(in) ::newday
  805. integer,intent(out)::status
  806. integer::region
  807. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  808. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write'
  809. integer:: j_var
  810. ! reference time:
  811. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  812. integer(kind=8) :: itauref ! reftime in seconds
  813. real :: reftime ! seconds from reference time
  814. real :: rangeday ! for bounds
  815. ! root writes netcdf arrays
  816. real, allocatable :: arr3d(:,:,:), arr2d(:,:)
  817. integer:: imr_f,jmr_f,lmr_f
  818. call goLabel(rname)
  819. call GO_Timer_Start( itim_write_day, status )
  820. IF_NOTOK_RETURN(status=1)
  821. if (region > 1) then
  822. write(gol,*) 'output_aerhemmip_write: region >1, only available in global mode!'
  823. call goErr
  824. status=1
  825. return
  826. end if
  827. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  828. ! entire region grid size
  829. imr = global_lli(1)%nlon
  830. jmr = global_lli(1)%nlat
  831. lmr = levi%nlev
  832. ! allocate 3D and 4D global arrays for gathering data
  833. if (isRoot) then
  834. allocate( arr3d(imr,jmr,lmr) )
  835. allocate( arr2d(imr,jmr) )
  836. else
  837. allocate( arr3d(1,1,1) )
  838. allocate( arr2d(1,1) )
  839. endif
  840. arr2d(:,:)=0.0
  841. arr3d(:,:,:)=0.0
  842. ! define the reference time in seconds (itauref)
  843. ! (for now in days since 1850-01-01 00:00, local variable)
  844. call date2tau( time_reftime6, itauref )
  845. ! calculate reftime as fractional days from itauref, hence division by 86400
  846. ! call date2tau( idater, itaucur )
  847. reftime = (itau - itauref) / 86400. - 1.0
  848. !23h59 as days
  849. rangeday=1.0!(23.0*3600.0+59.0*60.0+59.0)/86400.0
  850. do j_var =1,n_vars
  851. if (allvars(j_var)%table_id/='AERday')then
  852. cycle
  853. end if
  854. if (allvars(j_var)%dims==2)then
  855. if ( trim(allvars(j_var)%vname)/='minpblz' .and. trim(allvars(j_var)%vname)/='tasmin'.and.trim(allvars(j_var)%vname)/='maxpblz'.and. trim(allvars(j_var)%vname)/='tasmax')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'
  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. call PMx_Integrate_0d(region,i,j,1,pm_sizelimit,temp,status)
  2502. !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
  2503. allvars(j_var)%data2D(i,j)=temp/m_dat(region)%data(i,j,1)/dens*dtime!kg kg-1
  2504. else if (trim(allvars(j_var)%vname)=='tas')then
  2505. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*temper_dat(1)%data(i,j,1)!K
  2506. end if
  2507. end do
  2508. end do
  2509. !end if
  2510. ! surface daily variables
  2511. else if (trim(allvars(j_var)%class)=='sf1d')then
  2512. do i=i1,i2
  2513. do j=j1,j2
  2514. if (trim(allvars(j_var)%vname)=='ps')then
  2515. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)!Pa
  2516. else if (trim(allvars(j_var)%vname)=='toz')then
  2517. ! conversion (in order of execution):
  2518. !kg->g (1e3), g->molec (xmo3), m2->cm2(1e-4) , molec-> molec/m2(dxyp) , molec/cm2->dobson (DOBS)
  2519. 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
  2520. else if (trim(allvars(j_var)%vname)=='sfo3max')then
  2521. if (tracers(i,j,1,io3)> allvars(j_var)%data2D(i,j)) then
  2522. allvars(j_var)%data2D(i,j)=tracers(i,j,1,io3)*xmair/xmo3/m_dat(region)%data(i,j,1) !kmole kmole-1
  2523. end if
  2524. else if (trim(allvars(j_var)%vname)=='maxpblz')then
  2525. if (conv_dat(1)%blh(i,j)> allvars(j_var)%data2D(i,j)) then
  2526. allvars(j_var)%data2D(i,j)= conv_dat(1)%blh(i,j)!m
  2527. end if
  2528. else if (trim(allvars(j_var)%vname)=='minpblz')then
  2529. if (conv_dat(1)%blh(i,j)< allvars(j_var)%data2D(i,j)) then
  2530. allvars(j_var)%data2D(i,j)= conv_dat(1)%blh(i,j)!m
  2531. end if
  2532. else if (trim(allvars(j_var)%vname)=='tas')then
  2533. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*temper_dat(1)%data(i,j,1)!K
  2534. else if (trim(allvars(j_var)%vname)=='tasmin')then
  2535. if (temper_dat(1)%data(i,j,1)< allvars(j_var)%data2D(i,j)) then
  2536. allvars(j_var)%data2D(i,j)= temper_dat(1)%data(i,j,1)!K
  2537. end if
  2538. else if (trim(allvars(j_var)%vname)=='tasmax')then
  2539. if (temper_dat(1)%data(i,j,1)> allvars(j_var)%data2D(i,j)) then
  2540. allvars(j_var)%data2D(i,j)= temper_dat(1)%data(i,j,1)!K
  2541. end if
  2542. else if (trim(allvars(j_var)%vname)=='pr')then
  2543. 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
  2544. end if
  2545. end do
  2546. end do
  2547. !end if
  2548. else if (trim(allvars(j_var)%class)=='zonal')then
  2549. ! zonal mean needs to be done afterwards...
  2550. ! So just save the variables as 3D
  2551. do i=i1,i2
  2552. do j=j1,j2
  2553. do k=1,lmr
  2554. if (trim(allvars(j_var)%vname)=='ch4')then
  2555. 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
  2556. else if (trim(allvars(j_var)%vname)=='hno3')then
  2557. 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
  2558. else if (trim(allvars(j_var)%vname)=='o3')then
  2559. 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
  2560. else if (trim(allvars(j_var)%vname)=='ta')then
  2561. allvars(j_var)%data3D(i,j,k)=allvars(j_var)%data3D(i,j,k)+dtime*temper_dat(1)%data(i,j,k)!K
  2562. else if (trim(allvars(j_var)%vname)=='h2o')then
  2563. 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
  2564. else if (trim(allvars(j_var)%vname)=='zg')then
  2565. allvars(j_var)%data3D(i,j,k)= allvars(j_var)%data3D(i,j,k)+dtime*gph_dat(1)%data(i,j,k)!m
  2566. else if (trim(allvars(j_var)%vname)=='ho2')then
  2567. 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
  2568. else if (trim(allvars(j_var)%vname)=='oh')then
  2569. 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
  2570. else if (trim(allvars(j_var)%vname)=='noy')then
  2571. do icomp=1,size( allvars(j_var)%indices(:))
  2572. index= allvars(j_var)%indices(icomp)
  2573. xmcomp=ra(index)
  2574. if (allvars(j_var)%indices(icomp)>0) then
  2575. !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
  2576. if (allvars(j_var)%indices(icomp)<70) then
  2577. 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!???
  2578. else
  2579. 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!???
  2580. end if
  2581. end if
  2582. end do
  2583. end if
  2584. end do
  2585. end do
  2586. end do
  2587. else
  2588. ! optics and fixed are not accumulated here
  2589. ! optics in optics_calc
  2590. ! fixed not at all
  2591. if (trim(allvars(j_var)%class)/='optics' .and. trim(allvars(j_var)%class)/='fixed') then
  2592. write(gol,*) 'output_aerhemmip_accumulate: output class not found!!!',trim(allvars(j_var)%vname),trim(allvars(j_var)%class)
  2593. !call goPr
  2594. call goErr
  2595. status=1
  2596. return
  2597. end if
  2598. end if
  2599. end do
  2600. end if
  2601. ! zero accumulated budget variables for the amount between output steps
  2602. AC_diag_prod(region)%prod(i1:i2,j1:j2,:,1)=0.0
  2603. AC_diag_prod(region)%prod(i1:i2,j1:j2,:,2)=0.0
  2604. AC_diag_prod(region)%prod(i1:i2,j1:j2,:,3)=0.0
  2605. AC_diag_prod(region)%prod(i1:i2,j1:j2,:,4)=0.0
  2606. AC_loss(region)%prod(i1:i2,j1:j2,:,1:2)=0.0
  2607. AC_O3_lp(region)%prod(i1:i2,j1:j2,:,1:2)=0.0
  2608. deallocate(gphx)
  2609. deallocate(tx)
  2610. deallocate(temp_pm)
  2611. deallocate(pres3d)
  2612. deallocate(pres3dh)
  2613. call GO_Timer_Start( itim_accu_opt, status )
  2614. call calculate_optics(1,dhour,l_do_ec550aer_only,status)
  2615. call GO_Timer_End( itim_accu_opt, status )
  2616. call GO_Timer_End( itim_accu, status )
  2617. ! IF_NOTOK_RETURN(status=1)
  2618. call goLabel()
  2619. !status = 1
  2620. end subroutine accumulate_data
  2621. subroutine output_aerchemmip_done(status)
  2622. use partools, only: isRoot,myid
  2623. implicit none
  2624. integer :: status
  2625. character(len=*), parameter :: rname = mname//'/output_aerchemmip_done'
  2626. integer :: j_var, region
  2627. call goLabel(rname)
  2628. region = 1
  2629. if (isroot) then
  2630. do j_var=1,n_vars
  2631. call MDF_Close( allvars(j_var)%fileunit, status )
  2632. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  2633. end do
  2634. end if
  2635. deallocate(wdep_out )
  2636. deallocate(drydepos(region)%f2dslast)
  2637. deallocate(wetdepos(region)%f2dslast)
  2638. deallocate(emission(region)%f2dslast)
  2639. deallocate(dimension_data%lon)
  2640. deallocate(dimension_data%lat)
  2641. deallocate(dimension_data%lev)
  2642. do j_var=1,n_vars
  2643. deallocate(allvars(j_var)%data2D)
  2644. deallocate(allvars(j_var)%data3D)
  2645. end do
  2646. deallocate(allvars)
  2647. deallocate(fixedvars)
  2648. call goLabel()
  2649. status = 0
  2650. end subroutine output_aerchemmip_done
  2651. !subroutine add_variable(itm5,shortname,longname,unit,positive,standardname,varid,fileunit,filename,data_dims,status,class,table,pxmgas)
  2652. subroutine add_variable(itm5,shortname,longname,unit,data_dims,status,class,table,pxmgas)
  2653. use chem_param, only: mode_end_so4,mode_end_pom,mode_end_bc,mode_end_ss,mode_end_dust
  2654. use global_data, only: outdir
  2655. use datetime, only: tau2date, date2tau
  2656. use dims, only: itau,itaue,itaut
  2657. implicit none
  2658. integer:: itm5
  2659. character(len=*),intent(in)::shortname
  2660. character(len=*),intent(in)::longname
  2661. character(len=*)::unit
  2662. character(len=30)::standardname
  2663. character(len=*)::table
  2664. character(len=*),optional::class
  2665. real,optional::pxmgas
  2666. integer:: data_dims
  2667. integer,intent(out)::status
  2668. !LOCAL
  2669. character(len=4)::positive=''
  2670. integer:: fileunit=-1 !defined only when creating a file
  2671. integer:: varid=-1! defined when opening ncfile
  2672. !character(len=120)::filename
  2673. character(len=30)::table_id
  2674. !character(len=30)::source_id
  2675. !character(len=30)::experiment_id
  2676. character(len=30)::member_id
  2677. !character(len=30)::grid_label
  2678. character(len=30)::time_range
  2679. character(len=200)::filename1
  2680. character(len=10)::freq
  2681. real,dimension(:,:),pointer::data2D
  2682. ! real,dimension(:,:),pointer::dataZonal
  2683. real,dimension(:,:,:),pointer::data3D
  2684. real,dimension(:,:,:),pointer::budget
  2685. character(len=*), parameter :: rname = mname//'/output_aerchemmip_add_variable'
  2686. integer ::i1,i2,j1,j2,jmr,imr,lmr
  2687. integer, dimension(6) :: idater, idateend, idatett
  2688. integer :: endmonth, endday
  2689. character(len=30) :: idates
  2690. call tau2date(itau,idater)
  2691. ! define frequency from table
  2692. if (trim(table)=='AERhr')then
  2693. !table id depends on variable
  2694. table_id=table
  2695. freq='1hr'
  2696. else if (trim(table)=='AER6hr')then
  2697. !table id depends on variable
  2698. table_id=table
  2699. freq='6hr'
  2700. else if( trim(table)=='AERmon'.or.trim(table)=='AERmonZ'.or.trim(table)=='Emon')then
  2701. !table id depends on variable
  2702. table_id=table
  2703. freq='mon'
  2704. else if(trim(table)=='AERday')then
  2705. !table id depends on variable
  2706. table_id=table
  2707. freq='day'
  2708. else if(trim(table)=='AERfx')then
  2709. !table id depends on variable
  2710. table_id=table
  2711. freq='na'
  2712. else
  2713. freq='freq-nondefined'
  2714. table_id='table-nondefined'
  2715. end if
  2716. ! CREATE date string for output
  2717. !
  2718. ! ATM assumed that the output is initilised at the beginninh of year
  2719. endmonth=12
  2720. endday=31
  2721. !
  2722. if (freq=='mon')then
  2723. ! By default AERCHEMMIP runs are done by 1-year chunks -> idater(2) - idater(2)+11
  2724. write(idates, '(i4,i2.2,a,i4,i2.2)') idater(1), idater(2),'-', idater(1),endmonth
  2725. else if(freq=='day')then
  2726. !time range form Jan-1 ->Dec-31x
  2727. write(idates, '(i4,2i2.2,a,i4,2i2.2)') idater(1), idater(2), idater(3),'-', idater(1), endmonth, endday
  2728. else if(freq=='1hr')then
  2729. 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'
  2730. else if (freq=='6hr')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,'18','00'
  2732. end if
  2733. !statf(region)%fname = trim(outdir)//'/'//&
  2734. ! trim(f_dataid) //'_'//&
  2735. ! trim(f_model) //'_'//&
  2736. ! trim(aerocom_exper) //'_'//&
  2737. ! trim(f_dimstat)//'_'//&
  2738. ! trim(idates) //'_'//&
  2739. ! trim(aerocom_freq) //'.nc'
  2740. call goLabel(rname)
  2741. call GO_Timer_Start( itim_addvar, status )
  2742. IF_NOTOK_RETURN(status=1)
  2743. !outdir='output'
  2744. ! temporary
  2745. standardname=longname
  2746. ! source_id constant
  2747. !source_id='EC-EARTH-AerChem'
  2748. ! experiment depends on run
  2749. !experiment_id='exp_dynamic'
  2750. member_id='r'//trim(realization_i)//'i'//trim(initialization_i)//'p'//trim(physics_i)//'f'//trim(forcing_i)
  2751. !grid_label='3x2_degrees'
  2752. ! time range has divider in place since it can be omitted alltogether with non-time dependendent variables
  2753. if (trim(table)=='AERfx')then
  2754. time_range=''
  2755. else
  2756. time_range='_'//trim(idates)
  2757. end if
  2758. ! for fixed variables time range should not be written
  2759. n_vars=n_vars+1
  2760. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  2761. ! define sizes for arrays
  2762. imr=i2-i1+1
  2763. jmr=j2-j1+1
  2764. lmr = levi%nlev
  2765. if (trim(shortname)=='phalf') then
  2766. allocate(budget(i1:i2,j1:j2,1:lmr+1))
  2767. else
  2768. allocate(budget(i1:i2,j1:j2,1:lmr))
  2769. end if
  2770. budget(:,:,:)=0.0
  2771. ! 2D variables
  2772. if (data_dims==2) then
  2773. !Allocate holders for data
  2774. allocate(allvars(n_vars)%data2D(i1:i2,j1:j2))
  2775. allocate(allvars(n_vars)%data3D(1,1,1))
  2776. ! allocate local variables
  2777. allocate(data2D(i1:i2,j1:j2))
  2778. allocate(data3D(1,1,1))
  2779. ! zero local data holders
  2780. data2D(:,:)=0.0
  2781. ! dataZonal(:,:)=0.0
  2782. data3D(:,:,:)=0.0
  2783. !init variable
  2784. ! set default for minimum variables to high value
  2785. if (shortname=='minpblz' .or. shortname=='tasmin')then
  2786. data2D(:,:)=1000000.0
  2787. end if
  2788. !create filename
  2789. if (trim(class)=='crescendo')then
  2790. ! 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')
  2791. 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')
  2792. else
  2793. 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')
  2794. end if
  2795. allvars(n_vars)=varfile(itm5,shortname,longname,unit,positive,standardname,data2D,data3D,budget,-1,-1,&
  2796. 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)
  2797. !! LEFT HERE on purpose to see what variables go where in above statement
  2798. !!$ allvars(n_vars)%itm5=itm5
  2799. !!$ allvars(n_vars)%vname=shortname
  2800. !!$ allvars(n_vars)%lname=longname
  2801. !!$ allvars(n_vars)%unit=unit
  2802. !!$ allvars(n_vars)%positive=positive
  2803. !!$ allvars(n_vars)%standard_name=standardname
  2804. !!$ allvars(n_vars)%data2D=data2D
  2805. !!$ allvars(n_vars)%data3D=data3D
  2806. !!$ allvars(n_vars)%budgetdata=data3D
  2807. !!$ allvars(n_vars)varid=-1
  2808. !!$ allvars(n_vars)%filenunit=-1
  2809. !!$ allvars(n_vars)%filename=filename1
  2810. !!$ allvars(n_vars)%dimensions=2
  2811. !!$ allvars(n_vars)%lon_varid=-1
  2812. !!$ allvars(n_vars)%lat_varid=-1
  2813. !!$ allvars(n_vars)%lev_varid=-1
  2814. !!$ allvars(n_vars)%time_varid=-1
  2815. !!$ allvars(n_vars)%bounds_varid=-1
  2816. !!$ allvars(n_vars)%dims=dims
  2817. !!$ allvars(n_vars)%class=class
  2818. !!$ allvars(n_vars)%indices=(/0,0,0,0,0,0,0/))
  2819. !!$ allvars(n_vars)%xmgas=molarweight
  2820. !!$ allvars(n_vars)%table_id=
  2821. ! 3D variables
  2822. else if (data_dims==3) then
  2823. ! allocate holders for data
  2824. allocate(allvars(n_vars)%data2D(1,1))
  2825. if (trim(shortname)=='phalf') then
  2826. allocate(allvars(n_vars)%data3D(i1:i2,j1:j2,1:lmr+1))
  2827. allocate(data3D(i1:i2,j1:j2,1:lmr+1))
  2828. else
  2829. allocate(allvars(n_vars)%data3D(i1:i2,j1:j2,1:lmr))
  2830. allocate(data3D(i1:i2,j1:j2,1:lmr))
  2831. end if
  2832. ! allocate local variables
  2833. ! maybe remove these
  2834. allocate(data2D(1,1))
  2835. !allocate(data3D(i1:i2,j1:j2,1:lmr))
  2836. ! zero local data holders
  2837. data2D(:,:)=0.0
  2838. data3D(:,:,:)=0.0
  2839. !init variable
  2840. if (trim(class)=='crescendo')then
  2841. ! 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')
  2842. 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')
  2843. else
  2844. 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')
  2845. end if
  2846. allvars(n_vars)=varfile(itm5,shortname,longname,unit,positive,standardname,data2D,data3D,budget,-1,-1,&
  2847. 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)
  2848. end if
  2849. ! add chemical info also: (vars beginning with emi,wet,dry)
  2850. select case (trim(shortname(4:)))
  2851. case ('so4')
  2852. allvars(n_vars)%indices(1:7)=(/iso4nus,iso4ais,iso4acs,iso4cos,0,0,0/)!mode_end_so4
  2853. case ('so2')
  2854. allvars(n_vars)%indices(1)=iso2
  2855. case ('oa','emioa')
  2856. !allvars(n_vars)%indices(1:7)=(/ipomais,ipomacs,ipomcos,ipomaii,0,0,0/)!mode_end_pom
  2857. allvars(n_vars)%indices(1:9)=(/ipomais,ipomacs,ipomcos,ipomaii,isoanus,isoaais,isoaacs,isoacos,isoaaii/)!mode_end_pom
  2858. case ('poa','emipoa')
  2859. allvars(n_vars)%indices(1:4)=(/ipomais,ipomacs,ipomcos,ipomaii/)!mode_end_pom
  2860. case ('soa')
  2861. allvars(n_vars)%indices(1:7)=(/isoanus,isoaais,isoaacs,isoacos,isoaaii,0,0/)!mode_end_pom
  2862. case ('bc')
  2863. allvars(n_vars)%indices(1:7)=(/ibcaii,ibcais,ibcacs,ibccos,0,0,0/)!mode_end_bc
  2864. case ('ss','emiss')
  2865. allvars(n_vars)%indices(1:7)=(/issacs,isscos,0,0,0,0,0/)!mode_end_ss
  2866. case ('dust')
  2867. allvars(n_vars)%indices(1:7)=(/iduacs,iducos,iduaci,iducoi,0,0,0/)!mode_end_dust
  2868. case('nox')
  2869. !allvars(n_vars)%indices(1:2)=(/ino,ino2/)
  2870. allvars(n_vars)%indices(1)=inox
  2871. case('voc')
  2872. allvars(n_vars)%indices(1)=1!(/ipar,ieth,iole,iald2,imgly,0,0/)
  2873. case('bvoc')
  2874. allvars(n_vars)%indices(1:2)=(/iterp,iisop/)!ibvoc
  2875. case('nh3','sfnh3')
  2876. allvars(n_vars)%indices(1)=inh3
  2877. case('nh4')
  2878. allvars(n_vars)%indices(1)=inh4
  2879. case('noy')
  2880. allvars(n_vars)%indices(1:11)=(/ ino, iNO2, ino3, iHNO3, iNO3_a, ihno4, in2o5, iPAN, iOrgNtr, ihono, ich3o2no2/)
  2881. !allvars(n_vars)%indices(1)=ino2!(/ ino, iNO2, ino3, iHNO3, iNO3_a, ihno4, in2o5, iPAN, iOrgNtr, ihono, ich3o2no2/)
  2882. case('no3')
  2883. allvars(n_vars)%indices(1)=ino3_a
  2884. case('pm1')
  2885. allvars(n_vars)%indices(1)=-1
  2886. case('pm2p5','sfpm25')
  2887. allvars(n_vars)%indices(1)=-1
  2888. case('pm10')
  2889. allvars(n_vars)%indices(1)=-1
  2890. case('o3')
  2891. allvars(n_vars)%indices(1)=io3
  2892. case('co')
  2893. allvars(n_vars)%indices(1)=ico
  2894. case('dms')
  2895. allvars(n_vars)%indices(1)=idms
  2896. case('isop')
  2897. allvars(n_vars)%indices(1)=iisop
  2898. !case('terp')
  2899. ! allvars(n_vars)%indices(1)=iterp
  2900. end select
  2901. select case (trim(shortname))
  2902. case('noy')
  2903. allvars(n_vars)%indices(1:11)=(/ iNO, ino2, ino3, iHNO3, iNO3_a, ihno4, in2o5, iPAN, iOrgNtr, ihono, ich3o2no2/)
  2904. !allvars(n_vars)%indices(1)=ino2!(/ iNO, ino3, iHNO3, iNO3_a, ihno4, in2o5, iPAN, iOrgNtr, ihono, ich3o2no2/)
  2905. case('areacella')
  2906. allvars(n_vars)%indices(:)=0
  2907. areacella=n_vars
  2908. case('c2h2')
  2909. allvars(n_vars)%indices(1)=-1
  2910. case('c2h6')
  2911. allvars(n_vars)%indices(1)=ic2h6
  2912. case('c3h6')
  2913. allvars(n_vars)%indices(1)=ic3h6
  2914. case('c3h8')
  2915. allvars(n_vars)%indices(1)=ic3h8
  2916. case('ch3coch3')
  2917. allvars(n_vars)%indices(1)=iacet!ich3coch3
  2918. case('ch4')
  2919. allvars(n_vars)%indices(1)=ich4
  2920. case('co')
  2921. allvars(n_vars)%indices(1)=ico
  2922. case('so2')
  2923. allvars(n_vars)%indices(1)=iso2
  2924. case('co2')
  2925. allvars(n_vars)%indices(1)=-1
  2926. case('dms')
  2927. allvars(n_vars)%indices(1)=idms
  2928. case('h2o')
  2929. allvars(n_vars)%indices(1)=-1!ih2o
  2930. case('hcho')
  2931. allvars(n_vars)%indices(1)=ich2o
  2932. case('hcl')
  2933. allvars(n_vars)%indices(1)=-1!ihcl
  2934. case('hno3','sfmmrhno3')
  2935. allvars(n_vars)%indices(1)=ihno3
  2936. case('isop')
  2937. allvars(n_vars)%indices(1)=iisop
  2938. case('n2o')
  2939. allvars(n_vars)%indices(1)=-1!in2o
  2940. case('no', 'sfno')
  2941. allvars(n_vars)%indices(1)=ino
  2942. case('no2','sfno2')
  2943. allvars(n_vars)%indices(1)=ino2
  2944. case('o3','sfo3')
  2945. allvars(n_vars)%indices(1)=io3
  2946. case('o3ste')
  2947. allvars(n_vars)%indices(1)=io3s
  2948. case('oh')
  2949. allvars(n_vars)%indices(1)=ioh
  2950. case('pan')
  2951. allvars(n_vars)%indices(1)=ipan
  2952. !CRESCENDO variables
  2953. case('nh3','sfmmrnh3','sfnh3')
  2954. allvars(n_vars)%indices(1)=inh3
  2955. case('nh4','sfmmrnh4')
  2956. allvars(n_vars)%indices(1)=inh4
  2957. case('sfmmrno3')
  2958. allvars(n_vars)%indices(1)=ino3_a
  2959. case('pm1')
  2960. allvars(n_vars)%indices(1)=-1
  2961. case('pm2p5','sfpm25')
  2962. allvars(n_vars)%indices(1)=-1
  2963. case ('mmraerh2o_1','mmraerh2o_2','mmraerh2o_3','mmraerh2o_4','mmraerh2o')
  2964. allvars(n_vars)%indices(1)=-1
  2965. case ('sfmmrso4')
  2966. allvars(n_vars)%indices(1:4)=(/iso4nus,iso4ais,iso4acs,iso4cos/)
  2967. case ('sfmmrsoa')
  2968. allvars(n_vars)%indices(1:5)=(/isoanus,isoaais,isoaacs,isoacos,isoaaii/)
  2969. case ('sfmmroa')
  2970. allvars(n_vars)%indices(1:4)=(/ipomais,ipomacs,ipomcos,ipomaii/)
  2971. case ('sfmmrbc')
  2972. allvars(n_vars)%indices(1:4)=(/ibcais,ibcacs,ibccos,ibcaii/)
  2973. case ('sfmmrdustbel1','sfmmrdustabv1','sfmmrdustabv10','seddust','sfmmrdust')
  2974. allvars(n_vars)%indices(1:4)=(/iduacs,iducos,iduaci,iducoi/)
  2975. case ('sfmmrss')
  2976. allvars(n_vars)%indices(1:2)=(/issacs,isscos/)
  2977. case ('mmrsu1','sfmmrsu1')
  2978. allvars(n_vars)%indices(1)=iso4nus
  2979. case ('mmrsu2','sfmmrsu2')
  2980. allvars(n_vars)%indices(1)=iso4ais
  2981. case ('mmrsu3','sfmmrsu3')
  2982. allvars(n_vars)%indices(1)=iso4acs
  2983. case ('mmrsu4','sfmmrsu4')
  2984. allvars(n_vars)%indices(1)=iso4cos
  2985. case ('mmrsoa1','sfmmrsoa1')
  2986. allvars(n_vars)%indices(1)=isoanus
  2987. case ('mmrsoa2','sfmmrsoa2')
  2988. allvars(n_vars)%indices(1)=isoaais
  2989. case ('mmrsoa3','sfmmrsoa3')
  2990. allvars(n_vars)%indices(1)=isoaacs
  2991. case ('mmrsoa4','sfmmrsoa4')
  2992. allvars(n_vars)%indices(1)=isoacos
  2993. case ('mmrsoa5','sfmmrsoa5')
  2994. allvars(n_vars)%indices(1)=isoaaii
  2995. case ('mmroa2','sfmmroa2')
  2996. allvars(n_vars)%indices(1)=ipomais
  2997. case ('mmroa3','sfmmroa3')
  2998. allvars(n_vars)%indices(1)=ipomacs
  2999. case ('mmroa4','sfmmroa4')
  3000. allvars(n_vars)%indices(1)=ipomcos
  3001. case ('mmroa5','sfmmroa5')
  3002. allvars(n_vars)%indices(1)=ipomaii
  3003. case ('mmrbc2','sfmmrbc2')
  3004. allvars(n_vars)%indices(1)=ibcais
  3005. case ('mmrbc3','sfmmrbc3')
  3006. allvars(n_vars)%indices(1)=ibcacs
  3007. case ('mmrbc4','sfmmrbc4')
  3008. allvars(n_vars)%indices(1)=ibccos
  3009. case ('mmrbc5','sfmmrbc5')
  3010. allvars(n_vars)%indices(1)=ibcaii
  3011. case ('mmrss3','sfmmrss3')
  3012. allvars(n_vars)%indices(1)=issacs
  3013. case ('mmrss4','sfmmrss4')
  3014. allvars(n_vars)%indices(1)=isscos
  3015. case ('mmrdu3','sfmmrdu3')
  3016. allvars(n_vars)%indices(1)=iduacs
  3017. case ('mmrdu4','sfmmrdu4')
  3018. allvars(n_vars)%indices(1)=iducos
  3019. case ('mmrdu6','sfmmrdu6')
  3020. allvars(n_vars)%indices(1)=iduaci
  3021. case ('mmrdu7','sfmmrdu7')
  3022. allvars(n_vars)%indices(1)=iducoi
  3023. case ('sfndtot','sfnd100','ndtot')
  3024. allvars(n_vars)%indices(1:7)=(/inus_n,iais_n,iacs_n,icos_n,iaii_n,iaci_n,icoi_n/)
  3025. case ('nd1','sfnd1','sfnd1_tst')
  3026. allvars(n_vars)%indices(1)=inus_n
  3027. case ('nd2','sfnd2')
  3028. allvars(n_vars)%indices(1)=iais_n
  3029. case ('nd3','sfnd3')
  3030. allvars(n_vars)%indices(1)=iacs_n
  3031. case ('nd4','sfnd4')
  3032. allvars(n_vars)%indices(1)=icos_n
  3033. case ('nd5','sfnd5')
  3034. allvars(n_vars)%indices(1)=iaii_n
  3035. case ('nd6','sfnd6')
  3036. allvars(n_vars)%indices(1)=iaci_n
  3037. case ('nd7','sfnd7')
  3038. allvars(n_vars)%indices(1)=icoi_n
  3039. ! case('sfmmrnh3')
  3040. ! allvars(n_vars)%indices(1)=inh3
  3041. ! case('sfmmrnh4')
  3042. ! allvars(n_vars)%indices(1)=inh4
  3043. case('drydms')
  3044. allvars(n_vars)%indices(1)=idms
  3045. case('wetdms')
  3046. allvars(n_vars)%indices(1)=idms
  3047. case('dryno3')
  3048. allvars(n_vars)%indices(1)=ino3_a
  3049. case('wetno3')
  3050. allvars(n_vars)%indices(1)=ino3_a
  3051. case('dryhno3')
  3052. allvars(n_vars)%indices(1)=ihno3
  3053. case('wethno3')
  3054. allvars(n_vars)%indices(1)=ihno3
  3055. case('dryno2')
  3056. allvars(n_vars)%indices(1)=ino2
  3057. case('dryno')
  3058. allvars(n_vars)%indices(1)=ino
  3059. case('drypan')
  3060. allvars(n_vars)%indices(1)=ipan
  3061. case('sfo3max')
  3062. allvars(n_vars)%indices(1)=io3
  3063. case('mono')
  3064. allvars(n_vars)%indices(1)=iterp
  3065. case('co2mass')
  3066. allvars(n_vars)%indices(1)=-1! not available
  3067. case('chepsoa','chepsoa3d','chepsoa2d')
  3068. allvars(n_vars)%indices(1)=-1
  3069. case('flashrate')
  3070. allvars(n_vars)%indices(1)=-1
  3071. case('md')
  3072. allvars(n_vars)%indices(1)=-1
  3073. case('sedustCI')
  3074. allvars(n_vars)%indices(1)=iducoi
  3075. case('depdust')
  3076. allvars(n_vars)%indices(1:4)=(/iduacs,iducos,iduaci,iducoi/)
  3077. case('concdust')
  3078. allvars(n_vars)%indices(1:4)=(/iduacs,iducos,iduaci,iducoi/)
  3079. case('conccn')
  3080. allvars(n_vars)%indices(1:7)=(/inus_n,iais_n,iacs_n,icos_n,iaii_n,iaci_n,icoi_n/)
  3081. case('sconcss')
  3082. allvars(n_vars)%indices(1:2)=(/issacs,isscos/)
  3083. case('loaddust')
  3084. allvars(n_vars)%indices(1:4)=(/iduacs,iducos,iduaci,iducoi/)
  3085. case('lossch4')
  3086. allvars(n_vars)%indices(1)=ich4
  3087. case('lossco')
  3088. allvars(n_vars)%indices(1)=ico
  3089. end select
  3090. if (class=='crescendo') then
  3091. select case (trim(shortname))
  3092. case('od440dust')
  3093. allvars(n_vars)%indices(1)=-1
  3094. if (freq=='day' .and. data_dims==2)then
  3095. od440dustday=n_vars
  3096. end if
  3097. case('od440aer')
  3098. allvars(n_vars)%indices(1)=-1
  3099. if (freq=='1hr') then
  3100. od440aerhr=n_vars
  3101. else if (freq=='day') then
  3102. od440aerdaily=n_vars
  3103. else if (freq=='mon') then
  3104. od440aermonthly=n_vars
  3105. end if
  3106. case('od550aer')
  3107. allvars(n_vars)%indices(1)=-1
  3108. if (freq=='1hr')then
  3109. od550aerhr=n_vars
  3110. end if
  3111. case('od550dust')
  3112. if (freq=='day' .and. data_dims==2)then
  3113. od550dust2dday=n_vars
  3114. end if
  3115. case('od5503ddust')
  3116. if (freq=='day' .and. data_dims==3)then
  3117. od550dust3dday=n_vars
  3118. end if
  3119. case('ec550aer')
  3120. allvars(n_vars)%indices(1)=-1
  3121. ec550aermon=n_vars
  3122. end select
  3123. end if
  3124. if (class=='sf1d') then
  3125. select case (trim(shortname))
  3126. case('od550aer')
  3127. allvars(n_vars)%indices(1)=-1
  3128. od550aerdaily=n_vars
  3129. case('sfo3max')
  3130. allvars(n_vars)%indices(1)=io3
  3131. end select
  3132. end if
  3133. if(class=='optics') then
  3134. select case (trim(shortname))
  3135. case('ec550aer')
  3136. allvars(n_vars)%indices(1)=-1
  3137. ec550aer=n_vars
  3138. case('od550aer')
  3139. allvars(n_vars)%indices(1)=-1
  3140. od550aer=n_vars
  3141. case('od550so4')
  3142. allvars(n_vars)%indices(1)=-1
  3143. od550so4=n_vars
  3144. case('od550bc')
  3145. allvars(n_vars)%indices(1)=-1
  3146. od550bc=n_vars
  3147. case('od550oa')
  3148. allvars(n_vars)%indices(1)=-1
  3149. od550oa=n_vars
  3150. case('od550soa')
  3151. allvars(n_vars)%indices(1)=-1
  3152. od550soa=n_vars
  3153. case('od550ss')
  3154. allvars(n_vars)%indices(1)=-1
  3155. od550ss=n_vars
  3156. case('od550dust')
  3157. allvars(n_vars)%indices(1)=-1
  3158. od550dust=n_vars
  3159. case('od550no3')
  3160. allvars(n_vars)%indices(1)=-1
  3161. od550no3=n_vars
  3162. case('od550aerh2o')
  3163. allvars(n_vars)%indices(1)=-1
  3164. od550aerh2o=n_vars
  3165. case('od550lt1aer')
  3166. allvars(n_vars)%indices(1)=-1
  3167. od550lt1aer=n_vars
  3168. case('abs550aer')
  3169. allvars(n_vars)%indices(1)=-1
  3170. abs550aer=n_vars
  3171. case('od440aer')
  3172. allvars(n_vars)%indices(1)=-1
  3173. if (freq=='mon') then
  3174. od440aer=n_vars
  3175. !else if (freq=='day') then
  3176. ! od440aerdaily=n_vars
  3177. end if
  3178. case('od350aer')
  3179. allvars(n_vars)%indices(1)=-1
  3180. od350aer=n_vars
  3181. case('od870aer')
  3182. allvars(n_vars)%indices(1)=-1
  3183. od870aer=n_vars
  3184. end select
  3185. end if
  3186. call goLabel()
  3187. status = 0
  3188. call GO_Timer_End( itim_addvar, status )
  3189. IF_NOTOK_RETURN(status=1)
  3190. end subroutine add_variable
  3191. subroutine write_attributes(status,j_var)
  3192. implicit none
  3193. integer :: j_var
  3194. integer,intent(out)::status
  3195. character(len=*), parameter :: rname = mname//'/output_aerchemmip_writeattr'
  3196. call goLabel(rname)
  3197. call GO_Timer_Start( itim_attr, status )
  3198. IF_NOTOK_RETURN(status=1)
  3199. call MDF_Put_Att( allvars(j_var)%fileunit, MDF_GLOBAL, 'title', 'Model output for Aerchemmip', status )
  3200. IF_NOTOK_MDF(fid= allvars(j_var)%fileunit)
  3201. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'units', 'degrees_east', status)
  3202. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3203. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'axis', 'X', status)
  3204. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3205. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'long_name', 'longitude', status)
  3206. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3207. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'standard_name', 'longitude', status)
  3208. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3209. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'units', 'degrees_north', status)
  3210. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3211. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'axis', 'Y', status)
  3212. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3213. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'long_name', 'latitude', status)
  3214. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3215. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'standard_name', 'latitude', status)
  3216. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3217. ! allvars(j_var)%lev_varid
  3218. if (allvars(j_var)%dims==3) then
  3219. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'units', 'level', status)
  3220. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3221. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'axis', 'Z', status)
  3222. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3223. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'long_name', 'hybrid model level at layer midpoints', status)
  3224. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3225. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'standard_name', 'hybrid_model_level', status)
  3226. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3227. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'formula', 'a+b*ps', status)
  3228. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3229. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'positive', 'up', status)
  3230. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3231. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyam_varid , 'long_name', 'hybrid A coefficient at layer midpoints', status)
  3232. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3233. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyam_varid , 'units', 'Pa', status)
  3234. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3235. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybm_varid , 'long_name', 'hybrid B coefficient at layer midpoints', status)
  3236. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3237. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybm_varid , 'units', '1', status)
  3238. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3239. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyai_varid , 'long_name', 'hybrid A coefficient at layer interfaces', status)
  3240. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3241. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyai_varid , 'units', 'Pa', status)
  3242. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3243. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybi_varid , 'long_name', 'hybrid B coefficient at layer interfaces', status)
  3244. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3245. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybi_varid , 'units', '1', status)
  3246. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3247. END if
  3248. if (allvars(j_var)%table_id/='AERfx')then
  3249. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'units', 'days since 1750-01-01 00:00:00', status)
  3250. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3251. ! call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'axis', 'X', status)
  3252. ! IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3253. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'calendar', 'gregorian', status)
  3254. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3255. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'long_name', 'time', status)
  3256. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3257. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'axis', 'T', status)
  3258. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3259. !time bounds
  3260. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'bounds', 'time_bounds', status)
  3261. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3262. end if
  3263. !experiment=
  3264. !CMIP6 global attributes:
  3265. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'Conventions', 'CF-1.7 CMIP-6.0 UGRID-0.9', status)
  3266. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'activity_id', 'AerChemMIP', status)
  3267. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'branch_method','', status)
  3268. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'creation_date','', status)
  3269. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'data_specs_version','1.0.0', status)
  3270. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'experiment',trim(experiment), status)
  3271. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'experiment_id',trim(experiment_id), status)
  3272. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'forcing_index',trim(forcing_i), status)
  3273. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'frequency',trim(allvars(j_var)%freq), status)
  3274. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'further_info_url','MISSING', status)
  3275. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'grid','native '//trim(grid)//' degree grid', status)!module variables
  3276. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'grid_label',trim(grid_label), status)!module variables
  3277. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'initialization_index',trim(initialization_i), status)
  3278. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'institution','KNMI, The Netherlands; SMHI, Sweden; DMI, Denmark; &
  3279. &AEMET, Spain; Met Eireann, Ireland; CNR-ISAC, Italy; Instituto de Meteorologia, Portugal; FMI, Finland; BSC, Spain; &
  3280. &Centro de Geofisica, University of Lisbon, Portugal; ENEA, Italy; Geomar, Germany; Geophysical Institute, University of Bergen, Norway; &
  3281. &ICHEC, Ireland; ICTP, Italy; IMAU, The Netherlands; IRV, Sweden; Lund University, Sweden; &
  3282. &Meteorologiska Institutionen, Stockholms University, Sweden; Niels Bohr Institute, University of Copenhagen, Denmark; &
  3283. &NTNU, Norway; SARA, The Netherlands; Unite ASTR, Belgium; Universiteit Utrecht, The Netherlands; &
  3284. &Universiteit Wageningen, The Netherlands; University College Dublin, Ireland; Vrije Universiteit Amsterdam, the Netherlands; &
  3285. &University of Helsinki, Finland; KIT, Karlsruhe, Germany; USC, University of Santiago de Compostela, Spain; &
  3286. &Uppsala Universitet, Sweden; NLeSC, Netherlands eScience Center, The Netherlands', status)
  3287. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'institution_id','EC-Earth-Consortium', status)
  3288. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'license','NEEDS DEFINING', status)
  3289. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'mip_era','CMIP6', status)
  3290. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'nominal_resolution','250 km', status)!dmax
  3291. !dmax=r*phi/2*(1+((phi**2+lamb**2)/(phi*lamb))*np.arctan(lamb/phi))=348 r=6371, phi=2(lat), lamb=3(long)
  3292. !CMIP6 global attributes: 100 < dmax < 350 -> nominal resolution 250 km
  3293. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'physics_index',trim(physics_i), status)
  3294. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'product','output', status)!only choice
  3295. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'realization_index',trim(realization_i), status)!1 for primary or single realization
  3296. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'realm',trim(realm), status)! depends on run, some are AGCM
  3297. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source',trim(source), status)!
  3298. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source_id',trim(source_id), status)
  3299. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source_type',trim(source_type), status)
  3300. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'sub_experiment','', status)
  3301. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'sub_experiment_id','', status)
  3302. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'table_id',trim(allvars(j_var)%table_id), status)
  3303. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'tracking_id','', status)
  3304. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variable_id',trim(allvars(j_var)%vname), status)
  3305. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variant_label','', status)
  3306. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variant_label','', status)
  3307. call GO_Timer_End( itim_attr, status )
  3308. IF_NOTOK_RETURN(status=1)
  3309. call goLabel()
  3310. status = 0
  3311. end subroutine write_attributes
  3312. subroutine write_dimensions(status,j_var)
  3313. use dims, only : iyear0 !current year
  3314. use go_date, only : days_in_year,newDate
  3315. use partools , only : isRoot,myid
  3316. implicit none
  3317. integer :: j_var
  3318. integer,intent(out)::status
  3319. integer :: i1,i2,j1,j2,imr,jmr,lmr
  3320. integer :: lon_varid,lonid,lon_dimid
  3321. integer :: lat_varid,latid,lat_dimid
  3322. integer :: lev_varid,levid,lev_dimid
  3323. integer :: hym_varid,hym_dimid
  3324. integer :: hyi_varid,hyi_dimid
  3325. integer :: time_varid,timeid,time_dimid,bounds_dimid,bounds_varid,boudid
  3326. ! most of data is monthly mean, but change to dynamic number of output steps needed
  3327. integer :: nout_steps!=12
  3328. integer :: nhym
  3329. integer :: nhyi
  3330. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write_dim'
  3331. call goLabel(rname)
  3332. ! define dimensions
  3333. !call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3334. imr=dimension_data%nlon
  3335. jmr=dimension_data%nlat
  3336. lmr=dimension_data%nlev
  3337. nhym=lmr
  3338. nhyi=lmr+1
  3339. ! With parallel netcdf whole netcdf must be reserved at the time of initialisation
  3340. ! therefore we need to know the number of output steps per file.
  3341. ! Define number of output steps in a file depending on the output frequency
  3342. ! use newdate to create TDate structure, and use that in days_in_year
  3343. if (allvars(j_var)%table_id=='AERhr')then
  3344. nout_steps=24*days_in_year(newdate(iyear0))
  3345. else if (allvars(j_var)%table_id=='AER6hr')then
  3346. nout_steps=4*days_in_year(newdate(iyear0))
  3347. else if (allvars(j_var)%table_id=='AERday')then
  3348. nout_steps=days_in_year(newdate(iyear0))
  3349. else if (allvars(j_var)%table_id=='AERmon'.or. (allvars(j_var)%table_id=='AERmonZ'))then
  3350. nout_steps=12
  3351. end if
  3352. if (isroot) then
  3353. !DEFINE DIMENSIONS
  3354. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lon', imr,lon_dimid, status )
  3355. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3356. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lat', jmr, lat_dimid, status )
  3357. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3358. if (allvars(j_var)%dims==3) then
  3359. if (trim(allvars(j_var)%vname)=='phalf') then
  3360. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lev', lmr+1, lev_dimid, status )
  3361. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3362. else
  3363. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lev', lmr, lev_dimid, status )
  3364. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3365. end if
  3366. end if
  3367. if (allvars(j_var)%table_id/='AERfx')then
  3368. !call MDF_Def_Dim( allvars(j_var)%fileunit, 'time', nout_steps, time_dimid, status )
  3369. call MDF_Def_Dim( allvars(j_var)%fileunit, 'time', MDF_UNLIMITED, time_dimid, status )
  3370. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3371. call MDF_Def_Dim( allvars(j_var)%fileunit, 'bounds', 2, bounds_dimid, status )
  3372. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3373. end if
  3374. if (allvars(j_var)%dims==3) then
  3375. call MDF_Def_Dim( allvars(j_var)%fileunit, 'nhym', nhym, hym_dimid, status )
  3376. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3377. call MDF_Def_Dim( allvars(j_var)%fileunit, 'nhyi', nhyi, hyi_dimid, status )
  3378. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3379. end if
  3380. ! define dimension variables
  3381. ! longitude
  3382. call MDF_Def_Var( allvars(j_var)%fileunit, 'lon', MDF_DOUBLE, &
  3383. (/ lon_dimid/), allvars(j_var)%lon_varid, status )
  3384. ! define latitude variable
  3385. call MDF_Def_Var( allvars(j_var)%fileunit, 'lat', MDF_DOUBLE, &
  3386. (/ lat_dimid/), allvars(j_var)%lat_varid, status )
  3387. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3388. ! level
  3389. if (allvars(j_var)%dims==3) then
  3390. call MDF_Def_Var( allvars(j_var)%fileunit, 'lev', MDF_DOUBLE, &
  3391. (/ lev_dimid/), allvars(j_var)%lev_varid, status )
  3392. end if
  3393. if (allvars(j_var)%table_id/='AERfx')then
  3394. call MDF_Def_Var( allvars(j_var)%fileunit, 'time', MDF_DOUBLE, &
  3395. (/ time_dimid/), allvars(j_var)%time_varid, status )
  3396. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3397. call MDF_Def_Var( allvars(j_var)%fileunit, 'time_bounds', MDF_DOUBLE, &
  3398. (/ bounds_dimid,time_dimid/), allvars(j_var)%bounds_varid, status )
  3399. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3400. end if
  3401. if (allvars(j_var)%dims==3) then
  3402. ! define hybm variable
  3403. call MDF_Def_Var( allvars(j_var)%fileunit, 'hybm', MDF_DOUBLE, &
  3404. (/ hym_dimid/), allvars(j_var)%hybm_varid, status )
  3405. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3406. ! define hyam variable
  3407. call MDF_Def_Var( allvars(j_var)%fileunit, 'hyam', MDF_DOUBLE, &
  3408. (/ hym_dimid/), allvars(j_var)%hyam_varid, status )
  3409. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3410. ! define hybi variable
  3411. call MDF_Def_Var( allvars(j_var)%fileunit, 'hybi', MDF_DOUBLE, &
  3412. (/ hyi_dimid/), allvars(j_var)%hybi_varid, status )
  3413. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3414. ! define hyai variable
  3415. call MDF_Def_Var( allvars(j_var)%fileunit, 'hyai', MDF_DOUBLE, &
  3416. (/ hyi_dimid/), allvars(j_var)%hyai_varid, status )
  3417. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3418. end if
  3419. ! * Write out dimension variable values
  3420. ! Write out hybm
  3421. if (allvars(j_var)%dims==3) then
  3422. ! midpoints
  3423. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hybm_varid,levi%fb, status)
  3424. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3425. ! Write out hyam
  3426. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hyam_varid,levi%fa, status)
  3427. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3428. ! interfaces
  3429. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hybi_varid,levi%b, status)
  3430. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3431. ! Write out hyai
  3432. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hyai_varid,levi%a, status)
  3433. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3434. end if
  3435. ! Write out the longitudes
  3436. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%lon_varid, dimension_data%lon, status)
  3437. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3438. !write out the latitude to variable
  3439. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%lat_varid, dimension_data%lat, status)
  3440. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3441. if (allvars(j_var)%dims==3) then
  3442. if (trim(allvars(j_var)%vname)=='phalf') then
  3443. ! Write out the levels
  3444. 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)
  3445. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3446. else
  3447. 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)
  3448. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3449. end if
  3450. end if
  3451. ! Time will be written during output write -steps
  3452. end if
  3453. call goLabel()
  3454. status = 0
  3455. end subroutine write_dimensions
  3456. subroutine write_var(status,j_var)
  3457. implicit none
  3458. integer :: j_var
  3459. integer,intent(out)::status
  3460. integer :: i1,i2,j1,j2,imr,jmr,lmr
  3461. integer :: lon_varid,lonid
  3462. integer :: lat_varid,latid
  3463. integer :: lev_varid,levid
  3464. integer :: time_varid,timeid
  3465. character(len=*), parameter :: rname = mname//'/output_aerchemmip_write_dim'
  3466. call goLabel(rname)
  3467. ! define dimensions
  3468. !call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  3469. imr=dimension_data%nlon
  3470. jmr=dimension_data%nlat
  3471. lmr=dimension_data%nlev
  3472. ! define dimension variables
  3473. ! longitude
  3474. if (allvars(j_var)%dims==2.and.allvars(j_var)%table_id/='AERfx') then
  3475. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  3476. (/allvars(j_var)%lon_varid, allvars(j_var)%lat_varid, allvars(j_var)%time_varid/), allvars(j_var)%varid, status )
  3477. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3478. else if (allvars(j_var)%dims==2.and.allvars(j_var)%table_id=='AERfx') then
  3479. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  3480. (/allvars(j_var)%lon_varid, allvars(j_var)%lat_varid/), allvars(j_var)%varid, status )
  3481. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3482. else
  3483. !(allvars(j_var)%dims==3)
  3484. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  3485. (/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 )
  3486. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3487. end if
  3488. ! Write out the longitudes
  3489. call MDF_Put_Att( allvars(j_var)%fileunit, allvars(j_var)%varid, 'long_name', trim(allvars(j_var)%lname), status )
  3490. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3491. call MDF_Put_Att(allvars(j_var)%fileunit,allvars(j_var)%varid, 'standard_name', trim(allvars(j_var)%standard_name), status )
  3492. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3493. call MDF_Put_Att(allvars(j_var)%fileunit , allvars(j_var)%varid, 'units', trim(allvars(j_var)%unit), status )
  3494. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3495. call MDF_EndDef( allvars(j_var)%fileunit, status )
  3496. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  3497. call goLabel()
  3498. status = 0
  3499. end subroutine write_var
  3500. subroutine calculate_optics( region, dhour, l_do_ec550aer_only,status)
  3501. use optics, only : optics_aop_get
  3502. use MeteoData, only : gph_dat,temper_dat
  3503. USE toolbox, only : ltropo_ifs, lvlpress
  3504. use dims, only : lm
  3505. implicit none
  3506. integer :: i, j, k, imr, jmr, lmr, lwl, dtime
  3507. integer :: i1, i2, j1, j2,ivar
  3508. integer :: ie, je ! indices for subdomain extended with halo cells
  3509. integer, parameter :: l_halo=1
  3510. logical :: polar
  3511. integer :: istat, imode
  3512. real :: dens, load_tmp
  3513. Real, Dimension(:,:,:), Allocatable :: aop_output_ext ! extinctions
  3514. Real, Dimension(:,:), Allocatable :: aop_output_a ! single scattering albedo
  3515. Real, Dimension(:,:), Allocatable :: aop_output_g ! assymetry factor
  3516. Real, Dimension(:,:,:), Allocatable :: aop_output_add ! additional parameters
  3517. real, dimension(:,:,:,:,:), allocatable :: opt_ext
  3518. real, dimension(:,:,:,:), allocatable :: opt_a
  3519. real, dimension(:,:,:,:), allocatable :: opt_g
  3520. real, dimension(:,:,:,:,:), allocatable :: opt_add
  3521. real, dimension(:,:,:), allocatable :: volume
  3522. real, dimension(:,:), allocatable :: temp2d
  3523. real, dimension(:,:), allocatable :: tempdust2dday
  3524. real, dimension(:,:), allocatable :: tempdust2d440day
  3525. integer :: ncontr, lvec, lct, l, indoffset, nwl
  3526. integer :: nadd, nadd_max, indoffset_stat, indabs
  3527. integer :: iadd
  3528. integer :: region,dhour,status
  3529. real :: no3fac, wght, dwght, tabs
  3530. real,dimension(:),allocatable :: tx
  3531. integer :: itropo
  3532. real, dimension(:,:,:), pointer :: gph ! height (incl. oro)
  3533. real,dimension(:,:,:), pointer :: t ! temperature (K)
  3534. logical :: l_do_ec550aer_only
  3535. character(len=*), parameter :: rname = mname//'/output_aerchemmip_optics'
  3536. call goLabel(rname)
  3537. ! grid size
  3538. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2, hasNorthPole=polar )
  3539. imr = i2-i1+1
  3540. jmr = j2-j1+1
  3541. lmr = levi%nlev
  3542. allocate(tx(lm(region)))
  3543. t => temper_dat (region)%data
  3544. gph => gph_dat (region)%data
  3545. ! ---------------------
  3546. ! DO OPTICS IN PARALLEL
  3547. ! ---------------------
  3548. ! steps needed for that:
  3549. ! 1) according to the parallelisation there is different container sizes for
  3550. ! the results of the optics; these have to be allocated correctly
  3551. ! (aop_output_ext/a/g/add)
  3552. ! 2) the optics code is called (init/calculate_aop/done), see documentation
  3553. ! in the optics module
  3554. ! 3) the distributed fields (levels/tracers) are reshaped to global fields
  3555. ! (opt_ext/a/g/add), according to parallelisation
  3556. ! 4) fields are communicated such that the result contains the right
  3557. ! total extinctions, albedos, asymmetry factors etc.
  3558. ! 5) post-calculations (AOD etc.) are done and results are written
  3559. ! to mixf%../statf% containers as well as to the AOD dump files
  3560. ! 6) done...
  3561. ! ------------ REMARKS
  3562. ! IMPOSSIBLE / TOO EXPENSIVE (from the AEROCOM list of parameters for QUICKLOOK)
  3563. ! - gf @ 90% RH
  3564. ! - "AOD@550nm SOA", "AOD@550nm BB"
  3565. ! ---------------------------------
  3566. ! fill current M7 state into an appropriate container
  3567. ! and allocate output fields (ext,a,g)
  3568. ! ------------------------------------
  3569. ! ----- A T T E N T I O N ---------
  3570. ! in case for a 'split', we need a field big enough to contain
  3571. ! various contributions
  3572. ! (to be synchronously changed with optics_aop_calculate!!)
  3573. ! ncontr is here number of contributors
  3574. ! Total, SO4, BC, OC, SS, DU, NO3, Water, Fine, Fine Dust, Fine SS
  3575. ! Total(water), Total(nowater)
  3576. !ncontr = 10
  3577. ncontr = 12
  3578. ! Total, SO4, BC, OC,SOA, SS, DU, NO3, Water, lt1aer
  3579. dtime=dhour*3600
  3580. !TB Following additional fields are nnecessary but call to optics needs it...
  3581. ! Additional fields for surface dry aerosol
  3582. ! to be used for validation against in-situ data:
  3583. ! extinction, absorption, asymmetry factor
  3584. ! fine-mode contribution to extinction, absorption
  3585. nadd = 5
  3586. lvec = imr*jmr*lmr
  3587. ! allocate output fields for optics_calculate_aop
  3588. allocate( aop_output_ext(lvec, size(wdep_out), ncontr ) ) ! extinction
  3589. allocate( aop_output_a (lvec, size(wdep_out) ) ) ! single scattering albedo
  3590. allocate( aop_output_g (lvec, size(wdep_out) ) ) ! asymmetry factor
  3591. allocate( aop_output_add(lvec, size(wdep_out), nadd ) ) ! extinction/absorption due to dry aerosol at surface
  3592. call optics_aop_get(lvec, region, size(wdep_out),wdep_out, ncontr, .false., aop_output_ext, aop_output_a, aop_output_g, &
  3593. status, aop_output_add )
  3594. IF_NOTOK_RETURN(status=1)
  3595. ! allocate here result arrays for ext, abs, ssa, asymmetry parameter, additional parameters (PM10)
  3596. ! ncontr is number of contributors for 'split'
  3597. allocate( opt_ext( i1:i2, j1:j2, lmr, size(wdep_out), ncontr ) ) ; opt_ext = 0.0
  3598. allocate( opt_a ( i1:i2, j1:j2, lmr, size(wdep_out) ) ) ; opt_a = 0.0
  3599. allocate( opt_g ( i1:i2, j1:j2, lmr, size(wdep_out) ) ) ; opt_g = 0.0
  3600. allocate( opt_add( i1:i2, j1:j2, lmr, size(wdep_out), nadd ) ) ; opt_add = 0.0
  3601. ! ---------------------------------
  3602. ! unpack results from calculate_aop
  3603. ! ---------------------------------
  3604. do lwl = 1, size(wdep_out)
  3605. if( wdep_out(lwl)%split ) then
  3606. ! fill the array for the extinction coefficients of contributors
  3607. do lct = 1, ncontr
  3608. opt_ext(:,:,:,lwl,lct) = reshape( aop_output_ext(:,lwl,lct), (/imr,jmr,lmr/) )
  3609. end do
  3610. else
  3611. ! fill only total extinction coefficients
  3612. opt_ext(:,:,:,lwl,1) = reshape( aop_output_ext(:,lwl,1), (/imr,jmr,lmr/) )
  3613. endif
  3614. opt_a(:,:,:,lwl) = reshape( aop_output_a(:,lwl),(/imr,jmr,lmr/) )
  3615. opt_g(:,:,:,lwl) = reshape( aop_output_g(:,lwl),(/imr,jmr,lmr/) )
  3616. end do ! lwl
  3617. ! free temporary arrays for results from calculate_aop
  3618. deallocate( aop_output_ext )
  3619. deallocate( aop_output_a )
  3620. deallocate( aop_output_g )
  3621. deallocate( aop_output_add )
  3622. ! the following sections assume that for 550nm there is splitted information
  3623. ! available and that there is *NO* split for other wavelengths!
  3624. if( count( (wdep_out(:)%wl == 0.550) .and. wdep_out(:)%split ) /= 1 ) then
  3625. write(gol,*) 'user_output_aerocom: wrong setup with splitted AOD information.'; call goErr
  3626. TRACEBACK
  3627. status=1; return
  3628. end if
  3629. ! -------------------------------------
  3630. ! here additional calculations and
  3631. ! file writing begin
  3632. ! -------------------------------------
  3633. ! cycle over wavelengths
  3634. do lwl = 1, size(wdep_out)
  3635. if (.not. l_do_ec550aer_only)then
  3636. ! if split and if wavelength=550nm
  3637. if( wdep_out(lwl)%split ) then
  3638. if (wdep_out(lwl)%wl == 0.550) then
  3639. ! for 550nm:
  3640. ! 1) AODs
  3641. ! fill for contributors (total, SO4, BC, POM, SS, DU, NO3, H2O, fine, fine dust, fine SS)
  3642. ! 2) Absorption for 550nm (45)
  3643. ! Extinction is here the sum of scattering and absorption and
  3644. ! the scattering part is given by the albedo (SSA). Thus the
  3645. ! remainder is absorption: Abs = Ext * (1 - SSA)
  3646. indoffset = od550aer
  3647. allocate(temp2d(i1:i2,j1:j2))
  3648. allocate(tempdust2dday(i1:i2,j1:j2))
  3649. do lct = 1, ncontr
  3650. temp2d = 0.0
  3651. tempdust2dday=0.0
  3652. do j = j1, j2
  3653. do i = i1, i2
  3654. ! multiply with height elements and sum up
  3655. tabs = 0.0
  3656. ! AOD output will only be for troposphere in data request
  3657. tx(:)=t(i,j,:)
  3658. itropo = ltropo_ifs(region,i,j,tx,lm(region))
  3659. do l = 1, itropo!lmr
  3660. temp2d(i,j) = temp2d(i,j) + opt_ext(i,j,l,lwl,lct) * &
  3661. (gph_dat(region)%data(i,j,l+1) - &
  3662. gph_dat(region)%data(i,j,l ))
  3663. if( lct == 1 ) then ! TOTAL AOD
  3664. ! Absorption: do this only once for the totals
  3665. tabs = tabs + opt_ext(i,j,l,lwl,lct) * (1.0 - opt_a(i,j,l,lwl)) * &
  3666. (gph_dat(region)%data(i,j,l+1) - gph_dat(region)%data(i,j,l))
  3667. else if (lct==4) then ! OAAOD
  3668. ! add SOA aod (5)to POM aod (4) (AerChemMIP expects total oa in aod550oa)
  3669. temp2d(i,j) = temp2d(i,j) + opt_ext(i,j,l,lwl,5) * &
  3670. (gph_dat(region)%data(i,j,l+1) - &
  3671. gph_dat(region)%data(i,j,l ))
  3672. else if (lct==7) then ! DUSTAOD
  3673. if ( wdep_out(lwl)%wl == 0.550) then
  3674. if (crescendo_out) allvars(od550dust3dday)%data3D(i,j,l)= opt_ext(i,j,l,lwl,lct) * &
  3675. (gph_dat(region)%data(i,j,l+1) - &
  3676. gph_dat(region)%data(i,j,l ))
  3677. tempdust2dday(i,j)=tempdust2dday(i,j)+ opt_ext(i,j,l,lwl,lct) * &
  3678. (gph_dat(region)%data(i,j,l+1) - &
  3679. gph_dat(region)%data(i,j,l ))
  3680. else
  3681. tempdust2dday(i,j)=tempdust2dday(i,j)+ opt_ext(i,j,l,lwl,lct) * &
  3682. (gph_dat(region)%data(i,j,l+1) - &
  3683. gph_dat(region)%data(i,j,l ))
  3684. end if
  3685. end if
  3686. end do
  3687. ! Absorption: do this only once for the totals
  3688. if( lct == 1 ) then
  3689. allvars(abs550aer)%data2D(i,j)=allvars(abs550aer)%data2D(i,j) + tabs*dtime
  3690. !extra output for total od550aer (ncontr==1)
  3691. allvars(od550aerdaily)%data2D(i,j)=allvars(od550aerdaily)%data2D(i,j) + temp2d(i,j)*dtime
  3692. if (crescendo_out)then
  3693. allvars(od550aerhr)%data2D(i,j)= dtime*temp2d(i,j)
  3694. end if
  3695. allvars(od550aer)%data2D(i,j)=allvars(od550aer)%data2D(i,j) + temp2d(i,j)*dtime
  3696. else if (lct<11)Then !AOD by compounds
  3697. allvars(indoffset+lct-1)%data2D(i,j)=allvars(indoffset+lct-1)%data2D(i,j) + temp2d(i,j)*dtime
  3698. if (crescendo_out .and. lct==7 .and. wdep_out(lwl)%wl == 0.550) then !DUSTAOD for 550nm
  3699. allvars(od550dust2dday)%data2D(i,j)=allvars(od550dust2dday)%data2D(i,j) + tempdust2dday(i,j)*dtime
  3700. end if
  3701. end if
  3702. end do
  3703. end do
  3704. end do
  3705. deallocate( temp2d )
  3706. deallocate( tempdust2dday)
  3707. !if 440 has splits do this
  3708. else if (wdep_out(lwl)%wl == 0.440 ) then
  3709. indoffset = od440aer
  3710. !not needed for AERCHEMMIP
  3711. indabs = -1
  3712. !abs440aer
  3713. ! fill AODs
  3714. allocate(tempdust2d440day(i1:i2,j1:j2))
  3715. allocate(temp2d(i1:i2,j1:j2))
  3716. tempdust2d440day=0.0
  3717. temp2d = 0.0
  3718. tempdust2d440day=0.0
  3719. do j = j1, j2
  3720. do i = i1, i2
  3721. ! AOD output will only be for troposphere in data request
  3722. tx(:)=t(i,j,:)
  3723. itropo = ltropo_ifs(region,i,j,tx,lm(region))
  3724. ! multiply with height elements and sum up
  3725. tabs = 0.0
  3726. do l = 1, itropo!lmr
  3727. ! od440aer
  3728. lct=1 ! total aod
  3729. temp2d(i,j) = temp2d(i,j) + opt_ext(i,j,l,lwl,lct) * &
  3730. (gph_dat(region)%data(i,j,l+1) - &
  3731. gph_dat(region)%data(i,j,l ))
  3732. tabs = tabs + opt_ext(i,j,l,lwl,lct) * (1.0 - opt_a(i,j,l,lwl)) * &
  3733. (gph_dat(region)%data(i,j,l+1) - gph_dat(region)%data(i,j,l))
  3734. !OD440DUST
  3735. lct=7
  3736. tempdust2d440day(i,j)=tempdust2d440day(i,j)+ opt_ext(i,j,l,lwl,lct) * &
  3737. (gph_dat(region)%data(i,j,l+1) - &
  3738. gph_dat(region)%data(i,j,l ))
  3739. end do
  3740. if (indabs>0) then
  3741. allvars(indabs)%data2D(i,j)=allvars(indabs)%data2D(i,j) + tabs*dtime
  3742. end if
  3743. end do
  3744. end do
  3745. allvars(od440aer)%data2D=allvars(od440aer)%data2D + temp2d*dtime
  3746. if (crescendo_out)then
  3747. allvars(od440dustday)%data2D=allvars(od440dustday)%data2D + tempdust2d440day*dtime
  3748. allvars(od440aerdaily)%data2D=allvars(od440aerdaily)%data2D + temp2d*dtime
  3749. allvars(od440aerhr)%data2D=temp2d*dtime
  3750. end if
  3751. deallocate( tempdust2d440day)
  3752. deallocate( temp2d )
  3753. end if
  3754. else !NON SPLITS
  3755. ! for 440/870/350 nm:
  3756. ! 1) fill total AOD and AAOD and write to containers
  3757. ! 2) dump AOD fields
  3758. if ( wdep_out(lwl)%wl == 0.870 ) then
  3759. indoffset = od870aer
  3760. !not needed for AERCHEMMIP
  3761. indabs = -1
  3762. !abs870aer
  3763. elseif ( wdep_out(lwl)%wl == 0.440 ) then
  3764. indoffset = -1 !od440aer
  3765. !not needed for AERCHEMMIP
  3766. indabs = -1
  3767. !abs350aer
  3768. elseif ( wdep_out(lwl)%wl == 0.350 ) then
  3769. indoffset = od350aer
  3770. !not needed for AERCHEMMIP
  3771. indabs = -1
  3772. !abs350aer
  3773. else
  3774. write(gol,*) 'user_output_aerchemmip: wrong wavelength given for aerocom diagnostics' ; call goErr
  3775. TRACEBACK
  3776. status=1; return
  3777. end if
  3778. ! fill AODs, total only
  3779. allocate(temp2d(i1:i2,j1:j2))
  3780. temp2d = 0.0
  3781. do j = j1, j2
  3782. do i = i1, i2
  3783. ! multiply with height elements and sum up
  3784. tabs = 0.0
  3785. do l = 1, lmr
  3786. temp2d(i,j) = temp2d(i,j) + opt_ext(i,j,l,lwl,1) * &
  3787. (gph_dat(region)%data(i,j,l+1) - &
  3788. gph_dat(region)%data(i,j,l ))
  3789. tabs = tabs + opt_ext(i,j,l,lwl,1) * (1.0 - opt_a(i,j,l,lwl)) * &
  3790. (gph_dat(region)%data(i,j,l+1) - gph_dat(region)%data(i,j,l))
  3791. end do
  3792. if (indabs>0) then
  3793. allvars(indabs)%data2D(i,j)=allvars(indabs)%data2D(i,j) + tabs*dtime
  3794. end if
  3795. end do
  3796. end do
  3797. if ((indoffset)==od870aer) then
  3798. allvars(od870aer)%data2D=allvars(od870aer)%data2D + temp2d*dtime
  3799. end if
  3800. deallocate(temp2d)
  3801. endif
  3802. end if
  3803. ! Extinction in 3D
  3804. if ( wdep_out(lwl)%wl == 0.550 ) then
  3805. allvars(ec550aer)%data3D= opt_ext(:,:,:,lwl,1)
  3806. if (crescendo_out) allvars(ec550aermon)%data3D=allvars(ec550aermon)%data3D + opt_ext(:,:,:,lwl,1)*dtime
  3807. endif
  3808. end do
  3809. deallocate( opt_ext, opt_a, opt_g, opt_add )
  3810. deallocate( tx )
  3811. call goLabel() ; status = 0
  3812. end subroutine calculate_optics
  3813. real function mode_fraction(r,limit,imode) result(modfrac)
  3814. Use mo_aero_m7, only : nmod, cmedr2mmedr, sigma
  3815. implicit none
  3816. !real :: var
  3817. real :: r
  3818. real :: z
  3819. real :: limit
  3820. ! real :: sigma
  3821. real :: hr2=0.5*sqrt(2.0)
  3822. integer::imode
  3823. z=0.0
  3824. if( r<100*tiny(1.0))then
  3825. modfrac=1.0
  3826. else
  3827. z=(log(limit)-log(r*cmedr2mmedr(imode)))/log(sigma(imode))
  3828. modfrac=0.5+0.5*erf(z*hr2)
  3829. end if
  3830. end function mode_fraction
  3831. end MODULE USER_OUTPUT_AERCHEMMIP