user_output_c4mip.F90 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832
  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_C4MIP
  14. !
  15. ! !DESCRIPTION:
  16. !
  17. ! This module provides the code needed to produce the CMIP6 C4MIP
  18. ! output from TM5. Code is based on the user_output_aerocom.
  19. !
  20. ! output_c4mip_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_c4mip_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_c4mip_write
  28. ! - write the monthly variable data to netcdf-file
  29. ! - initialise the dataholders for accumulation of new month
  30. ! output_c4mip_write_hourly
  31. ! - write the hourly variable data to netcdf-file
  32. ! - initialise the dataholders for accumulation of new hour
  33. ! output_c4mip_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. ! Tommi Bergman 1.11.2019
  39. !\\
  40. !\\
  41. ! !INTERFACE:
  42. !
  43. MODULE USER_OUTPUT_C4MIP
  44. !
  45. ! !USES:
  46. !
  47. use go, only : gol, goErr, goPr, goLabel
  48. use GO, ONLY : GO_Timer_Def, GO_Timer_End, GO_Timer_Start
  49. use dims, only : nregions !=1, support for zooming with larger values not available for C4MIP
  50. use meteodata, only : global_lli, levi
  51. use MDF
  52. use TM5_DISTGRID, only : dgrid, Get_DistGrid, update_halo, update_halo_iband
  53. use chem_param
  54. !#ifdef with_m7
  55. ! use m7_data, only : h2o_mode
  56. !#endif
  57. implicit none
  58. private
  59. !
  60. ! !PUBLIC MEMBER FUNCTIONS:
  61. !
  62. public :: output_c4mip_init
  63. !public :: output_c4mip_step
  64. public :: output_c4mip_write_monthly
  65. public :: output_c4mip_write_hourly
  66. public :: output_c4mip_write_6hourly
  67. public :: output_c4mip_write_daily
  68. public :: output_c4mip_done
  69. public :: accumulate_c4mip_data
  70. ! public :: wdep_out
  71. character(len=*), parameter :: mname = 'user_output_c4mip'
  72. ! max indices, at maximum 7, one for each mode
  73. integer,parameter :: n_indices=11
  74. type varfile
  75. integer :: itm5 !
  76. character(len=16) :: vname !
  77. character(len=64) :: lname !
  78. character(len=11) :: unit !
  79. character(len=10) :: positive !
  80. character(len=130) :: standard_name !
  81. real,dimension (:,:),pointer :: data2D !
  82. real,dimension (:,:,:),pointer :: data3D !
  83. ! real,dimension (:,:,:),pointer :: budgetdata !
  84. integer :: varid !
  85. integer :: fileunit ! file unit number
  86. character(len=200) :: filename !
  87. integer :: dimensions !
  88. integer :: lon_varid !
  89. integer :: lat_varid !
  90. integer :: lev_varid !
  91. integer :: time_varid
  92. integer :: hyam_varid
  93. integer :: hybm_varid
  94. integer :: hyai_varid
  95. integer :: hybi_varid
  96. integer :: bounds_varid
  97. integer :: dims
  98. character(len=10) :: freq
  99. character(len=9) :: class ! which class of variable :emi, ddep, wdep,conc,aod,met,crescendo
  100. integer,dimension(n_indices) :: indices
  101. real :: xmgas
  102. character(len=20) :: table_id
  103. end type varfile
  104. type dimdata
  105. integer :: nlon ! size of x dimension of requested field
  106. integer :: nlat ! size of y dimension of requested field
  107. integer :: nlev ! size of z dimension of requested field
  108. real,dimension(:),pointer :: lon ! x dimension of requested field
  109. real,dimension(:),pointer :: lat ! y dimension of requested field
  110. real,dimension(:),pointer :: lev ! z dimension of requested field
  111. integer :: lonid ! x dimension id in nc
  112. integer :: latid ! y dimension id in nc
  113. integer :: levid ! z dimension id in nc
  114. integer :: timeid ! time dimension id in nc
  115. integer :: time_varid
  116. end type dimdata
  117. type(dimdata)::dimension_data
  118. !!!!
  119. integer::test_fileunit
  120. !!!!
  121. integer :: n_vars=0
  122. type(varfile), dimension(:), allocatable :: allvars
  123. type(varfile), dimension(:), allocatable :: fixedvars
  124. integer :: n_var_max=300
  125. integer :: n_fixed=3
  126. integer, public :: n_days_in_month
  127. character(len=20), public :: c4mip_exper ! AeroCom experiment name
  128. integer, save :: od550aer, &
  129. areacella,&
  130. sftlf,&
  131. orog
  132. integer :: fid ! file id for IF_NOTOK_MDF macro
  133. integer :: access_mode
  134. integer :: accumulation_mon,accumulation_day,accumulation_hr,accumulation_6hr
  135. integer :: timeidx_mon,timeidx_hr,timeidx_day,timeidx_6hr
  136. integer,parameter::iemiunit=1
  137. integer,parameter::iddepunit=1 !same dimensions as emi
  138. integer,parameter::iwdepunit=1 !same dimensions as emi
  139. integer,parameter::iprod3dunit=2
  140. integer,parameter::immrunit=3
  141. integer,parameter::idimensionlessunit=4
  142. integer,parameter::iheightunit=5
  143. integer,parameter::itempunit=6
  144. integer,parameter::io3unit=7
  145. integer,parameter::ipresunit=8
  146. integer,parameter::ivmrunit=9
  147. integer,parameter::irateunit=10
  148. integer,parameter::iloadunit=11
  149. integer,parameter::iextunit=12
  150. integer,parameter::iccunit=13
  151. integer,parameter::im3unit=14
  152. integer,parameter::imassunit=15
  153. 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',&
  154. 's-1','kg m-2','m-1','cm-3','m-3','kg'/)
  155. character (len=11), parameter::unit='m-3'
  156. Character(len=8),dimension(3),parameter :: monthly_var=(/'ps','co2','co2mass'/)
  157. character(len=11),dimension(3),parameter:: monthly_varunit=(/units(ipresunit), units(ivmrunit), units(iloadunit)/)
  158. real,dimension(3),parameter :: xmmonthly_var=(/1.0,xmco2,xmco2/)
  159. integer,dimension(3),parameter::monthly_dim=(/2,3,2/)
  160. !SPECIAL
  161. !6HOURLY
  162. !character(len=8),dimension(1),parameter:: ps6hr=(/'ps'/)
  163. !character(len=11),dimension(1),parameter:: ps6hrunit=(/units(ipresunit)/)
  164. !HOURLY
  165. character(len=8),dimension(3),parameter:: hourly_var=(/'ps','co2','co2mass'/) !,'co2mass1'/)
  166. character(len=11),dimension(3),parameter:: hourly_varunit=(/units(ipresunit), units(ivmrunit), units(iloadunit)/) ! , 'kg(co2)'/)
  167. real,dimension(3),parameter ::xmhourly=(/1.0,xmco2,xmco2/) !,xmco2/)
  168. integer,dimension(3),parameter::hourly_dim=(/2,3,2/) !,0/)
  169. !DAILY
  170. character(len=8),dimension(3),parameter:: daily_var=(/'ps','co2','co2mass'/)
  171. character(len=11),dimension(3),parameter:: daily_varunit=(/ units(ipresunit),units(ivmrunit), units(iloadunit)/)
  172. real,dimension(3),parameter ::xmdaily=(/-1.0,xmco2,xmco2/)
  173. integer,dimension(3),parameter::daily_dim=(/2,3,2/)
  174. ! global attributes that might change with run or something else
  175. character(len=3),parameter::grid='3x2'!'250 km'
  176. character(len=3),parameter::grid_label='gn'!'gnz' for zonal means
  177. character(len=300),parameter::c4mip_source='EC-Earth3-CC (2017): atmosphere: IFS cy36r4 (TL255, linearly &
  178. &reduced Gaussian grid equivalent to 512 x 256, 91 levels, top level: 0.01 hPa);atmospheric_chemistry: &
  179. &TM5 (3 deg. (long.) x 2 deg. (lat.), 34 levels, top level: 0.1 hPa; aerosol: TM5'
  180. character(len=17),parameter::c4mip_source_id='EC-Earth3-CC'
  181. character(len=20),public ::c4mip_source_type!='AOGCM CHEM AER' !or 'AGCM CHEM AER' for amip-runs
  182. character(len=60),public ::c4mip_realm
  183. character(len=60),public::c4mip_experiment_id
  184. character(len=60),public::c4mip_experiment
  185. character(len=1),public::realization_i='1'
  186. character(len=1),public::physics_i='1'
  187. character(len=1),public::forcing_i='1'
  188. character(len=1),public::initialization_i='1'
  189. integer, public:: c4mip_dhour
  190. ! Timers
  191. integer :: itim_init, itim_addvar, itim_write, itim_accu, itim_attr, itim_accu_opt, itim_write_hour, itim_write_day, &
  192. itim_write_mon, itim_write_gather
  193. contains
  194. subroutine output_c4mip_init(status)
  195. ! Open files
  196. ! allocate dataholders
  197. use dims, only : newsrun,itau,mlen
  198. use global_data, only : outdir
  199. use datetime, only : tau2date, date2tau
  200. use partools, only : MPI_INFO_NULL, localComm
  201. #ifdef with_m7
  202. !use optics, only : Optics_Init
  203. !use sedimentation, only : ised,nsed
  204. #endif
  205. use partools , only : isRoot,myid
  206. use global_data, only : region_dat
  207. use tm5_distgrid, only : gather
  208. use meteodata , only : lsmask_dat,oro_dat
  209. use Binas , only : grav
  210. implicit none
  211. !OUTPUT parameters
  212. integer, intent(out) :: status
  213. !LOCAL parameters
  214. integer :: region !iterator for regions
  215. integer :: nlon_region
  216. integer :: nlat_region
  217. integer :: nlev_region ! also global
  218. integer :: j_var
  219. !integer :: nlev_region ! also global
  220. !integer :: nlev_region ! also global
  221. integer :: itrac
  222. integer :: i_sed
  223. integer :: i,i1,i2,j1,j2,k,j,imr,jmr
  224. character(len=*), parameter :: rname = mname//'/output_c4mip_init'
  225. !FIXED VARS
  226. real, dimension(:),pointer :: dxyp
  227. real, allocatable :: arr2d(:,:)
  228. real ::xmcomp
  229. call goLabel(rname)
  230. ! define timers:
  231. call GO_Timer_Def( itim_init, 'output c4mip init', status )
  232. IF_NOTOK_RETURN(status=1)
  233. call GO_Timer_Def( itim_write, 'output c4mip write', status )
  234. IF_NOTOK_RETURN(status=1)
  235. call GO_Timer_Def( itim_write_gather, 'output c4mip write gather', status )
  236. IF_NOTOK_RETURN(status=1)
  237. call GO_Timer_Def( itim_write_day, 'output c4mip write day', status )
  238. IF_NOTOK_RETURN(status=1)
  239. call GO_Timer_Def( itim_write_hour, 'output c4mip write hour', status )
  240. IF_NOTOK_RETURN(status=1)
  241. call GO_Timer_Def( itim_write_mon, 'output c4mip write mon', status )
  242. IF_NOTOK_RETURN(status=1)
  243. call GO_Timer_Def( itim_accu, 'output c4mip accu', status )
  244. IF_NOTOK_RETURN(status=1)
  245. call GO_Timer_Def( itim_attr, 'output c4mip attr', status )
  246. IF_NOTOK_RETURN(status=1)
  247. call GO_Timer_Def( itim_addvar, 'output c4mip addvar', status )
  248. IF_NOTOK_RETURN(status=1)
  249. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  250. if (newsrun) then
  251. accumulation_mon=0.0
  252. accumulation_hr=0.0
  253. accumulation_6hr=0.0
  254. accumulation_day=0.0
  255. region=1
  256. ! intermediate structures for budgets
  257. imr = global_lli(1)%nlon
  258. jmr = global_lli(1)%nlat
  259. ! for areacella,orog,sftlf
  260. if (isRoot) then
  261. allocate( arr2d(imr,jmr) )
  262. else
  263. allocate( arr2d(1,1) )
  264. endif
  265. arr2d(:,:)=0.0
  266. ! for monthly output
  267. ! initialise with 31 for january
  268. n_days_in_month=31
  269. end if
  270. call GO_Timer_Start( itim_init, status )
  271. IF_NOTOK_RETURN(status=1)
  272. ! C4MIP only available for global-> region=1
  273. region=1
  274. !Initialise grid definitions
  275. nlon_region = global_lli(region)%nlon
  276. nlat_region = global_lli(region)%nlat
  277. nlev_region = levi%nlev
  278. dimension_data%nlon= nlon_region
  279. dimension_data%nlat= nlat_region
  280. dimension_data%nlev= nlev_region
  281. allocate(dimension_data%lon(nlon_region))
  282. allocate(dimension_data%lat(nlat_region))
  283. allocate(dimension_data%lev(nlev_region))
  284. dimension_data%lon=global_lli(region)%lon_deg
  285. dimension_data%lat=global_lli(region)%lat_deg
  286. ! initialise output timeidx used for keeping track which output steps is written
  287. timeidx_mon=1
  288. timeidx_day=1
  289. timeidx_hr=1
  290. timeidx_6hr=1
  291. ! allocate room for variables
  292. allocate(allvars(n_var_max))
  293. allocate(fixedvars(n_fixed))
  294. !!$ do i=1,size(ps6hr)
  295. !!$ call add_variable(-1,trim(ps6hr(i)),trim(ps6hr(i)),ps6hrunit(i),2,status,'ps6h','AER6hr',-1.0)
  296. !!$ end do
  297. ! Gas-phase species volume mixingratios
  298. do i=1,size(monthly_var)
  299. write(gol,*) 'monthly_var add,',trim(monthly_var(i))
  300. if (xmmonthly_var(i)>0.0) then
  301. call add_variable(-1,trim(monthly_var(i)),'volume mixing ratio of '//trim(monthly_var(i)), hourly_varunit(i),monthly_dim(i),status,'monthly','AERmon',xmmonthly_var(i))
  302. else
  303. write(gol,*) 'monthly_var with negative molar mass'
  304. end if
  305. end do
  306. ! add hourly output
  307. do i=1,size(hourly_var)
  308. call add_variable(-1,trim(hourly_var(i)),trim(hourly_var(i)),hourly_varunit(i),hourly_dim(i),status,'hourly','AERhr',xmhourly(i))
  309. end do
  310. ! add daily fields
  311. do i=1,size(daily_var)
  312. call add_variable(-1,trim(daily_var(i)),trim(daily_var(i)),daily_varunit(i),daily_dim(i),status,'daily','AERday',xmdaily(i))
  313. end do
  314. call add_variable(-1,'areacella','cell area','m2',2,status,'fixed','AERfx',-1.0)
  315. call add_variable(-1,'orog','surface_altitude','m',2,status,'fixed','AERfx',-1.0)
  316. call add_variable(-1,'sftlf','land_area_fraction','1',2,status,'fixed','AERfx',-1.0)
  317. !
  318. do j_var = 1, n_vars
  319. ! initialise a single file for each variables as per C4MIP specification
  320. ! overwrite existing files (clobber)
  321. if (isroot)call MDF_Create( allvars(j_var)%filename, MDF_NETCDF4, MDF_REPLACE, allvars(j_var)%fileunit, status )
  322. IF_NOTOK_RETURN(status=1)
  323. !For each file
  324. ! write grid dimension attributes
  325. if (isroot) call write_dimensions(status, j_var)
  326. IF_NOTOK_RETURN(status=1)
  327. ! write global attributes
  328. if (isroot) call write_attributes(status, j_var)
  329. IF_NOTOK_RETURN(status=1)
  330. !write dimension variables
  331. if (isroot) call write_var(status,j_var)
  332. IF_NOTOK_RETURN(status=1)
  333. if (allvars(j_var)%table_id=='AERfx')then
  334. if (trim(allvars(j_var)%vname)=='areacella')then
  335. ! Gridbox area
  336. dxyp => region_dat(1)%dxyp
  337. do j=j1,j2
  338. allvars(j_var)%data2D(i1:i2,j)=dxyp(j)
  339. end do
  340. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  341. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  342. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  343. else if (trim(allvars(j_var)%vname)=='orog')then
  344. ! Gridbox area
  345. allvars(j_var)%data2D(i1:i2,j1:j2) =oro_dat(region)%data(i1:i2,j1:j2,1)/grav
  346. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  347. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  348. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  349. else if (trim(allvars(j_var)%vname)=='sftlf')then
  350. ! Gridbox area
  351. allvars(j_var)%data2D(i1:i2,j1:j2)=lsmask_dat(1)%data(i1:i2,j1:j2,1)/100.
  352. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  353. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1/), count=(/imr,jmr/) )
  354. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  355. end if
  356. end if
  357. end do
  358. deallocate(arr2d)
  359. call GO_Timer_End( itim_init, status )
  360. IF_NOTOK_RETURN(status=1)
  361. call goLabel()
  362. status = 0
  363. end subroutine output_c4mip_init
  364. subroutine output_c4mip_write_monthly(region,newhour,status)
  365. use MeteoData, only : temper_dat,sst_dat,albedo_dat,ci_dat,lsp_dat,cp_dat,ssr_dat,str_dat,&
  366. blh_dat,gph_dat,lwc_dat,iwc_dat,cco_dat,cc_dat,humid_dat, m_dat,phlb_dat,sp_dat !
  367. use global_data, only : conv_dat
  368. use GO, only : TDate, NewDate
  369. use go_date,only: days_in_month!
  370. use datetime, only : tau2date,date2tau,julday !
  371. use dims, only : itau,iyear0 !current time
  372. !use ebischeme, only : AC_diag_prod,AC_O3_lp,AC_loss
  373. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  374. use partools , only : isRoot,myid
  375. ! use domain_decomp, only: gather
  376. implicit none
  377. logical,intent(in) ::newhour
  378. integer,intent(out)::status
  379. integer::region
  380. integer:: j_var
  381. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  382. character(len=*), parameter :: rname = mname//'/output_c4mip_write_monthly'
  383. real, allocatable :: arr3d(:,:,:),arr3dh(:,:,:),arr2d(:,:)
  384. integer, dimension(6) :: curdate
  385. ! reference time:
  386. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  387. integer(kind=8) :: itauref ! reftime in seconds
  388. real :: reftime ! seconds from reference time
  389. real :: rangemon
  390. type(Tdate)::curdate_tdate
  391. call goLabel(rname)
  392. call GO_Timer_Start( itim_write_mon, status )
  393. IF_NOTOK_RETURN(status=1)
  394. if (region > 1) then
  395. write(gol,*) 'output_c4mip_write_monthly: region >1, only available in global mode!'
  396. call goErr
  397. status=1
  398. return
  399. end if
  400. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  401. ! entire region grid size
  402. imr = global_lli(1)%nlon
  403. jmr = global_lli(1)%nlat
  404. lmr = levi%nlev
  405. ! define the reference time in seconds (itauref)
  406. ! (for now in days since 1850-01-01 00:00, local variable)
  407. ! returns the difference to current time, beginning of new step
  408. !
  409. call date2tau( time_reftime6, itauref )
  410. ! calculate reftime as fractional days from itauref, hence division by 86400
  411. ! call date2tau( idater, itaucur )
  412. ! itau is the 1st day of new month at 00:00 so we need to fix the reftime back half a month (15th day)
  413. ! ((cursecond - reftimesecond) / seconds_in_day) - days_in_last_month + 15days
  414. !reftime = (itau - itauref -n_days_in_month*24*3600 + 15*24*3600) / 86400.
  415. reftime = (itau - itauref ) / 86400.
  416. !get current date in integers
  417. call tau2date(itau, curdate)
  418. ! create a TDATE date variable of the previous month (curdate(3)-1)
  419. curdate_tdate=newdate(curdate(1),curdate(2),curdate(3)-1,curdate(4),curdate(5),curdate(6),calender='greg')
  420. ! get days in month and save for next step
  421. n_days_in_month=days_in_month(curdate_tdate)
  422. ! change reftime to beginning of last month (the month data is from)
  423. reftime=reftime-n_days_in_month
  424. !length of the month-1s(in days) for the time_bounds
  425. rangemon=n_days_in_month !-(1.0/86400.0)
  426. ! allocate 3D and 4D global arrays for gathering data
  427. ! only root needs the full array, but it must be allocated in all tasks
  428. if (isRoot) then
  429. allocate( arr3d(imr,jmr,lmr) )
  430. allocate( arr3dh(imr,jmr,lmr+1) )
  431. allocate( arr2d(imr,jmr) )
  432. else
  433. allocate( arr3d(1,1,1) )
  434. allocate( arr3dh(1,1,1) )
  435. allocate( arr2d(1,1) )
  436. endif
  437. arr2d(:,:)=0.0
  438. arr3d(:,:,:)=0.0
  439. arr3dh(:,:,:)=0.0
  440. do j_var =1,n_vars
  441. ! hourly and daily variables are handled separately
  442. if (allvars(j_var)%table_id=='AERhr'.or.allvars(j_var)%table_id=='AER6hr'.or.&
  443. allvars(j_var)%table_id=='AERday'.or.allvars(j_var)%table_id=='AERfx')then
  444. cycle
  445. end if
  446. if (allvars(j_var)%dims==2)then !2D
  447. if (trim(allvars(j_var)%vname)/='minpblz'.and.trim(allvars(j_var)%vname)/='tasmin'.and. &
  448. trim(allvars(j_var)%vname)/='maxpblz'.and.trim(allvars(j_var)%vname)/='tasmax')then
  449. allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_mon)
  450. end if
  451. call GO_Timer_Start( itim_write_gather, status )
  452. IF_NOTOK_RETURN(status=1)
  453. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0,status)
  454. call GO_Timer_End( itim_write_gather, status )
  455. IF_NOTOK_RETURN(status=1)
  456. IF_NOTOK_RETURN(status=1)
  457. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr2d, status, start=(/1,1,timeidx_mon/), &
  458. count=(/imr,jmr,1/) )
  459. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  460. ! Zero out the accumulated and written data for the next interval
  461. if (trim(allvars(j_var)%vname)=='minpblz' .or. trim(allvars(j_var)%vname)=='tasmin') then
  462. ! put high number so simple comparison is needed for finding minimum
  463. allvars(j_var)%data2D(i1:i2,j1:j2)=1e10
  464. else
  465. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  466. end if
  467. else !3D
  468. if (trim( allvars(j_var)%vname)=='phalf') then !lmr+1
  469. 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)
  470. call GO_Timer_Start( itim_write_gather, status )
  471. IF_NOTOK_RETURN(status=1)
  472. call gather( dgrid(1), allvars(j_var)%data3D , arr3dh(:,:,:), 0, status)
  473. IF_NOTOK_RETURN(status=1)
  474. call GO_Timer_End( itim_write_gather, status )
  475. IF_NOTOK_RETURN(status=1)
  476. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr3dh , status, start=(/1,1,1,timeidx_mon/), &
  477. count=(/imr,jmr,lmr+1,1/) )
  478. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  479. else
  480. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_mon)
  481. call GO_Timer_Start( itim_write_gather, status )
  482. IF_NOTOK_RETURN(status=1)
  483. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  484. IF_NOTOK_RETURN(status=1)
  485. call GO_Timer_End( itim_write_gather, status )
  486. IF_NOTOK_RETURN(status=1)
  487. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid, arr3d , status, start=(/1,1,1,timeidx_mon/), &
  488. count=(/imr,jmr,lmr,1/) )
  489. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  490. end if
  491. ! Zero out the accumulated and written data for the next interval
  492. allvars(j_var)%data3D(i1:i2,j1:j2,:)=0.0
  493. end if
  494. !end if
  495. ! write the date for timestep
  496. 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/) )
  497. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  498. if (isroot) call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%bounds_varid,(/ reftime,reftime+rangemon/) , status, &
  499. start=(/1,timeidx_mon/), count=(/2,1/) )
  500. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  501. end do
  502. deallocate( arr3d,arr3dh,arr2d)
  503. ! change time index
  504. timeidx_mon= timeidx_mon + 1
  505. ! accululated time to zero
  506. accumulation_mon=0
  507. call GO_Timer_End( itim_write_mon, status )
  508. IF_NOTOK_RETURN(status=1)
  509. call goLabel()
  510. status = 0
  511. end subroutine output_c4mip_write_monthly
  512. subroutine output_c4mip_write_daily(region,newday,status)
  513. use MeteoData, only : temper_dat, sst_dat, albedo_dat, ci_dat, lsp_dat, cp_dat, ssr_dat, str_dat, &
  514. blh_dat, gph_dat, lwc_dat, iwc_dat, cco_dat, cc_dat, humid_dat, m_dat, phlb_dat, sp_dat !
  515. use meteodata , only : global_lli, levi
  516. use partools , only : isRoot,myid
  517. use GO, only : TDate, NewDate!
  518. use datetime, only : tau2date,date2tau,julday !
  519. use dims, only : itau,iyear0 !current time
  520. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  521. implicit none
  522. logical,intent(in) ::newday
  523. integer,intent(out)::status
  524. integer::region
  525. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  526. character(len=*), parameter :: rname = mname//'/output_c4mip_write_daily'
  527. integer:: j_var
  528. ! reference time:
  529. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  530. integer(kind=8) :: itauref ! reftime in seconds
  531. real :: reftime ! seconds from reference time
  532. real :: rangeday ! for bounds
  533. ! root writes netcdf arrays
  534. real, allocatable :: arr3d(:,:,:), arr2d(:,:)
  535. 4 integer:: imr_f,jmr_f,lmr_f
  536. call goLabel(rname)
  537. call GO_Timer_Start( itim_write_day, status )
  538. IF_NOTOK_RETURN(status=1)
  539. if (region > 1) then
  540. write(gol,*) 'output_c4mip_write_daily: region >1, only available in global mode!'
  541. call goErr
  542. status=1
  543. return
  544. end if
  545. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  546. ! entire region grid size
  547. imr = global_lli(1)%nlon
  548. jmr = global_lli(1)%nlat
  549. lmr = levi%nlev
  550. ! allocate 3D and 4D global arrays for gathering data
  551. if (isRoot) then
  552. allocate( arr3d(imr,jmr,lmr) )
  553. allocate( arr2d(imr,jmr) )
  554. else
  555. allocate( arr3d(1,1,1) )
  556. allocate( arr2d(1,1) )
  557. endif
  558. arr2d(:,:)=0.0
  559. arr3d(:,:,:)=0.0
  560. ! define the reference time in seconds (itauref)
  561. ! (for now in days since 1850-01-01 00:00, local variable)
  562. call date2tau( time_reftime6, itauref )
  563. ! calculate reftime as fractional days from itauref, hence division by 86400
  564. ! call date2tau( idater, itaucur )
  565. reftime = (itau - itauref) / 86400. - 1.0
  566. !23h59 as days
  567. rangeday=1.0!(23.0*3600.0+59.0*60.0+59.0)/86400.0
  568. do j_var =1,n_vars
  569. if (allvars(j_var)%table_id/='AERday')then
  570. cycle
  571. end if
  572. if (allvars(j_var)%dims==2)then
  573. 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
  574. allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_day)
  575. end if
  576. call GO_Timer_Start( itim_write_gather, status )
  577. IF_NOTOK_RETURN(status=1)
  578. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0, status)
  579. IF_NOTOK_RETURN(status=1)
  580. call GO_Timer_End( itim_write_gather, status )
  581. IF_NOTOK_RETURN(status=1)
  582. 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/) )
  583. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  584. if (trim(allvars(j_var)%vname)=='minpblz' .or. trim(allvars(j_var)%vname)=='tasmin') then
  585. ! put high number so simple comparison is needed for finding minimum
  586. allvars(j_var)%data2D(i1:i2,j1:j2)=1e10
  587. else
  588. ! Zero out the accumulated and written data for the next interval
  589. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  590. end if
  591. else
  592. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_day)
  593. !end if
  594. call GO_Timer_Start( itim_write_gather, status )
  595. IF_NOTOK_RETURN(status=1)
  596. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  597. call GO_Timer_End( itim_write_gather, status )
  598. IF_NOTOK_RETURN(status=1) !if (trim(allvars(j_var)%vname)=='od5503ddust')then
  599. IF_NOTOK_RETURN(status=1)
  600. 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/) )
  601. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  602. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=0.0
  603. end if
  604. ! write the date for timestep
  605. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime+0.5/) , status, start=(/timeidx_day/), count=(/1/) )
  606. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  607. 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/) )
  608. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  609. end do
  610. deallocate(arr3d, arr2d)
  611. ! Timeindex to next day
  612. timeidx_day= timeidx_day + 1
  613. ! daily accumulated time to zero
  614. accumulation_day=0.0
  615. !status=1
  616. !return
  617. call GO_Timer_End( itim_write_day, status )
  618. IF_NOTOK_RETURN(status=1)
  619. call goLabel()
  620. status = 0
  621. end subroutine output_c4mip_write_daily
  622. subroutine output_c4mip_write_hourly(region,newhour,status)
  623. 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 !
  624. use GO, only : TDate, NewDate!
  625. use datetime, only : tau2date,date2tau,julday !
  626. use dims, only : itau,iyear0 !current time
  627. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  628. use partools , only : isRoot,myid
  629. implicit none
  630. logical,intent(in) ::newhour
  631. integer,intent(out)::status
  632. integer:: j_var
  633. integer::region
  634. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  635. character(len=*), parameter :: rname = mname//'/output_c4mip_write_hourly'
  636. real :: rangehr,range6hr ! hour in days for bounds in NC-file
  637. ! reference time:
  638. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  639. integer(kind=8) :: itauref ! reftime in seconds
  640. real :: reftime ! seconds from reference time
  641. ! root writes netcdf arrays
  642. real, allocatable :: arr3d(:,:,:) , arr2d(:,:)
  643. call goLabel(rname)
  644. call GO_Timer_Start( itim_write_hour, status )
  645. IF_NOTOK_RETURN(status=1)
  646. if (region > 1) then
  647. write(gol,*) 'output_c4mip_write_hourly: region >1, only available in global mode!'
  648. call goErr
  649. status=1
  650. return
  651. end if
  652. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  653. ! entire region grid size
  654. imr = global_lli(1)%nlon
  655. jmr = global_lli(1)%nlat
  656. lmr = levi%nlev
  657. ! allocate 3D and 4D global arrays for gathering data
  658. if (isRoot) then
  659. allocate( arr3d(imr,jmr,lmr) )
  660. allocate( arr2d(imr,jmr) )
  661. else
  662. ! other than root need the variable, but no space
  663. allocate( arr3d(1,1,1) )
  664. allocate( arr2d(1,1) )
  665. endif
  666. arr2d(:,:)=0.0
  667. arr3d(:,:,:)=0.0
  668. ! define the reference time in seconds (itauref)
  669. ! (for now in days since 1850-01-01 00:00, local variable)
  670. call date2tau( time_reftime6, itauref )
  671. ! call date2tau( idater, itaucur )
  672. rangehr=1.0/24.0!(3600)/86400.0
  673. do j_var =1,n_vars
  674. if (allvars(j_var)%table_id/='AERhr' .and. allvars(j_var)%table_id/='AER6hr' )then
  675. cycle
  676. end if
  677. if (allvars(j_var)%dims==0 .and.trim(allvars(j_var)%vname)=='co2mass1' )then
  678. reftime = (itau - itauref) / 86400. - (1./24)
  679. allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_hr)
  680. call gather( dgrid(1), allvars(j_var)%data2D , arr3d(:,:,1), 0, status)
  681. IF_NOTOK_RETURN(status=1)
  682. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%varid,(/sum(arr3d(:,:,1))/), status, start=(/timeidx_hr/), count=(/1/) )
  683. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  684. else if (allvars(j_var)%dims==2)then
  685. if ( trim(allvars(j_var)%table_id)=='AERhr') then
  686. reftime = (itau - itauref) / 86400. - (1./24)
  687. allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_hr)
  688. call GO_Timer_Start( itim_write_gather, status )
  689. IF_NOTOK_RETURN(status=1)
  690. call gather( dgrid(1), allvars(j_var)%data2D , arr3d(:,:,1), 0, status)
  691. IF_NOTOK_RETURN(status=1)
  692. call GO_Timer_End( itim_write_gather, status )
  693. IF_NOTOK_RETURN(status=1)
  694. 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/) )
  695. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  696. ! write the date for timestep
  697. 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/) )
  698. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  699. 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/) )
  700. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  701. ! Zero out the accumulated and written data for the next interval
  702. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  703. end if
  704. else
  705. if ( trim(allvars(j_var)%table_id)=='AERhr') then
  706. reftime = (itau - itauref) / 86400. - (1./24)
  707. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_hr)
  708. call GO_Timer_Start( itim_write_gather, status )
  709. IF_NOTOK_RETURN(status=1)
  710. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  711. call GO_Timer_End( itim_write_gather, status )
  712. IF_NOTOK_RETURN(status=1)
  713. 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/) )
  714. ! write the date for timestep
  715. 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/) )
  716. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  717. 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/) )
  718. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  719. ! Zero out the accumulated and written data for the next interval
  720. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=0.0
  721. end if
  722. end if
  723. !end if
  724. end do
  725. deallocate(arr3d, arr2d)
  726. ! changed index to next hour
  727. timeidx_hr= timeidx_hr + 1
  728. ! accumulated hours to zero, actually this will always be 1h
  729. accumulation_hr=0.0
  730. !status=1
  731. !return
  732. call GO_Timer_End( itim_write_hour, status )
  733. IF_NOTOK_RETURN(status=1)
  734. call goLabel()
  735. status = 0
  736. end subroutine output_c4mip_write_hourly
  737. subroutine output_c4mip_write_6hourly(region,newhour,status)
  738. 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 !
  739. use GO, only : TDate, NewDate!
  740. use datetime, only : tau2date,date2tau,julday !
  741. use dims, only : itau,iyear0 !current time
  742. use tm5_distgrid, only : dgrid, Get_DistGrid ,gather
  743. use partools , only : isRoot,myid
  744. !use ebischeme, only : AC_diag_prod,iprod_soa2dhour
  745. implicit none
  746. logical,intent(in) ::newhour
  747. integer,intent(out)::status
  748. integer::region
  749. integer:: j_var
  750. integer:: imr,jmr,i,i1,i2,j1,j2,lmr
  751. character(len=*), parameter :: rname = mname//'/output_c4mip_write_6hourly'
  752. ! reference time:
  753. integer, parameter :: time_reftime6(6) = (/1750,01,01,00,00,00/)
  754. integer(kind=8) :: itauref ! reftime in seconds
  755. real :: reftime ! seconds from reference time
  756. ! root writes netcdf arrays
  757. real, allocatable :: arr3d(:,:,:) , arr2d(:,:)
  758. call goLabel(rname)
  759. call GO_Timer_Start( itim_write_hour, status )
  760. IF_NOTOK_RETURN(status=1)
  761. if (region > 1) then
  762. write(gol,*) 'output_c4mip_write_6hourly: region >1, only available in global mode!'
  763. call goErr
  764. status=1
  765. return
  766. end if
  767. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  768. ! entire region grid size
  769. imr = global_lli(1)%nlon
  770. jmr = global_lli(1)%nlat
  771. lmr = levi%nlev
  772. ! allocate 3D and 4D global arrays for gathering data
  773. if (isRoot) then
  774. allocate( arr3d(imr,jmr,lmr) )
  775. allocate( arr2d(imr,jmr) )
  776. else
  777. ! other than root need the variable, but no space
  778. allocate( arr3d(1,1,1) )
  779. allocate( arr2d(1,1) )
  780. endif
  781. arr2d(:,:)=0.0
  782. arr3d(:,:,:)=0.0
  783. ! define the reference time in seconds (itauref)
  784. ! (for now in days since 1850-01-01 00:00, local variable)
  785. call date2tau( time_reftime6, itauref )
  786. ! call date2tau( idater, itaucur )
  787. reftime = (itau - itauref) / 86400.
  788. do j_var =1,n_vars
  789. if ( allvars(j_var)%table_id/='AER6hr' )then
  790. cycle
  791. end if
  792. if (allvars(j_var)%dims==2)then
  793. !allvars(j_var)%data2D(i1:i2,j1:j2)=allvars(j_var)%data2D(i1:i2,j1:j2)/real(accumulation_6hr)
  794. call GO_Timer_Start( itim_write_gather, status )
  795. IF_NOTOK_RETURN(status=1)
  796. call gather( dgrid(1), allvars(j_var)%data2D , arr2d(:,:), 0, status)
  797. IF_NOTOK_RETURN(status=1)
  798. call GO_Timer_End( itim_write_gather, status )
  799. IF_NOTOK_RETURN(status=1)
  800. 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/) )
  801. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  802. ! write the date for timestep
  803. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime/) , status, start=(/timeidx_6hr/), count=(/1/) )
  804. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  805. ! Zero out the accumulated and written data for the next interval
  806. allvars(j_var)%data2D(i1:i2,j1:j2)=0.0
  807. else
  808. !allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)/real(accumulation_6hr)
  809. call GO_Timer_Start( itim_write_gather, status )
  810. IF_NOTOK_RETURN(status=1)
  811. call gather( dgrid(1), allvars(j_var)%data3D , arr3d(:,:,:), 0, status)
  812. call GO_Timer_End( itim_write_gather, status )
  813. IF_NOTOK_RETURN(status=1)
  814. 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/) )
  815. ! write the date for timestep
  816. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit,allvars(j_var)%time_varid,(/ reftime/) , status, start=(/timeidx_6hr/), count=(/1/) )
  817. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  818. !start=(/i1,j1,1,timeidx_mon/), count=(/imr,jmr,lmr,1/) )
  819. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  820. ! Zero out the accumulated and written data for the next interval
  821. allvars(j_var)%data3D(i1:i2,j1:j2,1:lmr)=0.0
  822. end if
  823. end do
  824. deallocate(arr3d,arr2d)
  825. ! changed index to next 6hour
  826. timeidx_6hr= timeidx_6hr + 1
  827. ! exception for one 6hr field, no need to do another subroutine for it
  828. accumulation_6hr=0.0
  829. call GO_Timer_End( itim_write_hour, status )
  830. IF_NOTOK_RETURN(status=1)
  831. call goLabel()
  832. status = 0
  833. end subroutine output_c4mip_write_6hourly
  834. subroutine accumulate_c4mip_data(dhour,status)
  835. use GO , only : TDate, NewDate, rTotal, operator(-)
  836. use Grid , only : FPressure,HPressure
  837. use binas, only : rgas, rol,xmair,Dobs,Avog
  838. USE toolbox, only : ltropo_ifs, lvlpress
  839. !use datetime, only : tau2date
  840. use MeteoData, only : temper_dat, sst_dat, albedo_dat, ci_dat, lsp_dat, cp_dat, ssr_dat, str_dat, blh_dat, &
  841. gph_dat, lwc_dat, iwc_dat, cco_dat, cc_dat, humid_dat, m_dat, phlb_dat, sp_dat, pu_dat, pv_dat,pw_dat
  842. !use photolysis_data,only:phot_dat !
  843. use global_data, only : mass_dat, region_dat,conv_dat
  844. use dims, only : lm,sec_month
  845. use partools , only : isRoot,myid
  846. use dims, only: gtor, dx, dy, ybeg, xref, yref,ndyn
  847. use binas, only: ae
  848. implicit none
  849. character(len=*), parameter :: rname = mname//'/output_c4mip_accumulate_co2_data'
  850. ! integer :: indices(7)
  851. integer :: itrac,gasind
  852. integer :: i_sed
  853. integer :: i_emi
  854. integer :: i, j, k, imr, jmr, lmr, lwl, dtime,index,imode,m
  855. integer :: i1, i2, j1, j2
  856. integer :: ie, je ! indices for subdomain extended with halo cells
  857. integer,intent(in) :: dhour
  858. integer :: status
  859. integer :: j_var,region,i_var,i_wdep,sedindex,icomp
  860. real :: dens
  861. real :: vol
  862. real :: tempbud,xmcomp,temp
  863. real, dimension(:,:,:,:), pointer :: tracers ! transported tracers
  864. real, dimension(:), pointer :: dxyp
  865. integer, dimension(n_indices) :: indices
  866. real::xmgas
  867. real, dimension(:,:,:), pointer :: t ! temperature (K)
  868. !
  869. call goLabel(rname)
  870. call GO_Timer_Start( itim_accu, status )
  871. IF_NOTOK_RETURN(status=1)
  872. region=1
  873. ! grid size
  874. call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2)
  875. imr = i2-i1+1
  876. jmr = j2-j1+1
  877. lmr = levi%nlev
  878. t => temper_dat (region)%data
  879. !accumulation_6hr=0.0!accumulation_6hr+dtime
  880. ! Gridbox area
  881. dxyp => region_dat(region)%dxyp
  882. ! mass_dat keep data in kg/gridbox
  883. !
  884. tracers => mass_dat(region)%rm
  885. dtime = dhour*3600
  886. accumulation_mon=accumulation_mon+dtime
  887. accumulation_hr=accumulation_hr+dtime
  888. accumulation_day=accumulation_day+dtime
  889. do j_var = 1, n_vars
  890. indices(:)=allvars(j_var)%indices(:)
  891. !Here we use the tm5-indices to collect data for output
  892. if (trim(allvars(j_var)%class)=='fixed') then
  893. cycle
  894. else if (trim(allvars(j_var)%class)=='monthly')then
  895. index=indices(1)
  896. do k=1,lmr
  897. do j=j1,j2
  898. do i=i1,i2
  899. if (trim(allvars(j_var)%vname)=='ps')then
  900. if (k .eq. 1) allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)!Pa
  901. else if(trim(allvars(j_var)%vname)=='co2')then
  902. xmcomp=ra(index)
  903. 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
  904. else if(trim(allvars(j_var)%vname)=='co2mass')then
  905. index= allvars(j_var)%indices(1)
  906. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,k,index)/dxyp(j)! kg/m2
  907. else if (index<=0) then
  908. ! you should not end up here!!!
  909. cycle
  910. end if
  911. end do
  912. end do
  913. end do
  914. else if (trim(allvars(j_var)%class)=='ps6h')then
  915. do i=i1,i2
  916. do j=j1,j2
  917. if (trim(allvars(j_var)%vname)=='ps')then
  918. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)!Pa
  919. end if
  920. end do
  921. end do
  922. ! 1 hourly surface variables
  923. else if (trim(allvars(j_var)%class)=='hourly')then
  924. do i=i1,i2
  925. do j=j1,j2
  926. if (trim(allvars(j_var)%vname)=='ps')then
  927. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)!Pa
  928. else if (trim(allvars(j_var)%vname)=='co2') then
  929. index= indices(1)
  930. xmcomp=ra(index)
  931. do k=1,lmr
  932. 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
  933. end do
  934. else if(trim(allvars(j_var)%vname)=='co2mass')then
  935. do k=1,lmr
  936. index= allvars(j_var)%indices(1)
  937. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,k,index)/dxyp(j)!kg/m2
  938. end do
  939. else if(trim(allvars(j_var)%vname)=='co2mass1')then
  940. do k=1,lmr
  941. index= allvars(j_var)%indices(1)
  942. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,k,index)/dxyp(j)!kg/m2
  943. end do
  944. else if (trim(allvars(j_var)%vname)=='tas')then
  945. allvars(j_var)%data2D(i,j)=allvars(j_var)%data2D(i,j)+dtime*temper_dat(1)%data(i,j,1)!K
  946. end if
  947. end do
  948. end do
  949. ! surface daily variables
  950. else if (trim(allvars(j_var)%class)=='daily')then
  951. index= indices(1)
  952. do i=i1,i2
  953. do j=j1,j2
  954. if (trim(allvars(j_var)%vname)=='ps')then
  955. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*sp_dat(1)%data(i,j,1)!Pa
  956. else if (trim(allvars(j_var)%vname)=='co2') then
  957. xmcomp=ra(index)
  958. do k=1,lmr
  959. 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
  960. end do
  961. else if(trim(allvars(j_var)%vname)=='co2mass')then
  962. do k=1,lmr
  963. allvars(j_var)%data2D(i,j)= allvars(j_var)%data2D(i,j)+dtime*tracers(i,j,k,index)/dxyp(j)! kg/m2
  964. end do
  965. end if
  966. end do
  967. end do
  968. else
  969. write(gol,*) 'output_c4mip_accumulate: output class not found!!!',trim(allvars(j_var)%vname),trim(allvars(j_var)%class)
  970. !call goPr
  971. call goErr
  972. status=1
  973. return
  974. end if
  975. end do
  976. ! zero accumulated budget variables for the amount between output steps
  977. call GO_Timer_End( itim_accu, status )
  978. IF_NOTOK_RETURN(status=1)
  979. call goLabel()
  980. !status = 1
  981. end subroutine accumulate_c4mip_data
  982. subroutine output_c4mip_done(status)
  983. use partools, only: isRoot,myid
  984. implicit none
  985. integer :: status
  986. character(len=*), parameter :: rname = mname//'/output_c4mip_done'
  987. integer :: j_var, region
  988. call goLabel(rname)
  989. region = 1
  990. if (isroot) then
  991. do j_var=1,n_vars
  992. call MDF_Close( allvars(j_var)%fileunit, status )
  993. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  994. end do
  995. end if
  996. deallocate(dimension_data%lon)
  997. deallocate(dimension_data%lat)
  998. deallocate(dimension_data%lev)
  999. do j_var=1,n_vars
  1000. deallocate(allvars(j_var)%data2D)
  1001. deallocate(allvars(j_var)%data3D)
  1002. end do
  1003. deallocate(allvars)
  1004. deallocate(fixedvars)
  1005. call goLabel()
  1006. status = 0
  1007. end subroutine output_c4mip_done
  1008. subroutine add_variable(itm5,shortname,longname,unit,data_dims,status,class,table,pxmgas)
  1009. #ifdef with_m7
  1010. use chem_param, only: mode_end_so4,mode_end_pom,mode_end_bc,mode_end_ss,mode_end_dust
  1011. #else
  1012. use chem_param, only: ico2
  1013. #endif
  1014. use global_data, only: outdir
  1015. use datetime, only: tau2date, date2tau
  1016. use dims, only: itau,itaue,itaut
  1017. implicit none
  1018. integer:: itm5
  1019. character(len=*),intent(in)::shortname
  1020. character(len=*),intent(in)::longname
  1021. character(len=*)::unit
  1022. character(len=30)::standardname
  1023. character(len=*)::table
  1024. character(len=*),optional::class
  1025. real,optional::pxmgas
  1026. integer:: data_dims
  1027. integer,intent(out)::status
  1028. !LOCAL
  1029. character(len=4)::positive=''
  1030. integer:: fileunit=-1 !defined only when creating a file
  1031. integer:: varid=-1! defined when opening ncfile
  1032. !character(len=120)::filename
  1033. character(len=30)::table_id
  1034. !character(len=30)::c4mip_source_id
  1035. !character(len=30)::c4mip_experiment_id
  1036. character(len=30)::member_id
  1037. !character(len=30)::grid_label
  1038. character(len=30)::time_range
  1039. character(len=200)::filename1
  1040. character(len=10)::freq
  1041. real,dimension(:,:),pointer::data2D
  1042. ! real,dimension(:,:),pointer::dataZonal
  1043. real,dimension(:,:,:),pointer::data3D
  1044. ! real,dimension(:,:,:),pointer::budget
  1045. character(len=*), parameter :: rname = mname//'/output_c4mip_add_variable'
  1046. integer ::i1,i2,j1,j2,jmr,imr,lmr
  1047. integer, dimension(6) :: idater, idateend, idatett
  1048. integer :: endmonth, endday
  1049. character(len=30) :: idates
  1050. call tau2date(itau,idater)
  1051. ! define frequency from table
  1052. if (trim(table)=='AERhr')then
  1053. !table id depends on variable
  1054. table_id=table
  1055. freq='1hr'
  1056. else if (trim(table)=='AER6hr')then
  1057. !table id depends on variable
  1058. table_id=table
  1059. freq='6hr'
  1060. else if( trim(table)=='AERmon'.or.trim(table)=='AERmonZ'.or.trim(table)=='Emon')then
  1061. !table id depends on variable
  1062. table_id=table
  1063. freq='mon'
  1064. else if(trim(table)=='AERday')then
  1065. !table id depends on variable
  1066. table_id=table
  1067. freq='day'
  1068. else if(trim(table)=='AERfx')then
  1069. !table id depends on variable
  1070. table_id=table
  1071. freq='na'
  1072. else
  1073. freq='freq-nondefined'
  1074. table_id='table-nondefined'
  1075. end if
  1076. ! CREATE date string for output
  1077. !
  1078. ! ATM assumed that the output is initilised at the beginninh of year
  1079. endmonth=12
  1080. endday=31
  1081. !
  1082. if (freq=='mon')then
  1083. ! By default CO2 runs are done by 1-year chunks -> idater(2) - idater(2)+11
  1084. write(idates, '(i4,i2.2,a,i4,i2.2)') idater(1), idater(2),'-', idater(1),endmonth
  1085. else if(freq=='day')then
  1086. !time range form Jan-1 ->Dec-31x
  1087. write(idates, '(i4,2i2.2,a,i4,2i2.2)') idater(1), idater(2), idater(3),'-', idater(1), endmonth, endday
  1088. else if(freq=='1hr')then
  1089. 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'
  1090. else if (freq=='6hr')then
  1091. 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'
  1092. end if
  1093. call goLabel(rname)
  1094. call GO_Timer_Start( itim_addvar, status )
  1095. IF_NOTOK_RETURN(status=1)
  1096. !outdir='output'
  1097. ! temporary
  1098. standardname=longname
  1099. ! c4mip_source_id constant
  1100. !c4mip_source_id='EC-EARTH-CC'
  1101. ! experiment depends on run
  1102. !experiment_id='exp_dynamic'
  1103. member_id='r'//trim(realization_i)//'i'//trim(initialization_i)//'p'//trim(physics_i)//'f'//trim(forcing_i)
  1104. !grid_label='3x2_degrees'
  1105. ! time range has divider in place since it can be omitted alltogether with non-time dependendent variables
  1106. if (trim(table)=='AERfx')then
  1107. time_range=''
  1108. else
  1109. time_range='_'//trim(idates)
  1110. end if
  1111. ! for fixed variables time range should not be written
  1112. n_vars=n_vars+1
  1113. call Get_DistGrid( dgrid(1), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1114. ! define sizes for arrays
  1115. imr=i2-i1+1
  1116. jmr=j2-j1+1
  1117. lmr = levi%nlev
  1118. ! if (trim(shortname)=='phalf') then
  1119. ! allocate(budget(i1:i2,j1:j2,1:lmr+1))
  1120. ! else
  1121. ! allocate(budget(i1:i2,j1:j2,1:lmr))
  1122. ! end if
  1123. ! budget(:,:,:)=0.0
  1124. !write(2004,*)shortname
  1125. ! 2D variables
  1126. if (data_dims==2) then
  1127. !Allocate holders for data
  1128. allocate(allvars(n_vars)%data2D(i1:i2,j1:j2))
  1129. allocate(allvars(n_vars)%data3D(1,1,1))
  1130. ! allocate local variables
  1131. allocate(data2D(i1:i2,j1:j2))
  1132. allocate(data3D(1,1,1))
  1133. ! zero local data holders
  1134. data2D(:,:)=0.0
  1135. ! dataZonal(:,:)=0.0
  1136. data3D(:,:,:)=0.0
  1137. !init variable
  1138. ! set default for minimum variables to high value
  1139. if (shortname=='minpblz' .or. shortname=='tasmin')then
  1140. data2D(:,:)=1000000.0
  1141. end if
  1142. !create filename
  1143. if (trim(class)=='crescendo')then
  1144. ! filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(table_id)//'_'//trim(c4mip_source_id)//'_'//trim(experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//'_'//trim(time_range)//trim('.nc')
  1145. filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(class)//'_'//trim(table_id)//'_'//trim(c4mip_source_id)//'_'//trim(c4mip_experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//trim(time_range)//trim('.nc')
  1146. else
  1147. filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(table_id)//'_'//trim(c4mip_source_id)//'_'//trim(c4mip_experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//trim(time_range)//trim('.nc')
  1148. end if
  1149. allvars(n_vars)=varfile(itm5,shortname,longname,unit,positive,standardname,data2D,data3D,-1,-1,&
  1150. 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)
  1151. !! LEFT HERE on purpose to see what variables go where in above statement
  1152. !!$ allvars(n_vars)%itm5=itm5
  1153. !!$ allvars(n_vars)%vname=shortname
  1154. !!$ allvars(n_vars)%lname=longname
  1155. !!$ allvars(n_vars)%unit=unit
  1156. !!$ allvars(n_vars)%positive=positive
  1157. !!$ allvars(n_vars)%standard_name=standardname
  1158. !!$ allvars(n_vars)%data2D=data2D
  1159. !!$ allvars(n_vars)%data3D=data3D
  1160. !!$ allvars(n_vars)%budgetdata=data3D
  1161. !!$ allvars(n_vars)varid=-1
  1162. !!$ allvars(n_vars)%filenunit=-1
  1163. !!$ allvars(n_vars)%filename=filename1
  1164. !!$ allvars(n_vars)%dimensions=2
  1165. !!$ allvars(n_vars)%lon_varid=-1
  1166. !!$ allvars(n_vars)%lat_varid=-1
  1167. !!$ allvars(n_vars)%lev_varid=-1
  1168. !!$ allvars(n_vars)%time_varid=-1
  1169. !!$ allvars(n_vars)%bounds_varid=-1
  1170. !!$ allvars(n_vars)%dims=dims
  1171. !!$ allvars(n_vars)%class=class
  1172. !!$ allvars(n_vars)%indices=(/0,0,0,0,0,0,0/))
  1173. !!$ allvars(n_vars)%xmgas=molarweight
  1174. !!$ allvars(n_vars)%table_id=
  1175. ! 3D variables
  1176. else if (data_dims==3) then
  1177. ! allocate holders for data
  1178. allocate(allvars(n_vars)%data2D(1,1))
  1179. if (trim(shortname)=='phalf') then
  1180. allocate(allvars(n_vars)%data3D(i1:i2,j1:j2,1:lmr+1))
  1181. allocate(data3D(i1:i2,j1:j2,1:lmr+1))
  1182. else
  1183. allocate(allvars(n_vars)%data3D(i1:i2,j1:j2,1:lmr))
  1184. allocate(data3D(i1:i2,j1:j2,1:lmr))
  1185. end if
  1186. ! allocate local variables
  1187. ! maybe remove these
  1188. allocate(data2D(1,1))
  1189. !allocate(data3D(i1:i2,j1:j2,1:lmr))
  1190. ! zero local data holders
  1191. data2D(:,:)=0.0
  1192. data3D(:,:,:)=0.0
  1193. !init variable
  1194. filename1= trim(outdir)//'/'//trim(shortname)//'_'//trim(table_id)//'_'//trim(c4mip_source_id)//'_'//trim(c4mip_experiment_id)//'_'//trim(member_id)//'_'//trim(grid_label)//trim(time_range)//trim('.nc')
  1195. allvars(n_vars)=varfile(itm5,shortname,longname,unit,positive,standardname,data2D,data3D,-1,-1,&
  1196. 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)
  1197. end if
  1198. ! add chemical info also: (vars beginning with emi,wet,dry)
  1199. select case (trim(shortname(4:)))
  1200. case ('so2')
  1201. allvars(n_vars)%indices(1)=iso2
  1202. end select
  1203. select case (trim(shortname))
  1204. case('areacella')
  1205. allvars(n_vars)%indices(:)=0
  1206. areacella=n_vars
  1207. case('co2','co2mass','co2mass1')
  1208. write(2000,*) ico2,n_vars,trim(shortname),table
  1209. allvars(n_vars)%indices(1)=ico2
  1210. end select
  1211. call goLabel()
  1212. status = 0
  1213. call GO_Timer_End( itim_addvar, status )
  1214. IF_NOTOK_RETURN(status=1)
  1215. end subroutine add_variable
  1216. subroutine write_attributes(status,j_var)
  1217. implicit none
  1218. integer :: j_var
  1219. integer,intent(out)::status
  1220. character(len=*), parameter :: rname = mname//'/output_c4mip_writeattr'
  1221. call goLabel(rname)
  1222. call GO_Timer_Start( itim_attr, status )
  1223. IF_NOTOK_RETURN(status=1)
  1224. call MDF_Put_Att( allvars(j_var)%fileunit, MDF_GLOBAL, 'title', 'Model output for C4mip', status )
  1225. IF_NOTOK_MDF(fid= allvars(j_var)%fileunit)
  1226. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'units', 'degrees_east', status)
  1227. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1228. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'axis', 'X', status)
  1229. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1230. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'long_name', 'longitude', status)
  1231. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1232. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lon_varid , 'standard_name', 'longitude', status)
  1233. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1234. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'units', 'degrees_north', status)
  1235. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1236. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'axis', 'Y', status)
  1237. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1238. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'long_name', 'latitude', status)
  1239. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1240. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lat_varid , 'standard_name', 'latitude', status)
  1241. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1242. ! allvars(j_var)%lev_varid
  1243. if (allvars(j_var)%dims==3) then
  1244. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'units', 'level', status)
  1245. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1246. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'axis', 'Z', status)
  1247. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1248. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'long_name', 'hybrid model level at layer midpoints', status)
  1249. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1250. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'standard_name', 'hybrid_model_level', status)
  1251. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1252. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'formula', 'a+b*ps', status)
  1253. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1254. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%lev_varid , 'positive', 'up', status)
  1255. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1256. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyam_varid , 'long_name', 'hybrid A coefficient at layer midpoints', status)
  1257. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1258. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyam_varid , 'units', 'Pa', status)
  1259. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1260. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybm_varid , 'long_name', 'hybrid B coefficient at layer midpoints', status)
  1261. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1262. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybm_varid , 'units', '1', status)
  1263. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1264. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyai_varid , 'long_name', 'hybrid A coefficient at layer interfaces', status)
  1265. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1266. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hyai_varid , 'units', 'Pa', status)
  1267. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1268. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybi_varid , 'long_name', 'hybrid B coefficient at layer interfaces', status)
  1269. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1270. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%hybi_varid , 'units', '1', status)
  1271. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1272. END if
  1273. if (allvars(j_var)%table_id/='AERfx')then
  1274. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'units', 'days since 1750-01-01 00:00:00', status)
  1275. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1276. ! call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'axis', 'X', status)
  1277. ! IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1278. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'calendar', 'gregorian', status)
  1279. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1280. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'long_name', 'time', status)
  1281. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1282. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'axis', 'T', status)
  1283. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1284. !time bounds
  1285. call MDF_Put_Att( allvars(j_var)%fileunit,allvars(j_var)%time_varid , 'bounds', 'time_bounds', status)
  1286. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1287. end if
  1288. !experiment=
  1289. !CMIP6 global attributes:
  1290. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'Conventions', 'CF-1.7 CMIP-6.0 UGRID-0.9', status)
  1291. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'activity_id', 'C4mip', status)
  1292. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'branch_method','', status)
  1293. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'creation_date','', status)
  1294. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'data_specs_version','1.0.0', status)
  1295. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'experiment',trim(c4mip_experiment), status)
  1296. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'experiment_id',trim(c4mip_experiment_id), status)
  1297. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'forcing_index',trim(forcing_i), status)
  1298. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'frequency',trim(allvars(j_var)%freq), status)
  1299. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'further_info_url','MISSING', status)
  1300. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'grid','native '//trim(grid)//' degree grid', status)!module variables
  1301. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'grid_label',trim(grid_label), status)!module variables
  1302. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'initialization_index',trim(initialization_i), status)
  1303. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'institution','KNMI, The Netherlands; SMHI, Sweden; DMI, Denmark; &
  1304. &AEMET, Spain; Met Eireann, Ireland; CNR-ISAC, Italy; Instituto de Meteorologia, Portugal; FMI, Finland; BSC, Spain; &
  1305. &Centro de Geofisica, University of Lisbon, Portugal; ENEA, Italy; Geomar, Germany; Geophysical Institute, University of Bergen, Norway; &
  1306. &ICHEC, Ireland; ICTP, Italy; IMAU, The Netherlands; IRV, Sweden; Lund University, Sweden; &
  1307. &Meteorologiska Institutionen, Stockholms University, Sweden; Niels Bohr Institute, University of Copenhagen, Denmark; &
  1308. &NTNU, Norway; SARA, The Netherlands; Unite ASTR, Belgium; Universiteit Utrecht, The Netherlands; &
  1309. &Universiteit Wageningen, The Netherlands; University College Dublin, Ireland; Vrije Universiteit Amsterdam, the Netherlands; &
  1310. &University of Helsinki, Finland; KIT, Karlsruhe, Germany; USC, University of Santiago de Compostela, Spain; &
  1311. &Uppsala Universitet, Sweden; NLeSC, Netherlands eScience Center, The Netherlands', status)
  1312. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'institution_id','EC-Earth-Consortium', status)
  1313. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'license','NEEDS DEFINING', status)
  1314. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'mip_era','CMIP6', status)
  1315. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'nominal_resolution','250 km', status)!dmax
  1316. !dmax=r*phi/2*(1+((phi**2+lamb**2)/(phi*lamb))*np.arctan(lamb/phi))=348 r=6371, phi=2(lat), lamb=3(long)
  1317. !CMIP6 global attributes: 100 < dmax < 350 -> nominal resolution 250 km
  1318. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'physics_index',trim(physics_i), status)
  1319. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'product','output', status)!only choice
  1320. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'realization_index',trim(realization_i), status)!1 for primary or single realization
  1321. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'realm',trim(c4mip_realm), status)! depends on run, some are AGCM
  1322. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source',trim(c4mip_source), status)!
  1323. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source_id',trim(c4mip_source_id), status)
  1324. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'source_type',trim(c4mip_source_type), status)
  1325. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'sub_experiment','', status)
  1326. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'sub_experiment_id','', status)
  1327. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'table_id',trim(allvars(j_var)%table_id), status)
  1328. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'tracking_id','', status)
  1329. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variable_id',trim(allvars(j_var)%vname), status)
  1330. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variant_label','', status)
  1331. call MDF_Put_Att( allvars(j_var)%fileunit,MDF_GLOBAL , 'variant_label','', status)
  1332. call GO_Timer_End( itim_attr, status )
  1333. IF_NOTOK_RETURN(status=1)
  1334. call goLabel()
  1335. status = 0
  1336. end subroutine write_attributes
  1337. subroutine write_dimensions(status,j_var)
  1338. use dims, only : iyear0 !current year
  1339. use go_date, only : days_in_year,newDate
  1340. use partools , only : isRoot,myid
  1341. implicit none
  1342. integer :: j_var
  1343. integer,intent(out)::status
  1344. integer :: i1,i2,j1,j2,imr,jmr,lmr
  1345. integer :: lon_varid,lonid,lon_dimid
  1346. integer :: lat_varid,latid,lat_dimid
  1347. integer :: lev_varid,levid,lev_dimid
  1348. integer :: hym_varid,hym_dimid
  1349. integer :: hyi_varid,hyi_dimid
  1350. integer :: time_varid,timeid,time_dimid,bounds_dimid,bounds_varid,boudid
  1351. ! most of data is monthly mean, but change to dynamic number of output steps needed
  1352. integer :: nout_steps!=12
  1353. integer :: nhym
  1354. integer :: nhyi
  1355. character(len=*), parameter :: rname = mname//'/output_c4mip_write_dim'
  1356. call goLabel(rname)
  1357. ! define dimensions
  1358. !call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1359. imr=dimension_data%nlon
  1360. jmr=dimension_data%nlat
  1361. lmr=dimension_data%nlev
  1362. nhym=lmr
  1363. nhyi=lmr+1
  1364. ! With parallel netcdf whole netcdf must be reserved at the time of initialisation
  1365. ! therefore we need to know the number of output steps per file.
  1366. ! Define number of output steps in a file depending on the output frequency
  1367. ! use newdate to create TDate structure, and use that in days_in_year
  1368. if (allvars(j_var)%table_id=='AERhr')then
  1369. nout_steps=24*days_in_year(newdate(iyear0))
  1370. else if (allvars(j_var)%table_id=='AER6hr')then
  1371. nout_steps=4*days_in_year(newdate(iyear0))
  1372. else if (allvars(j_var)%table_id=='AERday')then
  1373. nout_steps=days_in_year(newdate(iyear0))
  1374. else if (allvars(j_var)%table_id=='AERmon'.or. (allvars(j_var)%table_id=='AERmonZ'))then
  1375. nout_steps=12
  1376. end if
  1377. if (isroot) then
  1378. !DEFINE DIMENSIONS
  1379. if (allvars(j_var)%dims>0) then
  1380. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lon', imr,lon_dimid, status )
  1381. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1382. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lat', jmr, lat_dimid, status )
  1383. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1384. end if
  1385. if (allvars(j_var)%dims==3) then
  1386. if (trim(allvars(j_var)%vname)=='phalf') then
  1387. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lev', lmr+1, lev_dimid, status )
  1388. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1389. else
  1390. call MDF_Def_Dim( allvars(j_var)%fileunit, 'lev', lmr, lev_dimid, status )
  1391. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1392. end if
  1393. end if
  1394. if (allvars(j_var)%table_id/='AERfx')then
  1395. !call MDF_Def_Dim( allvars(j_var)%fileunit, 'time', nout_steps, time_dimid, status )
  1396. call MDF_Def_Dim( allvars(j_var)%fileunit, 'time', MDF_UNLIMITED, time_dimid, status )
  1397. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1398. call MDF_Def_Dim( allvars(j_var)%fileunit, 'bounds', 2, bounds_dimid, status )
  1399. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1400. end if
  1401. if (allvars(j_var)%dims==3) then
  1402. call MDF_Def_Dim( allvars(j_var)%fileunit, 'nhym', nhym, hym_dimid, status )
  1403. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1404. call MDF_Def_Dim( allvars(j_var)%fileunit, 'nhyi', nhyi, hyi_dimid, status )
  1405. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1406. end if
  1407. ! define dimension variables
  1408. ! dim 0= global sum
  1409. if (allvars(j_var)%dims>0) then
  1410. ! longitude
  1411. call MDF_Def_Var( allvars(j_var)%fileunit, 'lon', MDF_DOUBLE, &
  1412. (/ lon_dimid/), allvars(j_var)%lon_varid, status )
  1413. ! define latitude variable
  1414. call MDF_Def_Var( allvars(j_var)%fileunit, 'lat', MDF_DOUBLE, &
  1415. (/ lat_dimid/), allvars(j_var)%lat_varid, status )
  1416. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1417. end if
  1418. ! level
  1419. if (allvars(j_var)%dims==3) then
  1420. call MDF_Def_Var( allvars(j_var)%fileunit, 'lev', MDF_DOUBLE, &
  1421. (/ lev_dimid/), allvars(j_var)%lev_varid, status )
  1422. end if
  1423. if (allvars(j_var)%table_id/='AERfx')then
  1424. call MDF_Def_Var( allvars(j_var)%fileunit, 'time', MDF_DOUBLE, &
  1425. (/ time_dimid/), allvars(j_var)%time_varid, status )
  1426. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1427. call MDF_Def_Var( allvars(j_var)%fileunit, 'time_bounds', MDF_DOUBLE, &
  1428. (/ bounds_dimid,time_dimid/), allvars(j_var)%bounds_varid, status )
  1429. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1430. end if
  1431. if (allvars(j_var)%dims==3) then
  1432. ! define hybm variable
  1433. call MDF_Def_Var( allvars(j_var)%fileunit, 'hybm', MDF_DOUBLE, &
  1434. (/ hym_dimid/), allvars(j_var)%hybm_varid, status )
  1435. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1436. ! define hyam variable
  1437. call MDF_Def_Var( allvars(j_var)%fileunit, 'hyam', MDF_DOUBLE, &
  1438. (/ hym_dimid/), allvars(j_var)%hyam_varid, status )
  1439. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1440. ! define hybi variable
  1441. call MDF_Def_Var( allvars(j_var)%fileunit, 'hybi', MDF_DOUBLE, &
  1442. (/ hyi_dimid/), allvars(j_var)%hybi_varid, status )
  1443. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1444. ! define hyai variable
  1445. call MDF_Def_Var( allvars(j_var)%fileunit, 'hyai', MDF_DOUBLE, &
  1446. (/ hyi_dimid/), allvars(j_var)%hyai_varid, status )
  1447. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1448. end if
  1449. ! * Write out dimension variable values
  1450. ! Write out hybm
  1451. if (allvars(j_var)%dims==3) then
  1452. ! midpoints
  1453. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hybm_varid,levi%fb, status)
  1454. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1455. ! Write out hyam
  1456. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hyam_varid,levi%fa, status)
  1457. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1458. ! interfaces
  1459. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hybi_varid,levi%b, status)
  1460. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1461. ! Write out hyai
  1462. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%hyai_varid,levi%a, status)
  1463. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1464. end if
  1465. ! Write out the longitudes
  1466. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%lon_varid, dimension_data%lon, status)
  1467. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1468. !write out the latitude to variable
  1469. if (isroot)call MDF_Put_Var( allvars(j_var)%fileunit, allvars(j_var)%lat_varid, dimension_data%lat, status)
  1470. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1471. if (allvars(j_var)%dims==3) then
  1472. if (trim(allvars(j_var)%vname)=='phalf') then
  1473. !N= levi%fb?
  1474. if (lmr+1==35)then
  1475. ! Write out the levels
  1476. 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)
  1477. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1478. else if (lmr==11)then
  1479. 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/), status)
  1480. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1481. else
  1482. write(gol,*) 'Number of levels not supported for c4mip output: ,',lmr
  1483. IF_ERROR_RETURN(status=1)
  1484. end if
  1485. ! end if
  1486. else
  1487. !N= levi%b
  1488. if (lmr==34) then
  1489. 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)
  1490. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1491. else if(lmr==10) then
  1492. 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/), status)
  1493. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1494. else
  1495. write(gol,*) 'Number of levels not supported for c4mip output: ,',lmr
  1496. IF_ERROR_RETURN(status=1)
  1497. end if
  1498. end if
  1499. end if
  1500. ! Time will be written during output write -steps
  1501. end if
  1502. call goLabel()
  1503. status = 0
  1504. end subroutine write_dimensions
  1505. subroutine write_var(status,j_var)
  1506. implicit none
  1507. integer :: j_var
  1508. integer,intent(out)::status
  1509. integer :: i1,i2,j1,j2,imr,jmr,lmr
  1510. integer :: lon_varid,lonid
  1511. integer :: lat_varid,latid
  1512. integer :: lev_varid,levid
  1513. integer :: time_varid,timeid
  1514. character(len=*), parameter :: rname = mname//'/output_c4mip_write_dim'
  1515. call goLabel(rname)
  1516. ! define dimensions
  1517. !call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
  1518. imr=dimension_data%nlon
  1519. jmr=dimension_data%nlat
  1520. lmr=dimension_data%nlev
  1521. ! define dimension variables
  1522. ! longitude
  1523. if (allvars(j_var)%dims==2.and.allvars(j_var)%table_id/='AERfx') then
  1524. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  1525. (/allvars(j_var)%lon_varid, allvars(j_var)%lat_varid, allvars(j_var)%time_varid/), allvars(j_var)%varid, status )
  1526. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1527. else if (allvars(j_var)%dims==2.and.allvars(j_var)%table_id=='AERfx') then
  1528. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  1529. (/allvars(j_var)%lon_varid, allvars(j_var)%lat_varid/), allvars(j_var)%varid, status )
  1530. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1531. else
  1532. !(allvars(j_var)%dims==3)
  1533. call MDF_Def_Var( allvars(j_var)%fileunit, allvars(j_var)%vname, MDF_DOUBLE, &
  1534. (/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 )
  1535. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1536. end if
  1537. ! Write out the longitudes
  1538. call MDF_Put_Att( allvars(j_var)%fileunit, allvars(j_var)%varid, 'long_name', trim(allvars(j_var)%lname), status )
  1539. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1540. call MDF_Put_Att(allvars(j_var)%fileunit,allvars(j_var)%varid, 'standard_name', trim(allvars(j_var)%standard_name), status )
  1541. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1542. call MDF_Put_Att(allvars(j_var)%fileunit , allvars(j_var)%varid, 'units', trim(allvars(j_var)%unit), status )
  1543. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1544. call MDF_EndDef( allvars(j_var)%fileunit, status )
  1545. IF_NOTOK_MDF(fid=allvars(j_var)%fileunit)
  1546. call goLabel()
  1547. status = 0
  1548. end subroutine write_var
  1549. end MODULE USER_OUTPUT_C4MIP