1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651 |
- !
- #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
- #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
- #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
- !
- #include "tm5.inc"
- !
- !-----------------------------------------------------------------------------
- ! TM5 !
- !-----------------------------------------------------------------------------
- !BOP
- !
- ! !MODULE: USER_OUTPUT_STATION
- !
- ! !DESCRIPTION: Routines to deal with output for specific stations.
- !
- ! This version adds code to the original version in order to
- ! write AOD and alpha to the station files (cf #ifdef with_optics)
- !\\
- !\\
- ! !INTERFACE:
- !
- MODULE USER_OUTPUT_STATION
- !
- ! !USES:
- !
- use GO, only : gol, goErr, goPr
- use binas, only : ae, twopi, grav
- use dims, only : im, jm, lm, dx, dy, xref, yref, xbeg, ybeg, xend, yend
- use dims, only : nregions, region_name, itaur, xcyc
- use chem_param, only : ntrace, ntracet, names, fscale
- use file_hdf, only : THdfFile, Init, Done, TSds, SetDim
- use ParTools, only : isRoot, myid
- IMPLICIT NONE
- PRIVATE
- !
- ! !PUBLIC MEMBER FUNCTIONS:
- !
- public :: read_stationlist ! read files with station definitions
- public :: init_station_output ! init output files
- public :: reset_stationconc_accumulator ! set to 0 acummulation arrays
- public :: output_stationconc ! accumulate arrays
- public :: evaluate_stationconc ! compute mean and std dev
- public :: write_stationconc ! write mean conc to file
-
- public :: free_stationfields ! close output files, free arrays
- #if defined(with_pm) || defined(with_optics)
- public :: n_stat2
- public :: io_hdf
- ! Optics wants to write wavelength information here.
- ! Optics can do it more easily than user_output.
- ! Optics uses user_output_station. This means that user_output_station
- ! cannot use optics.
- ! PM also uses this.
- #endif
- !
- ! !PRIVATE DATA MEMBERS:
- !
- character(len=100) :: StationlistFFilename2 ! list of 'validation' stations
- character(len=100) :: InputDir = './'
- logical :: output_stations_meteo = .true.
- character(len=300) :: StationSpeclist
- integer :: StationlistFileFormat ! 1: old format, 2: new format, 3: newer format
- integer :: n_stat2 ! number of 'validation' stations (not used for 4DVAR)
- integer, dimension(ntrace) :: station_speclist ! list of species for output (may differ per PE)
- integer :: station_nspec ! number of species for output (may differ per PE)
- integer, parameter :: n_metdat = 7 ! max number of meteo data (for output in station output file)
- integer, parameter :: n_interpol = 3 ! number of station interpolation methods
- integer, parameter :: n_neighbors = 6 ! number of neighboring grid cells used for estimate of represent. error
- character(len=4), dimension(n_interpol), parameter :: c_interpol = (/'_grd','_slp','_int'/)
- character(len=12),dimension(n_metdat ), parameter :: C_metdat = &
- (/'Temperature', &
- 'Pressure ',&
- 'uwind ',&
- 'vwind ',&
- 'windspeed ',&
- 'winddir ',&
- 'blh '/)
- character(len=12),dimension(n_metdat ), parameter :: U_metdat = &
- (/'K ', &
- 'hPa ', &
- 'm/s ', &
- 'm/s ', &
- 'm/s ', &
- 'degrees wrtN', &
- 'm '/)
- type(THdfFile) :: io_hdf ! contains HDF output file
- integer :: io_record = 0
- ! 'open' datasets of the io_hdf output file:
- type(TSds), dimension(:,:), allocatable :: Sds
- type(TSds), dimension(n_metdat) :: Sds_meteo
- type(TSds) :: Sds_idate
- #ifdef with_optics
- Type(TSds), public :: sds_station_aod
- Type(TSds), public :: sds_station_alpha
- #endif
- #ifdef with_pm
- Type(TSds), public :: sds_station_pm
- #endif
- ! --- const -------------------------
- character(len=*), parameter :: mname = 'user_output_station'
- !
- ! !PUBLIC TYPES:
- !
- type, public :: stations
- character(len=13) :: ident ! station identifier
- character(len=50) :: name ! station name
- real :: lat ! latitude of station
- real :: lon ! longitude of station
- real :: height ! height of station
- real :: height_sample ! sampling height
- real :: height_surface ! height of model surface
- real :: height_sample_above_surf ! height_sample-height_surface
- integer :: index ! index of station
- integer :: region
- integer :: is
- integer :: js
- integer :: ls
- character(len=2) :: type ! sampling type (FM = flask; CM = continuous)
- integer :: land ! land or ocean site
- integer :: nonsurf ! 1: nonsurface sites (e.g. towers); 0: 'regular' sites
- real,dimension(n_metdat) :: metdat ! meteodata (interpolated) at stations
- real,dimension(:,:),pointer :: c_mean ! c_mean(species, interpolation)
- real,dimension(:,:),pointer :: c_std ! c_std(species, interpolation)
- integer :: ncount ! counter
- logical :: ontile ! is located on current tile of domain decomposition
- ! In the chem version, the following comment was found:
- ! "No one is estimating representativeness errors. You can compare the
- ! different interpolations to acquire something similar." And the code
- ! with *_nb was commented.
- ! That code is kept live here in the user_output version until further decision.
-
- ! grid neighbors (for estimate of representativeness error)
- real,dimension(:,:),pointer :: c_mean_nb ! mean concentrations of neighbors (species, neighb. index)
- real,dimension(:,:),pointer :: c_std_nb ! standard deviation (species, neighb. index)
- integer,dimension(:,:),pointer :: ncount_nb ! counter (species, neighb. index)
- real,dimension(:),pointer :: dc_mod ! estimate of representativeness error (species)
- !(based on 3D gradient to grid cell neighbors)
- end type stations
- !
- ! !PUBLIC DATA MEMBERS:
- !
- type(stations), dimension(:), public, allocatable :: stat ! collection of stations
- character(len=100), public :: StationlistFFilename ! list of 'regular' stations
- logical, public :: write_Stationfiles = .true. ! do station
- integer, save, public :: n_stat ! number of 'regular' stations (used for 4DVAR)
- integer, save, public :: io_nrecords ! # record = # timesteps
- !
- ! !REVISION HISTORY:
- !
- ! Modified by Peter Beramaschi.
- ! Parallel version Maarten Krol Jul 2003
- ! jun 2005: switch to HDF output file
- ! jul 2007: paralel writing to increase performance..
- ! 10 Jul 2012 - Ph. Le Sager - merged with chem base version to account
- ! for with_optics, with_pm
- ! - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- CONTAINS
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: FREE_STATIONFIELDS
- !
- ! !DESCRIPTION: close output files and deallocate arrays
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE FREE_STATIONFIELDS( status )
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- integer, intent(inout) :: status
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer :: i_stat
- character(len=*), parameter :: rname = mname//'/free_stationfields'
- !__START_SUBROUTINE______________________________________________________
- if(write_Stationfiles) then
- call close_stationfiles( status )
- IF_NOTOK_RETURN(status=1)
- endif
- write(gol,*) '************************************', station_nspec ; call goPr
- !cmk : the following lines do not work on huygens????
- if (station_nspec > 0 ) then
- do i_stat = 1, n_stat+n_stat2
- deallocate(stat(i_stat)%c_mean)
- deallocate(stat(i_stat)%c_std )
- enddo
- do i_stat = 1, n_stat
- deallocate(stat(i_stat)%c_mean_nb)
- deallocate(stat(i_stat)%c_std_nb)
- deallocate(stat(i_stat)%ncount_nb)
- deallocate(stat(i_stat)%dc_mod)
- enddo
- deallocate( stat )
- end if
-
- status = 0
- END SUBROUTINE FREE_STATIONFIELDS
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: READ_STATIONLIST
- !
- ! !DESCRIPTION: Reads input files with stations definition. Allocate and
- ! fill station objects.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE READ_STATIONLIST( status )
- !
- ! !USES:
- !
- use GO, only : TrcFile, Init, Done, ReadRc
- use global_data, only : rcfile
- use chem_param, only : ntracet, names
- use tm5_distgrid, only : dgrid, get_distgrid
- use ParTools, only : isRoot
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- integer, intent(inout) :: status
- !
- ! !REVISION HISTORY:
- ! 16 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer :: slen1, slen2 !string length
- character(len=200) :: dummy
- integer :: fstatus
- integer :: i_stat
- integer :: region
- integer, dimension(6) :: idate_sim
- integer :: itau_sim, isim, ispec
- integer :: ipos, i, n
- integer :: i1, j1, i2, j2, is, js ! tile bounds and station indices
- real :: dxr, dyr ! x,y resolution (in degrees) for current region
- character(len=8) :: name_spec
- integer :: sunit1=110
- integer :: sunit2=111
-
- type(TrcFile) :: rcF
- character(len=*), parameter :: rname = mname//'/read_stationlist'
- !__START_SUBROUTINE______________________________________________________
- call Init( rcF, rcfile, status)
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'inputdir.station', InputDir,status)
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'input.station.filename', StationlistFFilename,status)
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'input.station.filename2', StationlistFFilename2,status)
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'input.station.fileformat', StationlistFileFormat,status)
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'station.speclist', StationSpeclist,status)
- IF_NOTOK_RETURN(status=1)
- call Done( rcF ,status)
- IF_NOTOK_RETURN(status=1)
- ! -------- count # of regular and validation stations
- n_stat=0
- n_stat2=0
- slen1=len_trim(StationlistFFilename)
- if ( slen1 > 0 ) then
- !=========================================
- ! open StationFile (with list of stations)
- !=========================================
- open(UNIT=sunit1, FORM='FORMATTED', &
- FILE=trim(InputDir)//trim(StationlistFFilename), &
- STATUS='OLD', ERR=1000)
- read(sunit1, '(a)') dummy
- ! count number of stations
- do
- read(sunit1, '(a)', end=100) dummy
- !if((dummy(1:1) /= ' ') .and. (dummy(1:7) /= 'species')) then
- n_stat = n_stat+1
- enddo
- 100 continue
- end if
- slen2=len_trim(StationlistFFilename2)
- if ( slen2 > 0 ) then
- !=========================================
- ! open StationFile (with list of stations)
- !=========================================
- open(UNIT=sunit2, FORM='FORMATTED', &
- FILE=trim(InputDir)//trim(StationlistFFilename2), &
- STATUS='OLD', ERR=1001)
- read(sunit2, '(a)') dummy
- ! count number of stations
- do
- read(sunit2, '(a)', END=200) dummy
- if((dummy(1:1) /= ' ') .and. (dummy(1:7) /= 'species')) then
- n_stat2 = n_stat2+1
- else
- goto 200
- endif
- enddo
- 200 continue
- end if
- ! ---- determine index of species in good order
- station_nspec = 0
- ipos = 1
- do
- i = index(StationSpeclist(ipos:),' ')
- if (i == 0) then
- name_spec = trim(StationSpeclist(ipos:))
- else
- name_spec = trim(StationSpeclist(ipos:ipos+i-1))
- ipos = ipos + i
- endif
- do n=1,ntracet
- if ((trim(name_spec).eq.trim(names(n))).or.(trim(name_spec).eq.'all')) then
- station_nspec = station_nspec + 1
- station_speclist(station_nspec) = n
- endif
- enddo
- if(trim(name_spec).eq.'') exit
- enddo
- write(gol,*) trim(mname),':station_nspec; station_speclist', &
- station_nspec, station_speclist(1:station_nspec)
- call goPr
- ! ---- allocate station objects
- if (station_nspec > 0) then
- allocate(stat(n_stat+n_stat2)) ! all PE have all station, but only some will fill data
-
- do i_stat = 1, n_stat+n_stat2
- allocate(stat(i_stat)%c_mean(station_nspec,n_interpol))
- allocate(stat(i_stat)%c_std(station_nspec,n_interpol))
- enddo
- do i_stat = 1, n_stat
- allocate(stat(i_stat)%c_mean_nb(station_nspec,n_neighbors))
- allocate(stat(i_stat)%c_std_nb(station_nspec,n_neighbors))
- allocate(stat(i_stat)%ncount_nb(station_nspec,n_neighbors))
- allocate(stat(i_stat)%dc_mod(station_nspec))
- enddo
-
- ! ---- Read/fill stations definition, assuming first they are in region #1
-
- dyr = dy/yref(1)
- dxr = dx/xref(1)
- call get_distgrid( dgrid(1), i_strt=i1, i_stop=i2, j_strt=j1, j_stop=j2)
- if ( slen1 > 0 ) then
- !=========================
- ! read 'regular' stations
- !=========================
- rewind(sunit1)
- read(sunit1, '(a)') dummy
- do i_stat=1, n_stat
- select case(StationlistFileFormat)
- case(1)
- read(sunit1, '(a7,1x,f8.2,f8.2,f8.1,1x,a50)') &
- stat(i_stat)%ident, &
- stat(i_stat)%lat, &
- stat(i_stat)%lon, &
- stat(i_stat)%height, &
- stat(i_stat)%name
- stat(i_stat)%nonsurf = 0
- case(2)
- read(sunit1, '(a11,f8.2,4x,f8.2,4x,f8.1,1x,a2,1x,i2,1x,a50)') &
- stat(i_stat)%ident, &
- stat(i_stat)%lat, &
- stat(i_stat)%lon, &
- stat(i_stat)%height, &
- stat(i_stat)%type, &
- stat(i_stat)%nonsurf, &
- stat(i_stat)%name
- case(3)
- read(sunit1, '(a13,f6.2,4x,f8.2,4x,f8.0,4x,i1,5x,i1,a50)') &
- stat(i_stat)%ident, &
- stat(i_stat)%lat, &
- stat(i_stat)%lon, &
- stat(i_stat)%height, &
- stat(i_stat)%land, &
- stat(i_stat)%nonsurf, &
- stat(i_stat)%name
- stat(i_stat)%ident = adjustl(stat(i_stat)%ident)
- endselect
- stat(i_stat)%index = i_stat
- ! assume global region as default for average mixing ratios
- stat(i_stat)%region = 1
- is = int((stat(i_stat)%lon-float(xbeg(1)))/dxr + 0.99999)
- js = int((stat(i_stat)%lat-float(ybeg(1)))/dyr + 0.99999)
- stat(i_stat)%is = is
- stat(i_stat)%js = js
- ! is it on current PE?
- if (is>=i1.and.is<=i2.and.js>=j1.and.js<=j2) then
- stat(i_stat)%ontile=.true.
- else
- stat(i_stat)%ontile=.false.
- end if
- end do
- ! close stationfile
- close(sunit1)
- endif
- if ( slen2 > 0 ) then
-
- !=========================
- ! read 'validation' stations
- !=========================
- rewind(sunit2)
- read(sunit2, '(a)') dummy
- do i_stat=n_stat+1, n_stat+n_stat2
- select case(StationlistFileFormat)
- case(1)
- read(sunit2, '(a7,1x,f8.2,f8.2,f8.1,1x,a50)') &
- stat(i_stat)%ident, &
- stat(i_stat)%lat, &
- stat(i_stat)%lon, &
- stat(i_stat)%height, &
- stat(i_stat)%name
- stat(i_stat)%nonsurf = 0
- case(2)
- read(sunit2, '(a11,f8.2,f8.2,f8.1,1x,a2,1x,i2,1x,a50)') &
- stat(i_stat)%ident, &
- stat(i_stat)%lat, &
- stat(i_stat)%lon, &
- stat(i_stat)%height, &
- stat(i_stat)%type, &
- stat(i_stat)%nonsurf, &
- stat(i_stat)%name
- case(3)
- read(sunit2, '(a13,f6.2,4x,f8.2,4x,f8.0,4x,i1,5x,i1,a50)') &
- stat(i_stat)%ident, &
- stat(i_stat)%lat, &
- stat(i_stat)%lon, &
- stat(i_stat)%height, &
- stat(i_stat)%land, &
- stat(i_stat)%nonsurf, &
- stat(i_stat)%name
- stat(i_stat)%ident = adjustl(stat(i_stat)%ident)
- endselect
- stat(i_stat)%index = i_stat
- ! assume global region as default for average mixing ratios
- stat(i_stat)%region = 1
- is = int((stat(i_stat)%lon-float(xbeg(1)))/dxr + 0.99999)
- js = int((stat(i_stat)%lat-float(ybeg(1)))/dyr + 0.99999)
- stat(i_stat)%is = is
- stat(i_stat)%js = js
- if (is>=i1.and.is<=i2.and.js>=j1.and.js<=j2) then
- stat(i_stat)%ontile=.true.
- else
- stat(i_stat)%ontile=.false.
- end if
- end do
- ! close stationfile
- close(sunit2)
- end if
-
- !=================================================
- ! determine region with highest refinement factor
- !=================================================
-
- do i_stat=1, n_stat+n_stat2
- do region=1, nregions
- dyr = dy/yref(region)
- dxr = dx/xref(region)
- if ( (stat(i_stat)%lon .ge. xbeg(region) .and. &
- stat(i_stat)%lon .le. xend(region)) .and. &
- (stat(i_stat)%lat .ge. ybeg(region) .and. &
- stat(i_stat)%lat .le. yend(region) ) ) then
- !=====================
- ! station is in region
- !=====================
- ! determine region with hightes refinement factor
- if (xref(region) > xref(stat(i_stat)%region)) then
- stat(i_stat)%region = region
- is = int((stat(i_stat)%lon-float(xbeg(region)))/dxr + 0.99999)
- js = int((stat(i_stat)%lat-float(ybeg(region)))/dyr + 0.99999)
- stat(i_stat)%is = is
- stat(i_stat)%js = js
- call get_distgrid( dgrid(region), i_strt=i1, i_stop=i2, j_strt=j1, j_stop=j2)
- if (is>=i1.and.is<=i2.and.js>=j1.and.js<=j2) then
- stat(i_stat)%ontile=.true.
- else
- stat(i_stat)%ontile=.false.
- end if
- end if
- end if
- end do
- end do
- if ( isRoot ) then
- write(gol,*) '==========================' ; call goPr
- write(gol,*) ' regular stations ' ; call goPr
- write(gol,*) '==========================' ; call goPr
- do i_stat=1, n_stat
- write(gol, '(a13,1x,f8.2,f8.2,f8.1,1x,i4,1x,i2,1x,a50)') &
- stat(i_stat)%ident, &
- stat(i_stat)%lat, &
- stat(i_stat)%lon, &
- stat(i_stat)%height, &
- stat(i_stat)%region, &
- stat(i_stat)%nonsurf, &
- stat(i_stat)%name ; call goPr
- end do
- write(gol,*) '==========================' ; call goPr
- write(gol,*) ' validation stations ' ; call goPr
- write(gol,*) '==========================' ; call goPr
-
- do i_stat=n_stat+1, n_stat+n_stat2
- write(gol, '(a11,1x,f8.2,f8.2,f8.1,1x,i4,1x,i2,1x,a50)') &
- stat(i_stat)%ident, &
- stat(i_stat)%lat, &
- stat(i_stat)%lon, &
- stat(i_stat)%height, &
- stat(i_stat)%region, &
- stat(i_stat)%nonsurf, &
- stat(i_stat)%name ; call goPr
- end do
- endif
- endif
- call reset_stationconc_accumulator
- ! ok
- status = 0
- return
- ! error handling
- 1000 write(gol,*) 'read_stationlist: could not open ' // trim(InputDir)//trim(StationlistFFilename) ; call goErr
- 1001 write(gol,*) 'read_stationlist: could not open ' // trim(InputDir)//trim(StationlistFFilename2) ; call goErr
- status = 1
- END SUBROUTINE READ_STATIONLIST
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: INIT_STATION_OUTPUT
- !
- ! !DESCRIPTION: initialize hdf files for station output.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE INIT_STATION_OUTPUT( status )
- !
- ! !USES:
- !
- use Dims, only : itaui, itaue, ndyn_max, idatei, idatee
- use file_hdf, only : Init, WriteAttribute, WriteData, TSds, Done
- use GO, only : TrcFile, Init, Done, ReadRc
- use global_data, only : rcfile, outdir
- use ParTools, only : isRoot
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 16 Mar 2012 - P. Le Sager -
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer :: i_stat
- integer :: io_status
- type(TrcFile) :: rcF
- character(len=12) :: xname
- integer :: i, ii, j
- type(TSds) :: sds_temp
- character(len=200) :: station_filename
- character(len=3) :: smyid
- character(len=10) :: sidatei, sidatee
- character(len=*), parameter :: rname = mname//'/init_station_output'
- !__START_SUBROUTINE______________________________________________________
- if (write_Stationfiles .and. station_nspec > 0)then
- call Init( rcF, rcfile ,status)
- IF_NOTOK_RETURN(status=1)
- call ReadRc( rcF, 'output.station.filename', station_filename,status)
- IF_NOTOK_RETURN(status=1)
- call Done( rcF ,status)
- IF_NOTOK_RETURN(status=1)
- #ifdef MPI
- i = index(station_filename,'.hdf')
- write(smyid,'(a1,i2.2)') '_',myid
- write(sidatei,'(i4.4,3i2.2)') idatei(1:4)
- write(sidatee,'(i4.4,3i2.2)') idatee(1:4)
- if(i /= 0) then
- station_filename = station_filename(1:i-1)//smyid//'_'//sidatei//'_'//sidatee//'.hdf'
- else
- station_filename = trim(station_filename)//smyid//'_'//sidatei//'_'//sidatee//'.hdf'
- endif
- #else
- i = index(station_filename,'.hdf')
- write(sidatei,'(i4.4,3i2.2)') idatei(1:4)
- write(sidatee,'(i4.4,3i2.2)') idatee(1:4)
- if(i /= 0) then
- station_filename = station_filename(1:i-1)//'_'//sidatei//'_'//sidatee//'.hdf'
- else
- station_filename = trim(station_filename)//'_'//sidatei//'_'//sidatee//'.hdf'
- endif
- #endif
- call Init( io_hdf, trim(outdir)//'/'//trim(station_filename),'create', status )
- IF_NOTOK_RETURN(status=1)
- io_record = 0
- Write(*,*) "Using itaui in stations"
- io_nrecords =abs(itaue-itaui)/ndyn_max
- call WriteAttribute( io_hdf, 'io_nrecords', io_nrecords,status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'n_stat', n_stat,status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'n_stat2', n_stat2,status) ! validation stations
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'n_spec', station_nspec,status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_speclist', station_speclist(1:station_nspec), status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_specnames', names(station_speclist(1:station_nspec)), status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_lat', stat(:)%lat, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_lon', stat(:)%lon, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_height', stat(:)%height, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_index', stat(:)%index, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_nonsurf', stat(:)%nonsurf, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_region', stat(:)%region, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_is', stat(:)%is, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_js', stat(:)%js, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_names', stat(:)%name, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'station_ident', stat(:)%ident, status)
- IF_NOTOK_RETURN(status=1)
- allocate(Sds(station_nspec, n_interpol))
- do i=1, station_nspec
- do ii= 1,n_interpol
- xname = trim(names(station_speclist(i)))//c_interpol(ii)
- call init(Sds(i,ii), io_hdf, xname, (/n_stat+n_stat2, io_nrecords/), 'real(4)', status)
- IF_NOTOK_RETURN(status=1)
- call SetDim( sds(i,ii), 0, 'n_stations', 'station number', (/ (j, j=1,n_stat+n_stat2) /) , status)
- IF_NOTOK_RETURN(status=1)
- call SetDim( sds(i,ii), 1, 'n_records ', 'time slot #', (/ (j, j=1,io_nrecords) /) , status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute(Sds(i,ii), 'Unit', 'Volume mixing ration (ppb)', status)
- IF_NOTOK_RETURN(status=1)
- enddo
- enddo
- if (.not. isRoot) output_stations_meteo = .false.
- if (output_stations_meteo) then
- do i=1,n_metdat
- call init(sds_meteo(i), io_hdf, c_metdat(i), (/n_stat+n_stat2, io_nrecords/), 'real(4)', status)
- IF_NOTOK_RETURN(status=1)
- call SetDim( sds_meteo(i), 0, 'n_stations', 'station number', (/ (j, j=1,n_stat+n_stat2) /) , status)
- IF_NOTOK_RETURN(status=1)
- call SetDim( sds_meteo(i), 1, 'n_records ', 'time slot #', (/ (j, j=1,io_nrecords) /) , status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute(Sds_meteo(i), 'Unit', u_metdat(i), status)
- IF_NOTOK_RETURN(status=1)
- enddo
- endif
- call init(sds_idate, io_hdf, 'idate', (/6, io_nrecords/), 'integer(2)', status)
- IF_NOTOK_RETURN(status=1)
- call SetDim( sds_idate, 1, 'n_records ', 'time slot #', (/ (j, j=1,io_nrecords) /), status )
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute(Sds_idate, 'Unit', 'year month day hour minutes seconds', status)
- IF_NOTOK_RETURN(status=1)
- end if ! write stationfiles = T
- ! ok
- status = 0
-
- END SUBROUTINE INIT_STATION_OUTPUT
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: CLOSE_STATIONFILES
- !
- ! !DESCRIPTION: close ouput files.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE CLOSE_STATIONFILES( status )
- !
- ! !USES:
- !
- use file_hdf, only : Done
- use ParTools, only : isRoot
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- integer, intent(inout) :: status
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer :: i, ii
- character(len=*), parameter :: rname = mname//'/close_station_files'
- !__START_SUBROUTINE______________________________________________________
- if (write_Stationfiles .and. station_nspec > 0)then
- do i=1, station_nspec
- do ii= 1,n_interpol
- call Done(sds(i,ii), status)
- IF_NOTOK_RETURN(status=1)
- enddo
- enddo
-
- if (.not.isRoot) output_stations_meteo = .false.
- if (output_stations_meteo) then
- do i=1,n_metdat
- call Done(sds_meteo(i),status)
- IF_NOTOK_RETURN(status=1)
- enddo
- endif
- call Done(sds_idate, status)
- IF_NOTOK_RETURN(status=1)
- deallocate(Sds)
-
- call Done(io_hdf, status)
- IF_NOTOK_RETURN(status=1)
- write(gol,*) 'Station file closed ' ; call goPr
- endif
- ! ok
- status = 0
- END SUBROUTINE CLOSE_STATIONFILES
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: OUTPUT_STATIONCONC
- !
- ! !DESCRIPTION: accumulate mean and std dev arrays
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE OUTPUT_STATIONCONC(region, status)
- !
- ! !USES:
- !
- use global_data, only : mass_dat
- #ifndef without_convection
- use global_data, only : conv_dat
- #endif
- use MeteoData, only : m_dat, gph_dat, temper_dat, pu_dat, pv_dat, phlb_dat
- use datetime, only : tau2date
- !
- ! !INPUT PARAMETERS:
- !
- integer,intent(in) :: region
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- integer,intent(inout):: status
- !
- ! !REVISION HISTORY:
- ! 16 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real,dimension(:,:,:,:),pointer :: rm ! tracer mass
- real,dimension(:,:,:,:),pointer :: rxm,rym,rzm ! slopes of tracer mass
- real,dimension(:,:,:) ,pointer :: m ! air mass
- real,dimension(:,:,:) ,pointer :: gph ! geopotential height
- ! real, dimension(:,:,:,:), allocatable, target :: rmg ! MPI arrays to gather fields.
- ! real, dimension(:,:,:,:), allocatable, target :: rxmg, rymg, rzmg
- ! real, dimension(:,:,: ), allocatable, target :: mg
- integer :: i_interpol ! interpolation procedures:
- real :: sampleheight
- ! 1: no interpolation
- ! 2: interpolation based on slopes
- ! 3: 3D linear interpolations
- integer :: i,j,l ! grid cell indices
- integer :: is,js,ls ! i,j,l index of grid cell in which station lis located
- integer :: isn,jsn,lsn ! i,j,l index of grid cell which is taken as neighbour for linear interpolation
- integer :: lst, lstn ! MPI implementation
- integer :: js_north, js_south ! j index of grid cell for neighbours for windspeed_v interpolation
- integer :: is_west ! i index of grid cell for neighbour for windspeed_u interpolation
- integer :: n ! index of tracer
- integer :: i_stat ! index of station
- real :: ris,rjs,rls ! deviation of station from center of the grid cell (-0.5 ... +0.5)
- real :: wcx,wcy,wcz ! x,y,z-weight of grid cell (1.0 ... 0.5)
- real :: dxr, dyr ! x,y resolution (in degrees) for current region
- real,dimension(0:lm(region)) :: height ! height of vertical grid boundaries
- integer, dimension(6) :: idate_f ! current idate for region
- integer :: sunit ! unit number for station output file
- real :: rm_interpol ! tracer mass, interpolated to station location
- integer :: ispec ! index over activated tracers
- !=============
- ! meteo output
- !=============
- real,dimension(n_stat,n_metdat) :: metdat ! meteodata (interpolated) at stations
- real,dimension(:,:,:), pointer :: T ! temperature
- real,dimension(:,:,:), pointer :: phlb ! pressure grid boundaries
- real,dimension(:,:,:), pointer :: pu ! mass flux x-direction [kg/s]
- real,dimension(:,:,:), pointer :: pv ! mass flux y-direction [kg/s]
- real,dimension(:,:), pointer :: blh ! boundary layer height [m]
- real :: T_interpol ! temperature, interpolated to station location
- real :: p_interpol ! pressure, interpolated to station location
- real :: windspeed_u_interpol ! wind speed [m/s] x-direction , interpolated to station location
- real :: windspeed_v_interpol ! wind speed [m/s] y-direction , interpolated to station location
- real :: windspeed_interpol ! wind speed [m/s] , interpolated to station location
- real :: winddir_interpol ! wind direction , interpolated to station location
- real :: blh_interpol ! boundary layer height , interpolated to station location
- real :: lat_j ! latitude of grid cell center js [degrees]
- real :: lat_jn ! latitude of grid cell center jsn [degrees]
- real :: ddx_j ! x-extension of grid cell js [m]
- real :: ddx_jn ! x-extension of grid cell jsn [m]
- real :: ddy ! y-extension of grid cell js [m]
- real :: vmr ! volume mi
- integer :: communicator,root_id,lmr,imr,jmr
- character(len=*), parameter :: rname = mname//'/output_station_conc'
- !__START_SUBROUTINE______________________________________________________
- if (station_nspec == 0) then
- status = 0
- return
- endif
- imr = im(region) ; jmr = jm(region) ; lmr = lm(region)
- m => m_dat(region)%data
- rm => mass_dat(region)%rm
- rxm => mass_dat(region)%rxm
- rym => mass_dat(region)%rym
- rzm => mass_dat(region)%rzm
- ! assign pointers (METEO)
- gph => gph_dat(region)%data
- t => temper_dat(region)%data
- pu => pu_dat(region)%data
- pv => pv_dat(region)%data
- #ifndef without_convection
- blh => conv_dat(region)%blh
- #endif
- phlb => phlb_dat(region)%data
- ! perform now on all PEs
- ! x and y resolution [degrees] for current region
- dyr = dy/yref(region)
- dxr = dx/xref(region)
- ! idate for current region
- call tau2date(itaur(region),idate_f)
- !====================
- ! loop over stations
- !====================
- do i_stat=1, n_stat+n_stat2
- if (stat(i_stat)%region == region) then
- if(stat(i_stat)%ontile) then
-
- !avoid edges!
- ris = (stat(i_stat)%lon-float(xbeg(region)))/dxr + 0.99999
- rjs = (stat(i_stat)%lat-float(ybeg(region)))/dyr + 0.99999
- is = int(ris) ! i-index of grid cell in which station is located
- js = int(rjs) ! j-index of grid cell in which station is located
- ! x-deviation from the center of the grid cell (-0.5...+0.5)
- ris = ris-is-0.5
- ! y-deviation from the center of the grid cell (-0.5...+0.5)
- rjs = rjs-js-0.5
- !=================================
- !the neighbour for x interpolation
- !=================================
- if ( ris .gt. 0 ) then
- isn = is+1
- else
- isn = is-1
- endif
- !=================================
- !the neighbour for y interpolation
- !=================================
- if ( rjs .gt. 0 ) then
- jsn = js+1
- else
- jsn = js-1
- endif
- ! x- / y-weighting of grid cell in which station is located
- wcx = (1.0-abs(ris)) ! 1.0 ... 0.5
- wcy = (1.0-abs(rjs)) ! 1.0 ... 0.5
- !=================================================================
- ! if index of neighbour is exceeding range of region set
- ! neighbour = current cell (i.e. no interpolation)
- ! in case of cyclic x-boundaries take corresponding cyclic i index
- !=================================================================
- if ( jsn == 0) jsn=1
- if ( jsn == jm(region)+1 ) jsn=jm(region) ! isn-->jsn (wouter Peters)
- ! if ( xcyc(region) == 0 ) then
- ! ! non-cyclic boundaries
- ! if ( isn == 0) isn=1
- ! if ( isn == im(region)+1 ) isn=im(region)
- ! else
- ! ! cyclic x-boundaries
- ! if ( isn == 0 ) isn=im(region)
- ! if ( isn == im(region)+1 ) isn=1
- ! end if
- !============================================
- ! interpolate the gph to xy position of station
- !============================================
- !ls = 1 !layer
- do l=0,lm(region)
- !CMK note: gph now from 1-->lm+1 (dec 2002)
- height(l) = wcx * wcy* gph(is,js,l+1) + &
- (1.0-wcx)* wcy* gph(isn,js,l+1) + &
- wcx *(1.0-wcy)* gph(is,jsn,l+1) + &
- (1.0-wcx)*(1.0-wcy)* gph(isn,jsn,l+1)
- end do
- !===========================
- ! determine layer of station
- !===========================
- if(stat(i_stat)%nonsurf == 1) then
- sampleheight=height(0)+stat(i_stat)%height
- else
- sampleheight=stat(i_stat)%height
- endif
- ! do not allow sampleheight below model surface
- sampleheight = max(sampleheight, height(0))
- do l=0,lm(region)
- if(height(l) > sampleheight) exit
- end do
- select case(l)
- case(0)
- !PB this should no longer occur !!
- ! force station to model surface
- ls = 1
- rls = -0.5
- case default
- ls = l ! station's layer
- ! the off-set from the center of the layer (-0.5--->+0.5)
- ! (interpolation is in (m))
- rls = (sampleheight - height(l-1)) / &
- (height(l)-height(l-1)) - 0.5
- end select
- stat(i_stat)%ls = ls ! store for output to file
- stat(i_stat)%height_sample = sampleheight ! store for output to file
- stat(i_stat)%height_surface = height(0) ! store for output to file
- stat(i_stat)%height_sample_above_surf = sampleheight-height(0) ! store for output to file
- !=================================
- !the neighbour for z interpolation
- !=================================
- if ( rls > 0 ) then
- lsn = ls+1
- else
- lsn = ls-1
- end if
- ! z-weighting of grid cell in which station is located
- wcz = (1.0-abs(rls)) !.0 ... 0.5
- !=========================================================
- ! if vertical neighbor is 0 (which does not exist)
- ! take vertical layer with l=2 for EXTRApolation to ground
- !=========================================================
- if(lsn == 0) then
- lsn=2
- wcz=1.0-rls ! 1.0 ... 1.5
- endif
- if(lsn == lmr+1) then
- !=========================================================
- ! if vertical neighbor is lmr+1 (which does not exist)
- ! -> no interpolation
- !=========================================================
- lsn=lmr ! no interpolation
- wcz=1.0
- endif
- do ispec=1,station_nspec
- n = station_speclist(ispec)
- lst = ls
- lstn = lsn
- !========================================
- ! value of grid box without interpolation
- !========================================
- vmr = rm(is,js,lst,n) / m(is,js,lst) * fscale(n)
- stat(i_stat)%c_mean(ispec,1) = &
- stat(i_stat)%c_mean(ispec,1) + vmr
- stat(i_stat)%c_std(ispec,1) = &
- stat(i_stat)%c_std(ispec,1) + vmr*vmr
- if(i_stat <= n_stat) then
- ! for 'regular' stations only
- !=================================================
- ! values of neigboring grid boxes
- ! (used as estimate for representativeness error
- !=================================================
- ! lower neighbor
- if(ls > 1)then
- vmr = rm(is,js,ls-1,n) / m(is,js,ls-1) * fscale(n)
- stat(i_stat)%c_mean_nb(ispec,1) = stat(i_stat)%c_mean_nb(ispec,1) + vmr
- stat(i_stat)%c_std_nb(ispec,1) = stat(i_stat)%c_std_nb(ispec,1) + vmr*vmr
- stat(i_stat)%ncount_nb(ispec,1) = stat(i_stat)%ncount_nb(ispec,1) + 1
- endif
- ! upper neighbor
- if(ls < lm(region)) then
- vmr = rm(is,js,ls+1,n) / m(is,js,ls+1) * fscale(n)
- stat(i_stat)%c_mean_nb(ispec,2) = stat(i_stat)%c_mean_nb(ispec,2) + vmr
- stat(i_stat)%c_std_nb(ispec,2) = stat(i_stat)%c_std_nb(ispec,2) + vmr*vmr
- stat(i_stat)%ncount_nb(ispec,2) = stat(i_stat)%ncount_nb(ispec,2) + 1
- endif
- ! western neighbor
- if(is > 1) then
- vmr = rm(is-1,js,ls,n) / m(is-1,js,ls) * fscale(n)
- stat(i_stat)%c_mean_nb(ispec,3) = stat(i_stat)%c_mean_nb(ispec,3) + vmr
- stat(i_stat)%c_std_nb(ispec,3) = stat(i_stat)%c_std_nb(ispec,3) + vmr*vmr
- stat(i_stat)%ncount_nb(ispec,3) = stat(i_stat)%ncount_nb(ispec,3) + 1
- endif
- ! eastern neighbor
- if(is < im(region)) then
- vmr = rm(is+1,js,ls,n) / m(is+1,js,ls) * fscale(n)
- stat(i_stat)%c_mean_nb(ispec,4) = stat(i_stat)%c_mean_nb(ispec,4) + vmr
- stat(i_stat)%c_std_nb(ispec,4) = stat(i_stat)%c_std_nb(ispec,4) + vmr*vmr
- stat(i_stat)%ncount_nb(ispec,4) = stat(i_stat)%ncount_nb(ispec,4) + 1
- endif
- ! southern neighbor
- if(js > 1) then
- vmr = rm(is,js-1,ls,n) / m(is,js-1,ls) * fscale(n)
- stat(i_stat)%c_mean_nb(ispec,5) = stat(i_stat)%c_mean_nb(ispec,5) + vmr
- stat(i_stat)%c_std_nb(ispec,5) = stat(i_stat)%c_std_nb(ispec,5) + vmr*vmr
- stat(i_stat)%ncount_nb(ispec,5) = stat(i_stat)%ncount_nb(ispec,5) + 1
- endif
- ! northern neighbor
- if(js < jm(region)) then
- vmr = rm(is,js+1,ls,n) / m(is,js+1,ls) * fscale(n)
- stat(i_stat)%c_mean_nb(ispec,6) = stat(i_stat)%c_mean_nb(ispec,6) + vmr
- stat(i_stat)%c_std_nb(ispec,6) = stat(i_stat)%c_std_nb(ispec,6) + vmr*vmr
- stat(i_stat)%ncount_nb(ispec,6) = stat(i_stat)%ncount_nb(ispec,6) + 1
- endif
- end if
-
-
- !========================================
- ! interpolation using slopes
- !========================================
- !rm-value is obtained from rm + slopes.
- !slope = rxm = (rm*dX/dx *deltaX/2)
- rm_interpol = rm(is,js,lst,n) + 2.0*(ris*rxm(is,js,lst,n) + &
- rjs*rym(is,js,lst,n) + &
- rls*rzm(is,js,lst,n) )
- rm_interpol = max(0.0,rm_interpol)
- vmr = rm_interpol/m(is,js,lst) *fscale(n)
- stat(i_stat)%c_mean(ispec,2) = &
- stat(i_stat)%c_mean(ispec,2) + vmr
- stat(i_stat)%c_std(ispec,2) = &
- stat(i_stat)%c_std(ispec,2) + vmr*vmr
- !========================================
- ! 3D linear interpolation
- !========================================
- ! this PE handles also the neighbour layer
- if (lstn <= lmr) then ! lstn = 0 is already excluded (apply vertical EXTRApolation with upper neighbor; see above)
- rm_interpol = wcx *wcy *wcz *rm(is,js,lst,n) /m(is,js,lst) + &
- (1.0-wcx)*wcy *wcz *rm(isn,js,lst,n) /m(isn,js,lst) + &
- wcx *(1.0-wcy)*wcz *rm(is,jsn,lst,n) /m(is,jsn,lst) + &
- (1.0-wcx)*(1.0-wcy)*wcz *rm(isn,jsn,lst,n) /m(isn,jsn,lst) + &
- wcx *wcy *(1.0-wcz) *rm(is,js,lstn,n) /m(is,js,lstn) + &
- (1.0-wcx)*wcy *(1.0-wcz) *rm(isn,js,lstn,n) /m(isn,js,lstn) + &
- wcx *(1.0-wcy)*(1.0-wcz) *rm(is,jsn,lstn,n) /m(is,jsn,lstn) + &
- (1.0-wcx)*(1.0-wcy)*(1.0-wcz) *rm(isn,jsn,lstn,n)/m(isn,jsn,lstn)
- else !other PE calculates neighbouring contribution
- !PB do NOT apply factor wcz here (no interpolation in z direction in this case) !!!!!
- rm_interpol = wcx *wcy *rm(is,js,lst,n) /m(is,js,lst) + &
- (1.0-wcx)*wcy *rm(isn,js,lst,n) /m(isn,js,lst) + &
- wcx *(1.0-wcy) *rm(is,jsn,lst,n) /m(is,jsn,lst) + &
- (1.0-wcx)*(1.0-wcy) *rm(isn,jsn,lst,n) /m(isn,jsn,lst)
- endif
- vmr = rm_interpol*fscale(n)
- stat(i_stat)%c_mean(ispec,3) = stat(i_stat)%c_mean(ispec,3) + vmr
- stat(i_stat)%c_std(ispec,3) = stat(i_stat)%c_std(ispec,3) + vmr*vmr
- end do !ispec
- !======================
- !meteo data at stations
- !======================
- if (output_stations_meteo) then
- !====================================
- ! 3D linear interpolation Temperature
- !====================================
- T_interpol = &
- wcx *wcy *wcz *T(is,js,ls) + &
- (1.0-wcx)*wcy *wcz *T(isn,js,ls) + &
- wcx *(1.0-wcy)*wcz *T(is,jsn,ls) + &
- (1.0-wcx)*(1.0-wcy)*wcz *T(isn,jsn,ls) + &
- wcx *wcy *(1.0-wcz) *T(is,js,lsn) + &
- (1.0-wcx)*wcy *(1.0-wcz) *T(isn,js,lsn) + &
- wcx *(1.0-wcy)*(1.0-wcz) *T(is,jsn,lsn) + &
- (1.0-wcx)*(1.0-wcy)*(1.0-wcz) *T(isn,jsn,lsn)
- stat(i_stat)%metdat(1) = stat(i_stat)%metdat(1) + T_interpol
-
- !====================================
- ! 3D linear interpolation pressure
- !====================================
- p_interpol =(((0.5-rls) * phlb(is,js,ls) + (0.5+rls) * phlb(is,js,ls+1)) * wcx * wcy + &
- ((0.5-rls) * phlb(isn,js,ls) + (0.5+rls) * phlb(isn,js,ls+1)) * (1.0-wcx) * wcy + &
- ((0.5-rls) * phlb(is,jsn,ls) + (0.5+rls) * phlb(is,jsn,ls+1)) * wcx * (1.0-wcy) + &
- ((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]
- stat(i_stat)%metdat(2) = stat(i_stat)%metdat(2) + p_interpol
- !====================================
- ! 3D windspeed_u_interpol (x-direction)
- !====================================
- ! pu is eastward flux through east grid box boundary
- ! windspeed_u_interpol wind component from east
- ! latitude of grid cell center js [degrees]
- lat_j =ybeg(region)+(js -0.5)*dyr
- ! latitude of grid cell center jsn [degrees]
- lat_jn=ybeg(region)+(jsn-0.5)*dyr
- ! x-extension of grid cell js [m]
- ddx_j =ae * twopi * dxr / 360.0 * cos(lat_j*twopi/360.0)
- ! x-extension of grid cell jsn [m]
- ddx_jn=ae * twopi * dxr / 360.0 * cos(lat_jn*twopi/360.0)
- is_west=is-1
- ! if ( xcyc(region) == 0 ) then
- ! ! non-cyclic boundaries
- ! if ( is_west == 0 ) is_west=1
- ! else
- ! ! cyclic x-boundaries
- ! if ( is_west == 0 ) is_west=im(region)
- ! end if
- !west border !east border
- windspeed_u_interpol=((0.5-ris) * pu(is_west,js,ls)/m(is_west,js,ls) + &
- (0.5+ris) * pu(is,js,ls)/ m(is,js,ls) ) * &
- ddx_j * wcy * wcz + &
- ((0.5-ris) * pu(is_west,jsn,ls)/m(is_west,jsn,ls) + &
- (0.5+ris) * pu(is,jsn,ls)/m(is,jsn,ls) ) * &
- ddx_jn * (1.0-wcy)* wcz + &
- ((0.5-ris) * pu(is_west,js,lsn)/m(is_west,js,lsn) + &
- (0.5+ris) * pu(is,js,lsn)/ m(is,js,lsn)) * &
- ddx_j * wcy * (1.0-wcz) + &
- ((0.5-ris) * pu(is_west,jsn,lsn)/m(is_west,js,lsn) + &
- (0.5+ris) * pu(is,jsn,lsn)/ m(is,jsn,lsn) ) * &
- ddx_jn * (1.0-wcy)* (1.0-wcz)
- !====================================
- ! 3D windspeed_v_interpol (y-direction)
- !====================================
- ! pv northward flux through south grid box boundary
- ! windspeed_v_interpol wind component from north
- ddy =ae * twopi * dyr / 360.0 ! y-extension of grid cell [m]
- js_south = js-1
- if (js_south==0) js_south=1
- js_north = js+1
- if (js_north==(jm(region)+1)) js_north=jm(region)
- !south border !north border
- windspeed_v_interpol=(( &
- (0.5-rjs)*pv(is,js,ls)/m(is,js_south,ls) + &
- (0.5+rjs)*pv(is,js_north,ls)/ m(is,js,ls) ) * &
- wcx * wcz + &
- ((0.5-rjs)*pv(isn,js,ls)/m(isn,js_south,ls) + &
- (0.5+rjs)*pv(isn,js_north,ls)/ m(isn,js,ls) ) * &
- (1.0 - wcx)* wcz + &
- ((0.5-rjs)*pv(is,js,lsn)/m(is,js_south,lsn) + &
- (0.5+rjs)*pv(is,js_north,lsn)/ m(is,js,lsn) ) * &
- wcx * (1.0-wcz) + &
- ((0.5-rjs)*pv(isn,js,lsn)/m(isn,js_south,lsn) + &
- (0.5+rjs)*pv(isn,js_north,lsn)/ m(isn,js,lsn) ) * &
- (1.0 - wcx)* (1.0-wcz) ) * &
- ddy
- windspeed_interpol = &
- sqrt(windspeed_u_interpol**2 + windspeed_v_interpol**2)
- stat(i_stat)%metdat(3) = &
- stat(i_stat)%metdat(3) + windspeed_u_interpol
- stat(i_stat)%metdat(4) = &
- stat(i_stat)%metdat(4) + windspeed_v_interpol
- stat(i_stat)%metdat(5) = &
- stat(i_stat)%metdat(5) + windspeed_interpol
- #ifndef without_convection
- !============================================
- ! interpolate the blh to xy position of station
- !============================================
- blh_interpol = &
- wcx * wcy* blh(is,js) + &
- (1.0-wcx)* wcy* blh(isn,js) + &
- wcx *(1.0-wcy)* blh(is,jsn) + &
- (1.0-wcx)*(1.0-wcy)* blh(isn,jsn)
- stat(i_stat)%metdat(7) = &
- stat(i_stat)%metdat(7) + blh_interpol
- #endif
- endif ! meteo out...
-
- stat(i_stat)%ncount = stat(i_stat)%ncount + 1
- end if ! on current tile
- end if ! on current region
- end do ! end i_stat loop
- nullify(m)
- nullify(rm)
- nullify(rxm)
- nullify(rym)
- nullify(rzm)
- nullify(gph)
- nullify(t)
- nullify(pu)
- nullify(pv)
- nullify(phlb)
- nullify(blh)
- ! ok
- status = 0
-
- END SUBROUTINE OUTPUT_STATIONCONC
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: RESET_STATIONCONC_ACCUMULATOR
- !
- ! !DESCRIPTION: initialize to 0 accumulation arrays for average station
- ! concentration
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE RESET_STATIONCONC_ACCUMULATOR
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer i_stat
- if (station_nspec > 0) then
- do i_stat=1, n_stat+n_stat2
- stat(i_stat)%c_mean(:,:) = 0.0
- stat(i_stat)%c_std(:,:) = 0.0
- if (output_stations_meteo) stat(i_stat)%metdat(:) = 0.0
- stat(i_stat)%ncount = 0
- end do
- end if
- ! You should also set the _nb-variables to zero. Otherwise, there is a random chance of crashing. Now I am not using them.
- ! do i_stat=1, n_stat
- ! stat(i_stat)%c_mean_nb = 0.0
- ! stat(i_stat)%c_std_nb = 0.0
- ! stat(i_stat)%ncount_nb = 0
- ! end do
- END SUBROUTINE RESET_STATIONCONC_ACCUMULATOR
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: EVALUATE_STATIONCONC
- !
- ! !DESCRIPTION: evaluate mean concentration and std
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE EVALUATE_STATIONCONC( status )
- !
- ! !USES:
- !
- use dims, only : idate
- use file_hdf, only : Init, WriteData, TSds, Done, select
- use file_hdf, only : CheckInfo
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- integer, intent(inout) :: status
- !
- ! !REVISION HISTORY:
- ! 16 Mar 2012 - P. Le Sager -
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer i_stat, i, ii, io_status
- integer n_data, isds, nsds, itp
- real temp
- character(len=12) :: xname
- real, dimension(:,:), allocatable :: cout ! to get output
- integer, dimension(:,:), allocatable :: iidate
- real :: windspeed_u_interpol ! wind speed [m/s] x-direction , interpolated to station location
- real :: windspeed_v_interpol ! wind speed [m/s] y-direction , interpolated to station location
- real :: windspeed_interpol ! wind speed [m/s] , interpolated to station location
- real :: winddir_interpol ! wind direction , interpolated to station location
- character(len=*), parameter :: rname = mname//'/evaluate_stationconc'
- !__START_SUBROUTINE______________________________________________________
- if (station_nspec > 0) then
- do i_stat=1, n_stat+n_stat2
- n_data = stat(i_stat)%ncount
- if (n_data > 0) then
- stat(i_stat)%c_mean(:,:) = stat(i_stat)%c_mean(:,:) / n_data
- if (output_stations_meteo) stat(i_stat)%metdat(:) = stat(i_stat)%metdat(:) / n_data
- if (n_data > 1) then
- do i=1, station_nspec
- do ii= 1, n_interpol
- temp = ((stat(i_stat)%c_std(i,ii) - n_data * ((stat(i_stat)%c_mean(i,ii))**2) ) / (n_data-1) )
- if(temp > 0) then
- stat(i_stat)%c_std(i,ii) = sqrt(temp)
- else
- stat(i_stat)%c_std(i,ii) = 0.0
- endif
- enddo
- enddo
- else
- stat(i_stat)%c_std(:,:)=-1.0
- end if
- else
- stat(i_stat)%c_mean(:,:)= -1.0
- stat(i_stat)%c_std(:,:) = -1.0
- if(output_stations_meteo) stat(i_stat)%metdat(:) = -999.
- end if
- ! Write down wind directions
- if(output_stations_meteo) then
- windspeed_u_interpol = stat(i_stat)%metdat(3)
- windspeed_v_interpol = stat(i_stat)%metdat(4)
- windspeed_interpol = stat(i_stat)%metdat(5)
- !====================================
- ! wind direction
- !====================================
-
- ! definition of winddirection:
- ! east : 90
- ! south : 180
- ! west : 270
- ! north : 360
- if ((windspeed_u_interpol < 0) .and. (windspeed_v_interpol < 0))then ! wind from north east (0...90)
- winddir_interpol = atan(windspeed_u_interpol / windspeed_v_interpol) * 360.0 / twopi
- else if ((windspeed_u_interpol < 0) .and. (windspeed_v_interpol > 0)) then ! wind from south east (90...180)
- winddir_interpol = 180.0+atan(windspeed_u_interpol / windspeed_v_interpol) * 360.0 / twopi
- else if ((windspeed_u_interpol < 0) .and. (windspeed_v_interpol == 0)) then ! wind from east (90)
- winddir_interpol = 90.0
- else if ((windspeed_u_interpol > 0) .and. (windspeed_v_interpol < 0)) then ! wind from north west (270... 360)
- winddir_interpol = 360.0+atan(windspeed_u_interpol / windspeed_v_interpol) * 360.0 / twopi
- else if ((windspeed_u_interpol > 0) .and. (windspeed_v_interpol > 0)) then ! wind from south west (180...270)
- winddir_interpol = 180.0+atan(windspeed_u_interpol / windspeed_v_interpol) * 360.0 / twopi
- else if ((windspeed_u_interpol > 0) .and. (windspeed_v_interpol == 0)) then ! wind from west (270)
- winddir_interpol = 270.0
- else if ((windspeed_u_interpol == 0) .and. (windspeed_v_interpol < 0)) then ! wind from north (360)
- winddir_interpol = 360.0
- else if ((windspeed_u_interpol == 0) .and. (windspeed_v_interpol > 0)) then ! wind from south (180)
- winddir_interpol = 180.0
- else if ((windspeed_u_interpol == 0) .and. (windspeed_v_interpol == 0)) then ! no wind
- winddir_interpol = -1.0
- else
- write(gol,*)'output_stationconc: error wind direction'; call goErr
- TRACEBACK
- status=1; return
- end if
- stat(i_stat)%metdat(6) = winddir_interpol
- endif
- end do
- end if
-
- !ok
- status = 0
-
- END SUBROUTINE EVALUATE_STATIONCONC
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: WRITE_STATIONCONC
- !
- ! !DESCRIPTION: write mean concentration
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE WRITE_STATIONCONC( status )
- !
- ! !USES:
- !
- use dims, only : idate
- use file_hdf, only : Init, WriteData, TSds, Done
- use file_hdf, only : WriteAttribute
- !
- ! !INPUT/OUTPUT PARAMETERS:
- !
- integer, intent(inout) :: status
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer i, ii, io_status, i_stat
- integer n_data, isds, nsds, itp
- real, dimension(:,:), allocatable :: cout ! to get output
- integer, dimension(:,:), allocatable :: iidate
- character(len=*), parameter :: rname = mname//'/write_stationconc'
- !__START_SUBROUTINE______________________________________________________
- ! output
- if (station_nspec > 0 ) then
- if (io_record == 0) then
- call WriteAttribute( io_hdf, 'station_ls', stat(:)%ls, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'height_sample', stat(:)%height_sample, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'height_surface', stat(:)%height_surface, status)
- IF_NOTOK_RETURN(status=1)
- call WriteAttribute( io_hdf, 'height_sample_above_surf', stat(:)%height_sample_above_surf, status)
- IF_NOTOK_RETURN(status=1)
- endif
- allocate(cout(n_stat+n_stat2,1))
- If (station_nspec > 0) Then
- do i=1, station_nspec
- do ii= 1,n_interpol
- do i_stat = 1, n_stat+n_stat2
- cout(i_stat,1) = stat(i_stat)%c_mean(i,ii)
- enddo
- call writedata(sds(i,ii), cout, status, start=(/0,io_record/))
- IF_NOTOK_RETURN(status=1)
- enddo
- enddo
- End If
- if (output_stations_meteo) then
- do i=1, n_metdat
- do i_stat = 1, n_stat+n_stat2
- cout(i_stat,1) = stat(i_stat)%metdat(i)
- enddo
- call writedata(sds_meteo(i), cout, status, start=(/0,io_record/))
- IF_NOTOK_RETURN(status=1)
- enddo
- endif
- deallocate(cout)
- allocate(iidate(6,1))
- iidate(:,1) = idate
- call writedata(sds_idate, iidate, status, start=(/0,io_record/) )
- IF_NOTOK_RETURN(status=1)
- deallocate(iidate)
- io_record = io_record + 1
- end if
- ! ok
- status = 0
- END SUBROUTINE WRITE_STATIONCONC
- !EOC
- END MODULE USER_OUTPUT_STATION
|