user_output.F90 36 KB

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