user_output_station.F90 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651
  1. !
  2. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  3. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  4. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  5. !
  6. #include "tm5.inc"
  7. !
  8. !-----------------------------------------------------------------------------
  9. ! TM5 !
  10. !-----------------------------------------------------------------------------
  11. !BOP
  12. !
  13. ! !MODULE: USER_OUTPUT_STATION
  14. !
  15. ! !DESCRIPTION: Routines to deal with output for specific stations.
  16. !
  17. ! This version adds code to the original version in order to
  18. ! write AOD and alpha to the station files (cf #ifdef with_optics)
  19. !\\
  20. !\\
  21. ! !INTERFACE:
  22. !
  23. MODULE USER_OUTPUT_STATION
  24. !
  25. ! !USES:
  26. !
  27. use GO, only : gol, goErr, goPr
  28. use binas, only : ae, twopi, grav
  29. use dims, only : im, jm, lm, dx, dy, xref, yref, xbeg, ybeg, xend, yend
  30. use dims, only : nregions, region_name, itaur, xcyc
  31. use chem_param, only : ntrace, ntracet, names, fscale
  32. use file_hdf, only : THdfFile, Init, Done, TSds, SetDim
  33. use ParTools, only : isRoot, myid
  34. IMPLICIT NONE
  35. PRIVATE
  36. !
  37. ! !PUBLIC MEMBER FUNCTIONS:
  38. !
  39. public :: read_stationlist ! read files with station definitions
  40. public :: init_station_output ! init output files
  41. public :: reset_stationconc_accumulator ! set to 0 acummulation arrays
  42. public :: output_stationconc ! accumulate arrays
  43. public :: evaluate_stationconc ! compute mean and std dev
  44. public :: write_stationconc ! write mean conc to file
  45. public :: free_stationfields ! close output files, free arrays
  46. #if defined(with_pm) || defined(with_optics)
  47. public :: n_stat2
  48. public :: io_hdf
  49. ! Optics wants to write wavelength information here.
  50. ! Optics can do it more easily than user_output.
  51. ! Optics uses user_output_station. This means that user_output_station
  52. ! cannot use optics.
  53. ! PM also uses this.
  54. #endif
  55. !
  56. ! !PRIVATE DATA MEMBERS:
  57. !
  58. character(len=100) :: StationlistFFilename2 ! list of 'validation' stations
  59. character(len=100) :: InputDir = './'
  60. logical :: output_stations_meteo = .true.
  61. character(len=300) :: StationSpeclist
  62. integer :: StationlistFileFormat ! 1: old format, 2: new format, 3: newer format
  63. integer :: n_stat2 ! number of 'validation' stations (not used for 4DVAR)
  64. integer, dimension(ntrace) :: station_speclist ! list of species for output (may differ per PE)
  65. integer :: station_nspec ! number of species for output (may differ per PE)
  66. integer, parameter :: n_metdat = 7 ! max number of meteo data (for output in station output file)
  67. integer, parameter :: n_interpol = 3 ! number of station interpolation methods
  68. integer, parameter :: n_neighbors = 6 ! number of neighboring grid cells used for estimate of represent. error
  69. character(len=4), dimension(n_interpol), parameter :: c_interpol = (/'_grd','_slp','_int'/)
  70. character(len=12),dimension(n_metdat ), parameter :: C_metdat = &
  71. (/'Temperature', &
  72. 'Pressure ',&
  73. 'uwind ',&
  74. 'vwind ',&
  75. 'windspeed ',&
  76. 'winddir ',&
  77. 'blh '/)
  78. character(len=12),dimension(n_metdat ), parameter :: U_metdat = &
  79. (/'K ', &
  80. 'hPa ', &
  81. 'm/s ', &
  82. 'm/s ', &
  83. 'm/s ', &
  84. 'degrees wrtN', &
  85. 'm '/)
  86. type(THdfFile) :: io_hdf ! contains HDF output file
  87. integer :: io_record = 0
  88. ! 'open' datasets of the io_hdf output file:
  89. type(TSds), dimension(:,:), allocatable :: Sds
  90. type(TSds), dimension(n_metdat) :: Sds_meteo
  91. type(TSds) :: Sds_idate
  92. #ifdef with_optics
  93. Type(TSds), public :: sds_station_aod
  94. Type(TSds), public :: sds_station_alpha
  95. #endif
  96. #ifdef with_pm
  97. Type(TSds), public :: sds_station_pm
  98. #endif
  99. ! --- const -------------------------
  100. character(len=*), parameter :: mname = 'user_output_station'
  101. !
  102. ! !PUBLIC TYPES:
  103. !
  104. type, public :: stations
  105. character(len=13) :: ident ! station identifier
  106. character(len=50) :: name ! station name
  107. real :: lat ! latitude of station
  108. real :: lon ! longitude of station
  109. real :: height ! height of station
  110. real :: height_sample ! sampling height
  111. real :: height_surface ! height of model surface
  112. real :: height_sample_above_surf ! height_sample-height_surface
  113. integer :: index ! index of station
  114. integer :: region
  115. integer :: is
  116. integer :: js
  117. integer :: ls
  118. character(len=2) :: type ! sampling type (FM = flask; CM = continuous)
  119. integer :: land ! land or ocean site
  120. integer :: nonsurf ! 1: nonsurface sites (e.g. towers); 0: 'regular' sites
  121. real,dimension(n_metdat) :: metdat ! meteodata (interpolated) at stations
  122. real,dimension(:,:),pointer :: c_mean ! c_mean(species, interpolation)
  123. real,dimension(:,:),pointer :: c_std ! c_std(species, interpolation)
  124. integer :: ncount ! counter
  125. logical :: ontile ! is located on current tile of domain decomposition
  126. ! In the chem version, the following comment was found:
  127. ! "No one is estimating representativeness errors. You can compare the
  128. ! different interpolations to acquire something similar." And the code
  129. ! with *_nb was commented.
  130. ! That code is kept live here in the user_output version until further decision.
  131. ! grid neighbors (for estimate of representativeness error)
  132. real,dimension(:,:),pointer :: c_mean_nb ! mean concentrations of neighbors (species, neighb. index)
  133. real,dimension(:,:),pointer :: c_std_nb ! standard deviation (species, neighb. index)
  134. integer,dimension(:,:),pointer :: ncount_nb ! counter (species, neighb. index)
  135. real,dimension(:),pointer :: dc_mod ! estimate of representativeness error (species)
  136. !(based on 3D gradient to grid cell neighbors)
  137. end type stations
  138. !
  139. ! !PUBLIC DATA MEMBERS:
  140. !
  141. type(stations), dimension(:), public, allocatable :: stat ! collection of stations
  142. character(len=100), public :: StationlistFFilename ! list of 'regular' stations
  143. logical, public :: write_Stationfiles = .true. ! do station
  144. integer, save, public :: n_stat ! number of 'regular' stations (used for 4DVAR)
  145. integer, save, public :: io_nrecords ! # record = # timesteps
  146. !
  147. ! !REVISION HISTORY:
  148. !
  149. ! Modified by Peter Beramaschi.
  150. ! Parallel version Maarten Krol Jul 2003
  151. ! jun 2005: switch to HDF output file
  152. ! jul 2007: paralel writing to increase performance..
  153. ! 10 Jul 2012 - Ph. Le Sager - merged with chem base version to account
  154. ! for with_optics, with_pm
  155. ! - adapted for lon-lat MPI domain decomposition
  156. !
  157. ! !REMARKS:
  158. !
  159. !EOP
  160. !------------------------------------------------------------------------
  161. CONTAINS
  162. !--------------------------------------------------------------------------
  163. ! TM5 !
  164. !--------------------------------------------------------------------------
  165. !BOP
  166. !
  167. ! !IROUTINE: FREE_STATIONFIELDS
  168. !
  169. ! !DESCRIPTION: close output files and deallocate arrays
  170. !\\
  171. !\\
  172. ! !INTERFACE:
  173. !
  174. SUBROUTINE FREE_STATIONFIELDS( status )
  175. !
  176. ! !INPUT/OUTPUT PARAMETERS:
  177. !
  178. integer, intent(inout) :: status
  179. !
  180. ! !REVISION HISTORY:
  181. !
  182. !EOP
  183. !------------------------------------------------------------------------
  184. !BOC
  185. integer :: i_stat
  186. character(len=*), parameter :: rname = mname//'/free_stationfields'
  187. !__START_SUBROUTINE______________________________________________________
  188. if(write_Stationfiles) then
  189. call close_stationfiles( status )
  190. IF_NOTOK_RETURN(status=1)
  191. endif
  192. write(gol,*) '************************************', station_nspec ; call goPr
  193. !cmk : the following lines do not work on huygens????
  194. if (station_nspec > 0 ) then
  195. do i_stat = 1, n_stat+n_stat2
  196. deallocate(stat(i_stat)%c_mean)
  197. deallocate(stat(i_stat)%c_std )
  198. enddo
  199. do i_stat = 1, n_stat
  200. deallocate(stat(i_stat)%c_mean_nb)
  201. deallocate(stat(i_stat)%c_std_nb)
  202. deallocate(stat(i_stat)%ncount_nb)
  203. deallocate(stat(i_stat)%dc_mod)
  204. enddo
  205. deallocate( stat )
  206. end if
  207. status = 0
  208. END SUBROUTINE FREE_STATIONFIELDS
  209. !EOC
  210. !--------------------------------------------------------------------------
  211. ! TM5 !
  212. !--------------------------------------------------------------------------
  213. !BOP
  214. !
  215. ! !IROUTINE: READ_STATIONLIST
  216. !
  217. ! !DESCRIPTION: Reads input files with stations definition. Allocate and
  218. ! fill station objects.
  219. !\\
  220. !\\
  221. ! !INTERFACE:
  222. !
  223. SUBROUTINE READ_STATIONLIST( status )
  224. !
  225. ! !USES:
  226. !
  227. use GO, only : TrcFile, Init, Done, ReadRc
  228. use global_data, only : rcfile
  229. use chem_param, only : ntracet, names
  230. use tm5_distgrid, only : dgrid, get_distgrid
  231. use ParTools, only : isRoot
  232. !
  233. ! !INPUT/OUTPUT PARAMETERS:
  234. !
  235. integer, intent(inout) :: status
  236. !
  237. ! !REVISION HISTORY:
  238. ! 16 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  239. !
  240. !EOP
  241. !------------------------------------------------------------------------
  242. !BOC
  243. integer :: slen1, slen2 !string length
  244. character(len=200) :: dummy
  245. integer :: fstatus
  246. integer :: i_stat
  247. integer :: region
  248. integer, dimension(6) :: idate_sim
  249. integer :: itau_sim, isim, ispec
  250. integer :: ipos, i, n
  251. integer :: i1, j1, i2, j2, is, js ! tile bounds and station indices
  252. real :: dxr, dyr ! x,y resolution (in degrees) for current region
  253. character(len=8) :: name_spec
  254. integer :: sunit1=110
  255. integer :: sunit2=111
  256. type(TrcFile) :: rcF
  257. character(len=*), parameter :: rname = mname//'/read_stationlist'
  258. !__START_SUBROUTINE______________________________________________________
  259. call Init( rcF, rcfile, status)
  260. IF_NOTOK_RETURN(status=1)
  261. call ReadRc( rcF, 'inputdir.station', InputDir,status)
  262. IF_NOTOK_RETURN(status=1)
  263. call ReadRc( rcF, 'input.station.filename', StationlistFFilename,status)
  264. IF_NOTOK_RETURN(status=1)
  265. call ReadRc( rcF, 'input.station.filename2', StationlistFFilename2,status)
  266. IF_NOTOK_RETURN(status=1)
  267. call ReadRc( rcF, 'input.station.fileformat', StationlistFileFormat,status)
  268. IF_NOTOK_RETURN(status=1)
  269. call ReadRc( rcF, 'station.speclist', StationSpeclist,status)
  270. IF_NOTOK_RETURN(status=1)
  271. call Done( rcF ,status)
  272. IF_NOTOK_RETURN(status=1)
  273. ! -------- count # of regular and validation stations
  274. n_stat=0
  275. n_stat2=0
  276. slen1=len_trim(StationlistFFilename)
  277. if ( slen1 > 0 ) then
  278. !=========================================
  279. ! open StationFile (with list of stations)
  280. !=========================================
  281. open(UNIT=sunit1, FORM='FORMATTED', &
  282. FILE=trim(InputDir)//trim(StationlistFFilename), &
  283. STATUS='OLD', ERR=1000)
  284. read(sunit1, '(a)') dummy
  285. ! count number of stations
  286. do
  287. read(sunit1, '(a)', end=100) dummy
  288. !if((dummy(1:1) /= ' ') .and. (dummy(1:7) /= 'species')) then
  289. n_stat = n_stat+1
  290. enddo
  291. 100 continue
  292. end if
  293. slen2=len_trim(StationlistFFilename2)
  294. if ( slen2 > 0 ) then
  295. !=========================================
  296. ! open StationFile (with list of stations)
  297. !=========================================
  298. open(UNIT=sunit2, FORM='FORMATTED', &
  299. FILE=trim(InputDir)//trim(StationlistFFilename2), &
  300. STATUS='OLD', ERR=1001)
  301. read(sunit2, '(a)') dummy
  302. ! count number of stations
  303. do
  304. read(sunit2, '(a)', END=200) dummy
  305. if((dummy(1:1) /= ' ') .and. (dummy(1:7) /= 'species')) then
  306. n_stat2 = n_stat2+1
  307. else
  308. goto 200
  309. endif
  310. enddo
  311. 200 continue
  312. end if
  313. ! ---- determine index of species in good order
  314. station_nspec = 0
  315. ipos = 1
  316. do
  317. i = index(StationSpeclist(ipos:),' ')
  318. if (i == 0) then
  319. name_spec = trim(StationSpeclist(ipos:))
  320. else
  321. name_spec = trim(StationSpeclist(ipos:ipos+i-1))
  322. ipos = ipos + i
  323. endif
  324. do n=1,ntracet
  325. if ((trim(name_spec).eq.trim(names(n))).or.(trim(name_spec).eq.'all')) then
  326. station_nspec = station_nspec + 1
  327. station_speclist(station_nspec) = n
  328. endif
  329. enddo
  330. if(trim(name_spec).eq.'') exit
  331. enddo
  332. write(gol,*) trim(mname),':station_nspec; station_speclist', &
  333. station_nspec, station_speclist(1:station_nspec)
  334. call goPr
  335. ! ---- allocate station objects
  336. if (station_nspec > 0) then
  337. allocate(stat(n_stat+n_stat2)) ! all PE have all station, but only some will fill data
  338. do i_stat = 1, n_stat+n_stat2
  339. allocate(stat(i_stat)%c_mean(station_nspec,n_interpol))
  340. allocate(stat(i_stat)%c_std(station_nspec,n_interpol))
  341. enddo
  342. do i_stat = 1, n_stat
  343. allocate(stat(i_stat)%c_mean_nb(station_nspec,n_neighbors))
  344. allocate(stat(i_stat)%c_std_nb(station_nspec,n_neighbors))
  345. allocate(stat(i_stat)%ncount_nb(station_nspec,n_neighbors))
  346. allocate(stat(i_stat)%dc_mod(station_nspec))
  347. enddo
  348. ! ---- Read/fill stations definition, assuming first they are in region #1
  349. dyr = dy/yref(1)
  350. dxr = dx/xref(1)
  351. call get_distgrid( dgrid(1), i_strt=i1, i_stop=i2, j_strt=j1, j_stop=j2)
  352. if ( slen1 > 0 ) then
  353. !=========================
  354. ! read 'regular' stations
  355. !=========================
  356. rewind(sunit1)
  357. read(sunit1, '(a)') dummy
  358. do i_stat=1, n_stat
  359. select case(StationlistFileFormat)
  360. case(1)
  361. read(sunit1, '(a7,1x,f8.2,f8.2,f8.1,1x,a50)') &
  362. stat(i_stat)%ident, &
  363. stat(i_stat)%lat, &
  364. stat(i_stat)%lon, &
  365. stat(i_stat)%height, &
  366. stat(i_stat)%name
  367. stat(i_stat)%nonsurf = 0
  368. case(2)
  369. read(sunit1, '(a11,f8.2,4x,f8.2,4x,f8.1,1x,a2,1x,i2,1x,a50)') &
  370. stat(i_stat)%ident, &
  371. stat(i_stat)%lat, &
  372. stat(i_stat)%lon, &
  373. stat(i_stat)%height, &
  374. stat(i_stat)%type, &
  375. stat(i_stat)%nonsurf, &
  376. stat(i_stat)%name
  377. case(3)
  378. read(sunit1, '(a13,f6.2,4x,f8.2,4x,f8.0,4x,i1,5x,i1,a50)') &
  379. stat(i_stat)%ident, &
  380. stat(i_stat)%lat, &
  381. stat(i_stat)%lon, &
  382. stat(i_stat)%height, &
  383. stat(i_stat)%land, &
  384. stat(i_stat)%nonsurf, &
  385. stat(i_stat)%name
  386. stat(i_stat)%ident = adjustl(stat(i_stat)%ident)
  387. endselect
  388. stat(i_stat)%index = i_stat
  389. ! assume global region as default for average mixing ratios
  390. stat(i_stat)%region = 1
  391. is = int((stat(i_stat)%lon-float(xbeg(1)))/dxr + 0.99999)
  392. js = int((stat(i_stat)%lat-float(ybeg(1)))/dyr + 0.99999)
  393. stat(i_stat)%is = is
  394. stat(i_stat)%js = js
  395. ! is it on current PE?
  396. if (is>=i1.and.is<=i2.and.js>=j1.and.js<=j2) then
  397. stat(i_stat)%ontile=.true.
  398. else
  399. stat(i_stat)%ontile=.false.
  400. end if
  401. end do
  402. ! close stationfile
  403. close(sunit1)
  404. endif
  405. if ( slen2 > 0 ) then
  406. !=========================
  407. ! read 'validation' stations
  408. !=========================
  409. rewind(sunit2)
  410. read(sunit2, '(a)') dummy
  411. do i_stat=n_stat+1, n_stat+n_stat2
  412. select case(StationlistFileFormat)
  413. case(1)
  414. read(sunit2, '(a7,1x,f8.2,f8.2,f8.1,1x,a50)') &
  415. stat(i_stat)%ident, &
  416. stat(i_stat)%lat, &
  417. stat(i_stat)%lon, &
  418. stat(i_stat)%height, &
  419. stat(i_stat)%name
  420. stat(i_stat)%nonsurf = 0
  421. case(2)
  422. read(sunit2, '(a11,f8.2,f8.2,f8.1,1x,a2,1x,i2,1x,a50)') &
  423. stat(i_stat)%ident, &
  424. stat(i_stat)%lat, &
  425. stat(i_stat)%lon, &
  426. stat(i_stat)%height, &
  427. stat(i_stat)%type, &
  428. stat(i_stat)%nonsurf, &
  429. stat(i_stat)%name
  430. case(3)
  431. read(sunit2, '(a13,f6.2,4x,f8.2,4x,f8.0,4x,i1,5x,i1,a50)') &
  432. stat(i_stat)%ident, &
  433. stat(i_stat)%lat, &
  434. stat(i_stat)%lon, &
  435. stat(i_stat)%height, &
  436. stat(i_stat)%land, &
  437. stat(i_stat)%nonsurf, &
  438. stat(i_stat)%name
  439. stat(i_stat)%ident = adjustl(stat(i_stat)%ident)
  440. endselect
  441. stat(i_stat)%index = i_stat
  442. ! assume global region as default for average mixing ratios
  443. stat(i_stat)%region = 1
  444. is = int((stat(i_stat)%lon-float(xbeg(1)))/dxr + 0.99999)
  445. js = int((stat(i_stat)%lat-float(ybeg(1)))/dyr + 0.99999)
  446. stat(i_stat)%is = is
  447. stat(i_stat)%js = js
  448. if (is>=i1.and.is<=i2.and.js>=j1.and.js<=j2) then
  449. stat(i_stat)%ontile=.true.
  450. else
  451. stat(i_stat)%ontile=.false.
  452. end if
  453. end do
  454. ! close stationfile
  455. close(sunit2)
  456. end if
  457. !=================================================
  458. ! determine region with highest refinement factor
  459. !=================================================
  460. do i_stat=1, n_stat+n_stat2
  461. do region=1, nregions
  462. dyr = dy/yref(region)
  463. dxr = dx/xref(region)
  464. if ( (stat(i_stat)%lon .ge. xbeg(region) .and. &
  465. stat(i_stat)%lon .le. xend(region)) .and. &
  466. (stat(i_stat)%lat .ge. ybeg(region) .and. &
  467. stat(i_stat)%lat .le. yend(region) ) ) then
  468. !=====================
  469. ! station is in region
  470. !=====================
  471. ! determine region with hightes refinement factor
  472. if (xref(region) > xref(stat(i_stat)%region)) then
  473. stat(i_stat)%region = region
  474. is = int((stat(i_stat)%lon-float(xbeg(region)))/dxr + 0.99999)
  475. js = int((stat(i_stat)%lat-float(ybeg(region)))/dyr + 0.99999)
  476. stat(i_stat)%is = is
  477. stat(i_stat)%js = js
  478. call get_distgrid( dgrid(region), i_strt=i1, i_stop=i2, j_strt=j1, j_stop=j2)
  479. if (is>=i1.and.is<=i2.and.js>=j1.and.js<=j2) then
  480. stat(i_stat)%ontile=.true.
  481. else
  482. stat(i_stat)%ontile=.false.
  483. end if
  484. end if
  485. end if
  486. end do
  487. end do
  488. if ( isRoot ) then
  489. write(gol,*) '==========================' ; call goPr
  490. write(gol,*) ' regular stations ' ; call goPr
  491. write(gol,*) '==========================' ; call goPr
  492. do i_stat=1, n_stat
  493. write(gol, '(a13,1x,f8.2,f8.2,f8.1,1x,i4,1x,i2,1x,a50)') &
  494. stat(i_stat)%ident, &
  495. stat(i_stat)%lat, &
  496. stat(i_stat)%lon, &
  497. stat(i_stat)%height, &
  498. stat(i_stat)%region, &
  499. stat(i_stat)%nonsurf, &
  500. stat(i_stat)%name ; call goPr
  501. end do
  502. write(gol,*) '==========================' ; call goPr
  503. write(gol,*) ' validation stations ' ; call goPr
  504. write(gol,*) '==========================' ; call goPr
  505. do i_stat=n_stat+1, n_stat+n_stat2
  506. write(gol, '(a11,1x,f8.2,f8.2,f8.1,1x,i4,1x,i2,1x,a50)') &
  507. stat(i_stat)%ident, &
  508. stat(i_stat)%lat, &
  509. stat(i_stat)%lon, &
  510. stat(i_stat)%height, &
  511. stat(i_stat)%region, &
  512. stat(i_stat)%nonsurf, &
  513. stat(i_stat)%name ; call goPr
  514. end do
  515. endif
  516. endif
  517. call reset_stationconc_accumulator
  518. ! ok
  519. status = 0
  520. return
  521. ! error handling
  522. 1000 write(gol,*) 'read_stationlist: could not open ' // trim(InputDir)//trim(StationlistFFilename) ; call goErr
  523. 1001 write(gol,*) 'read_stationlist: could not open ' // trim(InputDir)//trim(StationlistFFilename2) ; call goErr
  524. status = 1
  525. END SUBROUTINE READ_STATIONLIST
  526. !EOC
  527. !--------------------------------------------------------------------------
  528. ! TM5 !
  529. !--------------------------------------------------------------------------
  530. !BOP
  531. !
  532. ! !IROUTINE: INIT_STATION_OUTPUT
  533. !
  534. ! !DESCRIPTION: initialize hdf files for station output.
  535. !\\
  536. !\\
  537. ! !INTERFACE:
  538. !
  539. SUBROUTINE INIT_STATION_OUTPUT( status )
  540. !
  541. ! !USES:
  542. !
  543. use Dims, only : itaui, itaue, ndyn_max, idatei, idatee
  544. use file_hdf, only : Init, WriteAttribute, WriteData, TSds, Done
  545. use GO, only : TrcFile, Init, Done, ReadRc
  546. use global_data, only : rcfile, outdir
  547. use ParTools, only : isRoot
  548. !
  549. ! !OUTPUT PARAMETERS:
  550. !
  551. integer, intent(out) :: status
  552. !
  553. ! !REVISION HISTORY:
  554. ! 16 Mar 2012 - P. Le Sager -
  555. !
  556. ! !REMARKS:
  557. !
  558. !EOP
  559. !------------------------------------------------------------------------
  560. !BOC
  561. integer :: i_stat
  562. integer :: io_status
  563. type(TrcFile) :: rcF
  564. character(len=12) :: xname
  565. integer :: i, ii, j
  566. type(TSds) :: sds_temp
  567. character(len=200) :: station_filename
  568. character(len=3) :: smyid
  569. character(len=10) :: sidatei, sidatee
  570. character(len=*), parameter :: rname = mname//'/init_station_output'
  571. !__START_SUBROUTINE______________________________________________________
  572. if (write_Stationfiles .and. station_nspec > 0)then
  573. call Init( rcF, rcfile ,status)
  574. IF_NOTOK_RETURN(status=1)
  575. call ReadRc( rcF, 'output.station.filename', station_filename,status)
  576. IF_NOTOK_RETURN(status=1)
  577. call Done( rcF ,status)
  578. IF_NOTOK_RETURN(status=1)
  579. #ifdef MPI
  580. i = index(station_filename,'.hdf')
  581. write(smyid,'(a1,i2.2)') '_',myid
  582. write(sidatei,'(i4.4,3i2.2)') idatei(1:4)
  583. write(sidatee,'(i4.4,3i2.2)') idatee(1:4)
  584. if(i /= 0) then
  585. station_filename = station_filename(1:i-1)//smyid//'_'//sidatei//'_'//sidatee//'.hdf'
  586. else
  587. station_filename = trim(station_filename)//smyid//'_'//sidatei//'_'//sidatee//'.hdf'
  588. endif
  589. #else
  590. i = index(station_filename,'.hdf')
  591. write(sidatei,'(i4.4,3i2.2)') idatei(1:4)
  592. write(sidatee,'(i4.4,3i2.2)') idatee(1:4)
  593. if(i /= 0) then
  594. station_filename = station_filename(1:i-1)//'_'//sidatei//'_'//sidatee//'.hdf'
  595. else
  596. station_filename = trim(station_filename)//'_'//sidatei//'_'//sidatee//'.hdf'
  597. endif
  598. #endif
  599. call Init( io_hdf, trim(outdir)//'/'//trim(station_filename),'create', status )
  600. IF_NOTOK_RETURN(status=1)
  601. io_record = 0
  602. Write(*,*) "Using itaui in stations"
  603. io_nrecords =abs(itaue-itaui)/ndyn_max
  604. call WriteAttribute( io_hdf, 'io_nrecords', io_nrecords,status)
  605. IF_NOTOK_RETURN(status=1)
  606. call WriteAttribute( io_hdf, 'n_stat', n_stat,status)
  607. IF_NOTOK_RETURN(status=1)
  608. call WriteAttribute( io_hdf, 'n_stat2', n_stat2,status) ! validation stations
  609. IF_NOTOK_RETURN(status=1)
  610. call WriteAttribute( io_hdf, 'n_spec', station_nspec,status)
  611. IF_NOTOK_RETURN(status=1)
  612. call WriteAttribute( io_hdf, 'station_speclist', station_speclist(1:station_nspec), status)
  613. IF_NOTOK_RETURN(status=1)
  614. call WriteAttribute( io_hdf, 'station_specnames', names(station_speclist(1:station_nspec)), status)
  615. IF_NOTOK_RETURN(status=1)
  616. call WriteAttribute( io_hdf, 'station_lat', stat(:)%lat, status)
  617. IF_NOTOK_RETURN(status=1)
  618. call WriteAttribute( io_hdf, 'station_lon', stat(:)%lon, status)
  619. IF_NOTOK_RETURN(status=1)
  620. call WriteAttribute( io_hdf, 'station_height', stat(:)%height, status)
  621. IF_NOTOK_RETURN(status=1)
  622. call WriteAttribute( io_hdf, 'station_index', stat(:)%index, status)
  623. IF_NOTOK_RETURN(status=1)
  624. call WriteAttribute( io_hdf, 'station_nonsurf', stat(:)%nonsurf, status)
  625. IF_NOTOK_RETURN(status=1)
  626. call WriteAttribute( io_hdf, 'station_region', stat(:)%region, status)
  627. IF_NOTOK_RETURN(status=1)
  628. call WriteAttribute( io_hdf, 'station_is', stat(:)%is, status)
  629. IF_NOTOK_RETURN(status=1)
  630. call WriteAttribute( io_hdf, 'station_js', stat(:)%js, status)
  631. IF_NOTOK_RETURN(status=1)
  632. call WriteAttribute( io_hdf, 'station_names', stat(:)%name, status)
  633. IF_NOTOK_RETURN(status=1)
  634. call WriteAttribute( io_hdf, 'station_ident', stat(:)%ident, status)
  635. IF_NOTOK_RETURN(status=1)
  636. allocate(Sds(station_nspec, n_interpol))
  637. do i=1, station_nspec
  638. do ii= 1,n_interpol
  639. xname = trim(names(station_speclist(i)))//c_interpol(ii)
  640. call init(Sds(i,ii), io_hdf, xname, (/n_stat+n_stat2, io_nrecords/), 'real(4)', status)
  641. IF_NOTOK_RETURN(status=1)
  642. call SetDim( sds(i,ii), 0, 'n_stations', 'station number', (/ (j, j=1,n_stat+n_stat2) /) , status)
  643. IF_NOTOK_RETURN(status=1)
  644. call SetDim( sds(i,ii), 1, 'n_records ', 'time slot #', (/ (j, j=1,io_nrecords) /) , status)
  645. IF_NOTOK_RETURN(status=1)
  646. call WriteAttribute(Sds(i,ii), 'Unit', 'Volume mixing ration (ppb)', status)
  647. IF_NOTOK_RETURN(status=1)
  648. enddo
  649. enddo
  650. if (.not. isRoot) output_stations_meteo = .false.
  651. if (output_stations_meteo) then
  652. do i=1,n_metdat
  653. call init(sds_meteo(i), io_hdf, c_metdat(i), (/n_stat+n_stat2, io_nrecords/), 'real(4)', status)
  654. IF_NOTOK_RETURN(status=1)
  655. call SetDim( sds_meteo(i), 0, 'n_stations', 'station number', (/ (j, j=1,n_stat+n_stat2) /) , status)
  656. IF_NOTOK_RETURN(status=1)
  657. call SetDim( sds_meteo(i), 1, 'n_records ', 'time slot #', (/ (j, j=1,io_nrecords) /) , status)
  658. IF_NOTOK_RETURN(status=1)
  659. call WriteAttribute(Sds_meteo(i), 'Unit', u_metdat(i), status)
  660. IF_NOTOK_RETURN(status=1)
  661. enddo
  662. endif
  663. call init(sds_idate, io_hdf, 'idate', (/6, io_nrecords/), 'integer(2)', status)
  664. IF_NOTOK_RETURN(status=1)
  665. call SetDim( sds_idate, 1, 'n_records ', 'time slot #', (/ (j, j=1,io_nrecords) /), status )
  666. IF_NOTOK_RETURN(status=1)
  667. call WriteAttribute(Sds_idate, 'Unit', 'year month day hour minutes seconds', status)
  668. IF_NOTOK_RETURN(status=1)
  669. end if ! write stationfiles = T
  670. ! ok
  671. status = 0
  672. END SUBROUTINE INIT_STATION_OUTPUT
  673. !EOC
  674. !--------------------------------------------------------------------------
  675. ! TM5 !
  676. !--------------------------------------------------------------------------
  677. !BOP
  678. !
  679. ! !IROUTINE: CLOSE_STATIONFILES
  680. !
  681. ! !DESCRIPTION: close ouput files.
  682. !\\
  683. !\\
  684. ! !INTERFACE:
  685. !
  686. SUBROUTINE CLOSE_STATIONFILES( status )
  687. !
  688. ! !USES:
  689. !
  690. use file_hdf, only : Done
  691. use ParTools, only : isRoot
  692. !
  693. ! !INPUT/OUTPUT PARAMETERS:
  694. !
  695. integer, intent(inout) :: status
  696. !
  697. ! !REVISION HISTORY:
  698. !
  699. !EOP
  700. !------------------------------------------------------------------------
  701. !BOC
  702. integer :: i, ii
  703. character(len=*), parameter :: rname = mname//'/close_station_files'
  704. !__START_SUBROUTINE______________________________________________________
  705. if (write_Stationfiles .and. station_nspec > 0)then
  706. do i=1, station_nspec
  707. do ii= 1,n_interpol
  708. call Done(sds(i,ii), status)
  709. IF_NOTOK_RETURN(status=1)
  710. enddo
  711. enddo
  712. if (.not.isRoot) output_stations_meteo = .false.
  713. if (output_stations_meteo) then
  714. do i=1,n_metdat
  715. call Done(sds_meteo(i),status)
  716. IF_NOTOK_RETURN(status=1)
  717. enddo
  718. endif
  719. call Done(sds_idate, status)
  720. IF_NOTOK_RETURN(status=1)
  721. deallocate(Sds)
  722. call Done(io_hdf, status)
  723. IF_NOTOK_RETURN(status=1)
  724. write(gol,*) 'Station file closed ' ; call goPr
  725. endif
  726. ! ok
  727. status = 0
  728. END SUBROUTINE CLOSE_STATIONFILES
  729. !EOC
  730. !--------------------------------------------------------------------------
  731. ! TM5 !
  732. !--------------------------------------------------------------------------
  733. !BOP
  734. !
  735. ! !IROUTINE: OUTPUT_STATIONCONC
  736. !
  737. ! !DESCRIPTION: accumulate mean and std dev arrays
  738. !\\
  739. !\\
  740. ! !INTERFACE:
  741. !
  742. SUBROUTINE OUTPUT_STATIONCONC(region, status)
  743. !
  744. ! !USES:
  745. !
  746. use global_data, only : mass_dat
  747. #ifndef without_convection
  748. use global_data, only : conv_dat
  749. #endif
  750. use MeteoData, only : m_dat, gph_dat, temper_dat, pu_dat, pv_dat, phlb_dat
  751. use datetime, only : tau2date
  752. !
  753. ! !INPUT PARAMETERS:
  754. !
  755. integer,intent(in) :: region
  756. !
  757. ! !INPUT/OUTPUT PARAMETERS:
  758. !
  759. integer,intent(inout):: status
  760. !
  761. ! !REVISION HISTORY:
  762. ! 16 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
  763. !
  764. ! !REMARKS:
  765. !
  766. !EOP
  767. !------------------------------------------------------------------------
  768. !BOC
  769. real,dimension(:,:,:,:),pointer :: rm ! tracer mass
  770. real,dimension(:,:,:,:),pointer :: rxm,rym,rzm ! slopes of tracer mass
  771. real,dimension(:,:,:) ,pointer :: m ! air mass
  772. real,dimension(:,:,:) ,pointer :: gph ! geopotential height
  773. ! real, dimension(:,:,:,:), allocatable, target :: rmg ! MPI arrays to gather fields.
  774. ! real, dimension(:,:,:,:), allocatable, target :: rxmg, rymg, rzmg
  775. ! real, dimension(:,:,: ), allocatable, target :: mg
  776. integer :: i_interpol ! interpolation procedures:
  777. real :: sampleheight
  778. ! 1: no interpolation
  779. ! 2: interpolation based on slopes
  780. ! 3: 3D linear interpolations
  781. integer :: i,j,l ! grid cell indices
  782. integer :: is,js,ls ! i,j,l index of grid cell in which station lis located
  783. integer :: isn,jsn,lsn ! i,j,l index of grid cell which is taken as neighbour for linear interpolation
  784. integer :: lst, lstn ! MPI implementation
  785. integer :: js_north, js_south ! j index of grid cell for neighbours for windspeed_v interpolation
  786. integer :: is_west ! i index of grid cell for neighbour for windspeed_u interpolation
  787. integer :: n ! index of tracer
  788. integer :: i_stat ! index of station
  789. real :: ris,rjs,rls ! deviation of station from center of the grid cell (-0.5 ... +0.5)
  790. real :: wcx,wcy,wcz ! x,y,z-weight of grid cell (1.0 ... 0.5)
  791. real :: dxr, dyr ! x,y resolution (in degrees) for current region
  792. real,dimension(0:lm(region)) :: height ! height of vertical grid boundaries
  793. integer, dimension(6) :: idate_f ! current idate for region
  794. integer :: sunit ! unit number for station output file
  795. real :: rm_interpol ! tracer mass, interpolated to station location
  796. integer :: ispec ! index over activated tracers
  797. !=============
  798. ! meteo output
  799. !=============
  800. real,dimension(n_stat,n_metdat) :: metdat ! meteodata (interpolated) at stations
  801. real,dimension(:,:,:), pointer :: T ! temperature
  802. real,dimension(:,:,:), pointer :: phlb ! pressure grid boundaries
  803. real,dimension(:,:,:), pointer :: pu ! mass flux x-direction [kg/s]
  804. real,dimension(:,:,:), pointer :: pv ! mass flux y-direction [kg/s]
  805. real,dimension(:,:), pointer :: blh ! boundary layer height [m]
  806. real :: T_interpol ! temperature, interpolated to station location
  807. real :: p_interpol ! pressure, interpolated to station location
  808. real :: windspeed_u_interpol ! wind speed [m/s] x-direction , interpolated to station location
  809. real :: windspeed_v_interpol ! wind speed [m/s] y-direction , interpolated to station location
  810. real :: windspeed_interpol ! wind speed [m/s] , interpolated to station location
  811. real :: winddir_interpol ! wind direction , interpolated to station location
  812. real :: blh_interpol ! boundary layer height , interpolated to station location
  813. real :: lat_j ! latitude of grid cell center js [degrees]
  814. real :: lat_jn ! latitude of grid cell center jsn [degrees]
  815. real :: ddx_j ! x-extension of grid cell js [m]
  816. real :: ddx_jn ! x-extension of grid cell jsn [m]
  817. real :: ddy ! y-extension of grid cell js [m]
  818. real :: vmr ! volume mi
  819. integer :: communicator,root_id,lmr,imr,jmr
  820. character(len=*), parameter :: rname = mname//'/output_station_conc'
  821. !__START_SUBROUTINE______________________________________________________
  822. if (station_nspec == 0) then
  823. status = 0
  824. return
  825. endif
  826. imr = im(region) ; jmr = jm(region) ; lmr = lm(region)
  827. m => m_dat(region)%data
  828. rm => mass_dat(region)%rm
  829. rxm => mass_dat(region)%rxm
  830. rym => mass_dat(region)%rym
  831. rzm => mass_dat(region)%rzm
  832. ! assign pointers (METEO)
  833. gph => gph_dat(region)%data
  834. t => temper_dat(region)%data
  835. pu => pu_dat(region)%data
  836. pv => pv_dat(region)%data
  837. #ifndef without_convection
  838. blh => conv_dat(region)%blh
  839. #endif
  840. phlb => phlb_dat(region)%data
  841. ! perform now on all PEs
  842. ! x and y resolution [degrees] for current region
  843. dyr = dy/yref(region)
  844. dxr = dx/xref(region)
  845. ! idate for current region
  846. call tau2date(itaur(region),idate_f)
  847. !====================
  848. ! loop over stations
  849. !====================
  850. do i_stat=1, n_stat+n_stat2
  851. if (stat(i_stat)%region == region) then
  852. if(stat(i_stat)%ontile) then
  853. !avoid edges!
  854. ris = (stat(i_stat)%lon-float(xbeg(region)))/dxr + 0.99999
  855. rjs = (stat(i_stat)%lat-float(ybeg(region)))/dyr + 0.99999
  856. is = int(ris) ! i-index of grid cell in which station is located
  857. js = int(rjs) ! j-index of grid cell in which station is located
  858. ! x-deviation from the center of the grid cell (-0.5...+0.5)
  859. ris = ris-is-0.5
  860. ! y-deviation from the center of the grid cell (-0.5...+0.5)
  861. rjs = rjs-js-0.5
  862. !=================================
  863. !the neighbour for x interpolation
  864. !=================================
  865. if ( ris .gt. 0 ) then
  866. isn = is+1
  867. else
  868. isn = is-1
  869. endif
  870. !=================================
  871. !the neighbour for y interpolation
  872. !=================================
  873. if ( rjs .gt. 0 ) then
  874. jsn = js+1
  875. else
  876. jsn = js-1
  877. endif
  878. ! x- / y-weighting of grid cell in which station is located
  879. wcx = (1.0-abs(ris)) ! 1.0 ... 0.5
  880. wcy = (1.0-abs(rjs)) ! 1.0 ... 0.5
  881. !=================================================================
  882. ! if index of neighbour is exceeding range of region set
  883. ! neighbour = current cell (i.e. no interpolation)
  884. ! in case of cyclic x-boundaries take corresponding cyclic i index
  885. !=================================================================
  886. if ( jsn == 0) jsn=1
  887. if ( jsn == jm(region)+1 ) jsn=jm(region) ! isn-->jsn (wouter Peters)
  888. ! if ( xcyc(region) == 0 ) then
  889. ! ! non-cyclic boundaries
  890. ! if ( isn == 0) isn=1
  891. ! if ( isn == im(region)+1 ) isn=im(region)
  892. ! else
  893. ! ! cyclic x-boundaries
  894. ! if ( isn == 0 ) isn=im(region)
  895. ! if ( isn == im(region)+1 ) isn=1
  896. ! end if
  897. !============================================
  898. ! interpolate the gph to xy position of station
  899. !============================================
  900. !ls = 1 !layer
  901. do l=0,lm(region)
  902. !CMK note: gph now from 1-->lm+1 (dec 2002)
  903. height(l) = wcx * wcy* gph(is,js,l+1) + &
  904. (1.0-wcx)* wcy* gph(isn,js,l+1) + &
  905. wcx *(1.0-wcy)* gph(is,jsn,l+1) + &
  906. (1.0-wcx)*(1.0-wcy)* gph(isn,jsn,l+1)
  907. end do
  908. !===========================
  909. ! determine layer of station
  910. !===========================
  911. if(stat(i_stat)%nonsurf == 1) then
  912. sampleheight=height(0)+stat(i_stat)%height
  913. else
  914. sampleheight=stat(i_stat)%height
  915. endif
  916. ! do not allow sampleheight below model surface
  917. sampleheight = max(sampleheight, height(0))
  918. do l=0,lm(region)
  919. if(height(l) > sampleheight) exit
  920. end do
  921. select case(l)
  922. case(0)
  923. !PB this should no longer occur !!
  924. ! force station to model surface
  925. ls = 1
  926. rls = -0.5
  927. case default
  928. ls = l ! station's layer
  929. ! the off-set from the center of the layer (-0.5--->+0.5)
  930. ! (interpolation is in (m))
  931. rls = (sampleheight - height(l-1)) / &
  932. (height(l)-height(l-1)) - 0.5
  933. end select
  934. stat(i_stat)%ls = ls ! store for output to file
  935. stat(i_stat)%height_sample = sampleheight ! store for output to file
  936. stat(i_stat)%height_surface = height(0) ! store for output to file
  937. stat(i_stat)%height_sample_above_surf = sampleheight-height(0) ! store for output to file
  938. !=================================
  939. !the neighbour for z interpolation
  940. !=================================
  941. if ( rls > 0 ) then
  942. lsn = ls+1
  943. else
  944. lsn = ls-1
  945. end if
  946. ! z-weighting of grid cell in which station is located
  947. wcz = (1.0-abs(rls)) !.0 ... 0.5
  948. !=========================================================
  949. ! if vertical neighbor is 0 (which does not exist)
  950. ! take vertical layer with l=2 for EXTRApolation to ground
  951. !=========================================================
  952. if(lsn == 0) then
  953. lsn=2
  954. wcz=1.0-rls ! 1.0 ... 1.5
  955. endif
  956. if(lsn == lmr+1) then
  957. !=========================================================
  958. ! if vertical neighbor is lmr+1 (which does not exist)
  959. ! -> no interpolation
  960. !=========================================================
  961. lsn=lmr ! no interpolation
  962. wcz=1.0
  963. endif
  964. do ispec=1,station_nspec
  965. n = station_speclist(ispec)
  966. lst = ls
  967. lstn = lsn
  968. !========================================
  969. ! value of grid box without interpolation
  970. !========================================
  971. vmr = rm(is,js,lst,n) / m(is,js,lst) * fscale(n)
  972. stat(i_stat)%c_mean(ispec,1) = &
  973. stat(i_stat)%c_mean(ispec,1) + vmr
  974. stat(i_stat)%c_std(ispec,1) = &
  975. stat(i_stat)%c_std(ispec,1) + vmr*vmr
  976. if(i_stat <= n_stat) then
  977. ! for 'regular' stations only
  978. !=================================================
  979. ! values of neigboring grid boxes
  980. ! (used as estimate for representativeness error
  981. !=================================================
  982. ! lower neighbor
  983. if(ls > 1)then
  984. vmr = rm(is,js,ls-1,n) / m(is,js,ls-1) * fscale(n)
  985. stat(i_stat)%c_mean_nb(ispec,1) = stat(i_stat)%c_mean_nb(ispec,1) + vmr
  986. stat(i_stat)%c_std_nb(ispec,1) = stat(i_stat)%c_std_nb(ispec,1) + vmr*vmr
  987. stat(i_stat)%ncount_nb(ispec,1) = stat(i_stat)%ncount_nb(ispec,1) + 1
  988. endif
  989. ! upper neighbor
  990. if(ls < lm(region)) then
  991. vmr = rm(is,js,ls+1,n) / m(is,js,ls+1) * fscale(n)
  992. stat(i_stat)%c_mean_nb(ispec,2) = stat(i_stat)%c_mean_nb(ispec,2) + vmr
  993. stat(i_stat)%c_std_nb(ispec,2) = stat(i_stat)%c_std_nb(ispec,2) + vmr*vmr
  994. stat(i_stat)%ncount_nb(ispec,2) = stat(i_stat)%ncount_nb(ispec,2) + 1
  995. endif
  996. ! western neighbor
  997. if(is > 1) then
  998. vmr = rm(is-1,js,ls,n) / m(is-1,js,ls) * fscale(n)
  999. stat(i_stat)%c_mean_nb(ispec,3) = stat(i_stat)%c_mean_nb(ispec,3) + vmr
  1000. stat(i_stat)%c_std_nb(ispec,3) = stat(i_stat)%c_std_nb(ispec,3) + vmr*vmr
  1001. stat(i_stat)%ncount_nb(ispec,3) = stat(i_stat)%ncount_nb(ispec,3) + 1
  1002. endif
  1003. ! eastern neighbor
  1004. if(is < im(region)) then
  1005. vmr = rm(is+1,js,ls,n) / m(is+1,js,ls) * fscale(n)
  1006. stat(i_stat)%c_mean_nb(ispec,4) = stat(i_stat)%c_mean_nb(ispec,4) + vmr
  1007. stat(i_stat)%c_std_nb(ispec,4) = stat(i_stat)%c_std_nb(ispec,4) + vmr*vmr
  1008. stat(i_stat)%ncount_nb(ispec,4) = stat(i_stat)%ncount_nb(ispec,4) + 1
  1009. endif
  1010. ! southern neighbor
  1011. if(js > 1) then
  1012. vmr = rm(is,js-1,ls,n) / m(is,js-1,ls) * fscale(n)
  1013. stat(i_stat)%c_mean_nb(ispec,5) = stat(i_stat)%c_mean_nb(ispec,5) + vmr
  1014. stat(i_stat)%c_std_nb(ispec,5) = stat(i_stat)%c_std_nb(ispec,5) + vmr*vmr
  1015. stat(i_stat)%ncount_nb(ispec,5) = stat(i_stat)%ncount_nb(ispec,5) + 1
  1016. endif
  1017. ! northern neighbor
  1018. if(js < jm(region)) then
  1019. vmr = rm(is,js+1,ls,n) / m(is,js+1,ls) * fscale(n)
  1020. stat(i_stat)%c_mean_nb(ispec,6) = stat(i_stat)%c_mean_nb(ispec,6) + vmr
  1021. stat(i_stat)%c_std_nb(ispec,6) = stat(i_stat)%c_std_nb(ispec,6) + vmr*vmr
  1022. stat(i_stat)%ncount_nb(ispec,6) = stat(i_stat)%ncount_nb(ispec,6) + 1
  1023. endif
  1024. end if
  1025. !========================================
  1026. ! interpolation using slopes
  1027. !========================================
  1028. !rm-value is obtained from rm + slopes.
  1029. !slope = rxm = (rm*dX/dx *deltaX/2)
  1030. rm_interpol = rm(is,js,lst,n) + 2.0*(ris*rxm(is,js,lst,n) + &
  1031. rjs*rym(is,js,lst,n) + &
  1032. rls*rzm(is,js,lst,n) )
  1033. rm_interpol = max(0.0,rm_interpol)
  1034. vmr = rm_interpol/m(is,js,lst) *fscale(n)
  1035. stat(i_stat)%c_mean(ispec,2) = &
  1036. stat(i_stat)%c_mean(ispec,2) + vmr
  1037. stat(i_stat)%c_std(ispec,2) = &
  1038. stat(i_stat)%c_std(ispec,2) + vmr*vmr
  1039. !========================================
  1040. ! 3D linear interpolation
  1041. !========================================
  1042. ! this PE handles also the neighbour layer
  1043. if (lstn <= lmr) then ! lstn = 0 is already excluded (apply vertical EXTRApolation with upper neighbor; see above)
  1044. rm_interpol = wcx *wcy *wcz *rm(is,js,lst,n) /m(is,js,lst) + &
  1045. (1.0-wcx)*wcy *wcz *rm(isn,js,lst,n) /m(isn,js,lst) + &
  1046. wcx *(1.0-wcy)*wcz *rm(is,jsn,lst,n) /m(is,jsn,lst) + &
  1047. (1.0-wcx)*(1.0-wcy)*wcz *rm(isn,jsn,lst,n) /m(isn,jsn,lst) + &
  1048. wcx *wcy *(1.0-wcz) *rm(is,js,lstn,n) /m(is,js,lstn) + &
  1049. (1.0-wcx)*wcy *(1.0-wcz) *rm(isn,js,lstn,n) /m(isn,js,lstn) + &
  1050. wcx *(1.0-wcy)*(1.0-wcz) *rm(is,jsn,lstn,n) /m(is,jsn,lstn) + &
  1051. (1.0-wcx)*(1.0-wcy)*(1.0-wcz) *rm(isn,jsn,lstn,n)/m(isn,jsn,lstn)
  1052. else !other PE calculates neighbouring contribution
  1053. !PB do NOT apply factor wcz here (no interpolation in z direction in this case) !!!!!
  1054. rm_interpol = wcx *wcy *rm(is,js,lst,n) /m(is,js,lst) + &
  1055. (1.0-wcx)*wcy *rm(isn,js,lst,n) /m(isn,js,lst) + &
  1056. wcx *(1.0-wcy) *rm(is,jsn,lst,n) /m(is,jsn,lst) + &
  1057. (1.0-wcx)*(1.0-wcy) *rm(isn,jsn,lst,n) /m(isn,jsn,lst)
  1058. endif
  1059. vmr = rm_interpol*fscale(n)
  1060. stat(i_stat)%c_mean(ispec,3) = stat(i_stat)%c_mean(ispec,3) + vmr
  1061. stat(i_stat)%c_std(ispec,3) = stat(i_stat)%c_std(ispec,3) + vmr*vmr
  1062. end do !ispec
  1063. !======================
  1064. !meteo data at stations
  1065. !======================
  1066. if (output_stations_meteo) then
  1067. !====================================
  1068. ! 3D linear interpolation Temperature
  1069. !====================================
  1070. T_interpol = &
  1071. wcx *wcy *wcz *T(is,js,ls) + &
  1072. (1.0-wcx)*wcy *wcz *T(isn,js,ls) + &
  1073. wcx *(1.0-wcy)*wcz *T(is,jsn,ls) + &
  1074. (1.0-wcx)*(1.0-wcy)*wcz *T(isn,jsn,ls) + &
  1075. wcx *wcy *(1.0-wcz) *T(is,js,lsn) + &
  1076. (1.0-wcx)*wcy *(1.0-wcz) *T(isn,js,lsn) + &
  1077. wcx *(1.0-wcy)*(1.0-wcz) *T(is,jsn,lsn) + &
  1078. (1.0-wcx)*(1.0-wcy)*(1.0-wcz) *T(isn,jsn,lsn)
  1079. stat(i_stat)%metdat(1) = stat(i_stat)%metdat(1) + T_interpol
  1080. !====================================
  1081. ! 3D linear interpolation pressure
  1082. !====================================
  1083. p_interpol =(((0.5-rls) * phlb(is,js,ls) + (0.5+rls) * phlb(is,js,ls+1)) * wcx * wcy + &
  1084. ((0.5-rls) * phlb(isn,js,ls) + (0.5+rls) * phlb(isn,js,ls+1)) * (1.0-wcx) * wcy + &
  1085. ((0.5-rls) * phlb(is,jsn,ls) + (0.5+rls) * phlb(is,jsn,ls+1)) * wcx * (1.0-wcy) + &
  1086. ((0.5-rls) * phlb(isn,jsn,ls)+ (0.5+rls) * phlb(isn,jsn,ls+1))* (1.0-wcx) * (1.0-wcy) ) *0.01 ![Pa] -> [hPa]
  1087. stat(i_stat)%metdat(2) = stat(i_stat)%metdat(2) + p_interpol
  1088. !====================================
  1089. ! 3D windspeed_u_interpol (x-direction)
  1090. !====================================
  1091. ! pu is eastward flux through east grid box boundary
  1092. ! windspeed_u_interpol wind component from east
  1093. ! latitude of grid cell center js [degrees]
  1094. lat_j =ybeg(region)+(js -0.5)*dyr
  1095. ! latitude of grid cell center jsn [degrees]
  1096. lat_jn=ybeg(region)+(jsn-0.5)*dyr
  1097. ! x-extension of grid cell js [m]
  1098. ddx_j =ae * twopi * dxr / 360.0 * cos(lat_j*twopi/360.0)
  1099. ! x-extension of grid cell jsn [m]
  1100. ddx_jn=ae * twopi * dxr / 360.0 * cos(lat_jn*twopi/360.0)
  1101. is_west=is-1
  1102. ! if ( xcyc(region) == 0 ) then
  1103. ! ! non-cyclic boundaries
  1104. ! if ( is_west == 0 ) is_west=1
  1105. ! else
  1106. ! ! cyclic x-boundaries
  1107. ! if ( is_west == 0 ) is_west=im(region)
  1108. ! end if
  1109. !west border !east border
  1110. windspeed_u_interpol=((0.5-ris) * pu(is_west,js,ls)/m(is_west,js,ls) + &
  1111. (0.5+ris) * pu(is,js,ls)/ m(is,js,ls) ) * &
  1112. ddx_j * wcy * wcz + &
  1113. ((0.5-ris) * pu(is_west,jsn,ls)/m(is_west,jsn,ls) + &
  1114. (0.5+ris) * pu(is,jsn,ls)/m(is,jsn,ls) ) * &
  1115. ddx_jn * (1.0-wcy)* wcz + &
  1116. ((0.5-ris) * pu(is_west,js,lsn)/m(is_west,js,lsn) + &
  1117. (0.5+ris) * pu(is,js,lsn)/ m(is,js,lsn)) * &
  1118. ddx_j * wcy * (1.0-wcz) + &
  1119. ((0.5-ris) * pu(is_west,jsn,lsn)/m(is_west,js,lsn) + &
  1120. (0.5+ris) * pu(is,jsn,lsn)/ m(is,jsn,lsn) ) * &
  1121. ddx_jn * (1.0-wcy)* (1.0-wcz)
  1122. !====================================
  1123. ! 3D windspeed_v_interpol (y-direction)
  1124. !====================================
  1125. ! pv northward flux through south grid box boundary
  1126. ! windspeed_v_interpol wind component from north
  1127. ddy =ae * twopi * dyr / 360.0 ! y-extension of grid cell [m]
  1128. js_south = js-1
  1129. if (js_south==0) js_south=1
  1130. js_north = js+1
  1131. if (js_north==(jm(region)+1)) js_north=jm(region)
  1132. !south border !north border
  1133. windspeed_v_interpol=(( &
  1134. (0.5-rjs)*pv(is,js,ls)/m(is,js_south,ls) + &
  1135. (0.5+rjs)*pv(is,js_north,ls)/ m(is,js,ls) ) * &
  1136. wcx * wcz + &
  1137. ((0.5-rjs)*pv(isn,js,ls)/m(isn,js_south,ls) + &
  1138. (0.5+rjs)*pv(isn,js_north,ls)/ m(isn,js,ls) ) * &
  1139. (1.0 - wcx)* wcz + &
  1140. ((0.5-rjs)*pv(is,js,lsn)/m(is,js_south,lsn) + &
  1141. (0.5+rjs)*pv(is,js_north,lsn)/ m(is,js,lsn) ) * &
  1142. wcx * (1.0-wcz) + &
  1143. ((0.5-rjs)*pv(isn,js,lsn)/m(isn,js_south,lsn) + &
  1144. (0.5+rjs)*pv(isn,js_north,lsn)/ m(isn,js,lsn) ) * &
  1145. (1.0 - wcx)* (1.0-wcz) ) * &
  1146. ddy
  1147. windspeed_interpol = &
  1148. sqrt(windspeed_u_interpol**2 + windspeed_v_interpol**2)
  1149. stat(i_stat)%metdat(3) = &
  1150. stat(i_stat)%metdat(3) + windspeed_u_interpol
  1151. stat(i_stat)%metdat(4) = &
  1152. stat(i_stat)%metdat(4) + windspeed_v_interpol
  1153. stat(i_stat)%metdat(5) = &
  1154. stat(i_stat)%metdat(5) + windspeed_interpol
  1155. #ifndef without_convection
  1156. !============================================
  1157. ! interpolate the blh to xy position of station
  1158. !============================================
  1159. blh_interpol = &
  1160. wcx * wcy* blh(is,js) + &
  1161. (1.0-wcx)* wcy* blh(isn,js) + &
  1162. wcx *(1.0-wcy)* blh(is,jsn) + &
  1163. (1.0-wcx)*(1.0-wcy)* blh(isn,jsn)
  1164. stat(i_stat)%metdat(7) = &
  1165. stat(i_stat)%metdat(7) + blh_interpol
  1166. #endif
  1167. endif ! meteo out...
  1168. stat(i_stat)%ncount = stat(i_stat)%ncount + 1
  1169. end if ! on current tile
  1170. end if ! on current region
  1171. end do ! end i_stat loop
  1172. nullify(m)
  1173. nullify(rm)
  1174. nullify(rxm)
  1175. nullify(rym)
  1176. nullify(rzm)
  1177. nullify(gph)
  1178. nullify(t)
  1179. nullify(pu)
  1180. nullify(pv)
  1181. nullify(phlb)
  1182. nullify(blh)
  1183. ! ok
  1184. status = 0
  1185. END SUBROUTINE OUTPUT_STATIONCONC
  1186. !EOC
  1187. !--------------------------------------------------------------------------
  1188. ! TM5 !
  1189. !--------------------------------------------------------------------------
  1190. !BOP
  1191. !
  1192. ! !IROUTINE: RESET_STATIONCONC_ACCUMULATOR
  1193. !
  1194. ! !DESCRIPTION: initialize to 0 accumulation arrays for average station
  1195. ! concentration
  1196. !\\
  1197. !\\
  1198. ! !INTERFACE:
  1199. !
  1200. SUBROUTINE RESET_STATIONCONC_ACCUMULATOR
  1201. !
  1202. ! !REVISION HISTORY:
  1203. !
  1204. !EOP
  1205. !------------------------------------------------------------------------
  1206. !BOC
  1207. integer i_stat
  1208. if (station_nspec > 0) then
  1209. do i_stat=1, n_stat+n_stat2
  1210. stat(i_stat)%c_mean(:,:) = 0.0
  1211. stat(i_stat)%c_std(:,:) = 0.0
  1212. if (output_stations_meteo) stat(i_stat)%metdat(:) = 0.0
  1213. stat(i_stat)%ncount = 0
  1214. end do
  1215. end if
  1216. ! You should also set the _nb-variables to zero. Otherwise, there is a random chance of crashing. Now I am not using them.
  1217. ! do i_stat=1, n_stat
  1218. ! stat(i_stat)%c_mean_nb = 0.0
  1219. ! stat(i_stat)%c_std_nb = 0.0
  1220. ! stat(i_stat)%ncount_nb = 0
  1221. ! end do
  1222. END SUBROUTINE RESET_STATIONCONC_ACCUMULATOR
  1223. !EOC
  1224. !--------------------------------------------------------------------------
  1225. ! TM5 !
  1226. !--------------------------------------------------------------------------
  1227. !BOP
  1228. !
  1229. ! !IROUTINE: EVALUATE_STATIONCONC
  1230. !
  1231. ! !DESCRIPTION: evaluate mean concentration and std
  1232. !\\
  1233. !\\
  1234. ! !INTERFACE:
  1235. !
  1236. SUBROUTINE EVALUATE_STATIONCONC( status )
  1237. !
  1238. ! !USES:
  1239. !
  1240. use dims, only : idate
  1241. use file_hdf, only : Init, WriteData, TSds, Done, select
  1242. use file_hdf, only : CheckInfo
  1243. !
  1244. ! !INPUT/OUTPUT PARAMETERS:
  1245. !
  1246. integer, intent(inout) :: status
  1247. !
  1248. ! !REVISION HISTORY:
  1249. ! 16 Mar 2012 - P. Le Sager -
  1250. !
  1251. ! !REMARKS:
  1252. !
  1253. !EOP
  1254. !------------------------------------------------------------------------
  1255. !BOC
  1256. integer i_stat, i, ii, io_status
  1257. integer n_data, isds, nsds, itp
  1258. real temp
  1259. character(len=12) :: xname
  1260. real, dimension(:,:), allocatable :: cout ! to get output
  1261. integer, dimension(:,:), allocatable :: iidate
  1262. real :: windspeed_u_interpol ! wind speed [m/s] x-direction , interpolated to station location
  1263. real :: windspeed_v_interpol ! wind speed [m/s] y-direction , interpolated to station location
  1264. real :: windspeed_interpol ! wind speed [m/s] , interpolated to station location
  1265. real :: winddir_interpol ! wind direction , interpolated to station location
  1266. character(len=*), parameter :: rname = mname//'/evaluate_stationconc'
  1267. !__START_SUBROUTINE______________________________________________________
  1268. if (station_nspec > 0) then
  1269. do i_stat=1, n_stat+n_stat2
  1270. n_data = stat(i_stat)%ncount
  1271. if (n_data > 0) then
  1272. stat(i_stat)%c_mean(:,:) = stat(i_stat)%c_mean(:,:) / n_data
  1273. if (output_stations_meteo) stat(i_stat)%metdat(:) = stat(i_stat)%metdat(:) / n_data
  1274. if (n_data > 1) then
  1275. do i=1, station_nspec
  1276. do ii= 1, n_interpol
  1277. temp = ((stat(i_stat)%c_std(i,ii) - n_data * ((stat(i_stat)%c_mean(i,ii))**2) ) / (n_data-1) )
  1278. if(temp > 0) then
  1279. stat(i_stat)%c_std(i,ii) = sqrt(temp)
  1280. else
  1281. stat(i_stat)%c_std(i,ii) = 0.0
  1282. endif
  1283. enddo
  1284. enddo
  1285. else
  1286. stat(i_stat)%c_std(:,:)=-1.0
  1287. end if
  1288. else
  1289. stat(i_stat)%c_mean(:,:)= -1.0
  1290. stat(i_stat)%c_std(:,:) = -1.0
  1291. if(output_stations_meteo) stat(i_stat)%metdat(:) = -999.
  1292. end if
  1293. ! Write down wind directions
  1294. if(output_stations_meteo) then
  1295. windspeed_u_interpol = stat(i_stat)%metdat(3)
  1296. windspeed_v_interpol = stat(i_stat)%metdat(4)
  1297. windspeed_interpol = stat(i_stat)%metdat(5)
  1298. !====================================
  1299. ! wind direction
  1300. !====================================
  1301. ! definition of winddirection:
  1302. ! east : 90
  1303. ! south : 180
  1304. ! west : 270
  1305. ! north : 360
  1306. if ((windspeed_u_interpol < 0) .and. (windspeed_v_interpol < 0))then ! wind from north east (0...90)
  1307. winddir_interpol = atan(windspeed_u_interpol / windspeed_v_interpol) * 360.0 / twopi
  1308. else if ((windspeed_u_interpol < 0) .and. (windspeed_v_interpol > 0)) then ! wind from south east (90...180)
  1309. winddir_interpol = 180.0+atan(windspeed_u_interpol / windspeed_v_interpol) * 360.0 / twopi
  1310. else if ((windspeed_u_interpol < 0) .and. (windspeed_v_interpol == 0)) then ! wind from east (90)
  1311. winddir_interpol = 90.0
  1312. else if ((windspeed_u_interpol > 0) .and. (windspeed_v_interpol < 0)) then ! wind from north west (270... 360)
  1313. winddir_interpol = 360.0+atan(windspeed_u_interpol / windspeed_v_interpol) * 360.0 / twopi
  1314. else if ((windspeed_u_interpol > 0) .and. (windspeed_v_interpol > 0)) then ! wind from south west (180...270)
  1315. winddir_interpol = 180.0+atan(windspeed_u_interpol / windspeed_v_interpol) * 360.0 / twopi
  1316. else if ((windspeed_u_interpol > 0) .and. (windspeed_v_interpol == 0)) then ! wind from west (270)
  1317. winddir_interpol = 270.0
  1318. else if ((windspeed_u_interpol == 0) .and. (windspeed_v_interpol < 0)) then ! wind from north (360)
  1319. winddir_interpol = 360.0
  1320. else if ((windspeed_u_interpol == 0) .and. (windspeed_v_interpol > 0)) then ! wind from south (180)
  1321. winddir_interpol = 180.0
  1322. else if ((windspeed_u_interpol == 0) .and. (windspeed_v_interpol == 0)) then ! no wind
  1323. winddir_interpol = -1.0
  1324. else
  1325. write(gol,*)'output_stationconc: error wind direction'; call goErr
  1326. TRACEBACK
  1327. status=1; return
  1328. end if
  1329. stat(i_stat)%metdat(6) = winddir_interpol
  1330. endif
  1331. end do
  1332. end if
  1333. !ok
  1334. status = 0
  1335. END SUBROUTINE EVALUATE_STATIONCONC
  1336. !EOC
  1337. !--------------------------------------------------------------------------
  1338. ! TM5 !
  1339. !--------------------------------------------------------------------------
  1340. !BOP
  1341. !
  1342. ! !IROUTINE: WRITE_STATIONCONC
  1343. !
  1344. ! !DESCRIPTION: write mean concentration
  1345. !\\
  1346. !\\
  1347. ! !INTERFACE:
  1348. !
  1349. SUBROUTINE WRITE_STATIONCONC( status )
  1350. !
  1351. ! !USES:
  1352. !
  1353. use dims, only : idate
  1354. use file_hdf, only : Init, WriteData, TSds, Done
  1355. use file_hdf, only : WriteAttribute
  1356. !
  1357. ! !INPUT/OUTPUT PARAMETERS:
  1358. !
  1359. integer, intent(inout) :: status
  1360. !
  1361. ! !REVISION HISTORY:
  1362. !
  1363. !EOP
  1364. !------------------------------------------------------------------------
  1365. !BOC
  1366. integer i, ii, io_status, i_stat
  1367. integer n_data, isds, nsds, itp
  1368. real, dimension(:,:), allocatable :: cout ! to get output
  1369. integer, dimension(:,:), allocatable :: iidate
  1370. character(len=*), parameter :: rname = mname//'/write_stationconc'
  1371. !__START_SUBROUTINE______________________________________________________
  1372. ! output
  1373. if (station_nspec > 0 ) then
  1374. if (io_record == 0) then
  1375. call WriteAttribute( io_hdf, 'station_ls', stat(:)%ls, status)
  1376. IF_NOTOK_RETURN(status=1)
  1377. call WriteAttribute( io_hdf, 'height_sample', stat(:)%height_sample, status)
  1378. IF_NOTOK_RETURN(status=1)
  1379. call WriteAttribute( io_hdf, 'height_surface', stat(:)%height_surface, status)
  1380. IF_NOTOK_RETURN(status=1)
  1381. call WriteAttribute( io_hdf, 'height_sample_above_surf', stat(:)%height_sample_above_surf, status)
  1382. IF_NOTOK_RETURN(status=1)
  1383. endif
  1384. allocate(cout(n_stat+n_stat2,1))
  1385. If (station_nspec > 0) Then
  1386. do i=1, station_nspec
  1387. do ii= 1,n_interpol
  1388. do i_stat = 1, n_stat+n_stat2
  1389. cout(i_stat,1) = stat(i_stat)%c_mean(i,ii)
  1390. enddo
  1391. call writedata(sds(i,ii), cout, status, start=(/0,io_record/))
  1392. IF_NOTOK_RETURN(status=1)
  1393. enddo
  1394. enddo
  1395. End If
  1396. if (output_stations_meteo) then
  1397. do i=1, n_metdat
  1398. do i_stat = 1, n_stat+n_stat2
  1399. cout(i_stat,1) = stat(i_stat)%metdat(i)
  1400. enddo
  1401. call writedata(sds_meteo(i), cout, status, start=(/0,io_record/))
  1402. IF_NOTOK_RETURN(status=1)
  1403. enddo
  1404. endif
  1405. deallocate(cout)
  1406. allocate(iidate(6,1))
  1407. iidate(:,1) = idate
  1408. call writedata(sds_idate, iidate, status, start=(/0,io_record/) )
  1409. IF_NOTOK_RETURN(status=1)
  1410. deallocate(iidate)
  1411. io_record = io_record + 1
  1412. end if
  1413. ! ok
  1414. status = 0
  1415. END SUBROUTINE WRITE_STATIONCONC
  1416. !EOC
  1417. END MODULE USER_OUTPUT_STATION