tracer_data.F90       coverage:  55.56 %func     24.34 %block


     1) module tracer_data
     2) !----------------------------------------------------------------------- 
     3) ! module used to read (and interpolate) offline tracer data (sources and
     4) ! mixing ratios)
     5) ! Created by: Francis Vitt -- 2 May 2006
     6) ! Modified by : Jim Edwards -- 10 March 2009
     7) ! Modified by : Cheryl Craig and Chih-Chieh (Jack) Chen  -- February 2010
     8) !----------------------------------------------------------------------- 
     9) 
    10)   use perf_mod,     only : t_startf, t_stopf
    11)   use shr_kind_mod, only : r8 => shr_kind_r8,r4 => shr_kind_r4, shr_kind_cl, SHR_KIND_CS
    12)   use time_manager, only : get_curr_date, get_step_size, get_curr_calday
    13)   use spmd_utils,   only : masterproc
    14)   use ppgrid,       only : pcols, pver, pverp, begchunk, endchunk
    15)   use cam_abortutils,   only : endrun
    16)   use cam_logfile,  only : iulog
    17)   
    18)   use physics_buffer, only : physics_buffer_desc, pbuf_get_field, pbuf_get_index
    19)   use time_manager, only : set_time_float_from_date, set_date_from_time_float
    20)   use pio,          only : file_desc_t, var_desc_t, &
    21)                            pio_seterrorhandling, pio_internal_error, pio_bcast_error, &
    22)                            pio_setdebuglevel, &
    23)                            pio_char, pio_noerr, &
    24)                            pio_inq_dimid, pio_inq_varid, &
    25)                            pio_def_dim, pio_def_var, &
    26)                            pio_put_att, pio_put_var, &
    27)                            pio_get_var, pio_get_att, pio_nowrite, pio_inq_dimlen, &
    28)                            pio_inq_vardimid, pio_inq_dimlen, pio_closefile, &
    29)                            pio_inquire_variable
    30) 
    31)   implicit none
    32) 
    33)   private  ! all unless made public
    34)   save 
    35) 
    36)   public :: trfld, input3d, input2d, trfile
    37)   public :: trcdata_init
    38)   public :: advance_trcdata
    39)   public :: get_fld_data
    40)   public :: put_fld_data
    41)   public :: get_fld_ndx
    42)   public :: write_trc_restart
    43)   public :: read_trc_restart
    44)   public :: init_trc_restart
    45)   public :: incr_filename
    46) 
    47) 
    48)   ! !PUBLIC MEMBERS
    49) 
    50)   type input3d
    51)      real(r8), dimension(:,:,:), pointer :: data => null()
    52)   endtype input3d
    53) 
    54)   type input2d
    55)      real(r8), dimension(:,:), pointer :: data => null()
    56)   endtype input2d
    57) 
    58)   type trfld
    59)      real(r8), dimension(:,:,:), pointer :: data => null()
    60)      type(input3d), dimension(4) :: input
    61)      character(len=32) :: srcnam
    62)      character(len=32) :: fldnam
    63)      character(len=32) :: units
    64)      type(var_desc_t) :: var_id
    65)      integer :: coords(4) ! LATDIM | LONDIM | LEVDIM | TIMDIM
    66)      integer :: order(4) ! LATDIM | LONDIM | LEVDIM | TIMDIM
    67)      logical :: srf_fld = .false.
    68)      integer :: pbuf_ndx = -1
    69)   endtype trfld
    70) 
    71)   type trfile
    72)      type(input2d), dimension(4) :: ps_in
    73)      character(len=shr_kind_cl) :: pathname = ' '
    74)      character(len=shr_kind_cl) :: curr_filename = ' '
    75)      character(len=shr_kind_cl) :: next_filename = ' '
    76)      type(file_desc_t) :: curr_fileid
    77)      type(file_desc_t) :: next_fileid
    78) 
    79)      type(var_desc_t), pointer :: currfnameid => null() ! pio restart file var id 
    80)      type(var_desc_t), pointer :: nextfnameid => null() ! pio restart file var id
    81) 
    82)      character(len=shr_kind_cl) :: filenames_list = ''
    83)      real(r8) :: datatimem = -1.e36_r8     ! time of prv. values read in
    84)      real(r8) :: datatimep = -1.e36_r8     ! time of nxt. values read in
    85)      real(r8) :: datatimes(4)
    86)      integer :: interp_recs
    87)      real(r8), pointer, dimension(:) :: curr_data_times => null()
    88)      real(r8), pointer, dimension(:) :: next_data_times => null()
    89)      logical :: remove_trc_file = .false.  ! delete file when finished with it
    90)      real(r8) :: offset_time
    91)      integer :: cyc_ndx_beg
    92)      integer :: cyc_ndx_end
    93)      integer :: cyc_yr = 0
    94)      real(r8) :: one_yr = 0
    95)      real(r8) :: curr_mod_time ! model time - calendar day
    96)      real(r8) :: next_mod_time ! model time - calendar day - next time step
    97)      integer :: nlon
    98)      integer :: nlat
    99)      integer :: nlev
   100)      integer :: nilev
   101)      integer :: ps_coords(3) ! LATDIM | LONDIM | TIMDIM
   102)      integer :: ps_order(3) ! LATDIM | LONDIM | TIMDIM
   103)      real(r8), pointer, dimension(:) :: lons => null()
   104)      real(r8), pointer, dimension(:) :: lats => null()
   105)      real(r8), pointer, dimension(:) :: levs => null()
   106)      real(r8), pointer, dimension(:) :: ilevs => null()
   107)      real(r8), pointer, dimension(:) :: hyam => null()
   108)      real(r8), pointer, dimension(:) :: hybm => null()
   109)      real(r8), pointer, dimension(:,:) :: ps => null()
   110)      real(r8), pointer, dimension(:) :: hyai => null()
   111)      real(r8), pointer, dimension(:) :: hybi => null()
   112)      real(r8), pointer, dimension(:,:) :: weight_x => null(), weight_y => null()
   113)      integer, pointer, dimension(:) :: count_x => null(), count_y => null()
   114)      integer, pointer, dimension(:,:) :: index_x => null(), index_y => null()
   115)      real(r8)                        :: p0
   116)      type(var_desc_t) :: ps_id
   117)      logical,  allocatable, dimension(:) :: in_pbuf
   118)      logical :: has_ps = .false.
   119)      logical :: zonal_ave = .false.
   120)      logical :: alt_data = .false.     
   121)      logical :: cyclical = .false.
   122)      logical :: cyclical_list = .false.
   123)      logical :: weight_by_lat = .false.
   124)      logical :: conserve_column = .false.
   125)      logical :: fill_in_months = .false.
   126)      logical :: fixed = .false.
   127)      logical :: initialized = .false.
   128)      logical :: top_bndry = .false.
   129)      logical :: stepTime = .false.  ! Do not interpolate in time, but use stepwise times
   130)   endtype trfile
   131) 
   132)   integer, public, parameter :: MAXTRCRS = 100
   133) 
   134)   integer, parameter :: LONDIM = 1
   135)   integer, parameter :: LATDIM = 2
   136)   integer, parameter :: LEVDIM = 3
   137)   integer, parameter :: TIMDIM = 4
   138) 
   139)   integer, parameter :: PS_TIMDIM = 3
   140) 
   141)   integer, parameter :: ZA_LATDIM = 1
   142)   integer, parameter :: ZA_LEVDIM = 2
   143)   integer, parameter :: ZA_TIMDIM = 3
   144) 
   145)   integer, parameter :: nm=1    ! array index for previous (minus) data
   146)   integer, parameter :: np=2    ! array index for next (plus) data
   147) 
   148)   integer :: plon, plat
   149) 
   150) contains
   151) 
   152) !--------------------------------------------------------------------------
   153) !--------------------------------------------------------------------------
   154)   subroutine trcdata_init( specifier, filename, filelist, datapath, flds, file, &
   155)                            rmv_file, data_cycle_yr, data_fixed_ymd, data_fixed_tod, data_type )
   156) 
   157)     use mo_constants,    only : d2r
   158)     use cam_control_mod, only : nsrest
   159)     use dyn_grid,        only : get_dyn_grid_parm
   160)     use string_utils,    only : to_upper
   161)     use horizontal_interpolate, only : xy_interp_init
   162) #if ( defined SPMD )
   163)     use mpishorthand,    only: mpicom, mpir8, mpiint
   164) #endif
   165) 
   166)     implicit none
   167) 
   168)     character(len=*),    intent(in)    :: specifier(:)
   169)     character(len=*),    intent(in)    :: filename
   170)     character(len=*),    intent(in)    :: filelist
   171)     character(len=*),    intent(in)    :: datapath
   172)     type(trfld), dimension(:), pointer :: flds
   173)     type(trfile),        intent(inout) :: file
   174)     logical,             intent(in)    :: rmv_file
   175)     integer,             intent(in)    :: data_cycle_yr
   176)     integer,             intent(in)    :: data_fixed_ymd
   177)     integer,             intent(in)    :: data_fixed_tod
   178)     character(len=*),    intent(in)    :: data_type
   179) 
   180)     integer :: f, mxnflds, astat
   181)     integer :: str_yr, str_mon, str_day
   182)     integer :: lon_dimid, lat_dimid, lev_dimid, tim_dimid, old_dimid
   183)     integer :: dimids(4), did
   184)     type(var_desc_t) :: varid
   185)     integer :: idx
   186)     integer :: ierr
   187)     integer :: errcode
   188)     real(r8) :: start_time, time1, time2
   189)     integer :: i1,i2,j1,j2
   190)     integer :: nvardims, vardimids(4)
   191) 
   192)     character(len=80) :: data_units
   193) 
   194)     call specify_fields( specifier, flds )
   195) 
   196)     file%datatimep=-1.e36_r8
   197)     file%datatimem=-1.e36_r8
   198) 
   199)     mxnflds = 0 
   200)     if (associated(flds)) mxnflds = size( flds )
   201) 
   202)     if (mxnflds < 1) return
   203)     
   204)     file%remove_trc_file = rmv_file
   205)     file%pathname = trim(datapath)
   206)     file%filenames_list = trim(filelist)
   207) 
   208)     file%fill_in_months = .false.
   209)     file%cyclical = .false.  
   210)     file%cyclical_list = .false.  
   211) 
   212) ! does not work when compiled with pathf90
   213) !    select case ( to_upper(data_type) )
   214)     select case ( data_type )
   215)     case( 'FIXED' )
   216)        file%fixed = .true.
   217)     case( 'INTERP_MISSING_MONTHS' )
   218)        file%fill_in_months = .true.
   219)     case( 'CYCLICAL' )
   220)        file%cyclical = .true.
   221)        file%cyc_yr = data_cycle_yr
   222)     case( 'CYCLICAL_LIST' )
   223)        file%cyclical_list = .true.
   224)        file%cyc_yr = data_cycle_yr
   225)     case( 'SERIAL' )
   226)     case default 
   227)        write(iulog,*) 'trcdata_init: invalid data type: '//trim(data_type)//' file: '//trim(filename)
   228)        write(iulog,*) 'trcdata_init: valid data types: SERIAL | CYCLICAL | CYCLICAL_LIST | FIXED | INTERP_MISSING_MONTHS '
   229)        call endrun('trcdata_init: invalid data type: '//trim(data_type)//' file: '//trim(filename))
   230)     endselect
   231) 
   232)     if ( (.not.file%fixed) .and. ((data_fixed_ymd>0._r8) .or.(data_fixed_tod>0._r8))) then
   233)        call endrun('trcdata_init: Cannot specify data_fixed_ymd or data_fixed_tod if data type is not FIXED')
   234)     endif
   235)     if ( (.not.file%cyclical) .and. (data_cycle_yr>0._r8) ) then
   236)        call endrun('trcdata_init: Cannot specify data_cycle_yr if data type is not CYCLICAL')
   237)     endif
   238) 
   239)     if (masterproc) then
   240)        write(iulog,*) 'trcdata_init: data type: '//trim(data_type)//' file: '//trim(filename)
   241)     endif
   242) 
   243)     ! if there is no list of files (len_trim(file%filenames_list)<1) then
   244)     !  -> set curr_filename from namelist rather from restart data
   245)     if ( len_trim(file%curr_filename)<1 .or. len_trim(file%filenames_list)<1 .or. file%fixed ) then ! initial run
   246)        file%curr_filename = trim(filename)
   247) 
   248)        call get_model_time(file)
   249) 
   250)        if ( file%fixed ) then
   251)           str_yr = data_fixed_ymd/10000
   252)           str_mon = (data_fixed_ymd - str_yr*10000)/100
   253)           str_day = data_fixed_ymd - str_yr*10000 - str_mon*100
   254)           call set_time_float_from_date( start_time, str_yr, str_mon, str_day, data_fixed_tod )
   255)           file%offset_time = start_time - file%curr_mod_time
   256)        else
   257)           file%offset_time = 0
   258)        endif
   259)     endif
   260) 
   261)     call set_time_float_from_date( time2, 2, 1, 1, 0 )
   262)     call set_time_float_from_date( time1, 1, 1, 1, 0 )
   263)     file%one_yr = time2-time1
   264) 
   265)     if ( file%cyclical .or. file%cyclical_list) then
   266)        file%cyc_ndx_beg = -1
   267)        file%cyc_ndx_end = -1
   268)        if ( file%cyc_yr /= 0 ) then
   269)           call set_time_float_from_date( time1, file%cyc_yr  , 1, 1, 0 )
   270)           call set_time_float_from_date( time2, file%cyc_yr+1, 1, 1, 0 )
   271)           file%one_yr = time2-time1
   272)        endif
   273) 
   274)        call open_trc_datafile( file%curr_filename, file%pathname, file%curr_fileid, file%curr_data_times, &
   275)             cyc_ndx_beg=file%cyc_ndx_beg, cyc_ndx_end=file%cyc_ndx_end, cyc_yr=file%cyc_yr )
   276)     else
   277)        call open_trc_datafile( file%curr_filename, file%pathname, file%curr_fileid, file%curr_data_times )
   278)        file%curr_data_times = file%curr_data_times - file%offset_time
   279)     endif
   280) 
   281)     call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR)
   282)     ierr = pio_inq_dimid( file%curr_fileid, 'lon', idx )
   283)     call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR)
   284) 
   285)     file%zonal_ave = (ierr/=PIO_NOERR)
   286) 
   287)     plon = get_dyn_grid_parm('plon')
   288)     plat = get_dyn_grid_parm('plat')
   289) 
   290)     if ( .not. file%zonal_ave ) then
   291) 
   292)        call get_dimension( file%curr_fileid, 'lon', file%nlon, dimid=old_dimid, data=file%lons )
   293) 
   294)        file%lons =  file%lons * d2r
   295) 
   296)        lon_dimid = old_dimid
   297) 
   298)     endif
   299) 
   300)     ierr = pio_inq_dimid( file%curr_fileid, 'time', old_dimid)
   301) 
   302)     ! Hack to work with weird netCDF and old gcc or NAG bug.
   303)     tim_dimid = old_dimid
   304) 
   305)     call get_dimension( file%curr_fileid, 'lat', file%nlat, dimid=old_dimid, data=file%lats )
   306)     file%lats =  file%lats * d2r
   307) 
   308)     lat_dimid = old_dimid
   309) 
   310)     allocate( file%ps(file%nlon,file%nlat), stat=astat )
   311)     if( astat /= 0 ) then
   312)        write(iulog,*) 'trcdata_init: file%ps allocation error = ',astat
   313)        call endrun('trcdata_init: failed to allocate x array')
   314)     end if
   315) 
   316)     call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR)
   317)     ierr = pio_inq_varid( file%curr_fileid, 'PS', file%ps_id )
   318)     file%has_ps = (ierr==PIO_NOERR)
   319)     ierr = pio_inq_dimid( file%curr_fileid, 'altitude', idx )
   320)     file%alt_data = (ierr==PIO_NOERR)
   321) 
   322)     call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR)
   323) 
   324)     if ( file%has_ps) then
   325)        ierr = pio_inq_vardimid (file%curr_fileid, file%ps_id, dimids(1:3))
   326)        do did = 1,3
   327)           if      ( dimids(did) == lon_dimid ) then
   328)              file%ps_coords(LONDIM) = did
   329)              file%ps_order(did) = LONDIM
   330)           else if ( dimids(did) == lat_dimid ) then
   331)              file%ps_coords(LATDIM) = did
   332)              file%ps_order(did) = LATDIM
   333)           else if ( dimids(did) == tim_dimid ) then
   334)              file%ps_coords(PS_TIMDIM) = did
   335)              file%ps_order(did) = PS_TIMDIM
   336)           endif
   337)        enddo
   338)     endif
   339) 
   340)     if (masterproc) then 
   341)        write(iulog,*) 'trcdata_init: file%has_ps = ' , file%has_ps 
   342)     endif ! masterproc
   343) 
   344)     if (file%alt_data) then
   345)        call get_dimension( file%curr_fileid, 'altitude_int', file%nilev,  data=file%ilevs  )
   346)        call get_dimension( file%curr_fileid, 'altitude',     file%nlev, dimid=old_dimid, data=file%levs  )
   347)     else
   348)        call get_dimension( file%curr_fileid, 'lev', file%nlev, dimid=old_dimid, data=file%levs  )
   349)        if (old_dimid>0) then
   350)           file%levs =  file%levs*100._r8 ! mbar->pascals
   351)        endif
   352)     endif
   353) 
   354)     ! For some bizarre reason, netCDF with older gcc is keeping a pointer to the dimid, and overwriting it later!
   355)     ! Hackish workaround is to make a copy...
   356)     lev_dimid = old_dimid
   357) 
   358)     if (file%has_ps) then
   359) 
   360)        allocate( file%hyam(file%nlev),  file%hybm(file%nlev), stat=astat )
   361)        if( astat /= 0 ) then
   362)           write(iulog,*) 'trcdata_init: file%hyam,file%hybm allocation error = ',astat
   363)           call endrun('trcdata_init: failed to allocate file%hyam and file%hybm arrays')
   364)        end if
   365) 
   366)        allocate( file%hyai(file%nlev+1),  file%hybi(file%nlev+1), stat=astat )
   367)        if( astat /= 0 ) then
   368)           write(iulog,*) 'trcdata_init: file%hyai,file%hybi allocation error = ',astat
   369)           call endrun('trcdata_init: failed to allocate file%hyai and file%hybi arrays')
   370)        end if
   371) 
   372)        call pio_seterrorhandling(File%curr_fileid, PIO_BCAST_ERROR)
   373)        ierr = pio_inq_varid( file%curr_fileid, 'P0', varid)
   374)        call pio_seterrorhandling(File%curr_fileid, PIO_INTERNAL_ERROR)
   375) 
   376)        if ( ierr == PIO_NOERR ) then
   377)           ierr = pio_get_var( file%curr_fileid, varid, file%p0 )
   378)        else
   379)           file%p0 = 100000._r8
   380)        endif
   381)        ierr = pio_inq_varid( file%curr_fileid, 'hyam', varid )
   382)        ierr = pio_get_var( file%curr_fileid, varid, file%hyam )
   383)        ierr = pio_inq_varid( file%curr_fileid, 'hybm', varid )
   384)        ierr = pio_get_var( file%curr_fileid, varid, file%hybm )
   385)        if (file%conserve_column) then
   386)           ierr = pio_inq_varid( file%curr_fileid, 'hyai', varid )
   387)           ierr = pio_get_var( file%curr_fileid, varid, file%hyai )
   388)           ierr = pio_inq_varid( file%curr_fileid, 'hybi', varid )
   389)           ierr = pio_get_var( file%curr_fileid, varid, file%hybi )
   390)        endif
   391) 
   392)        allocate( file         %ps  (pcols,begchunk:endchunk), stat=astat   )
   393)        if( astat/= 0 ) then
   394)           write(iulog,*) 'trcdata_init: failed to allocate file%ps array; error = ',astat
   395)           call endrun
   396)        end if
   397)        allocate( file%ps_in(1)%data(pcols,begchunk:endchunk), stat=astat   )
   398)        if( astat/= 0 ) then
   399)           write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(1)%data array; error = ',astat
   400)           call endrun
   401)        end if
   402)        allocate( file%ps_in(2)%data(pcols,begchunk:endchunk), stat=astat   )
   403)        if( astat/= 0 ) then
   404)           write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(2)%data array; error = ',astat
   405)           call endrun
   406)        end if
   407)        if( file%fill_in_months ) then
   408)           allocate( file%ps_in(3)%data(pcols,begchunk:endchunk), stat=astat   )
   409)           if( astat/= 0 ) then
   410)              write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(3)%data array; error = ',astat
   411)              call endrun
   412)           end if
   413)           allocate( file%ps_in(4)%data(pcols,begchunk:endchunk), stat=astat   )
   414)           if( astat/= 0 ) then
   415)              write(iulog,*) 'trcdata_init: failed to allocate file%ps_in(4)%data array; error = ',astat
   416)              call endrun
   417)           end if
   418)        end if
   419)     endif
   420) 
   421)     flds_loop: do f = 1,mxnflds
   422) 
   423)        ! get netcdf variable id for the field
   424)        ierr = pio_inq_varid( file%curr_fileid, flds(f)%srcnam, flds(f)%var_id )
   425) 
   426)        ! determine if the field has a vertical dimension
   427) 
   428)        if (lev_dimid>0) then
   429)           ierr = pio_inquire_variable(  file%curr_fileid, flds(f)%var_id, ndims=nvardims )
   430)           ierr = pio_inquire_variable(  file%curr_fileid, flds(f)%var_id, dimids=vardimids(:nvardims) )
   431)           flds(f)%srf_fld = .not.any(vardimids(:nvardims)==lev_dimid)
   432)        else
   433)           flds(f)%srf_fld = .true.
   434)        endif
   435) 
   436)        ! allocate memory only if not already in pbuf2d
   437) 
   438)        if ( .not. file%in_pbuf(f) ) then 
   439)           if ( flds(f)%srf_fld .or. file%top_bndry ) then
   440)              allocate( flds(f)         %data(pcols,1,begchunk:endchunk), stat=astat   )
   441)           else
   442)              allocate( flds(f)         %data(pcols,pver,begchunk:endchunk), stat=astat   )
   443)           endif
   444)           if( astat/= 0 ) then
   445)              write(iulog,*) 'trcdata_init: failed to allocate flds(f)%data array; error = ',astat
   446)              call endrun
   447)           end if
   448)        else
   449)           flds(f)%pbuf_ndx = pbuf_get_index(flds(f)%fldnam,errcode)
   450)        endif
   451)    
   452)        if (flds(f)%srf_fld) then
   453)           allocate( flds(f)%input(1)%data(pcols,1,begchunk:endchunk), stat=astat   )
   454)        else
   455)           allocate( flds(f)%input(1)%data(pcols,file%nlev,begchunk:endchunk), stat=astat   )
   456)        endif
   457)        if( astat/= 0 ) then
   458)           write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(1)%data array; error = ',astat
   459)           call endrun
   460)        end if
   461)        if (flds(f)%srf_fld) then
   462)           allocate( flds(f)%input(2)%data(pcols,1,begchunk:endchunk), stat=astat   )
   463)        else
   464)           allocate( flds(f)%input(2)%data(pcols,file%nlev,begchunk:endchunk), stat=astat   )
   465)        endif
   466)        if( astat/= 0 ) then
   467)           write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(2)%data array; error = ',astat
   468)           call endrun
   469)        end if
   470) 
   471)        if( file%fill_in_months ) then
   472)           if (flds(f)%srf_fld) then
   473)              allocate( flds(f)%input(3)%data(pcols,1,begchunk:endchunk), stat=astat   )
   474)           else
   475)              allocate( flds(f)%input(3)%data(pcols,file%nlev,begchunk:endchunk), stat=astat   )
   476)           endif
   477)           if( astat/= 0 ) then
   478)              write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(3)%data array; error = ',astat
   479)              call endrun
   480)           end if
   481)           if (flds(f)%srf_fld) then
   482)              allocate( flds(f)%input(4)%data(pcols,1,begchunk:endchunk), stat=astat   )
   483)           else
   484)              allocate( flds(f)%input(4)%data(pcols,file%nlev,begchunk:endchunk), stat=astat   )
   485)           endif
   486)           if( astat/= 0 ) then
   487)              write(iulog,*) 'trcdata_init: failed to allocate flds(f)%input(4)%data array; error = ',astat
   488)              call endrun
   489)           end if
   490)        endif
   491) 
   492)        if ( file%zonal_ave ) then
   493)           ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids(1:3))
   494)           do did = 1,3
   495)              if      ( dimids(did) == lat_dimid ) then
   496)                 flds(f)%coords(ZA_LATDIM) = did
   497)                 flds(f)%order(did) = ZA_LATDIM
   498)              else if ( dimids(did) == lev_dimid ) then
   499)                 flds(f)%coords(ZA_LEVDIM) = did
   500)                 flds(f)%order(did) = ZA_LEVDIM
   501)              else if ( dimids(did) == tim_dimid ) then
   502)                 flds(f)%coords(ZA_TIMDIM) = did
   503)                 flds(f)%order(did) = ZA_TIMDIM
   504)              endif
   505)           enddo
   506)        else if ( flds(f)%srf_fld ) then
   507)           ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids(1:3))
   508)           do did = 1,3
   509)              if      ( dimids(did) == lon_dimid ) then
   510)                 flds(f)%coords(LONDIM) = did
   511)                 flds(f)%order(did) = LONDIM
   512)              else if ( dimids(did) == lat_dimid ) then
   513)                 flds(f)%coords(LATDIM) = did
   514)                 flds(f)%order(did) = LATDIM
   515)              else if ( dimids(did) == tim_dimid ) then
   516)                 flds(f)%coords(PS_TIMDIM) = did
   517)                 flds(f)%order(did) = PS_TIMDIM
   518)              endif
   519)           enddo
   520)        else
   521)           ierr = pio_inq_vardimid (file%curr_fileid, flds(f)%var_id, dimids)
   522)           do did = 1,4
   523)              if      ( dimids(did) == lon_dimid ) then
   524)                 flds(f)%coords(LONDIM) = did
   525)                 flds(f)%order(did) = LONDIM
   526)              else if ( dimids(did) == lat_dimid ) then
   527)                 flds(f)%coords(LATDIM) = did
   528)                 flds(f)%order(did) = LATDIM
   529)              else if ( dimids(did) == lev_dimid ) then
   530)                 flds(f)%coords(LEVDIM) = did
   531)                 flds(f)%order(did) = LEVDIM
   532)              else if ( dimids(did) == tim_dimid ) then
   533)                 flds(f)%coords(TIMDIM) = did
   534)                 flds(f)%order(did) = TIMDIM
   535)              endif
   536)           enddo
   537)        endif
   538) 
   539)        ierr = pio_get_att( file%curr_fileid, flds(f)%var_id, 'units', data_units)
   540)        data_units = trim(data_units)
   541)        flds(f)%units = data_units(1:32)
   542) 
   543)     enddo flds_loop
   544) 
   545) ! if weighting by latitude, compute weighting for horizontal interpolation
   546)     if( file%weight_by_lat ) then
   547) ! get dimensions of CAM resolution
   548)         plon = get_dyn_grid_parm('plon')
   549)         plat = get_dyn_grid_parm('plat')
   550)         
   551) ! weight_x & weight_y are weighting function for x & y interpolation
   552)         allocate(file%weight_x(plon,file%nlon))
   553)         allocate(file%weight_y(plat,file%nlat))
   554)         allocate(file%count_x(plon))
   555)         allocate(file%count_y(plat))
   556)         allocate(file%index_x(plon,file%nlon))
   557)         allocate(file%index_y(plat,file%nlat))
   558)         file%weight_x(:,:) = 0.0_r8
   559)         file%weight_y(:,:) = 0.0_r8
   560)         file%count_x(:) = 0
   561)         file%count_y(:) = 0
   562)         file%index_x(:,:) = 0
   563)         file%index_y(:,:) = 0
   564) 
   565)         if(masterproc) then
   566) ! compute weighting 
   567)             call xy_interp_init(file%nlon,file%nlat,file%lons,file%lats,plon,plat,file%weight_x,file%weight_y)
   568) 
   569)             do i2=1,plon
   570)                file%count_x(i2) = 0
   571)                do i1=1,file%nlon
   572)                   if(file%weight_x(i2,i1).gt.0.0_r8 ) then
   573)                      file%count_x(i2) = file%count_x(i2) + 1
   574)                      file%index_x(i2,file%count_x(i2)) = i1
   575)                   endif
   576)                enddo
   577)             enddo
   578) 
   579)             do j2=1,plat
   580)                file%count_y(j2) = 0
   581)                do j1=1,file%nlat
   582)                   if(file%weight_y(j2,j1).gt.0.0_r8 ) then
   583)                      file%count_y(j2) = file%count_y(j2) + 1
   584)                      file%index_y(j2,file%count_y(j2)) = j1
   585)                   endif
   586)                enddo
   587)             enddo
   588)         endif
   589) 
   590) #if ( defined SPMD)
   591)         call mpibcast(file%weight_x, plon*file%nlon, mpir8 , 0, mpicom)
   592)         call mpibcast(file%weight_y, plat*file%nlat, mpir8 , 0, mpicom)
   593)         call mpibcast(file%count_x, plon, mpiint , 0, mpicom)
   594)         call mpibcast(file%count_y, plat, mpiint , 0, mpicom)
   595)         call mpibcast(file%index_x, plon*file%nlon, mpiint , 0, mpicom)
   596)         call mpibcast(file%index_y, plat*file%nlat, mpiint , 0, mpicom)
   597) #endif
   598)     endif
   599) 
   600)   end subroutine trcdata_init
   601) 
   602) !-----------------------------------------------------------------------
   603) ! Reads more data if needed and interpolates data to current model time 
   604) !-----------------------------------------------------------------------
   605)   subroutine advance_trcdata( flds, file, state, pbuf2d )
   606)     use physics_types,only : physics_state
   607)     use physics_buffer, only : physics_buffer_desc
   608)     use ppgrid, only : pver,pcols
   609) 
   610)     implicit none
   611) 
   612)     type(trfile),        intent(inout) :: file
   613)     type(trfld),         intent(inout) :: flds(:)
   614)     type(physics_state), intent(in)    :: state(begchunk:endchunk)
   615)     
   616)     type(physics_buffer_desc), optional, pointer :: pbuf2d(:,:)
   617)     integer :: ncol
   618)     real(r8) :: data_time
   619)     real(r8) :: t(pcols,pver)          ! input temperature (K)
   620)     real(r8) :: rho(pcols,pver)          ! input temperature (K)
   621)     real(r8) :: pmid(pcols,pver)       ! pressure at layer midpoints (pa)
   622) !--------------------------------------BLH-----------------------------------    
   623) 
   624)     call t_startf('advance_trcdata')
   625)     if ( .not.( file%fixed .and. file%initialized ) ) then
   626) 
   627)        call get_model_time(file)
   628) 
   629)        data_time = file%datatimep
   630) 
   631)        if ( file%cyclical .or. file%cyclical_list ) then
   632)           ! wrap around
   633)           if ( (file%datatimep<file%datatimem) .and. (file%curr_mod_time>file%datatimem) ) then
   634)              data_time = data_time + file%one_yr 
   635)           endif
   636)        endif
   637) 
   638)     ! For stepTime need to advance if the times are equal
   639)     ! Should not impact other runs?
   640)        if ( file%curr_mod_time >= data_time ) then
   641)           call t_startf('read_next_trcdata')
   642)           call read_next_trcdata(state, flds, file )
   643)           call t_stopf('read_next_trcdata')
   644)           if(masterproc) write(iulog,*) 'READ_NEXT_TRCDATA ', flds%fldnam
   645)        end if
   646) 
   647)     endif
   648)     
   649)     ! need to interpolate the data, regardless
   650)     ! each mpi task needs to interpolate
   651)     call t_startf('interpolate_trcdata')
   652)     if(present(pbuf2d)) then
   653)        call interpolate_trcdata( state, flds, file, pbuf2d )
   654)     else
   655)        call interpolate_trcdata( state, flds, file )
   656)     endif
   657)     call t_stopf('interpolate_trcdata')
   658) 
   659)     file%initialized = .true.
   660) 
   661)     call t_stopf('advance_trcdata')
   662) 
   663)   end subroutine advance_trcdata
   664) 
   665) !-------------------------------------------------------------------
   666) !-------------------------------------------------------------------
   667)   subroutine get_fld_data( flds, field_name, data, ncol, lchnk, pbuf )
   668) 
   669)     use physics_buffer, only : physics_buffer_desc, pbuf_get_field
   670) 
   671)     implicit none
   672) 
   673)     type(trfld), intent(inout) :: flds(:)
   674)     character(len=*), intent(in) :: field_name
   675)     real(r8), intent(out) :: data(:,:)
   676)     integer, intent(in) :: lchnk
   677)     integer, intent(in) :: ncol
   678)     type(physics_buffer_desc), pointer :: pbuf(:)
   679)     
   680) 
   681)     integer :: f, nflds
   682)     real(r8),pointer  :: tmpptr(:,:)
   683) 
   684)     data(:,:) = 0._r8
   685)     nflds = size(flds)
   686) 
   687)     do f = 1, nflds
   688)        if ( trim(flds(f)%fldnam) == trim(field_name) ) then
   689)           if ( flds(f)%pbuf_ndx>0 ) then
   690)              call pbuf_get_field(pbuf, flds(f)%pbuf_ndx, tmpptr)
   691)              data(:ncol,:) = tmpptr(:ncol,:)
   692)           else
   693)              data(:ncol,:) = flds(f)%data(:ncol,:,lchnk)
   694)           endif
   695)        endif
   696)     enddo
   697) 
   698)  end subroutine get_fld_data
   699) 
   700) !-------------------------------------------------------------------
   701) !-------------------------------------------------------------------
   702)   subroutine put_fld_data( flds, field_name, data, ncol, lchnk, pbuf )
   703) 
   704)     use physics_buffer, only : physics_buffer_desc, pbuf_get_field
   705) 
   706)     implicit none
   707) 
   708)     type(trfld), intent(inout) :: flds(:)
   709)     character(len=*), intent(in) :: field_name
   710)     real(r8), intent(in) :: data(:,:)
   711)     integer, intent(in) :: lchnk
   712)     integer, intent(in) :: ncol
   713)     type(physics_buffer_desc), pointer :: pbuf(:)
   714)     
   715) 
   716)     integer :: f, nflds
   717)     real(r8),pointer  :: tmpptr(:,:)
   718) 
   719)     nflds = size(flds)
   720) 
   721)     do f = 1, nflds
   722)        if ( trim(flds(f)%fldnam) == trim(field_name) ) then
   723)           if ( flds(f)%pbuf_ndx>0 ) then
   724)              call pbuf_get_field(pbuf, flds(f)%pbuf_ndx, tmpptr)
   725)              tmpptr(:ncol,:) = data(:ncol,:)
   726)           else
   727)              flds(f)%data(:ncol,:,lchnk) = data(:ncol,:)
   728)           endif
   729)        endif
   730)     enddo
   731) 
   732)  end subroutine put_fld_data
   733) 
   734) !-------------------------------------------------------------------
   735) !-------------------------------------------------------------------
   736)   subroutine get_fld_ndx( flds, field_name, idx  )
   737) 
   738)     implicit none
   739) 
   740)     type(trfld), intent(in) :: flds(:)
   741)     character(len=*), intent(in) :: field_name
   742)     integer, intent(out) :: idx    
   743)     integer :: f, nflds
   744) 
   745)     idx = -1
   746)     nflds = size(flds)
   747) 
   748)     do f = 1, nflds
   749)        if ( trim(flds(f)%fldnam) == trim(field_name) ) then
   750)           idx = f
   751)           return
   752)        endif
   753)     enddo
   754) 
   755)   end subroutine get_fld_ndx
   756) 
   757) !------------------------------------------------------------------------------
   758) !------------------------------------------------------------------------------
   759)   subroutine get_model_time(file)
   760)     implicit none
   761)     type(trfile), intent(inout) :: file
   762) 
   763)     integer yr, mon, day, ncsec  ! components of a date
   764) 
   765)     call get_curr_date(yr, mon, day, ncsec)
   766) 
   767)     if ( file%cyclical .or. file%cyclical_list) yr = file%cyc_yr
   768)     call set_time_float_from_date( file%curr_mod_time, yr, mon, day, ncsec )
   769)     file%next_mod_time = file%curr_mod_time + get_step_size()/86400._r8
   770) 
   771)   end subroutine get_model_time
   772) 
   773) !------------------------------------------------------------------------------
   774) !------------------------------------------------------------------------------
   775)   subroutine check_files( file, fids, itms, times_found)
   776) 
   777)     implicit none
   778) 
   779)     type(trfile),      intent(inout) :: file
   780)     type(file_desc_t), intent(out)   :: fids(2) ! ids of files that contains these recs
   781)     integer, optional, intent(out)   :: itms(2)
   782)     logical, optional, intent(inout) :: times_found
   783) 
   784)     !-----------------------------------------------------------------------
   785)     ! 	... local variables
   786)     !-----------------------------------------------------------------------
   787)     logical            :: list_cycled
   788) 
   789)     list_cycled = .false.
   790) 
   791)    !-----------------------------------------------------------------------
   792)    !        If next time beyond the end of the time list,
   793)    !        then increment the filename and move on to the next file
   794)    !-----------------------------------------------------------------------
   795)     if ((file%next_mod_time > file%curr_data_times(size(file%curr_data_times))).or.file%cyclical_list) then
   796)        if (file%cyclical_list) then
   797)           if ( associated(file%next_data_times) ) then
   798)               if ((file%curr_mod_time > file%datatimep)) then
   799) 
   800)                call advance_file(file)
   801)      
   802)             endif
   803)          endif
   804) 
   805)        endif
   806)        if ( .not. associated(file%next_data_times) ) then
   807)           ! open next file if not already opened...
   808)           if (file%cyclical_list) then
   809)               file%next_filename = incr_filename( file%curr_filename, filenames_list=file%filenames_list, datapath=file%pathname ,&
   810)                                                   cyclical_list=file%cyclical_list, list_cycled=list_cycled)
   811)           else
   812)               file%next_filename = incr_filename( file%curr_filename, filenames_list=file%filenames_list, datapath=file%pathname)
   813)           endif
   814)           call open_trc_datafile( file%next_filename, file%pathname, file%next_fileid, file%next_data_times )
   815)           file%next_data_times = file%next_data_times - file%offset_time
   816)        endif
   817)     endif
   818)     
   819)     !-----------------------------------------------------------------------
   820)     !        If using next_data_times and the current is greater than or equal to the next, then
   821)     !        close the current file, and set up for next file.
   822)     !-----------------------------------------------------------------------
   823)     if ( associated(file%next_data_times) ) then
   824)        if (file%cyclical_list .and. list_cycled) then    ! special case - list cycled 
   825) 
   826)           file%datatimem = file%curr_data_times(size(file%curr_data_times)) 
   827)           itms(1)=size(file%curr_data_times)
   828)           fids(1)=file%curr_fileid
   829) 
   830)           file%datatimep = file%next_data_times(1)
   831)           itms(2)=1
   832)           fids(2) = file%next_fileid
   833) 
   834)           times_found = .true.
   835) 
   836)        else if (file%curr_mod_time >= file%next_data_times(1)) then
   837) 
   838)           call advance_file(file)
   839) 
   840)        endif
   841)     endif
   842) 
   843)   end subroutine check_files
   844) 
   845) !-----------------------------------------------------------------------
   846) !-----------------------------------------------------------------------
   847)   function incr_filename( filename, filenames_list, datapath, cyclical_list, list_cycled )
   848) 
   849)     !-----------------------------------------------------------------------
   850)     ! 	... Increment or decrement a date string withing a filename
   851)     !           the filename date section is assumed to be of the form
   852)     !           yyyy-dd-mm
   853)     !-----------------------------------------------------------------------
   854) 
   855)     use string_utils, only : incstr
   856)     use shr_file_mod, only : shr_file_getunit, shr_file_freeunit
   857) 
   858)     implicit none
   859) 
   860) 
   861)     character(len=*),           intent(in)    :: filename ! present dynamical dataset filename
   862)     character(len=*), optional, intent(in)    :: filenames_list 
   863)     character(len=*), optional, intent(in)    :: datapath
   864)     logical         , optional, intent(in)    :: cyclical_list  ! If true, allow list to cycle
   865)     logical         , optional, intent(out)   :: list_cycled
   866)     character(len=shr_kind_cl)                :: incr_filename         ! next filename in the sequence
   867) 
   868) 
   869)     ! set new next_filename ...
   870) 
   871)     !-----------------------------------------------------------------------
   872)     !	... local variables
   873)     !-----------------------------------------------------------------------
   874)     integer :: pos, pos1, istat
   875)     character(len=shr_kind_cl) :: fn_new, line, filepath
   876)     character(len=6)   :: seconds
   877)     character(len=5)   :: num
   878)     integer :: ios,unitnumber
   879) 
   880)     if (present(list_cycled)) list_cycled = .false.
   881) 
   882)     if (( .not. present(filenames_list)) .or.(len_trim(filenames_list) == 0)) then
   883)        !-----------------------------------------------------------------------
   884)        !	... ccm type filename
   885)        !-----------------------------------------------------------------------
   886)        pos = len_trim( filename )
   887)        fn_new = filename(:pos)
   888)        if ( masterproc ) write(iulog,*) 'incr_flnm: old filename = ',trim(fn_new)
   889)        if( fn_new(pos-2:) == '.nc' ) then
   890)           pos = pos - 3
   891)        end if
   892)        istat = incstr( fn_new(:pos), 1 )
   893)        if( istat /= 0 ) then
   894)           write(iulog,*) 'incr_flnm: incstr returned ', istat
   895)           write(iulog,*) '           while trying to decrement ',trim( fn_new )
   896)           call endrun
   897)        end if
   898) 
   899)     else
   900) 
   901)        !-------------------------------------------------------------------
   902)        !  ... open filenames_list
   903)        !-------------------------------------------------------------------
   904)        if ( masterproc ) write(iulog,*) 'incr_flnm: old filename = ',trim(filename)
   905)        if ( masterproc ) write(iulog,*) 'incr_flnm: open filenames_list : ',trim(filenames_list)
   906)        unitnumber = shr_file_getUnit()
   907)        if ( present(datapath) ) then
   908)          filepath = trim(datapath) //'/'// trim(filenames_list)
   909)        else
   910)          filepath = trim(datapath)
   911)        endif
   912) 
   913)        open( unit=unitnumber, file=filepath, iostat=ios, status="OLD")
   914)        if (ios /= 0) then
   915)           call endrun('not able to open filenames_list file: '//trim(filepath))
   916)        endif
   917) 
   918)        !-------------------------------------------------------------------
   919)        !  ...  read file names
   920)        !-------------------------------------------------------------------
   921)        read( unit=unitnumber, fmt='(A)', iostat=ios ) line 
   922)        if (ios /= 0) then
   923)           call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list))
   924)        endif
   925) 
   926)        !-------------------------------------------------------------------
   927)        !      If current filename is '', then initialize with the first filename read in
   928)        !      and skip this section.
   929)        !-------------------------------------------------------------------
   930)        if (filename /= '') then 
   931) 
   932)           !-------------------------------------------------------------------
   933)           !       otherwise read until find current filename
   934)           !-------------------------------------------------------------------
   935)           do while( trim(line) /= trim(filename) )
   936)              read( unit=unitnumber, fmt='(A)', iostat=ios ) line 
   937)              if (ios /= 0) then
   938)                 call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list))
   939)              endif
   940)           enddo
   941)    
   942)           !-------------------------------------------------------------------
   943)           !      Read next filename
   944)           !-------------------------------------------------------------------
   945)           read( unit=unitnumber, fmt='(A)', iostat=ios ) line 
   946) 
   947)           !---------------------------------------------------------------------------------
   948)           !       If cyclical_list, then an end of file is not an error, but rather 
   949)           !       a signal to rewind and start over
   950)           !---------------------------------------------------------------------------------
   951) 
   952)           if (ios /= 0) then
   953)              if (present(cyclical_list)) then
   954)                 if (cyclical_list) then
   955)                    list_cycled=.true.
   956)                    rewind(unitnumber)
   957)                    read( unit=unitnumber, fmt='(A)', iostat=ios ) line 
   958)                      ! Error here should never happen, but check just in case
   959)                    if (ios /= 0) then
   960)                       call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list))
   961)                    endif
   962)                 else
   963)                    call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list))
   964)                 endif
   965)              else
   966)                 call endrun('not able to increment file name from filenames_list file: '//trim(filenames_list))
   967)              endif
   968)           endif
   969) 
   970)        endif
   971) 
   972)        !---------------------------------------------------------------------------------
   973)        !     Assign the current filename and close the filelist
   974)        !---------------------------------------------------------------------------------
   975)        fn_new = trim(line)
   976) 
   977)        close(unit=unitnumber)
   978)        call shr_file_freeUnit(unitnumber)
   979)     endif
   980) 
   981)     !---------------------------------------------------------------------------------
   982)     !      return the current filename 
   983)     !---------------------------------------------------------------------------------
   984)     incr_filename = trim(fn_new)
   985)     if ( masterproc ) write(iulog,*) 'incr_flnm: new filename = ',trim(incr_filename)
   986) 
   987)   end function incr_filename
   988) 
   989) !------------------------------------------------------------------------------
   990) !------------------------------------------------------------------------------
   991)   subroutine find_times( itms, fids, time, file, datatimem, datatimep, times_found )
   992) 
   993)     implicit none
   994) 
   995)     type(trfile), intent(in) :: file
   996)     real(r8), intent(out) :: datatimem, datatimep
   997) 
   998)     integer, intent(out) :: itms(2) ! record numbers that bracket time
   999)     type(file_desc_t), intent(out) :: fids(2) ! ids of files that contains these recs
  1000) 
  1001)     real(r8), intent(in) :: time    ! time of interest
  1002)     logical, intent(inout)  :: times_found
  1003) 
  1004)     integer :: np1        ! current forward time index of dataset
  1005)     integer :: n,i      ! 
  1006)     integer :: curr_tsize, next_tsize, all_tsize
  1007)     integer :: astat
  1008)     integer :: cyc_tsize
  1009) 
  1010)     real(r8), allocatable, dimension(:):: all_data_times
  1011) 
  1012)     curr_tsize = size(file%curr_data_times)
  1013)     next_tsize = 0
  1014)     if ( associated(file%next_data_times)) next_tsize = size(file%next_data_times)
  1015) 
  1016)     all_tsize = curr_tsize + next_tsize
  1017) 
  1018)     allocate( all_data_times( all_tsize ), stat=astat )
  1019)     if( astat/= 0 ) then
  1020)        write(iulog,*) 'find_times: failed to allocate all_data_times array; error = ',astat
  1021)        call endrun
  1022)     end if
  1023) 
  1024)     all_data_times(:curr_tsize) = file%curr_data_times(:)
  1025)     if (next_tsize > 0) all_data_times(curr_tsize+1:all_tsize) = file%next_data_times(:)
  1026) 
  1027)     if ( .not. file%cyclical ) then
  1028)        if ( all( all_data_times(:) > time ) ) then
  1029)           write(iulog,*) 'FIND_TIMES: ALL data times are after ', time
  1030)           write(iulog,*) 'FIND_TIMES: data times: ',all_data_times(:)
  1031)           write(iulog,*) 'FIND_TIMES: time: ',time
  1032)           call endrun('find_times: all(all_data_times(:) > time) '// trim(file%curr_filename) )
  1033)        endif
  1034) 
  1035)        ! find bracketing times 
  1036)        find_times_loop : do n=1, all_tsize-1
  1037)           np1 = n + 1
  1038)           datatimem = all_data_times(n)   !+ file%offset_time
  1039)           datatimep = all_data_times(np1) !+ file%offset_time
  1040)        ! When stepTime, datatimep may not equal the time (as only datatimem is used)
  1041)        ! Should not break other runs?
  1042)           if ( (time .ge. datatimem) .and. (time .lt. datatimep) ) then
  1043)              times_found = .true.
  1044)              exit find_times_loop
  1045)           endif
  1046)        enddo find_times_loop
  1047) 
  1048)     else  ! file%cyclical
  1049) 
  1050)        cyc_tsize = file%cyc_ndx_end - file%cyc_ndx_beg + 1
  1051) 
  1052)        if ( cyc_tsize > 1 ) then
  1053) 
  1054)           call findplb(all_data_times(file%cyc_ndx_beg:file%cyc_ndx_end),cyc_tsize, time, n )
  1055) 
  1056)           if (n == cyc_tsize) then
  1057)              np1 = 1
  1058)           else
  1059)              np1 = n+1
  1060)           endif
  1061) 
  1062)           datatimem = all_data_times(n  +file%cyc_ndx_beg-1)   
  1063)           datatimep = all_data_times(np1+file%cyc_ndx_beg-1) 
  1064)           times_found = .true.
  1065) 
  1066)        endif
  1067)     endif
  1068) 
  1069)     if ( .not. times_found ) then
  1070)        if (masterproc) then
  1071)           write(iulog,*)'FIND_TIMES: Failed to find dates bracketing desired time =', time
  1072)           write(iulog,*)' datatimem = ',file%datatimem
  1073)           write(iulog,*)' datatimep = ',file%datatimep
  1074)           write(iulog,*)' all_data_times = ',all_data_times
  1075)           !call endrun()
  1076)           return
  1077)        endif
  1078)     endif
  1079) 
  1080)     deallocate( all_data_times, stat=astat )
  1081)     if( astat/= 0 ) then
  1082)        write(iulog,*) 'find_times: failed to deallocate all_data_times array; error = ',astat
  1083)        call endrun
  1084)     end if
  1085)   
  1086)     if ( .not. file%cyclical ) then
  1087)       itms(1) = n
  1088)       itms(2) = np1
  1089)     else
  1090)       itms(1) = n   +file%cyc_ndx_beg-1
  1091)       itms(2) = np1 +file%cyc_ndx_beg-1
  1092)     endif
  1093) 
  1094)     fids(:) = file%curr_fileid
  1095) 
  1096)     do i=1,2
  1097)        if ( itms(i) > curr_tsize ) then 
  1098)           itms(i) = itms(i) - curr_tsize 
  1099)           fids(i) = file%next_fileid
  1100)        endif
  1101)     enddo
  1102) 
  1103)   end subroutine find_times
  1104) 
  1105) !------------------------------------------------------------------------
  1106) !------------------------------------------------------------------------
  1107)   subroutine read_next_trcdata(state, flds, file )
  1108)     
  1109)     use shr_const_mod, only:pi => shr_const_pi
  1110)     use physics_types,only : physics_state
  1111)     use ppgrid,           only: pcols, pver, pverp,begchunk,endchunk
  1112)     use physconst,        only: rair
  1113)     use scamMod
  1114)     use rad_constituents, only: rad_cnst_get_info, rad_cnst_get_aer_props, &
  1115)                             rad_cnst_get_mode_props, rad_cnst_get_mode_num
  1116)     
  1117)     implicit none
  1118) 
  1119)     type (trfile), intent(inout) :: file
  1120)     type (trfld),intent(inout) :: flds(:)
  1121)     type(physics_state), intent(in)    :: state(begchunk:endchunk)
  1122)     
  1123)     integer :: recnos(4),i,f,nflds      ! 
  1124)     integer :: cnt4(4)            ! array of counts for each dimension
  1125)     integer :: strt4(4)           ! array of starting indices
  1126)     integer :: cnt3(3)            ! array of counts for each dimension
  1127)     integer :: strt3(3)           ! array of starting indices
  1128)     type(file_desc_t) :: fids(4)
  1129)     logical :: times_found 
  1130) 
  1131)     integer :: cur_yr, cur_mon, cur_day, cur_sec, yr1, yr2, mon, date, sec
  1132)     real(r8) :: series1_time, series2_time
  1133)     type(file_desc_t) :: fid1, fid2
  1134)    
  1135)     integer :: nspec,nmodes,n,ii,kk,l1,k,lchnk
  1136)     real(r8) :: profile_p(pver),pp(pver),meanP,meanO,sumii,volfrac,specdens,aero_den(6)
  1137)     real(r8) :: q_a(3,6)
  1138)     real(r8) :: rho(pcols,pver)        ! air density (kg m-3)
  1139)     character(len=20) :: aername
  1140)     character(len=3) :: arnam(7) = (/'so4','pom','soa','bc ','dst','ncl','num'/)
  1141) 
  1142)     nflds = size(flds)
  1143)     times_found = .false.
  1144) 
  1145)     if(single_column .and. scm_observed_aero) then
  1146) 
  1147)       call ver_profile_aero(pp)
  1148)       ! The following do loop gets the species properties and calculates the aerosol
  1149)       ! mass mixing ratio of each species from observed total number and size distribution
  1150)       ! properties in the unit kg/m^3 for the 3 modes. Data is read from the forcing file.
  1151)       ! For mode 1 (accumulation mode) q_a(1,1)=q(so4),q_a(1,2)=q(pom),q_a(1,3)=q(soa),
  1152)       ! q_a(1,4)=q(bc),q_a(1,5)=q(dst),q_a(1,6)=q(ncl).
  1153)       ! For mode 2 (aitken mode) q_a(2,1)=q(so4),q_a(2,2)=q(soa),q_a(2,3)=q(ncl).
  1154)       ! For mode 3 (coarse mode) q_a(3,1)=q(dst),q_a(3,2)=q(ncl),q_a(3,3)=q(so4).
  1155) 
  1156)       call rad_cnst_get_info(0, nmodes=nmodes)
  1157)       do n=1, nmodes
  1158)         call rad_cnst_get_info(0, n, nspec=nspec)
  1159)         do l1 = 1, nspec
  1160)           call rad_cnst_get_aer_props(0, n,l1,density_aer=specdens)
  1161)           call rad_cnst_get_aer_props(0, n, l1, aername=aername)
  1162)           aero_den(l1)=specdens
  1163)           q_a(n,l1) = specdens*scm_div(n,l1)*scm_num(n)*((pi/6.0_r8)*( &
  1164)                       scm_dgnum(n)**3)*exp(4.5_r8*(log(scm_std(n))**2) )) 
  1165)         enddo
  1166)       enddo
  1167)       
  1168)       do k = 1, pver
  1169)         do ii = 1, state(begchunk)%ncol
  1170)           rho(ii,k) = state(begchunk)%pmid(ii,k)/(rair*state(begchunk)%t(ii,k))
  1171)         enddo
  1172)       enddo
  1173)     end if
  1174) 
  1175)     do while( .not. times_found )
  1176)       call find_times( recnos, fids, file%curr_mod_time,file,file%datatimem,file%datatimep, times_found )
  1177)       if ( .not. times_found ) then
  1178)         call check_files( file, fids, recnos, times_found )
  1179)       endif
  1180)     enddo
  1181) 
  1182)     ! If single column do not interpolate aerosol data, just use the step function. 
  1183)     !   The exception is if we are trying to "replay" a column from the full model
  1184)     if(single_column .and. .not. use_replay) then
  1185)       file%stepTime = .true.
  1186)     endif
  1187) 
  1188)     if (file%stepTime) then
  1189)        file%interp_recs = 1
  1190)     else
  1191)        file%interp_recs = 2
  1192)     end if
  1193) 
  1194)     if ( file%fill_in_months ) then
  1195) 
  1196)        if( file%datatimep-file%datatimem > file%one_yr ) then
  1197) 
  1198)           call get_curr_date(cur_yr, cur_mon, cur_day, cur_sec)
  1199) 
  1200)           call set_date_from_time_float(file%datatimem, yr1, mon, date, sec )
  1201)           call set_date_from_time_float(file%datatimep, yr2, mon, date, sec )
  1202) 
  1203)           call set_time_float_from_date( series1_time, yr1, cur_mon, cur_day, cur_sec )
  1204)           call set_time_float_from_date( series2_time, yr2, cur_mon, cur_day, cur_sec )
  1205) 
  1206)           fid1 = fids(1)
  1207)           fid2 = fids(2)
  1208)           file%cyclical = .true.
  1209)           call set_cycle_indices( fid1, file%cyc_ndx_beg, file%cyc_ndx_end, yr1)
  1210)           call find_times( recnos(1:2), fids(1:2), series1_time, file, file%datatimes(1), file%datatimes(2), times_found )
  1211) 
  1212)           if ( .not. times_found ) then
  1213)               call endrun('read_next_trcdata: time not found for series1_time')
  1214)           endif
  1215)           call set_cycle_indices( fid2, file%cyc_ndx_beg, file%cyc_ndx_end, yr2)
  1216) 
  1217)           if ( fid1%fh /= fid2%fh ) then
  1218)             file%cyc_ndx_beg = file%cyc_ndx_beg + size(file%curr_data_times)
  1219)             file%cyc_ndx_end = file%cyc_ndx_end + size(file%curr_data_times)
  1220)           endif
  1221)           call find_times( recnos(3:4), fids(3:4), series2_time, file, file%datatimes(3), file%datatimes(4), times_found )
  1222)           if ( .not. times_found ) then
  1223)               call endrun('read_next_trcdata: time not found for series2_time')
  1224)           endif
  1225)           file%cyclical = .false.
  1226)           file%interp_recs = 4
  1227) 
  1228)           call set_date_from_time_float( file%datatimes(1), yr1, mon, date, sec )
  1229)           call set_time_float_from_date( file%datatimem, cur_yr,  mon, date, sec )
  1230)           if (file%datatimes(1) > file%datatimes(2) ) then ! wrap around
  1231)             if ( cur_mon == 1 ) then 
  1232)                call set_time_float_from_date( file%datatimem, cur_yr-1,  mon, date, sec )
  1233)             endif 
  1234)           endif
  1235) 
  1236)           call set_date_from_time_float( file%datatimes(2), yr1, mon, date, sec )
  1237)           call set_time_float_from_date( file%datatimep, cur_yr,  mon, date, sec )
  1238)           if (file%datatimes(1) > file%datatimes(2) ) then ! wrap around
  1239)             if ( cur_mon == 12 ) then
  1240)               call set_time_float_from_date( file%datatimep, cur_yr+1,  mon, date, sec )
  1241)             endif 
  1242)           endif
  1243) 
  1244)        endif
  1245) 
  1246)     endif
  1247) 
  1248)     !
  1249)     ! Set up hyperslab corners
  1250)     !
  1251)     strt4(:) = 1
  1252)     strt3(:) = 1
  1253) 
  1254)     do i=1,file%interp_recs
  1255) 
  1256)        do f = 1,nflds
  1257)           if ( file%zonal_ave ) then
  1258)              cnt3(flds(f)%coords(ZA_LATDIM)) = file%nlat
  1259)              if (flds(f)%srf_fld) then
  1260)                 cnt3(flds(f)%coords(ZA_LEVDIM)) = 1
  1261)              else
  1262)                 cnt3(flds(f)%coords(ZA_LEVDIM)) = file%nlev
  1263)              endif
  1264)              cnt3(flds(f)%coords(ZA_TIMDIM)) = 1
  1265)              strt3(flds(f)%coords(ZA_TIMDIM)) = recnos(i)
  1266)              call read_za_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt3, cnt3, file, &
  1267)                   (/ flds(f)%order(ZA_LATDIM),flds(f)%order(ZA_LEVDIM) /) )
  1268)           else if ( flds(f)%srf_fld ) then
  1269)              cnt3( flds(f)%coords(LONDIM)) = file%nlon
  1270)              cnt3( flds(f)%coords(LATDIM)) = file%nlat
  1271)              cnt3( flds(f)%coords(PS_TIMDIM)) = 1
  1272)              strt3(flds(f)%coords(PS_TIMDIM)) = recnos(i)
  1273)              call read_2d_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data(:,1,:), strt3, cnt3, file, &
  1274)                  (/ flds(f)%order(LONDIM),flds(f)%order(LATDIM) /) )
  1275)           else
  1276)              cnt4(flds(f)%coords(LONDIM)) = file%nlon
  1277)              cnt4(flds(f)%coords(LATDIM)) = file%nlat
  1278)              cnt4(flds(f)%coords(LEVDIM)) = file%nlev
  1279)              cnt4(flds(f)%coords(TIMDIM)) = 1
  1280)              strt4(flds(f)%coords(TIMDIM)) = recnos(i)
  1281)              call read_3d_trc( fids(i), flds(f)%var_id, flds(f)%input(i)%data, strt4, cnt4, file, &
  1282)                   (/ flds(f)%order(LONDIM),flds(f)%order(LATDIM),flds(f)%order(LEVDIM) /))
  1283) 
  1284)              !
  1285)              ! This section sets the observed aersol mass and number mixing ratios in the
  1286)              ! appropriate variables. The observed aerosol inforamtion is read from the
  1287)              ! forcing file as total number and size distribution parameters. Then the total 
  1288)              ! volume is calculated.Using the desnsity of each species, the mass is calculated. 
  1289)              ! Finally the number is partition among the each species using the species fraction 
  1290)              ! data read from the forcing file.  
  1291)              !
  1292)              if(single_column .and. scm_observed_aero) then
  1293)                 kk=index(trim(flds(f)%fldnam),'_')-1
  1294)                 if(index(trim(flds(f)%fldnam),'1') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then
  1295)                      if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1296)                            call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, &
  1297)                                 rho,pp,q_a(1,1),state(begchunk)%ncol)
  1298)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(2).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1299)                            call replace_aero_data(flds(f)%fldnam,arnam(2),flds(f)%input(i)%data, &
  1300)                                 rho,pp,q_a(1,2),state(begchunk)%ncol)
  1301)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(3).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1302)                            call replace_aero_data(flds(f)%fldnam,arnam(3),flds(f)%input(i)%data, &
  1303)                                rho,pp,q_a(1,3),state(begchunk)%ncol)
  1304)                     elseif(flds(f)%fldnam(1:kk).eq.arnam(4).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1305)                            call replace_aero_data(flds(f)%fldnam,arnam(4),flds(f)%input(i)%data, &
  1306)                                 rho,pp,q_a(1,4),state(begchunk)%ncol)
  1307)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(5).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1308)                            call replace_aero_data(flds(f)%fldnam,arnam(5),flds(f)%input(i)%data, &
  1309)                                 rho,pp,q_a(1,5),state(begchunk)%ncol)
  1310)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1311)                            call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, &
  1312)                                 rho,pp,q_a(1,6),state(begchunk)%ncol)
  1313)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1314)                            call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, &
  1315)                                 rho,pp,scm_num(1),state(begchunk)%ncol)
  1316)                      endif
  1317)                 elseif(index(trim(flds(f)%fldnam),'2') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then
  1318)                      if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1319)                            call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, &
  1320)                                 rho,pp,q_a(2,1),state(begchunk)%ncol)
  1321)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(3).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1322)                            call replace_aero_data(flds(f)%fldnam,arnam(3),flds(f)%input(i)%data, &
  1323)                                rho,pp,q_a(2,2),state(begchunk)%ncol)
  1324)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1325)                            call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, &
  1326)                                 rho,pp,q_a(2,3),state(begchunk)%ncol)
  1327)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1328)                            call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, &
  1329)                                 rho,pp,scm_num(2),state(begchunk)%ncol)
  1330)                      endif
  1331)                 elseif(index(trim(flds(f)%fldnam),'3') > 0 .and.index(trim(flds(f)%fldnam),'log') < 1) then
  1332)                      if(flds(f)%fldnam(1:kk).eq.arnam(1).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1333)                            call replace_aero_data(flds(f)%fldnam,arnam(1),flds(f)%input(i)%data, &
  1334)                                 rho,pp,q_a(3,3),state(begchunk)%ncol)
  1335)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(5).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1336)                            call replace_aero_data(flds(f)%fldnam,arnam(5),flds(f)%input(i)%data, &
  1337)                                 rho,pp,q_a(3,1),state(begchunk)%ncol)
  1338)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(6).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1339)                            call replace_aero_data(flds(f)%fldnam,arnam(6),flds(f)%input(i)%data, &
  1340)                                 rho,pp,q_a(3,2),state(begchunk)%ncol)
  1341)                      elseif(flds(f)%fldnam(1:kk).eq.arnam(7).and.index(trim(flds(f)%fldnam),'log') < 1) then
  1342)                            call replace_aero_data(flds(f)%fldnam,arnam(7),flds(f)%input(i)%data, &
  1343)                                 rho,pp,scm_num(3),state(begchunk)%ncol)
  1344)                      endif
  1345)                 endif 
  1346)              endif !scm_observed_aero
  1347)           endif
  1348) 
  1349)        enddo
  1350) 
  1351)        if ( file%has_ps ) then
  1352)           cnt3(file%ps_coords(LONDIM)) = file%nlon
  1353)           cnt3(file%ps_coords(LATDIM)) = file%nlat
  1354)           cnt3(file%ps_coords(PS_TIMDIM)) = 1
  1355)           strt3(file%ps_coords(PS_TIMDIM)) = recnos(i)
  1356)           call read_2d_trc( fids(i), file%ps_id, file%ps_in(i)%data, strt3, cnt3, file, &
  1357)                (/ file%ps_order(LONDIM),file%ps_order(LATDIM) /) )
  1358)        endif
  1359) 
  1360)     enddo
  1361) 
  1362)   end subroutine read_next_trcdata
  1363) 
  1364) !--------------------------------------------------------------------------------
  1365) !This subroutine replaces the climatological aerosol information by the observed
  1366) !once after they are read
  1367) !
  1368)    subroutine   replace_aero_data(aerofulnam,spnam,aero_q_data,rho,pp,q_mix,ncoli)
  1369)          use ppgrid,           only:  pcols,pver,begchunk,endchunk
  1370)          
  1371)          implicit none
  1372)          real(r8), intent(inout) :: aero_q_data(pcols,pver,begchunk:endchunk)
  1373)          real(r8), intent(in) :: rho(pcols,pver),pp(pver) 
  1374)          real(r8) :: sumii,meanO
  1375)          real(r8), intent(in) :: q_mix
  1376)          character(len=32),intent(in) ::aerofulnam
  1377)          character(len=3),intent(in) :: spnam
  1378)          character(len=32) ::aerosubnam
  1379)          integer, intent(in) :: ncoli 
  1380)          integer :: ii,k,countj
  1381)                
  1382)                 if(trim(aerofulnam(1:2)).eq.'bc') then
  1383)                   aerosubnam=aerofulnam(1:4)
  1384)                 else
  1385)                   aerosubnam=aerofulnam(1:5)
  1386)                 endif
  1387)            
  1388)            if((trim(aerosubnam).eq.(trim(spnam)//'_a').or.trim(aerosubnam).eq.(trim(spnam)//'_c')) &
  1389)                .and.index(trim(aerofulnam),'log') < 1) then
  1390) 
  1391)                      aero_q_data=q_mix
  1392)                    sumii=0._r8
  1393)                    countj =0
  1394)                   do ii = 1, ncoli
  1395)                     do k = 1, pver
  1396)                       if(pp(k).gt.0._r8) then
  1397)                         countj=countj+1
  1398)                       endif
  1399)                       if(trim(spnam).ne.'num') then
  1400)                           aero_q_data(ii,k,begchunk)=(aero_q_data(ii,k,begchunk)*pp(k)) /rho(ii,k)
  1401)                       endif
  1402)                          sumii=sumii + aero_q_data(ii,k,begchunk)
  1403)                     enddo
  1404)                   enddo
  1405)                    meanO=sumii/countj
  1406)                   do k = 1, pver
  1407)                     if(meanO.ne.0.) then
  1408)                           aero_q_data(1,k,begchunk)=pp(k)*meanO
  1409)                      else                 
  1410)                         aero_q_data(1,k,begchunk)=0._r8
  1411)                     endif
  1412)                   enddo
  1413)               endif
  1414) 
  1415)    end subroutine replace_aero_data
  1416)    
  1417) !---------------------------------------------------------------------------
  1418) !This subroutine generates a heavyside type profiles for the observed aerosol.
  1419) !This setting is constant profile in the lower atmosphere and then exponentially 
  1420) !decreasing to zero at the top of the atmosphere. The level of initial decay is 
  1421) !controlled by "initial_val". Larger than -3.5 pushes the decay point up and smaller 
  1422) !brings it closer to the surface.
  1423) !   
  1424)    subroutine ver_profile_aero(vertprof_aero)
  1425)               use mo_constants, only : pi
  1426)               use ppgrid,       only:  pcols,pver
  1427)          
  1428)          implicit none
  1429)          real(r8), intent(inout) :: vertprof_aero(pver)
  1430)          real(r8) :: initial_val = -3.5_r8
  1431)          integer :: k
  1432)             
  1433)          do k=1,pver
  1434)            if(k==1) then
  1435)              vertprof_aero(k)=0._r8
  1436)            elseif(k==2) then
  1437)              vertprof_aero(k)=1._r8/(1._r8 + exp(-2._r8*initial_val * pi)) 
  1438)            else
  1439)              vertprof_aero(k)=1._r8/(1._r8 + exp(-2._r8*(initial_val * pi + pi/4._r8*(k-2)))) 
  1440)            endif
  1441)          enddo 
  1442)    end subroutine ver_profile_aero
  1443) 
  1444) !------------------------------------------------------------------------
  1445) 
  1446) 
  1447)   subroutine read_2d_trc( fid, vid, loc_arr, strt, cnt, file, order )
  1448)     use interpolate_data,  only : lininterp_init, lininterp, interp_type, lininterp_finish
  1449) 
  1450)     use phys_grid,    only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p, get_lon_all_p, get_lat_all_p 
  1451)     use mo_constants, only : pi
  1452)     use dycore,       only: dycore_is		
  1453)     use polar_avg,    only: polar_average
  1454)     use horizontal_interpolate, only : xy_interp
  1455) 
  1456)     implicit none
  1457)     type(file_desc_t), intent(in) :: fid
  1458)     type(var_desc_t), intent(in) :: vid
  1459)     integer, intent(in) :: strt(:), cnt(:), order(2)
  1460)     real(r8),intent(out)  :: loc_arr(:,:)
  1461)     type (trfile), intent(in) :: file
  1462) 
  1463)     real(r8) :: to_lats(pcols), to_lons(pcols), wrk(pcols)
  1464)     real(r8), allocatable, target :: wrk2d(:,:)
  1465)     real(r8), pointer :: wrk2d_in(:,:)
  1466) 
  1467)     integer :: tsize, c, i, j, ierr, ncols
  1468)     real(r8), parameter :: zero=0_r8, twopi=2_r8*pi
  1469)     type(interp_type) :: lon_wgts, lat_wgts    
  1470)     integer :: lons(pcols), lats(pcols)
  1471) 
  1472)      nullify(wrk2d_in)
  1473)      allocate( wrk2d(cnt(1),cnt(2)), stat=ierr )
  1474)      if( ierr /= 0 ) then
  1475)         write(iulog,*) 'read_2d_trc: wrk2d allocation error = ',ierr
  1476)         call endrun
  1477)      end if
  1478) 
  1479)      if(order(1)/=1 .or. order(2)/=2 .or. cnt(1)/=file%nlon .or. cnt(2)/=file%nlat) then
  1480)         allocate( wrk2d_in(file%nlon, file%nlat), stat=ierr )
  1481)         if( ierr /= 0 ) then
  1482)            write(iulog,*) 'read_2d_trc: wrk2d_in allocation error = ',ierr
  1483)            call endrun
  1484)         end if
  1485)      end if
  1486) 
  1487) 
  1488)     ierr = pio_get_var( fid, vid, strt, cnt, wrk2d )
  1489)     if(associated(wrk2d_in)) then
  1490)        wrk2d_in = reshape( wrk2d(:,:),(/file%nlon,file%nlat/), order=order )
  1491)        deallocate(wrk2d)
  1492)     else
  1493)        wrk2d_in => wrk2d
  1494)     end if
  1495) 
  1496)     j=1
  1497) 
  1498) ! if weighting by latitude, the perform horizontal interpolation by using weight_x, weight_y
  1499) 
  1500)    if(file%weight_by_lat) then
  1501) 
  1502)       call t_startf('xy_interp')
  1503) 
  1504)       do c = begchunk,endchunk
  1505)         ncols = get_ncols_p(c)
  1506)         call get_lon_all_p(c,ncols,lons)
  1507)         call get_lat_all_p(c,ncols,lats)
  1508) 
  1509)         call xy_interp(file%nlon,file%nlat,1,plon,plat,pcols,ncols,file%weight_x,file%weight_y,wrk2d_in,loc_arr(:,c-begchunk+1),  &
  1510)                             lons,lats,file%count_x,file%count_y,file%index_x,file%index_y) 
  1511)       enddo
  1512) 
  1513)       call t_stopf('xy_interp')
  1514) 
  1515)     else
  1516)       do c=begchunk,endchunk
  1517)         ncols = get_ncols_p(c)
  1518)         call get_rlat_all_p(c, pcols, to_lats)
  1519)         call get_rlon_all_p(c, pcols, to_lons)
  1520) 
  1521)         call lininterp_init(file%lons, file%nlon, to_lons, ncols, 2, lon_wgts, zero, twopi)
  1522)         call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts)
  1523) 
  1524)         call lininterp(wrk2d_in, file%nlon, file%nlat, loc_arr(1:ncols,c-begchunk+1), ncols, lon_wgts, lat_wgts)    
  1525)        
  1526)         call lininterp_finish(lon_wgts)
  1527)         call lininterp_finish(lat_wgts)
  1528)       end do
  1529)     endif
  1530) 
  1531)     if(allocated(wrk2d)) then
  1532)        deallocate(wrk2d)
  1533)     else
  1534)        deallocate(wrk2d_in)
  1535)     end if
  1536)     if(dycore_is('LR')) call polar_average(loc_arr)
  1537)   end subroutine read_2d_trc
  1538) 
  1539) !------------------------------------------------------------------------
  1540) 
  1541)   subroutine read_za_trc( fid, vid, loc_arr, strt, cnt, file, order )
  1542)     use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish
  1543)     use phys_grid,        only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p	
  1544)     use mo_constants,     only : pi
  1545)     use dycore,           only : dycore_is		
  1546)     use polar_avg,        only : polar_average
  1547) 
  1548)     implicit none
  1549)     type(file_desc_t), intent(in) :: fid
  1550)     type(var_desc_t),  intent(in) :: vid
  1551)     integer,           intent(in) :: strt(:), cnt(:)
  1552)     integer,           intent(in) :: order(2)
  1553)     real(r8),          intent(out):: loc_arr(:,:,:)
  1554)     type (trfile),     intent(in) :: file
  1555) 
  1556)     type(interp_type) :: lat_wgts
  1557)     real(r8) :: to_lats(pcols), to_lons(pcols), wrk(pcols)
  1558)     real(r8), allocatable, target :: wrk2d(:,:)
  1559)     real(r8), pointer :: wrk2d_in(:,:)
  1560)     integer :: c, k, ierr, ncols
  1561) 
  1562)      nullify(wrk2d_in)
  1563)      allocate( wrk2d(cnt(1),cnt(2)), stat=ierr )
  1564)      if( ierr /= 0 ) then
  1565)         write(iulog,*) 'read_2d_trc: wrk2d allocation error = ',ierr
  1566)         call endrun
  1567)      end if
  1568) 
  1569)      if(order(1)/=1 .or. order(2)/=2 .or. cnt(1)/=file%nlat .or. cnt(2)/=file%nlev) then
  1570)         allocate( wrk2d_in(file%nlat, file%nlev), stat=ierr )
  1571)         if( ierr /= 0 ) then
  1572)            write(iulog,*) 'read_2d_trc: wrk2d_in allocation error = ',ierr
  1573)            call endrun
  1574)         end if
  1575)      end if
  1576) 
  1577) 
  1578)     ierr = pio_get_var( fid, vid, strt, cnt, wrk2d )
  1579)     if(associated(wrk2d_in)) then
  1580)        wrk2d_in = reshape( wrk2d(:,:),(/file%nlat,file%nlev/), order=order )
  1581)        deallocate(wrk2d)
  1582)     else
  1583)        wrk2d_in => wrk2d
  1584)     end if
  1585) 
  1586)     do c=begchunk,endchunk
  1587)        ncols = get_ncols_p(c)
  1588)        call get_rlat_all_p(c, pcols, to_lats)
  1589) 
  1590)        call lininterp_init(file%lats, file%nlat, to_lats, ncols, 1, lat_wgts)
  1591)        do k=1,file%nlev
  1592)           call lininterp(wrk2d_in(:,k), file%nlat, wrk(1:ncols), ncols, lat_wgts)    
  1593)           loc_arr(1:ncols,k,c-begchunk+1) = wrk(1:ncols)
  1594)        end do
  1595)        call lininterp_finish(lat_wgts)
  1596)     end do
  1597) 
  1598)     if(allocated(wrk2d)) then
  1599)        deallocate(wrk2d)
  1600)     else
  1601)        deallocate(wrk2d_in)
  1602)     end if
  1603) !    if(dycore_is('LR')) call polar_average(loc_arr)
  1604)   end subroutine read_za_trc
  1605) 
  1606) !------------------------------------------------------------------------
  1607) 
  1608)   subroutine read_3d_trc( fid, vid, loc_arr, strt, cnt, file, order)
  1609)     use interpolate_data, only : lininterp_init, lininterp, interp_type, lininterp_finish
  1610)     use phys_grid,        only : pcols, begchunk, endchunk, get_ncols_p, get_rlat_all_p, get_rlon_all_p, get_lon_all_p,&
  1611)                                  get_lat_all_p 
  1612)     use mo_constants,     only : pi
  1613)     use dycore,           only : dycore_is		
  1614)     use polar_avg,        only : polar_average
  1615)     use dycore,           only  : dycore_is
  1616)     use horizontal_interpolate, only : xy_interp
  1617) 
  1618)     implicit none
  1619) 
  1620)     type(file_desc_t), intent(in) :: fid
  1621)     type(var_desc_t), intent(in) :: vid
  1622)     integer, intent(in) :: strt(:), cnt(:), order(3)
  1623)     real(r8),intent(out)  :: loc_arr(:,:,:)
  1624)     
  1625)     type (trfile), intent(in) :: file
  1626) 
  1627)     integer :: i,j,k, astat, c, ncols
  1628)     integer :: lons(pcols), lats(pcols)
  1629) 
  1630)     integer                     :: jlim(2), jl, ju, ierr
  1631)     integer                     :: gndx
  1632) 
  1633)     real(r8), allocatable, target :: wrk3d(:,:,:)
  1634)     real(r8), pointer :: wrk3d_in(:,:,:)
  1635)     real(r8) :: to_lons(pcols), to_lats(pcols)
  1636)     real(r8), parameter :: zero=0_r8, twopi=2_r8*pi
  1637)     type(interp_type) :: lon_wgts, lat_wgts    
  1638) 
  1639)     loc_arr(:,:,:) = 0._r8
  1640)     nullify(wrk3d_in)
  1641)     allocate(wrk3d(cnt(1),cnt(2),cnt(3)), stat=ierr)
  1642)     if( ierr /= 0 ) then
  1643)        write(iulog,*) 'read_3d_trc: wrk3d allocation error = ',ierr
  1644)        call endrun
  1645)     end if
  1646) 
  1647)     ierr = pio_get_var( fid, vid, strt, cnt, wrk3d )
  1648) 
  1649)     if(order(1)/=1 .or. order(2)/=2 .or. order(3)/=3 .or. &
  1650)          cnt(1)/=file%nlon.or.cnt(2)/=file%nlat.or.cnt(3)/=file%nlev) then
  1651)        allocate(wrk3d_in(file%nlon,file%nlat,file%nlev),stat=ierr)
  1652)        if( ierr /= 0 ) then
  1653)           write(iulog,*) 'read_3d_trc: wrk3d allocation error = ',ierr
  1654)           call endrun
  1655)        end if
  1656)        wrk3d_in = reshape( wrk3d(:,:,:),(/file%nlon,file%nlat,file%nlev/), order=order )
  1657)        deallocate(wrk3d)
  1658)     else
  1659)        wrk3d_in => wrk3d
  1660)     end if
  1661) 
  1662)     j=1
  1663) 
  1664) ! If weighting by latitude, then perform horizontal interpolation by using weight_x, weight_y
  1665) 
  1666)    if(file%weight_by_lat) then
  1667) 
  1668)      call t_startf('xy_interp')
  1669) 
  1670)      do c = begchunk,endchunk
  1671)         ncols = get_ncols_p(c)
  1672)         call get_lon_all_p(c,ncols,lons)
  1673)         call get_lat_all_p(c,ncols,lats)
  1674) 
  1675)         call xy_interp(file%nlon,file%nlat,file%nlev,plon,plat,pcols,ncols,file%weight_x,file%weight_y,wrk3d_in, &
  1676)              loc_arr(:,:,c-begchunk+1), lons,lats,file%count_x,file%count_y,file%index_x,file%index_y) 
  1677)      enddo
  1678) 
  1679)      call t_stopf('xy_interp')
  1680) 
  1681)    else
  1682)     do c=begchunk,endchunk
  1683)        ncols = get_ncols_p(c)
  1684)        call get_rlat_all_p(c, pcols, to_lats)
  1685)        call get_rlon_all_p(c, pcols, to_lons)
  1686) 
  1687)        call lininterp_init(file%lons, file%nlon, to_lons(1:ncols), ncols, 2, lon_wgts, zero, twopi)
  1688)        call lininterp_init(file%lats, file%nlat, to_lats(1:ncols), ncols, 1, lat_wgts)
  1689) 
  1690) 
  1691)        call lininterp(wrk3d_in, file%nlon, file%nlat, file%nlev, loc_arr(:,:,c-begchunk+1), ncols, pcols, lon_wgts, lat_wgts)    	
  1692) 
  1693) 
  1694)        call lininterp_finish(lon_wgts)
  1695)        call lininterp_finish(lat_wgts)
  1696)     end do
  1697)    endif
  1698) 
  1699)     if(allocated(wrk3d)) then
  1700)        deallocate( wrk3d, stat=astat )
  1701)     else
  1702)        deallocate( wrk3d_in, stat=astat )
  1703)     end if
  1704)     if( astat/= 0 ) then
  1705)        write(iulog,*) 'read_3d_trc: failed to deallocate wrk3d array; error = ',astat
  1706)        call endrun
  1707)     endif
  1708)     if(dycore_is('LR')) call polar_average(file%nlev, loc_arr)
  1709)   end subroutine read_3d_trc
  1710) 
  1711) !------------------------------------------------------------------------------
  1712) 
  1713)   subroutine interpolate_trcdata( state, flds, file, pbuf2d )
  1714)     use mo_util,      only : rebin
  1715)     use physics_types,only : physics_state
  1716)     use physconst,    only : cday
  1717)     use physics_buffer, only : physics_buffer_desc, pbuf_get_field
  1718) 
  1719)     implicit none
  1720) 
  1721)     type(physics_state), intent(in) :: state(begchunk:endchunk)                 
  1722)     type (trfld),        intent(inout) :: flds(:)
  1723)     type (trfile),       intent(inout) :: file
  1724)     
  1725)     type(physics_buffer_desc), optional, pointer :: pbuf2d(:,:)
  1726) 
  1727) 
  1728)     real(r8) :: fact1, fact2
  1729)     real(r8) :: deltat
  1730)     integer :: f,nflds,c,ncol, i,k
  1731)     real(r8) :: ps(pcols)
  1732)     real(r8) :: datain(pcols,file%nlev)
  1733)     real(r8) :: pin(pcols,file%nlev)
  1734)     real(r8)            :: model_z(pverp)
  1735)     real(r8), parameter :: m2km  = 1.e-3_r8
  1736)     real(r8), pointer :: data_out3d(:,:,:)
  1737)     real(r8), pointer :: data_out(:,:)
  1738)     integer :: chnk_offset
  1739) 
  1740)     nflds = size(flds)
  1741) 
  1742)     if ( file%interp_recs == 4 ) then
  1743)        deltat = file%datatimes(3) - file%datatimes(1)
  1744)        fact1 = (file%datatimes(3) - file%datatimem)/deltat
  1745)        fact2 = 1._r8-fact1
  1746) !$OMP PARALLEL DO PRIVATE (C, NCOL, F)
  1747)        do c = begchunk,endchunk
  1748)           ncol = state(c)%ncol
  1749)           if ( file%has_ps ) then
  1750)              file%ps_in(1)%data(:ncol,c) = fact1*file%ps_in(1)%data(:ncol,c) + fact2*file%ps_in(3)%data(:ncol,c) 
  1751)           endif
  1752)           do f = 1,nflds
  1753)              flds(f)%input(1)%data(:ncol,:,c) = fact1*flds(f)%input(1)%data(:ncol,:,c) + fact2*flds(f)%input(3)%data(:ncol,:,c) 
  1754)           enddo
  1755)        enddo
  1756) 
  1757)        deltat = file%datatimes(4) - file%datatimes(2)
  1758)        fact1 = (file%datatimes(4) - file%datatimep)/deltat
  1759)        fact2 = 1._r8-fact1
  1760) 
  1761) !$OMP PARALLEL DO PRIVATE (C, NCOL, F)
  1762)        do c = begchunk,endchunk
  1763)           ncol = state(c)%ncol
  1764)           if ( file%has_ps ) then
  1765)              file%ps_in(2)%data(:ncol,c) = fact1*file%ps_in(2)%data(:ncol,c) + fact2*file%ps_in(4)%data(:ncol,c) 
  1766)           endif
  1767)           do f = 1,nflds
  1768)              flds(f)%input(2)%data(:ncol,:,c) = fact1*flds(f)%input(2)%data(:ncol,:,c) + fact2*flds(f)%input(4)%data(:ncol,:,c) 
  1769)           enddo
  1770)        enddo
  1771) 
  1772)     endif
  1773)     !-------------------------------------------------------------------------
  1774)     !       If file%interp_recs=1 then no time interpolation -- set
  1775)     !       fact1=1 and fact2=0 and will just use first value unmodified
  1776)     !-------------------------------------------------------------------------
  1777) 
  1778)     if (file%interp_recs == 1) then
  1779)        fact1=1._r8
  1780)        fact2=0._r8
  1781)     else
  1782)        file%interp_recs = 2
  1783) 
  1784)        deltat = file%datatimep - file%datatimem
  1785) 
  1786)        if ( file%cyclical .and. (deltat < 0._r8) ) then
  1787)           deltat = deltat+file%one_yr
  1788)           if ( file%datatimep >= file%curr_mod_time ) then
  1789)              fact1 = (file%datatimep - file%curr_mod_time)/deltat
  1790)           else
  1791)              fact1 = (file%datatimep+file%one_yr - file%curr_mod_time)/deltat
  1792)           endif
  1793)        else
  1794)              fact1 = (file%datatimep - file%curr_mod_time)/deltat
  1795)        endif
  1796) 
  1797)        ! this assures that FIXED data are b4b on restarts
  1798)        if ( file%fixed ) then
  1799)           fact1 = dble(int(fact1*cday+.5_r8))/dble(cday)
  1800)        endif
  1801)        fact2 = 1._r8-fact1
  1802)     endif
  1803) 
  1804)     chnk_offset=-begchunk+1
  1805) 
  1806)     fld_loop: do f = 1,nflds
  1807) 
  1808)        if (flds(f)%pbuf_ndx<=0) then
  1809)           data_out3d => flds(f)%data(:,:,:)
  1810)        endif
  1811) 
  1812) !$OMP PARALLEL DO PRIVATE (C, NCOL, PS, I, K, PIN, DATAIN, MODEL_Z, DATA_OUT)
  1813)        do c = begchunk,endchunk
  1814)           if (flds(f)%pbuf_ndx>0) then
  1815)              if(.not.present(pbuf2d)) then                
  1816)                 call endrun ('tracer_data.F90(subr interpolate_trcdata):' // &
  1817)                      'pbuf2d must be passed as an argument for pbuf_get_field subr call')
  1818)              endif
  1819)              call pbuf_get_field(pbuf2d, c, flds(f)%pbuf_ndx, data_out)
  1820)           else
  1821)              data_out => data_out3d(:,:,c+chnk_offset)
  1822)           endif
  1823)           ncol = state(c)%ncol
  1824)           if (file%alt_data) then
  1825) 
  1826)              if (fact2 == 0) then  ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps)
  1827)                 datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c)
  1828)              else
  1829)                 datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) + fact2*flds(f)%input(np)%data(:ncol,:,c) 
  1830)              end if
  1831)              do i = 1,ncol
  1832)                 model_z(1:pverp) = m2km * state(c)%zi(i,pverp:1:-1)
  1833)                 call rebin( file%nlev, pver, file%ilevs, model_z, datain(i,:), data_out(i,:) )
  1834)              enddo
  1835) 
  1836)           else
  1837) 
  1838)              if ( file%nlev>1 ) then
  1839)                 if ( file%has_ps ) then
  1840)                    if (fact2 == 0) then  ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps)
  1841)                       ps(:ncol) = fact1*file%ps_in(nm)%data(:ncol,c)
  1842)                    else
  1843)                       ps(:ncol) = fact1*file%ps_in(nm)%data(:ncol,c) + fact2*file%ps_in(np)%data(:ncol,c) 
  1844)                    end if
  1845)                    do i = 1,ncol
  1846)                       do k = 1,file%nlev
  1847)                          pin(i,k) = file%p0*file%hyam(k) + ps(i)*file%hybm(k)
  1848)                       enddo
  1849)                    enddo
  1850)                 else
  1851)                    do k = 1,file%nlev
  1852)                       pin(:,k) = file%levs(k)
  1853)                    enddo
  1854)                 endif
  1855)              endif
  1856) 
  1857)              if (flds(f)%srf_fld) then
  1858)                 do i = 1,ncol
  1859)                    if (fact2 == 0) then  ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps)
  1860)                       data_out(i,1) = &
  1861)                            fact1*flds(f)%input(nm)%data(i,1,c)
  1862)                    else
  1863)                       data_out(i,1) = &
  1864)                            fact1*flds(f)%input(nm)%data(i,1,c) + fact2*flds(f)%input(np)%data(i,1,c) 
  1865)                    endif
  1866)                 enddo
  1867)              else
  1868)                 if (fact2 == 0) then  ! This needed as %data is not set if fact2=0 (and lahey compiler core dumps)
  1869)                    datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c)
  1870)                 else
  1871)                    datain(:ncol,:) = fact1*flds(f)%input(nm)%data(:ncol,:,c) + fact2*flds(f)%input(np)%data(:ncol,:,c)
  1872)                 end if
  1873)                 if ( file%top_bndry ) then
  1874)                    call vert_interp_ub(ncol, file%nlev, file%levs,  datain(:ncol,:), data_out(:ncol,:) )
  1875)                 else if(file%conserve_column) then
  1876)                    call vert_interp_mixrat(ncol,file%nlev,pver,state(c)%pint, &
  1877)                         datain, data_out(:,:), &
  1878)                         file%p0,ps,file%hyai,file%hybi)
  1879)                 else
  1880)                    call vert_interp(ncol, file%nlev, pin, state(c)%pmid, datain, data_out(:,:) )
  1881)                 endif
  1882)              endif
  1883) 
  1884)           endif
  1885)        enddo
  1886) 
  1887)     enddo fld_loop
  1888) 
  1889)   end subroutine interpolate_trcdata
  1890) 
  1891) !-----------------------------------------------------------------------
  1892) !-----------------------------------------------------------------------
  1893)   subroutine get_dimension( fid, dname, dsize, dimid, data )
  1894)     implicit none
  1895)     type(file_desc_t), intent(inout) :: fid
  1896)     character(*), intent(in) :: dname
  1897)     integer, intent(out) :: dsize
  1898) 
  1899)     integer, optional, intent(out) :: dimid
  1900)     real(r8), optional, pointer, dimension(:) :: data
  1901) 
  1902)     integer :: vid, ierr, id
  1903) 
  1904)     call pio_seterrorhandling( fid, PIO_BCAST_ERROR)
  1905)     ierr = pio_inq_dimid( fid, dname, id )
  1906)     call pio_seterrorhandling( fid, PIO_INTERNAL_ERROR)
  1907) 
  1908)     if ( ierr==PIO_NOERR ) then
  1909) 
  1910)        ierr = pio_inq_dimlen( fid, id, dsize )
  1911) 
  1912)        if ( present(dimid) ) then
  1913)           dimid = id
  1914)        endif
  1915) 
  1916)        if ( present(data) ) then
  1917)           if ( associated(data) ) then
  1918)              deallocate(data, stat=ierr)
  1919)              if( ierr /= 0 ) then
  1920)                 write(iulog,*) 'get_dimension: data deallocation error = ',ierr
  1921)                 call endrun('get_dimension: failed to deallocate data array')
  1922)              end if
  1923)           endif
  1924)           allocate( data(dsize), stat=ierr )
  1925)           if( ierr /= 0 ) then
  1926)              write(iulog,*) 'get_dimension: data allocation error = ',ierr
  1927)              call endrun('get_dimension: failed to allocate data array')
  1928)           end if
  1929) 
  1930)           ierr =  pio_inq_varid( fid, dname, vid )
  1931)           ierr =  pio_get_var( fid, vid, data )
  1932)        endif
  1933)     else
  1934)        dsize = 1
  1935)        if ( present(dimid) ) then
  1936)           dimid = -1
  1937)        endif
  1938)     endif
  1939) 
  1940)   end subroutine get_dimension
  1941) 
  1942) !-----------------------------------------------------------------------
  1943) !-----------------------------------------------------------------------
  1944)   subroutine set_cycle_indices( fileid, cyc_ndx_beg, cyc_ndx_end, cyc_yr )
  1945) 
  1946)     implicit none
  1947) 
  1948)     type(file_desc_t), intent(inout)  :: fileid
  1949)     integer, intent(out) :: cyc_ndx_beg
  1950)     integer, intent(out) :: cyc_ndx_end
  1951)     integer, intent(in)  :: cyc_yr
  1952) 
  1953)     integer, allocatable , dimension(:) :: dates, datesecs
  1954)     integer :: timesize, i, astat, year, ierr
  1955)     type(var_desc_T) :: dateid
  1956)     call get_dimension( fileid, 'time', timesize )
  1957)     cyc_ndx_beg=-1
  1958) 
  1959)     allocate( dates(timesize), stat=astat  )
  1960)     if( astat/= 0 ) then
  1961)        write(*,*) 'set_cycle_indices: failed to allocate dates array; error = ',astat
  1962)        call endrun
  1963)     end if
  1964) 
  1965)     ierr = pio_inq_varid(   fileid, 'date',  dateid  )
  1966)     ierr = pio_get_var( fileid, dateid, dates )
  1967) 
  1968)     do i=1,timesize
  1969)        year = dates(i) / 10000
  1970)        if ( year == cyc_yr ) then
  1971)           if  (cyc_ndx_beg < 0)  then
  1972)              cyc_ndx_beg = i
  1973)           endif
  1974)           cyc_ndx_end = i
  1975)        endif
  1976)     enddo
  1977)     deallocate( dates, stat=astat  )
  1978)     if( astat/= 0 ) then
  1979)        write(*,*) 'set_cycle_indices: failed to deallocate dates array; error = ',astat
  1980)        call endrun
  1981)     end if
  1982)     if (cyc_ndx_beg < 0) then
  1983)        write(*,*) 'set_cycle_indices: cycle year not found : ' , cyc_yr
  1984)        call endrun('set_cycle_indices: cycle year not found')
  1985)     endif
  1986) 
  1987)   end subroutine set_cycle_indices
  1988) !-----------------------------------------------------------------------
  1989) 
  1990) !-----------------------------------------------------------------------
  1991)   subroutine open_trc_datafile( fname, path, piofile, times, cyc_ndx_beg, cyc_ndx_end, cyc_yr )
  1992) 
  1993)     use ioFileMod,     only: getfil
  1994)     use cam_pio_utils, only: cam_pio_openfile
  1995) 
  1996)     implicit none
  1997) 
  1998)     character(*), intent(in) :: fname
  1999)     character(*), intent(in) :: path
  2000)     type(file_desc_t), intent(inout) :: piofile
  2001)     real(r8), pointer :: times(:)
  2002) 
  2003)     integer, optional, intent(out) :: cyc_ndx_beg
  2004)     integer, optional, intent(out) :: cyc_ndx_end
  2005)     integer, optional, intent(in) :: cyc_yr
  2006) 
  2007)     character(len=shr_kind_cl) :: filen, filepath
  2008)     integer :: year, month, day, dsize, i, timesize
  2009)     integer :: dateid,secid
  2010)     integer, allocatable , dimension(:) :: dates, datesecs
  2011)     integer :: astat, ierr
  2012)     logical :: need_first_ndx
  2013) 
  2014)     if (len_trim(path) == 0) then
  2015)        filepath = trim(fname)
  2016)     else
  2017)        filepath = trim(path) // '/' // trim(fname)
  2018)     end if
  2019)     !
  2020)     ! open file and get fileid
  2021)     !
  2022)     call getfil( filepath, filen, 0 )
  2023)     call cam_pio_openfile( piofile, filen, PIO_NOWRITE)
  2024)     if(masterproc) write(iulog,*)'open_trc_datafile: ',trim(filen)
  2025) 
  2026)     call get_dimension(piofile, 'time', timesize)
  2027)     
  2028)     if ( associated(times) ) then
  2029)        deallocate(times, stat=ierr)
  2030)        if( ierr /= 0 ) then
  2031)           write(iulog,*) 'open_trc_datafile: data deallocation error = ',ierr
  2032)           call endrun('open_trc_datafile: failed to deallocate data array')
  2033)        end if
  2034)     endif
  2035)     allocate( times(timesize), stat=ierr )
  2036)     if( ierr /= 0 ) then
  2037)        write(iulog,*) 'open_trc_datafile: data allocation error = ',ierr
  2038)        call endrun('open_trc_datafile: failed to allocate data array')
  2039)     end if
  2040) 
  2041)     allocate( dates(timesize), stat=astat  )
  2042)     if( astat/= 0 ) then
  2043)        if(masterproc) write(iulog,*) 'open_trc_datafile: failed to allocate dates array; error = ',astat
  2044)        call endrun
  2045)     end if
  2046)     allocate( datesecs(timesize), stat=astat  )
  2047)     if( astat/= 0 ) then
  2048)        if(masterproc) write(iulog,*) 'open_trc_datafile: failed to allocate datesec array; error = ',astat
  2049)        call endrun
  2050)     end if
  2051) 
  2052)     ierr =  pio_inq_varid( piofile, 'date',    dateid  )
  2053)     call pio_seterrorhandling( piofile, PIO_BCAST_ERROR)
  2054)     ierr = pio_inq_varid( piofile, 'datesec', secid  )
  2055)     call pio_seterrorhandling( piofile, PIO_INTERNAL_ERROR)
  2056)     
  2057)     if(ierr==PIO_NOERR) then
  2058)        ierr = pio_get_var( piofile, secid,  datesecs  )
  2059)     else
  2060)        datesecs=0
  2061)     end if
  2062) 
  2063)     ierr =  pio_get_var( piofile, dateid, dates )
  2064)     need_first_ndx=.true.
  2065) 
  2066)     do i=1,timesize
  2067)        year = dates(i) / 10000
  2068)        month = mod(dates(i),10000)/100
  2069)        day = mod(dates(i),100)
  2070)        call set_time_float_from_date( times(i), year, month, day, datesecs(i) )
  2071)        if ( present(cyc_yr) ) then
  2072)           if ( year == cyc_yr ) then
  2073)              if ( present(cyc_ndx_beg) .and. need_first_ndx ) then
  2074)                 cyc_ndx_beg = i
  2075)                 need_first_ndx = .false.
  2076)              endif
  2077)              if ( present(cyc_ndx_end) ) then
  2078)                 cyc_ndx_end = i
  2079)              endif
  2080)           endif
  2081)        endif
  2082)     enddo
  2083) 
  2084)     deallocate( dates, stat=astat  )
  2085)     if( astat/= 0 ) then
  2086)        if(masterproc) write(iulog,*) 'open_trc_datafile: failed to deallocate dates array; error = ',astat
  2087)        call endrun
  2088)     end if
  2089)     deallocate( datesecs, stat=astat  )       
  2090)     if( astat/= 0 ) then
  2091)        if(masterproc) write(iulog,*) 'open_trc_datafile: failed to deallocate datesec array; error = ',astat
  2092)        call endrun
  2093)     end if
  2094)        
  2095)     if ( present(cyc_yr) .and. present(cyc_ndx_beg) ) then
  2096)        if (cyc_ndx_beg < 0) then
  2097)           write(iulog,*) 'open_trc_datafile: cycle year not found : ' , cyc_yr
  2098)           call endrun('open_trc_datafile: cycle year not found')
  2099)        endif
  2100)     endif
  2101) 
  2102)   end subroutine open_trc_datafile
  2103) 
  2104) !--------------------------------------------------------------------------
  2105) !--------------------------------------------------------------------------
  2106)   subroutine specify_fields( specifier, fields )
  2107) 
  2108)     implicit none
  2109) 
  2110)     character(len=*), intent(in) :: specifier(:)
  2111)     type(trfld), pointer, dimension(:) :: fields
  2112) 
  2113)     integer :: fld_cnt, astat
  2114)     integer :: i,j
  2115)     character(len=shr_kind_cl) :: str1, str2
  2116)     character(len=32), allocatable, dimension(:) :: fld_name,  src_name
  2117)     integer :: nflds
  2118) 
  2119)     nflds = size(specifier)
  2120) 
  2121)     allocate(fld_name(nflds),  src_name(nflds), stat=astat )
  2122)     if( astat/= 0 ) then
  2123)        write(iulog,*) 'specify_fields: failed to allocate fld_name, src_name arrays; error = ',astat
  2124)        call endrun
  2125)     end if
  2126) 
  2127)     fld_cnt = 0
  2128) 
  2129)     count_cnst: do i = 1, nflds
  2130) 
  2131)        if ( len_trim( specifier(i) ) == 0 ) then
  2132)           exit count_cnst
  2133)        endif
  2134) 
  2135)        j = scan( specifier(i),':')
  2136) 
  2137)        if (j > 0) then
  2138)           str1 = trim(adjustl( specifier(i)(:j-1) ))
  2139)           str2 = trim(adjustl( specifier(i)(j+1:) ))
  2140)           fld_name(i) = trim(adjustl( str1 ))
  2141)           src_name(i) = trim(adjustl( str2 ))
  2142)        else
  2143)           fld_name(i) = trim(adjustl( specifier(i) ))
  2144)           src_name(i) = trim(adjustl( specifier(i) ))
  2145)        endif
  2146) 
  2147)        fld_cnt = fld_cnt + 1
  2148) 
  2149)     enddo count_cnst
  2150) 
  2151)     if( fld_cnt < 1 ) then
  2152)        nullify(fields)
  2153)        return
  2154)     end if
  2155) 
  2156)     !-----------------------------------------------------------------------
  2157)     ! 	... allocate field type array
  2158)     !-----------------------------------------------------------------------
  2159)     allocate( fields(fld_cnt), stat=astat )
  2160)     if( astat/= 0 ) then
  2161)        write(iulog,*) 'specify_fields: failed to allocate fields array; error = ',astat
  2162)        call endrun
  2163)     end if
  2164) 
  2165)     do i = 1,fld_cnt
  2166)        fields(i)%fldnam = fld_name(i)
  2167)        fields(i)%srcnam = src_name(i)
  2168)     enddo
  2169) 
  2170)     deallocate(fld_name, src_name)
  2171) 
  2172)   end subroutine specify_fields
  2173) 
  2174) !------------------------------------------------------------------------------
  2175) 
  2176)   subroutine init_trc_restart( whence, piofile, tr_file )
  2177) 
  2178)     implicit none
  2179)     character(len=*), intent(in) :: whence
  2180)     type(file_desc_t), intent(inout) :: piofile
  2181)     type(trfile), intent(inout) :: tr_file
  2182)  
  2183)     character(len=32) :: name
  2184)     integer :: ioerr, mcdimid, maxlen
  2185)  
  2186) 
  2187)     ! Dimension should already be defined in restart file
  2188)     call pio_seterrorhandling(pioFile, PIO_BCAST_ERROR)
  2189)     ioerr = pio_inq_dimid(pioFile,'max_chars', mcdimid)
  2190)     call pio_seterrorhandling(pioFile, PIO_INTERNAL_ERROR)
  2191)     ! but define it if nessasary
  2192)     if(ioerr/= PIO_NOERR) then
  2193)        ioerr = pio_def_dim(pioFile, 'max_chars', SHR_KIND_CL, mcdimid)
  2194)     end if
  2195) 
  2196)     if(len_trim(tr_file%curr_filename)>1) then
  2197)        allocate(tr_file%currfnameid)
  2198)        name = trim(whence)//'_curr_fname'
  2199)        ioerr = pio_def_var(pioFile, name,pio_char,  (/mcdimid/), tr_file%currfnameid)
  2200)        ioerr = pio_put_att(pioFile, tr_file%currfnameid, 'offset_time', tr_file%offset_time)
  2201)        maxlen = len_trim(tr_file%curr_filename)
  2202)        ioerr = pio_put_att(pioFile, tr_file%currfnameid, 'actual_len', maxlen)	
  2203)     else
  2204)        nullify(tr_file%currfnameid)
  2205)     end if
  2206) 
  2207)     if(len_trim(tr_file%next_filename)>1) then
  2208)        allocate(tr_file%nextfnameid)
  2209)        name = trim(whence)//'_next_fname'
  2210)        ioerr = pio_def_var(pioFile, name,pio_char,  (/mcdimid/), tr_file%nextfnameid)
  2211)        maxlen = len_trim(tr_file%next_filename)
  2212)        ioerr = pio_put_att(pioFile, tr_file%nextfnameid, 'actual_len', maxlen)
  2213)     else
  2214)        nullify(tr_file%nextfnameid)
  2215)     end if
  2216)   end subroutine init_trc_restart
  2217) !-------------------------------------------------------------------------
  2218) ! writes file names to restart file
  2219) !-------------------------------------------------------------------------
  2220)   subroutine write_trc_restart( piofile, tr_file )
  2221) 
  2222)     implicit none
  2223) 
  2224)     type(file_desc_t), intent(inout) :: piofile
  2225)     type(trfile), intent(inout) :: tr_file
  2226) 
  2227)     integer :: ioerr, slen   ! error status
  2228)     if(associated(tr_file%currfnameid)) then
  2229)        ioerr = pio_put_var(pioFile, tr_file%currfnameid, tr_file%curr_filename)
  2230)        deallocate(tr_file%currfnameid)
  2231)        nullify(tr_file%currfnameid)
  2232)     end if
  2233)     if(associated(tr_file%nextfnameid)) then
  2234)        ioerr = pio_put_var(pioFile, tr_file%nextfnameid, tr_file%next_filename)
  2235)        deallocate(tr_file%nextfnameid)
  2236)        nullify(tr_file%nextfnameid)
  2237)     end if
  2238)   end subroutine write_trc_restart
  2239) 
  2240) !-------------------------------------------------------------------------
  2241) ! reads file names from restart file
  2242) !-------------------------------------------------------------------------
  2243)   subroutine read_trc_restart( whence, piofile, tr_file )
  2244) 
  2245)     implicit none
  2246) 
  2247)     character(len=*), intent(in) :: whence
  2248)     type(file_desc_t), intent(inout) :: piofile
  2249)     type(trfile), intent(inout) :: tr_file
  2250)     type(var_desc_t) :: vdesc
  2251)     character(len=64) :: name
  2252)     integer :: ioerr   ! error status
  2253)     integer :: slen
  2254) 
  2255)     call PIO_SetErrorHandling(piofile, PIO_BCAST_ERROR)
  2256)     name = trim(whence)//'_curr_fname'
  2257)     ioerr = pio_inq_varid(piofile, name, vdesc)
  2258)     if(ioerr==PIO_NOERR) then
  2259)        tr_file%curr_filename=' '
  2260)        ioerr = pio_get_att(piofile, vdesc, 'offset_time', tr_file%offset_time)
  2261)        ioerr = pio_get_att(piofile, vdesc, 'actual_len', slen)
  2262)        ioerr = pio_get_var(piofile, vdesc, tr_file%curr_filename)
  2263)        if(slen<SHR_KIND_CL) tr_file%curr_filename(slen+1:)=' '
  2264)     end if
  2265) 
  2266)     name = trim(whence)//'_next_fname'
  2267)     ioerr = pio_inq_varid(piofile, name, vdesc)
  2268)     if(ioerr==PIO_NOERR) then
  2269)        tr_file%next_filename=' '
  2270)        ioerr = pio_get_att(piofile, vdesc, 'actual_len', slen)
  2271)        ioerr = pio_get_var(piofile, vdesc, tr_file%next_filename)
  2272)        if(slen<SHR_KIND_CL) tr_file%next_filename(slen+1:)=' '
  2273)     end if
  2274)     call PIO_SetErrorHandling(piofile, PIO_INTERNAL_ERROR)
  2275) 
  2276) 
  2277) 
  2278)   end subroutine read_trc_restart
  2279) !------------------------------------------------------------------------------
  2280)    subroutine vert_interp_mixrat( ncol, nsrc, ntrg, trg_x, src, trg, p0, ps, hyai, hybi)
  2281)   
  2282)     implicit none
  2283) 
  2284)     integer, intent(in)   :: ncol 
  2285)     integer, intent(in)   :: nsrc                  ! dimension source array
  2286)     integer, intent(in)   :: ntrg                  ! dimension target array
  2287)     real(r8)              :: src_x(nsrc+1)         ! source coordinates
  2288)     real(r8), intent(in)      :: trg_x(pcols,ntrg+1)         ! target coordinates
  2289)     real(r8), intent(in)      :: src(pcols,nsrc)             ! source array
  2290)     real(r8), intent(out)     :: trg(pcols,ntrg)             ! target array
  2291) 
  2292)     real(r8) :: ps(pcols), p0, hyai(nsrc+1), hybi(nsrc+1)
  2293)     !---------------------------------------------------------------
  2294)     !   ... local variables
  2295)     !---------------------------------------------------------------
  2296)     integer  :: i, j, n
  2297)     integer  :: sil
  2298)     real(r8)     :: tl, y
  2299)     real(r8)     :: bot, top
  2300)    
  2301)   
  2302)     
  2303)     do n = 1,ncol
  2304)     
  2305)     do i=1,nsrc+1
  2306)      src_x(i) = p0*hyai(i)+ps(n)*hybi(i)
  2307)     enddo
  2308) 
  2309)     do i = 1, ntrg
  2310)        tl = trg_x(n,i+1)
  2311)        if( (tl.gt.src_x(1)).and.(trg_x(n,i).lt.src_x(nsrc+1)) ) then
  2312)           do sil = 1,nsrc
  2313)              if( (tl-src_x(sil))*(tl-src_x(sil+1)).le.0.0_r8 ) then
  2314)                 exit
  2315)              end if
  2316)           end do
  2317) 
  2318)           if( tl.gt.src_x(nsrc+1)) sil = nsrc
  2319) 
  2320)           y = 0.0_r8
  2321)           bot = min(tl,src_x(nsrc+1))   
  2322)           top = trg_x(n,i)
  2323)           do j = sil,1,-1
  2324)            if( top.lt.src_x(j) ) then
  2325)              y = y+(bot-src_x(j))*src(n,j)
  2326)             bot = src_x(j)
  2327)            else
  2328)             y = y+(bot-top)*src(n,j)
  2329)             exit
  2330)            endif
  2331)           enddo
  2332)           trg(n,i) = y
  2333)        else
  2334)         trg(n,i) = 0.0_r8
  2335)        end if
  2336)     end do
  2337) 
  2338)     if( trg_x(n,ntrg+1).lt.src_x(nsrc+1) ) then
  2339)      top = trg_x(n,ntrg+1)
  2340)      bot = src_x(nsrc+1)
  2341)      y = 0.0_r8
  2342)      do j=nsrc,1,-1
  2343)       if( top.lt.src_x(j) ) then
  2344)        y = y+(bot-src_x(j))*src(n,j)
  2345)        bot = src_x(j)
  2346)       else
  2347)        y = y+(bot-top)*src(n,j)
  2348)        exit
  2349)       endif
  2350)      enddo
  2351)      trg(n,ntrg) = trg(n,ntrg)+y
  2352)     endif
  2353) 
  2354) ! turn mass into mixing ratio 
  2355)     do i=1,ntrg
  2356)      trg(n,i) = trg(n,i)/(trg_x(n,i+1)-trg_x(n,i))
  2357)     enddo
  2358)     
  2359)     enddo
  2360) 
  2361)    end subroutine vert_interp_mixrat
  2362) !------------------------------------------------------------------------------
  2363)   subroutine vert_interp( ncol, levsiz, pin, pmid, datain, dataout )
  2364)     !-------------------------------------------------------------------------- 
  2365)     ! 
  2366)     ! Interpolate data from current time-interpolated values to model levels
  2367)     !--------------------------------------------------------------------------
  2368)     implicit none
  2369)     ! Arguments
  2370)     !
  2371)     integer,  intent(in)  :: ncol                ! number of atmospheric columns
  2372)     integer,  intent(in)  :: levsiz
  2373)     real(r8), intent(in)  :: pin(pcols,levsiz)
  2374)     real(r8), intent(in)  :: pmid(pcols,pver)          ! level pressures 
  2375)     real(r8), intent(in)  :: datain(pcols,levsiz)
  2376)     real(r8), intent(out) :: dataout(pcols,pver)     
  2377) 
  2378)     !
  2379)     ! local storage
  2380)     !
  2381) 
  2382)     integer ::  i                   ! longitude index
  2383)     integer ::  k, kk, kkstart      ! level indices
  2384)     integer ::  kupper(pcols)       ! Level indices for interpolation
  2385)     real(r8) :: dpu                ! upper level pressure difference
  2386)     real(r8) :: dpl                ! lower level pressure difference
  2387) 
  2388) 
  2389) 
  2390)     !--------------------------------------------------------------------------
  2391)     !
  2392)     ! Initialize index array
  2393)     !
  2394)     do i=1,ncol
  2395)        kupper(i) = 1
  2396)     end do
  2397) 
  2398)     do k=1,pver
  2399)        !
  2400)        ! Top level we need to start looking is the top level for the previous k
  2401)        ! for all column points
  2402)        !
  2403)        kkstart = levsiz
  2404)        do i=1,ncol
  2405)           kkstart = min0(kkstart,kupper(i))
  2406)        end do
  2407)        !
  2408)        ! Store level indices for interpolation
  2409)        !
  2410)        do kk=kkstart,levsiz-1
  2411)           do i=1,ncol
  2412)              if (pin(i,kk).lt.pmid(i,k) .and. pmid(i,k).le.pin(i,kk+1)) then
  2413)                 kupper(i) = kk
  2414)              end if
  2415)           end do
  2416)        end do
  2417)        ! interpolate or extrapolate...
  2418)        do i=1,ncol
  2419)           if (pmid(i,k) .lt. pin(i,1)) then
  2420)              dataout(i,k) = datain(i,1)*pmid(i,k)/pin(i,1)
  2421)           else if (pmid(i,k) .gt. pin(i,levsiz)) then
  2422)              dataout(i,k) = datain(i,levsiz)
  2423)           else
  2424)              dpu = pmid(i,k) - pin(i,kupper(i))
  2425)              dpl = pin(i,kupper(i)+1) - pmid(i,k)
  2426)              dataout(i,k) = (datain(i,kupper(i) )*dpl + &
  2427)                   datain(i,kupper(i)+1)*dpu)/(dpl + dpu)
  2428)           end if
  2429)        end do
  2430)     end do
  2431) 
  2432) 
  2433)   end subroutine vert_interp
  2434) 
  2435) !------------------------------------------------------------------------------
  2436)   subroutine vert_interp_ub( ncol, nlevs, plevs,  datain, dataout )
  2437)     use ref_pres, only : ptop_ref
  2438) 
  2439) 
  2440)     !----------------------------------------------------------------------- 
  2441)     ! 
  2442)     ! Interpolate data from current time-interpolated values to top interface pressure
  2443)     !  -- from mo_tgcm_ubc.F90
  2444)     !--------------------------------------------------------------------------
  2445)     implicit none
  2446)     ! Arguments
  2447)     !
  2448)     integer,  intent(in)  :: ncol
  2449)     integer,  intent(in)  :: nlevs
  2450)     real(r8), intent(in)  :: plevs(nlevs)
  2451)     real(r8), intent(in)  :: datain(ncol,nlevs)
  2452)     real(r8), intent(out) :: dataout(ncol)   
  2453) 
  2454)     !
  2455)     ! local variables
  2456)     !
  2457)     integer  :: i,ku,kl,kk
  2458)     real(r8) :: pinterp, delp
  2459)     
  2460)     pinterp = ptop_ref
  2461) 
  2462)     if( pinterp <= plevs(1) ) then
  2463)        kl = 1
  2464)        ku = 1
  2465)        delp = 0._r8
  2466)     else if( pinterp >= plevs(nlevs) ) then
  2467)        kl = nlevs
  2468)        ku = nlevs
  2469)        delp = 0._r8
  2470)     else
  2471) 
  2472)        do kk = 2,nlevs
  2473)           if( pinterp <= plevs(kk) ) then
  2474)              ku = kk
  2475)              kl = kk - 1
  2476)              delp = log( pinterp/plevs(kk) ) / log( plevs(kk-1)/plevs(kk) )
  2477)              exit
  2478)           end if
  2479)        end do
  2480) 
  2481)     end if
  2482) 
  2483)     do i = 1,ncol
  2484)        dataout(i) = datain(i,kl) + delp * (datain(i,ku) - datain(i,kl))
  2485)     end do
  2486) 
  2487)   end subroutine vert_interp_ub
  2488) !------------------------------------------------------------------------------
  2489) 
  2490) !------------------------------------------------------------------------------
  2491) !------------------------------------------------------------------------------
  2492)   subroutine advance_file(file)
  2493) 
  2494)     !------------------------------------------------------------------------------
  2495)     !   This routine advances to the next file
  2496)     !------------------------------------------------------------------------------
  2497) 
  2498)     use shr_sys_mod, only: shr_sys_system
  2499)     use ioFileMod, only: getfil
  2500) 
  2501)     implicit none
  2502) 
  2503)     type(trfile), intent(inout) :: file
  2504) 
  2505)     !-----------------------------------------------------------------------
  2506)     !   local variables
  2507)     !-----------------------------------------------------------------------
  2508)     character(len=shr_kind_cl) :: ctmp
  2509)     character(len=shr_kind_cl) :: loc_fname   
  2510)     integer            :: istat, astat
  2511) 
  2512)     !-----------------------------------------------------------------------
  2513)     !   close current file ...
  2514)     !-----------------------------------------------------------------------
  2515)     call pio_closefile( file%curr_fileid )
  2516) 
  2517)     !-----------------------------------------------------------------------
  2518)     !   remove if requested
  2519)     !-----------------------------------------------------------------------
  2520)     if( file%remove_trc_file ) then
  2521)        call getfil( file%curr_filename, loc_fname, 0 )
  2522)        write(iulog,*) 'advance_file: removing file = ',trim(loc_fname) 
  2523)        ctmp = 'rm -f ' // trim(loc_fname) 
  2524)        write(iulog,*) 'advance_file: fsystem issuing command - '
  2525)        write(iulog,*) trim(ctmp)
  2526)        call shr_sys_system( ctmp, istat )
  2527)     end if
  2528)    
  2529)     !-----------------------------------------------------------------------
  2530)     !   Advance the filename and file id
  2531)     !-----------------------------------------------------------------------
  2532)     file%curr_filename = file%next_filename
  2533)     file%curr_fileid = file%next_fileid
  2534)    
  2535)     !-----------------------------------------------------------------------
  2536)     !   Advance the curr_data_times
  2537)     !-----------------------------------------------------------------------
  2538)     deallocate( file%curr_data_times, stat=astat )
  2539)     if( astat/= 0 ) then
  2540)        write(iulog,*) 'advance_file: failed to deallocate file%curr_data_times array; error = ',astat
  2541)        call endrun
  2542)     end if
  2543)     allocate( file%curr_data_times( size( file%next_data_times ) ), stat=astat )
  2544)     if( astat/= 0 ) then
  2545)        write(iulog,*) 'advance_file: failed to allocate file%curr_data_times array; error = ',astat
  2546)        call endrun
  2547)     end if
  2548)     file%curr_data_times(:) = file%next_data_times(:)
  2549)     
  2550)     !-----------------------------------------------------------------------
  2551)     !   delete information about next file (as was just assigned to current)
  2552)     !-----------------------------------------------------------------------
  2553)     file%next_filename = ''
  2554)     
  2555)     deallocate( file%next_data_times, stat=astat )
  2556)     if( astat/= 0 ) then
  2557)        write(iulog,*) 'advance_file: failed to deallocate file%next_data_times array; error = ',astat
  2558)        call endrun
  2559)     end if
  2560)     nullify( file%next_data_times )
  2561) 
  2562)   end subroutine advance_file
  2563) 
  2564) end module tracer_data

generated by
Intel(R) C++/Fortran Compiler code-coverage tool
Web-Page Owner: Nobody