user_output.F90 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. !
  2. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  3. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  4. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  5. !
  6. #include "tm5.inc"
  7. !
  8. !-----------------------------------------------------------------------------
  9. ! TM5 !
  10. !-----------------------------------------------------------------------------
  11. !BOP
  12. !
  13. ! !MODULE: USER_OUTPUT
  14. !
  15. ! !DESCRIPTION: Contains calls to user-specific output routines, e.g.
  16. ! instantaneous mix files, station output, output of flight
  17. ! tracks etc.
  18. !\\
  19. !\\
  20. ! !INTERFACE:
  21. !
  22. MODULE USER_OUTPUT
  23. use GO, only : gol, goErr, goPr
  24. use GO, ONLY : GO_Timer_Def, GO_Timer_End, GO_Timer_Start
  25. use user_output_noaa, only : noaa_data
  26. #ifdef with_m7
  27. use user_output_aerocom, only : aerocom_freq, aerocom_exper, aerocom_dhour
  28. use user_output_aerchemmip, only : experiment,experiment_id, realm,source_type,aerchemmip_dhour, crescendo_out
  29. use user_output_general, only : gen_freq, gen_exper, all_chemistry
  30. use user_output_general, only : nCCNdiag, nSat, SuperSat
  31. #endif
  32. implicit none
  33. private
  34. !
  35. ! !PUBLIC MEMBER FUNCTIONS:
  36. !
  37. public :: user_output_init
  38. public :: user_output_step
  39. public :: user_output_mean
  40. public :: user_output_done
  41. !
  42. ! !PRIVATE DATA MEMBERS:
  43. !
  44. logical :: settings_data = .false. ! signal for model settings output
  45. logical :: flight_data = .false. ! signal for flight output
  46. logical :: station_data = .true. ! signal for station output
  47. logical :: mix_data = .false. ! signal for mix output
  48. integer :: mix_data_dhour ! ... and its output period
  49. logical :: mmix_data = .false. ! signal for mean mix output
  50. logical :: aerchemmip = .false. ! signal for AERCHEMMIP diagnostics
  51. logical :: aerchemmip_1h = .true. ! signal for AERCHEMMIP diagnostics
  52. logical :: aerocom_data = .false. ! signal for AEROCOM diagnostics
  53. !integer :: aerocom_dhour ! ... and its calling period
  54. logical :: aerocom_stat = .false. ! signal for AEROCOM station diagnostics
  55. logical :: output_pdump = .false. ! signal for chemistry time series output
  56. integer :: output_pdump_dsec ! ... and its lowest output period
  57. logical :: column_data ! signal for column output
  58. integer :: column_data_dtsec ! ... and its output period (in seconds)
  59. logical :: flask_data = .false. ! signal for flask output
  60. logical :: gen_data = .false. ! signal for GEN diagnostics
  61. integer :: gen_dhour ! ... and its calling period
  62. logical :: gen_2d = .false. ! signal for GEN surface and budget
  63. logical :: gen_3d = .false. ! signal for GEN 3D tracer output
  64. #ifdef with_cf_output
  65. logical :: output_cf = .false.
  66. integer :: output_cf_dhour ! every dhour hour
  67. #endif
  68. character(len=*), parameter :: mname = 'user_output'
  69. !Timers:
  70. integer :: itim_aero_init, itim_aero_step, itim_aero_write
  71. integer :: itim_gen_init, itim_gen_step, itim_gen_write
  72. !, itim_nh3, itim_sox, itim_dms, itim_ch4, itim_isop, itim_rn222
  73. !
  74. ! !REVISION HISTORY:
  75. ! 6 Feb 2011 - Achim Strunk - Added aerocom-2 diagnostics output.
  76. ! 9 Jul 2012 - Ph. Le Sager - merged (1) with version in proj/chem/base (to
  77. ! account for optics data for
  78. ! user_output_station) and (2) with version in
  79. ! the base/trunk (to account for output_common)
  80. ! and (3) with version in Climaqs proj to
  81. ! incorporate pdump as replacement for retro output
  82. ! 3 Jul 2013 - Andy Jacobson
  83. ! - Updated modules to use dynamic time-step weighting
  84. ! - Added flask, column,mmix output to trunk
  85. ! - Revised mix to used netCDF4 output
  86. !
  87. ! 25 Aug 2015 - T. van Noije - Added switch for monthly AeroCom output
  88. !
  89. ! !REMARKS:
  90. !
  91. !EOP
  92. !------------------------------------------------------------------------
  93. CONTAINS
  94. !--------------------------------------------------------------------------
  95. ! TM5 !
  96. !--------------------------------------------------------------------------
  97. !BOP
  98. !
  99. ! !IROUTINE: USER_OUTPUT_INIT
  100. !
  101. ! !DESCRIPTION: Initialise user-specified model output (all regions)
  102. !\\
  103. !\\
  104. ! !INTERFACE:
  105. !
  106. subroutine user_output_init( status )
  107. !
  108. ! !USES:
  109. !
  110. use GO, only : TrcFile, Init, Done, ReadRc
  111. use dims, only : ndyn_max, nregions
  112. use MeteoData, only : Set, temper_dat
  113. use global_data, only : rcfile
  114. use User_Output_Common, only : User_Output_Common_Init
  115. use User_Output_Settings, only : User_Output_Settings_Init
  116. use user_output_mmix, only : mmix_init
  117. use user_output_station, only : read_stationlist, init_station_output
  118. use user_output_noaa, only : init_noaa_events
  119. use user_output_mix, only : user_output_mix_init, mix_netcdf_attributes
  120. use user_output_column, only : user_output_column_init
  121. use user_output_pdump, only : output_pdump_init
  122. use user_output_flask, only : user_output_flask_init
  123. #ifdef with_cf_output
  124. use user_output_cf, only : output_cf_init
  125. #endif
  126. ! #ifdef with_optics
  127. ! Use Optics , only : Optics_Init, Optics_RcInit
  128. ! #endif
  129. ! #ifdef with_pm
  130. ! Use PM , only : PM_Init
  131. ! #endif
  132. !
  133. ! !INPUT/OUTPUT PARAMETERS:
  134. !
  135. integer, intent(inout) :: status
  136. !
  137. ! !REVISION HISTORY:
  138. ! 6 Feb 2011 - Achim Strunk - modified for aerocom-2 diagnostics.
  139. !
  140. ! !REMARKS:
  141. !
  142. !EOP
  143. !------------------------------------------------------------------------
  144. !BOC
  145. character(len=*), parameter :: rname = mname//'/user_output_init'
  146. ! --- local -------------------------------
  147. type(TrcFile) :: rcF
  148. Character (len=200) :: wavelengthsstring
  149. Character (len=200) :: pmsizelimits
  150. Character (len=300) :: alphastring
  151. integer :: n
  152. ! --- begin -------------------------------
  153. ! init common stuff:
  154. call User_Output_Common_Init( status )
  155. IF_NOTOK_RETURN(status=1)
  156. call Init( rcF, rcfile, status )
  157. IF_NOTOK_RETURN(status=1)
  158. ! ------------
  159. ! S E T T I N G S
  160. ! ------------
  161. ! put out settings ?
  162. call ReadRc( rcF, 'settings.output', settings_data, status, default=.false. )
  163. IF_ERROR_RETURN(status=1)
  164. ! apply ?
  165. if ( settings_data ) then
  166. write (gol,'(a,": user output settings ...")') rname; call goPr
  167. call User_Output_Settings_Init( rcF, status )
  168. IF_NOTOK_RETURN(status=1)
  169. end if
  170. ! ------------
  171. ! S T A T I O N S
  172. ! ------------
  173. call ReadRc( rcF, 'output.station', station_data, status, default=.false. )
  174. IF_ERROR_RETURN(status=1)
  175. if ( station_data ) then
  176. call read_stationlist(status)
  177. IF_NOTOK_RETURN(status=1)
  178. call init_station_output(status)
  179. IF_NOTOK_RETURN(status=1)
  180. end if
  181. ! ------------
  182. ! N O A A
  183. ! ------------
  184. call ReadRc( rcF, 'output.noaa', noaa_data, status, default=.false. )
  185. IF_ERROR_RETURN(status=1)
  186. if ( noaa_data ) then
  187. call init_noaa_events(status)
  188. IF_NOTOK_RETURN(status=1)
  189. end if
  190. ! ------------
  191. ! F L I G H T
  192. ! ------------
  193. call ReadRc( rcF, 'output.flight', flight_data, status, default=.false. )
  194. IF_ERROR_RETURN(status=1)
  195. ! ------------
  196. ! F L A S K
  197. ! ------------
  198. call ReadRc( rcF, 'output.flask', flask_data, status, default=.false.)
  199. IF_ERROR_RETURN(status=1)
  200. if(flask_data) then
  201. call user_output_flask_init(rcF,status)
  202. IF_NOTOK_RETURN(status=1)
  203. endif
  204. ! ------------
  205. ! M I X
  206. ! ------------
  207. call ReadRc( rcF, 'output.mix', mix_data, status )
  208. IF_NOTOK_RETURN(status=1)
  209. if ( mix_data ) then
  210. call ReadRc( rcF, 'output.mix.dhour', mix_data_dhour, status )
  211. IF_NOTOK_RETURN(status=1)
  212. call ReadRc( rcF, 'output.mix.attributes.notes', mix_netcdf_attributes%notes, status, default="")
  213. IF_ERROR_RETURN(status=1)
  214. call ReadRc( rcF, 'output.mix.attributes.disclaimer', mix_netcdf_attributes%disclaimer, status, default="")
  215. IF_ERROR_RETURN(status=1)
  216. call ReadRc( rcF, 'output.mix.attributes.email', mix_netcdf_attributes%email, status, default="")
  217. IF_ERROR_RETURN(status=1)
  218. call ReadRc( rcF, 'output.mix.attributes.url', mix_netcdf_attributes%url, status, default="")
  219. IF_ERROR_RETURN(status=1)
  220. call ReadRc( rcF, 'output.mix.attributes.institution', mix_netcdf_attributes%institution, status, default="")
  221. IF_ERROR_RETURN(status=1)
  222. call ReadRc( rcF, 'output.mix.attributes.conventions', mix_netcdf_attributes%conventions, status, default="CF-1.5")
  223. IF_ERROR_RETURN(status=1)
  224. call ReadRc( rcF, 'output.mix.attributes.source', mix_netcdf_attributes%source, status, default="")
  225. IF_ERROR_RETURN(status=1)
  226. call user_output_mix_init(status)
  227. IF_NOTOK_RETURN(status=1)
  228. end if
  229. ! ------------
  230. ! M M I X
  231. ! ------------
  232. ! initialise accumulation of the mean mixing ratio fields
  233. call ReadRc( rcF, 'output.mmix', mmix_data, status )
  234. IF_NOTOK_RETURN(status=1)
  235. if ( mmix_data ) then
  236. call mmix_init(status)
  237. IF_NOTOK_RETURN(status=1)
  238. ! require temperature then
  239. do n = 1, nregions
  240. call Set( temper_dat(n), status, used=.true. )
  241. end do
  242. end if
  243. ! ------------
  244. ! A E R O C O M
  245. ! ------------
  246. #ifdef with_m7
  247. ! initialise AEROCOM Diagnostics (hourly, daily or monthly)
  248. call ReadRc( rcF, 'output.aerocom', aerocom_data, status )
  249. IF_NOTOK_RETURN(status=1)
  250. if( aerocom_data ) then
  251. call ReadRc( rcF, 'output.aerocom.freq', aerocom_freq, status, default='monthly' )
  252. IF_NOTOK_RETURN(status=1)
  253. call ReadRc( rcF, 'output.aerocom.exper', aerocom_exper, status, default='AP3' )
  254. IF_NOTOK_RETURN(status=1)
  255. call ReadRc( rcF, 'output.aerocom.dhour', aerocom_dhour, status )
  256. IF_NOTOK_RETURN(status=1)
  257. call ReadRc( rcF, 'output.aerocom.stations', aerocom_stat, status )
  258. IF_NOTOK_RETURN(status=1)
  259. end if
  260. call ReadRc( rcF, 'output.general', gen_data, status )
  261. IF_NOTOK_RETURN(status=1)
  262. if( gen_data ) then
  263. call ReadRc( rcF, 'output.general.freq', gen_freq, status, default='hourly' )
  264. IF_NOTOK_RETURN(status=1)
  265. call ReadRc( rcF, 'output.general.exper', gen_exper, status, default='AP3' )
  266. IF_NOTOK_RETURN(status=1)
  267. !output frequency
  268. call ReadRc( rcF, 'output.general.dhour', gen_dhour, status )
  269. IF_NOTOK_RETURN(status=1)
  270. ! output all chemistry species or predefined smaller set (see user_output_general: variable gas_output
  271. call ReadRc( rcF, 'output.general.all_chemistry', all_chemistry, status, default=.false.)
  272. IF_NOTOK_RETURN(status=1)
  273. ! output 2D-fields: emi,load,surfconc,wetdep,drydep,sed,optics
  274. call ReadRc( rcF, 'output.general.2d', gen_2d, status )
  275. IF_NOTOK_RETURN(status=1)
  276. ! output 3D-fields: particle number/mass concentrations and diameters, chemistry species,
  277. call ReadRc( rcF, 'output.general.3d', gen_3d, status )
  278. IF_NOTOK_RETURN(status=1)
  279. !call ReadRc( rcF, 'output.general.author', gen_author, status )
  280. !IF_NOTOK_RETURN(status=1)
  281. !call ReadRc( rcF, 'output.general.institute', gen_institute, status )
  282. !IF_NOTOK_RETURN(status=1)
  283. !call ReadRc( rcF, 'output.general.', gen_, status )
  284. !IF_NOTOK_RETURN(status=1)
  285. call ReadRc( rcF, 'input.diagnostic.CCN', nCCNdiag, status)
  286. IF_NOTOK_RETURN(status=1)
  287. IF (nCCNdiag) THEN
  288. call ReadRc( rcF, 'input.supersat', nSat, status)
  289. IF_NOTOK_RETURN(status=1)
  290. ALLOCATE(SuperSat(nSat))
  291. call ReadRc( rcF, 'supersat.values', SuperSat, status)
  292. SuperSat(:) = SuperSat(:) / 100.e0 ! convert from %RH
  293. IF_NOTOK_RETURN(status=1)
  294. ENDIF
  295. end if
  296. #endif
  297. ! ------------
  298. ! A E R C H E M M I P
  299. ! ------------
  300. #ifdef with_m7
  301. ! initialise AERCHEMMIP Diagnostics (hourly, daily or monthly)
  302. call ReadRc( rcF, 'output.aerchemmip', aerchemmip, status )
  303. IF_NOTOK_RETURN(status=1)
  304. if( aerchemmip ) then
  305. call ReadRc( rcF, 'output.aerchemmip.1h', aerchemmip_1h, status )
  306. IF_NOTOK_RETURN(status=1)
  307. ! NOT IMPLEMENTED - 6hr- ouput is harcoded in aerchem_output.F90
  308. ! call ReadRc( rcF, 'output.aerchemmip.dhour', aerchemmip_dhour, status )
  309. ! IF_NOTOK_RETURN(status=1)
  310. aerchemmip_dhour=1
  311. call ReadRc( rcF, 'output.aerchemmip.experiment', experiment, status, default='AerChemMIP' )
  312. IF_ERROR_RETURN(status=1)
  313. call ReadRc( rcF, 'output.aerchemmip.realm', realm, status, default='atmosChem' )
  314. IF_ERROR_RETURN(status=1)
  315. call ReadRc( rcF, 'output.aerchemmip.sourcetype', source_type, status, default='AP3' )
  316. IF_ERROR_RETURN(status=1)
  317. call ReadRc( rcF, 'output.aerchemmip.experimentid', experiment_id, status )
  318. IF_NOTOK_RETURN(status=1)
  319. call ReadRc( rcF, 'output.crescendo', crescendo_out, status )
  320. IF_NOTOK_RETURN(status=1)
  321. end if
  322. #endif
  323. ! ------------
  324. ! P D U M P
  325. ! ------------
  326. ! put out in pdump format ?
  327. call ReadRc( rcF, 'output.pdump', output_pdump, status, default=.false. )
  328. IF_ERROR_RETURN(status=1)
  329. ! init if necessary:
  330. if ( output_pdump ) then
  331. ! init output; return ouptut time step
  332. call Output_PDUMP_Init( rcF, output_pdump_dsec, status )
  333. IF_NOTOK_RETURN(status=1)
  334. end if
  335. #ifdef with_cf_output
  336. ! ------------
  337. ! C F
  338. ! ------------
  339. ! put out in retro format ?
  340. call ReadRc( rcF, 'output.cf', output_cf, status, default=.false. )
  341. IF_ERROR_RETURN(status=1)
  342. ! init if necessary:
  343. if ( output_cf ) then
  344. ! init output; return ouptut time step
  345. call Output_CF_Init( rcF, output_cf_dhour, status )
  346. IF_NOTOK_RETURN(status=1)
  347. end if
  348. #endif
  349. ! ------------
  350. ! O P T I C S
  351. ! ------------
  352. ! Optics. I just need one thing of the rc-file before closing it.
  353. ! We could remove the compiler flags with_optics and with_pm if we want to
  354. ! We just do with_optics if you include at least one wavelength
  355. ! We just do with_pm if you include at least one sizelimit
  356. ! Now, we simply use the compiler flags.
  357. ! #ifdef with_optics
  358. ! call ReadRc( rcF, 'optics.lookup.table', lookuptable,status) ! the only line in climaqs proj. FIXME: others needed?
  359. ! IF_NOTOK_RETURN(status=1)
  360. ! call ReadRc( rcF, 'optics.wavelengths', wavelengthsstring,status)
  361. ! IF_NOTOK_RETURN(status=1)
  362. ! call ReadRc( rcF, 'optics.alphas', alphastring,status,default="")
  363. ! IF_ERROR_RETURN(status=1)
  364. ! Call Optics_RCInit(wavelengthsstring,alphastring,status) ! This code is so ugly, I do not want to pollute Optics_Init with this.
  365. ! IF_NOTOK_RETURN(status=1)
  366. ! Call Optics_Init(lookuptable,station_data,status)
  367. ! IF_NOTOK_RETURN(status=1)
  368. ! #endif
  369. ! PM output.
  370. ! #ifdef with_pm
  371. ! Call ReadRc( rcF, 'pm.sizelimits', pmsizelimits,status)
  372. ! IF_NOTOK_RETURN(status=1)
  373. ! ! Do not do anything if we have no stations
  374. ! if (station_data) then
  375. ! Call PM_Init(pmsizelimits,status)
  376. ! IF_NOTOK_RETURN(status=1)
  377. ! end if
  378. ! #endif
  379. ! ------------
  380. ! C O L U M N
  381. ! ------------
  382. ! output column data?
  383. call ReadRc( rcF, 'output.column', column_data, status, default = .false. )
  384. IF_ERROR_RETURN( status=1 )
  385. ! apply?
  386. if ( column_data ) then
  387. call ReadRc( rcF, 'output.column.dtsec', column_data_dtsec, status , default = ndyn_max)
  388. IF_ERROR_RETURN(status=1)
  389. write (gol,*) trim(mname)//'/column_data_dtsec:', column_data_dtsec; call goPr
  390. call user_output_column_init( status )
  391. IF_NOTOK_RETURN( status=1 )
  392. end if
  393. call GO_Timer_Def( itim_aero_init, 'user_output_aerocom_init', status )
  394. IF_NOTOK_RETURN(status=1)
  395. call GO_Timer_Def( itim_aero_step, 'user_output_aerocom_step', status )
  396. IF_NOTOK_RETURN(status=1)
  397. call GO_Timer_Def( itim_aero_write, 'user_output_aerocom_write', status )
  398. IF_NOTOK_RETURN(status=1)
  399. call GO_Timer_Def( itim_gen_init, 'user_output_general_init', status )
  400. IF_NOTOK_RETURN(status=1)
  401. call GO_Timer_Def( itim_gen_step, 'user_output_general_step', status )
  402. IF_NOTOK_RETURN(status=1)
  403. call GO_Timer_Def( itim_gen_write, 'user_output_general_write', status )
  404. IF_NOTOK_RETURN(status=1)
  405. ! close rcfile:
  406. call Done( rcF, status )
  407. IF_NOTOK_RETURN(status=1)
  408. ! ok
  409. status = 0
  410. END SUBROUTINE USER_OUTPUT_INIT
  411. !EOC
  412. !--------------------------------------------------------------------------
  413. ! TM5 !
  414. !--------------------------------------------------------------------------
  415. !BOP
  416. !
  417. ! !IROUTINE: USER_OUTPUT_DONE
  418. !
  419. ! !DESCRIPTION: Finalise user-specified model output for the region given
  420. !\\
  421. !\\
  422. ! !INTERFACE:
  423. !
  424. subroutine user_output_done( status )
  425. !
  426. ! !USES:
  427. !
  428. use dims, only : nregions,newhour,newday,newmonth
  429. use User_Output_Settings, only : User_Output_Settings_Done
  430. use User_Output_Common, only : User_Output_Common_Done
  431. use user_output_mmix, only : write_mmix, mmix_Done
  432. use user_output_station, only : free_stationfields
  433. use user_output_noaa, only : write_noaa_events
  434. use user_output_mix , only : user_output_mix_done
  435. use user_output_column , only : user_output_column_done
  436. use user_output_flask , only : user_output_flask_done
  437. #ifdef with_m7
  438. use user_output_aerocom, only : output_aerocom_done, output_aerocom_write
  439. use user_output_aerchemmip, only : output_aerchemmip_done, output_aerchemmip_write, output_aerchemmip_write_hourly, output_aerchemmip_write_daily, crescendo_out
  440. use user_output_general, only : output_general_done, output_general_write
  441. use user_output_general, only : nCCNdiag, SuperSat
  442. #endif
  443. use user_output_pdump, only : output_pdump_done
  444. #ifdef with_cf_output
  445. use user_output_cf, only : output_cf_done
  446. #endif
  447. !
  448. ! !OUTPUT PARAMETERS:
  449. !
  450. integer, intent(out) :: status
  451. !
  452. ! !REVISION HISTORY:
  453. ! 6 Feb 2011 - Achim Strunk - Added aerocom-2 case.
  454. !
  455. ! !REMARKS:
  456. !
  457. !EOP
  458. !------------------------------------------------------------------------
  459. !BOC
  460. character(len=*), parameter :: rname = mname//'/user_output_done'
  461. integer :: region
  462. ! --- begin -----------------------------
  463. ! settings output enabled ?
  464. if ( settings_data ) then
  465. ! done with module:
  466. call User_Output_Settings_Done( status )
  467. IF_NOTOK_RETURN(status=1)
  468. end if
  469. ! I do the done of Optics first, since it borrows the station's hdf.
  470. ! I will give user_output_station the honor to finalize the station's hdf.
  471. ! Maybe not necessary, but it looks nicer first to finalize the sds's
  472. ! and then finalize the hdf.
  473. ! #ifdef with_optics
  474. ! Call Optics_Done(station_data,status)
  475. ! IF_NOTOK_RETURN(status=1)
  476. ! #endif
  477. ! #ifdef with_pm
  478. ! if (station_data) then
  479. ! Call PM_Done(status)
  480. ! IF_NOTOK_RETURN(status=1)
  481. ! end if
  482. ! #endif
  483. if ( column_data ) then
  484. call user_output_column_done( status )
  485. IF_NOTOK_RETURN( status=1 )
  486. endif
  487. ! write the mean mixing ratio fields to file
  488. if ( mmix_data ) then
  489. call write_mmix(status)
  490. IF_NOTOK_RETURN(status=1)
  491. call mmix_Done(status)
  492. IF_NOTOK_RETURN(status=1)
  493. end if
  494. if ( station_data) then
  495. call free_stationfields(status)
  496. IF_NOTOK_RETURN(status=1)
  497. endif
  498. #ifdef with_m7
  499. if( aerocom_data ) then
  500. ! start timing:
  501. call GO_Timer_Start( itim_aero_write, status )
  502. IF_NOTOK_RETURN(status=1)
  503. ! write last data set before done
  504. do region = 1, nregions
  505. call output_aerocom_write(region, aerocom_stat, status)
  506. IF_NOTOK_RETURN(status=1)
  507. end do
  508. call GO_Timer_End( itim_aero_write, status )
  509. IF_NOTOK_RETURN(status=1)
  510. call output_aerocom_done(aerocom_stat, status)
  511. IF_NOTOK_RETURN(status=1)
  512. end if
  513. if( gen_data ) then
  514. ! start timing:
  515. call GO_Timer_Start( itim_gen_write, status )
  516. IF_NOTOK_RETURN(status=1)
  517. ! write last data set before done
  518. do region = 1, nregions
  519. call output_general_write(region, status)
  520. IF_NOTOK_RETURN(status=1)
  521. end do
  522. call GO_Timer_End( itim_gen_write, status )
  523. IF_NOTOK_RETURN(status=1)
  524. call output_general_done( status)
  525. IF_NOTOK_RETURN(status=1)
  526. endif
  527. if ( nCCNdiag ) then
  528. deallocate(SuperSat)
  529. endif
  530. if( aerchemmip ) then
  531. region=1
  532. !if (.not. newday)then
  533. call output_aerchemmip_write(region, .true.,status)
  534. ! write last data set before done
  535. IF_NOTOK_RETURN(status=1)
  536. !end if
  537. !if (.not. newday)then
  538. call output_aerchemmip_write_daily(region, .true.,status)
  539. ! write last data set before done
  540. IF_NOTOK_RETURN(status=1)
  541. !end if
  542. ! There should be no unfinished hours to write out
  543. ! so the run will end at the end of 1h time step, when
  544. ! output is already written out
  545. if (.not. newhour(1))then
  546. call output_aerchemmip_write_hourly(region, .true.,status)
  547. IF_NOTOK_RETURN(status=1)
  548. end if
  549. call output_aerchemmip_done(status)
  550. IF_NOTOK_RETURN(status=1)
  551. end if
  552. #endif
  553. if ( noaa_data) then
  554. call write_noaa_events(status)
  555. IF_NOTOK_RETURN(status=1)
  556. endif
  557. if(flask_data) then
  558. call user_output_flask_done(status)
  559. IF_NOTOK_RETURN(status=1)
  560. endif
  561. if ( mix_data ) then
  562. call user_output_mix_done( status )
  563. IF_NOTOK_RETURN(status=1)
  564. endif
  565. if ( output_pdump ) then
  566. call Output_Pdump_Done( status )
  567. IF_NOTOK_RETURN(status=1)
  568. end if
  569. #ifdef with_cf_output
  570. if ( output_cf ) then
  571. call Output_cf_Done( status )
  572. IF_NOTOK_RETURN(status=1)
  573. end if
  574. #endif
  575. ! done with common stuff:
  576. call User_Output_Common_Done( status )
  577. IF_NOTOK_RETURN(status=1)
  578. ! ok
  579. status = 0
  580. END SUBROUTINE USER_OUTPUT_DONE
  581. !EOC
  582. !--------------------------------------------------------------------------
  583. ! TM5 !
  584. !--------------------------------------------------------------------------
  585. !BOP
  586. !
  587. ! !IROUTINE: USER_OUTPUT_STEP
  588. !
  589. ! !DESCRIPTION: Define user-specified model output for the region given
  590. ! Called every time step
  591. !\\
  592. !\\
  593. ! !INTERFACE:
  594. !
  595. subroutine user_output_step( region, status )
  596. !
  597. ! !USES:
  598. !
  599. use dims, only : itaur, newsrun, itaui, newday
  600. !>>> TvN
  601. #ifdef with_m7
  602. use dims, only : newmonth, newhour,newday
  603. #endif
  604. !<<< TvN
  605. use datetime, only : tau2date
  606. use user_output_station, only : output_stationconc
  607. use user_output_noaa, only : get_noaa
  608. use user_output_flight, only : get_flightdata
  609. use user_output_column, only : user_output_column_accum,user_output_column_evaluate,user_output_column_write,user_output_column_reset
  610. use user_output_mix, only : user_output_mix_accum,user_output_mix_write
  611. use user_output_mmix, only : accumulate_mmix
  612. use user_output_flask, only : user_output_flask_sample
  613. use user_output_pdump , only : Output_Pdump_Step
  614. #ifdef with_m7
  615. use user_output_aerocom, only : output_aerocom_step, output_aerocom_init
  616. use user_output_aerocom, only : output_aerocom_write
  617. use user_output_aerchemmip, only : output_aerchemmip_init,output_aerchemmip_write,accumulate_data, output_aerchemmip_done,output_aerchemmip_write_hourly,output_aerchemmip_write_daily
  618. use user_output_general, only : output_general_step, output_general_init
  619. use user_output_general, only : output_general_write
  620. #endif
  621. ! #ifdef with_optics
  622. ! Use Optics, only : Optics_Step
  623. ! #endif
  624. ! #ifdef with_pm
  625. ! Use PM, only : PM_Step
  626. ! #endif
  627. #ifdef with_cf_output
  628. use user_output_cf , only : Output_cf_Step
  629. #endif
  630. !
  631. ! !INPUT PARAMETERS:
  632. !
  633. integer, intent(in) :: region
  634. !
  635. ! !OUTPUT PARAMETERS:
  636. !
  637. integer, intent(out) :: status
  638. !
  639. ! !REVISION HISTORY:
  640. ! 6 Feb 2011 - Achim Strunk - modified for aerocom-2 diagnostics.
  641. !
  642. ! !REMARKS:
  643. !
  644. !EOP
  645. !------------------------------------------------------------------------
  646. !BOC
  647. character(len=*), parameter :: rname = mname//'/user_output_step'
  648. ! --- local ------------------------------
  649. integer :: total_sec
  650. integer, dimension(6) :: idate_f
  651. #ifdef with_m7
  652. logical :: newaer
  653. #endif
  654. ! --- begin ------------------------------
  655. call tau2date(itaur(region),idate_f)
  656. if ( mmix_data ) then
  657. call accumulate_mmix( region,status )
  658. IF_NOTOK_RETURN(status=1)
  659. endif
  660. ! #ifdef with_optics
  661. ! Call Optics_Step(region,status)
  662. ! IF_NOTOK_RETURN(status=1)
  663. ! #endif
  664. if ( station_data ) then
  665. call output_stationconc(region, status)
  666. IF_NOTOK_RETURN(status=1)
  667. ! #ifdef with_pm
  668. ! Call PM_Step(region,status)
  669. ! IF_NOTOK_RETURN(status=1)
  670. ! #endif
  671. endif
  672. ! The third keyword here ("force") is for instantaneous sampling. Default
  673. ! value of .false. yields a four-hour window centered on sample time.
  674. !
  675. if ( noaa_data ) call get_noaa(region,itaur(region),.false.)
  676. if ( flight_data ) then
  677. call get_flightdata(region, idate_f, status)
  678. IF_NOTOK_RETURN(status=1)
  679. endif
  680. if(flask_data) then
  681. call user_output_flask_sample(region,itaur(region),status)
  682. IF_NOTOK_RETURN(status=1)
  683. endif
  684. if ( mix_data ) then
  685. if ( modulo(itaur(region)-itaui,mix_data_dhour*3600) == 0 ) then
  686. call user_output_mix_write(region, status )
  687. IF_NOTOK_RETURN(status=1)
  688. endif
  689. call user_output_mix_accum(region, status)
  690. IF_NOTOK_RETURN(status=1)
  691. end if
  692. if (column_data) then
  693. call user_output_column_accum( region, status )
  694. IF_NOTOK_RETURN( status=1 )
  695. if ( (itaur(region)-itaui .gt. 0) .and. (modulo(itaur(region)-itaui,column_data_dtsec) == 0 )) then
  696. call user_output_column_evaluate( status )
  697. IF_NOTOK_RETURN(status=1)
  698. call user_output_column_write( region, status )
  699. IF_NOTOK_RETURN(status=1)
  700. call user_output_column_reset( status )
  701. IF_NOTOK_RETURN(status=1)
  702. endif
  703. endif
  704. #ifdef with_m7
  705. ! -------------------
  706. ! AEROCOM DIAGNOSTICS
  707. ! -------------------
  708. IF( aerocom_data ) then
  709. ! write (for previous hour, day or month) in case we reach a new hour, day or month
  710. select case (trim(aerocom_freq))
  711. case ('hourly')
  712. if (modulo(idate_f(4),aerocom_dhour)==0)then
  713. newaer = newhour(region)
  714. else
  715. newaer = .false.
  716. end if
  717. case ('daily')
  718. newaer = newday
  719. case ('monthly')
  720. newaer = newmonth
  721. end select
  722. ! start timing:
  723. call GO_Timer_Start( itim_aero_write, status )
  724. IF_NOTOK_RETURN(status=1)
  725. if ( newaer .and. .NOT. newsrun ) then
  726. call output_aerocom_write(region, aerocom_stat, status)
  727. IF_NOTOK_RETURN(status=1)
  728. end if
  729. call GO_Timer_End( itim_aero_write, status )
  730. IF_NOTOK_RETURN(status=1)
  731. ! start timing:
  732. call GO_Timer_Start( itim_aero_init, status )
  733. IF_NOTOK_RETURN(status=1)
  734. ! initialise for each new hour, day or month
  735. if ( newaer ) then
  736. call output_aerocom_init( aerocom_stat, status )
  737. IF_NOTOK_RETURN(status=1)
  738. end if
  739. ! stop timing
  740. call GO_Timer_End( itim_aero_init, status )
  741. IF_NOTOK_RETURN(status=1)
  742. ! start timing:
  743. call GO_Timer_Start( itim_aero_step, status )
  744. IF_NOTOK_RETURN(status=1)
  745. ! do an accumulation step
  746. if ( (modulo(idate_f(4),aerocom_dhour)==0) .and. all(idate_f(5:6)==0) ) then
  747. call output_aerocom_step( region, aerocom_dhour, aerocom_stat, status )
  748. IF_NOTOK_RETURN(status=1)
  749. end if
  750. !stop timing
  751. call GO_Timer_End( itim_aero_step, status )
  752. IF_NOTOK_RETURN(status=1)
  753. end IF
  754. if (gen_data) then
  755. ! write (for previous hour, day or month) in case we reach a new hour, day or month
  756. select case (trim(gen_freq))
  757. case ('hourly')
  758. newaer = newhour(region)
  759. case ('daily')
  760. newaer = newday
  761. case ('monthly')
  762. newaer = newmonth
  763. end select
  764. ! start timing:
  765. call GO_Timer_Start( itim_gen_write, status )
  766. IF_NOTOK_RETURN(status=1)
  767. if ( newaer .and. .NOT. newsrun ) then
  768. call output_general_write(region, status)
  769. IF_NOTOK_RETURN(status=1)
  770. end if
  771. call GO_Timer_End( itim_gen_write, status )
  772. IF_NOTOK_RETURN(status=1)
  773. call GO_Timer_Start( itim_gen_init, status )
  774. IF_NOTOK_RETURN(status=1)
  775. ! initialise for each new hour, day or month
  776. if ( newaer ) then
  777. call output_general_init( status )
  778. IF_NOTOK_RETURN(status=1)
  779. end if
  780. ! stop timing
  781. call GO_Timer_End( itim_gen_init, status )
  782. IF_NOTOK_RETURN(status=1)
  783. call GO_Timer_Start( itim_gen_step, status )
  784. IF_NOTOK_RETURN(status=1)
  785. ! do an accumulation step
  786. if ( (modulo(idate_f(4),gen_dhour)==0) .and. all(idate_f(5:6)==0) ) then
  787. call output_general_step( region, gen_dhour, status )
  788. IF_NOTOK_RETURN(status=1)
  789. end if
  790. !stop timing
  791. call GO_Timer_End( itim_gen_step, status )
  792. IF_NOTOK_RETURN(status=1)
  793. end IF
  794. ! -------------------
  795. !
  796. if (aerchemmip) then
  797. if (newsrun) then
  798. call output_aerchemmip_init( status )
  799. IF_NOTOK_RETURN(status=1)
  800. end if
  801. !accumulate every hour
  802. if ( newhour(1) ) then
  803. ! if ( (modulo(idate_f(4),aerchemmip_dhour)==0) .and. all(idate_f(5:6)==0) ) then
  804. call accumulate_data(aerchemmip_dhour,status)
  805. IF_NOTOK_RETURN(status=1)
  806. end if
  807. !monthly
  808. if (newmonth .and. .NOT. newsrun ) then
  809. !if (newhour .and. .NOT. newsrun ) then
  810. call output_aerchemmip_write(region, newhour(1), status)
  811. IF_NOTOK_RETURN(status=1)
  812. end if
  813. !hourly
  814. !newhour(1) means newhour at region 1 (global, now zooming expected in AERCHEMMIP)
  815. if (newhour(1) .and. .NOT. newsrun .and. aerchemmip_1h) then
  816. call output_aerchemmip_write_hourly(region, newhour(1),status)
  817. IF_NOTOK_RETURN(status=1)
  818. end if
  819. !daily
  820. if (newday .and. .NOT. newsrun ) then
  821. call output_aerchemmip_write_daily(region, newhour(1),status)
  822. IF_NOTOK_RETURN(status=1)
  823. end if
  824. end if
  825. #endif
  826. !
  827. if ( output_pdump ) then
  828. total_sec = idate_f(4)*3600 + idate_f(5)*60 + idate_f(6)
  829. if ( modulo(total_sec,output_pdump_dsec) == 0 ) then
  830. call Output_Pdump_Step( region, idate_f, status )
  831. IF_NOTOK_RETURN(status=1)
  832. end if
  833. end if
  834. #ifdef with_cf_output
  835. if ( output_cf ) then
  836. if ( (modulo(idate_f(4),output_cf_dhour)==0) .and. all(idate_f(5:6)==0) ) then
  837. call Output_CF_Step( region, idate_f, status )
  838. IF_NOTOK_RETURN(status=1)
  839. end if
  840. end if
  841. #endif
  842. ! ok
  843. status = 0
  844. END SUBROUTINE USER_OUTPUT_STEP
  845. !EOC
  846. !--------------------------------------------------------------------------
  847. ! TM5 !
  848. !--------------------------------------------------------------------------
  849. !BOP
  850. !
  851. ! !IROUTINE: USER_OUTPUT_MEAN
  852. !
  853. ! !DESCRIPTION: Calculate and write means at stations.
  854. !\\
  855. !\\
  856. ! !INTERFACE:
  857. !
  858. subroutine user_output_mean(status)
  859. !
  860. ! !USES:
  861. !
  862. use dims, only : itau, ndyn_max
  863. use user_output_station, only : evaluate_stationconc, reset_stationconc_accumulator, write_stationconc
  864. ! #ifdef with_optics
  865. ! Use Optics , only : Optics_Write
  866. ! #endif
  867. ! #ifdef with_pm
  868. ! Use PM, only : PM_Write
  869. ! #endif
  870. !
  871. ! !INPUT/OUTPUT PARAMETERS:
  872. !
  873. integer, intent(inout) :: status
  874. !
  875. ! !REVISION HISTORY:
  876. ! 6 Feb 2011 - Achim Strunk -
  877. !
  878. ! !REMARKS:
  879. !
  880. !EOP
  881. !------------------------------------------------------------------------
  882. !BOC
  883. character(len=*), parameter :: rname = mname//'/user_output_mean'
  884. IF(station_data)THEN
  885. IF(mod(itau, ndyn_max) == 0) THEN
  886. CALL evaluate_stationconc(status)
  887. IF_NOTOK_RETURN(status=1)
  888. CALL write_stationconc(status)
  889. IF_NOTOK_RETURN(status=1)
  890. CALL reset_stationconc_accumulator
  891. ENDIF
  892. ENDIF
  893. ! #ifdef with_optics
  894. ! ! Write Optics as if it is a station file, so at the end of one whole time step.
  895. ! ! We might have a parallellization problem, since we are parallel in levels or tracers,
  896. ! ! and I do not know what is what. However, the AOD is already integrated over levels
  897. ! ! and tracers, so it may not make a difference after all.
  898. ! Call Optics_Write (station_data,status)
  899. ! IF_NOTOK_RETURN(status=1)
  900. ! #endif
  901. ! #ifdef with_pm
  902. ! ! Write particulate matter like the optics data into the station files
  903. ! If (station_data) Then
  904. ! Call PM_Write (status)
  905. ! IF_NOTOK_RETURN(status=1)
  906. ! End If
  907. ! #endif
  908. ! ok
  909. status = 0
  910. end subroutine user_output_mean
  911. END MODULE USER_OUTPUT