sat_hist.F90       coverage:  18.75 %func     3.34 %block


     1) !-------------------------------------------------------------------------------
     2) ! Outputs history field columns as specified by a satellite track data file
     3) !
     4) ! Created by Francis Vitt -- 17 Sep 2010
     5) !-------------------------------------------------------------------------------
     6) module sat_hist
     7) 
     8)   use perf_mod,      only: t_startf, t_stopf
     9)   use shr_kind_mod,  only: r8 => shr_kind_r8
    10)   use cam_logfile,   only: iulog
    11)   use ppgrid,        only: pcols, pver, begchunk, endchunk
    12)   use cam_history_support, only: fieldname_lenp2, max_string_len, ptapes
    13)   use spmd_utils,    only: masterproc, iam
    14)   use cam_abortutils,    only: endrun
    15) 
    16)   use pio,           only: file_desc_t, iosystem_desc_t, iosystem_desc_t, var_desc_t, io_desc_t
    17)   use pio,           only: pio_openfile, pio_redef, pio_enddef, pio_inq_dimid, pio_inq_varid, pio_seterrorhandling, pio_def_var
    18)   use pio,           only: pio_inq_dimlen, pio_get_att, pio_put_att, pio_get_var, pio_put_var, pio_write_darray
    19)   use pio,           only: pio_real, pio_int, pio_double
    20)   use pio,           only: PIO_WRITE,PIO_NOWRITE, PIO_NOERR, PIO_BCAST_ERROR, PIO_INTERNAL_ERROR, PIO_Rearr_box, PIO_GLOBAL
    21)   use spmd_utils,    only: mpicom
    22) #ifdef SPMD
    23)   use mpishorthand,  only: mpichar, mpiint
    24) #endif
    25)    use physconst, only: pi 
    26)   
    27)   implicit none
    28) 
    29)   private
    30)   save
    31) 
    32)   public :: sat_hist_readnl
    33)   public :: sat_hist_init
    34)   public :: sat_hist_write
    35)   public :: sat_hist_define
    36)   public :: is_satfile
    37) 
    38)   character(len=max_string_len)  :: sathist_track_infile
    39)   type(file_desc_t) :: infile
    40) 
    41)   integer :: half_step
    42)   logical :: has_sat_hist = .false.
    43) 
    44)   integer :: sathist_nclosest
    45)   integer :: sathist_ntimestep
    46) 
    47)   real(r8), allocatable :: obs_lats(:)
    48)   real(r8), allocatable :: obs_lons(:)
    49) 
    50)   logical  :: doy_format
    51)   real(r8) :: first_datetime
    52)   real(r8) :: last_datetime
    53)   integer  :: last_start_index
    54)   integer  :: time_ndx
    55)   integer  :: t_buffer_size
    56)   integer, allocatable :: date_buffer(:), time_buffer(:)
    57)   integer :: sat_tape_num=ptapes-1
    58) 
    59)   
    60)   ! input file
    61)   integer :: n_profiles
    62)   integer :: time_vid, date_vid, lat_vid, lon_vid, instr_vid, orbit_vid, prof_vid, zenith_vid
    63) 
    64)   integer :: in_julian_vid
    65)   integer :: in_localtime_vid
    66)   integer :: in_doy_vid
    67)   integer :: in_occ_type_vid
    68) 
    69)   integer :: in_start_col
    70) 
    71) 
    72)   ! output file
    73)   type(var_desc_t) :: out_latid, out_lonid, out_dstid, out_instrid, out_zenithid, out_orbid, out_profid
    74)   type(var_desc_t) :: out_instr_lat_vid, out_instr_lon_vid
    75)   type(var_desc_t) :: out_obs_date_vid, out_obs_time_vid
    76)   type(var_desc_t) :: out_julian_vid
    77)   type(var_desc_t) :: out_localtime_vid
    78)   type(var_desc_t) :: out_doy_vid
    79)   type(var_desc_t) :: out_occ_type_vid
    80) 
    81)   logical, parameter :: debug = .false.
    82) 
    83)   real(r8), parameter :: rad2deg = 180._r8/pi            ! degrees per radian
    84) 
    85) contains
    86)   
    87) !-------------------------------------------------------------------------------
    88) 
    89)   logical function is_satfile (file_index)
    90)     integer, intent(in) :: file_index ! index of file in question
    91)     is_satfile = file_index == sat_tape_num
    92)   end function is_satfile
    93) 
    94) !-------------------------------------------------------------------------------
    95)   subroutine sat_hist_readnl(nlfile, hfilename_spec, mfilt, fincl, nhtfrq, avgflag_pertape)
    96)     
    97)     use namelist_utils,      only: find_group_name
    98)     use units,               only: getunit, freeunit
    99)     use cam_history_support, only: pflds
   100)     use cam_instance,        only: inst_suffix
   101) 
   102)     implicit none
   103) 
   104)     character(len=*), intent(in) :: nlfile  ! filepath for file containing namelist input
   105)     character(len=*), intent(inout) :: hfilename_spec(:)
   106)     character(len=*), intent(inout) :: fincl(:,:)
   107)     character(len=1), intent(inout) :: avgflag_pertape(:)
   108)     integer,          intent(inout) :: mfilt(:), nhtfrq(:)
   109)     
   110)     ! Local variables
   111)     integer :: unitn, ierr
   112)     character(len=*), parameter :: subname = 'sat_hist_readnl'
   113)     integer :: f, fcnt
   114) 
   115)     character(len=fieldname_lenp2) :: sathist_fincl(pflds)
   116)     character(len=max_string_len)  :: sathist_hfilename_spec
   117)     integer :: sathist_mfilt, sat_tape_num
   118) 
   119)     namelist /satellite_options_nl/ sathist_track_infile, sathist_hfilename_spec, sathist_fincl, &
   120)          sathist_mfilt, sathist_nclosest, sathist_ntimestep
   121) 
   122)     ! set defaults
   123) 
   124)     sathist_track_infile = ' '
   125)     sathist_hfilename_spec = '%c.cam' // trim(inst_suffix) // '.hs.%y-%m-%d-%s.nc'
   126)     sathist_fincl(:) = ' '
   127)     sathist_mfilt = 100000
   128)     sathist_nclosest = 1
   129)     sathist_ntimestep = 1
   130) 
   131)     !read namelist options
   132) 
   133)     if (masterproc) then
   134)        unitn = getunit()
   135)        open( unitn, file=trim(nlfile), status='old' )
   136)        call find_group_name(unitn, 'satellite_options_nl', status=ierr)
   137)        if (ierr == 0) then
   138)           read(unitn, satellite_options_nl, iostat=ierr)
   139)           if (ierr /= 0) then
   140)              call endrun(subname // ':: ERROR reading namelist')
   141)           end if
   142)        end if
   143)        close(unitn)
   144)        call freeunit(unitn)
   145)     end if
   146) 
   147) #ifdef SPMD
   148)     ! broadcast the options to all MPI tasks
   149)     call mpibcast(sathist_track_infile,   len(sathist_track_infile),   mpichar, 0, mpicom)
   150)     call mpibcast(sathist_hfilename_spec, len(sathist_hfilename_spec), mpichar, 0, mpicom)
   151)     call mpibcast(sathist_fincl,          pflds*len(sathist_fincl(1)), mpichar, 0, mpicom)
   152)     call mpibcast(sathist_mfilt,          1,                           mpiint,  0, mpicom)
   153)     call mpibcast(sathist_nclosest,       1,                           mpiint,  0, mpicom)
   154)     call mpibcast(sathist_ntimestep,      1,                           mpiint,  0, mpicom)
   155) #endif
   156) 
   157)     has_sat_hist = len_trim(sathist_track_infile) > 0
   158) 
   159)     if (.not.has_sat_hist) return
   160) 
   161)      sat_tape_num=ptapes-1
   162)      hfilename_spec(sat_tape_num) = sathist_hfilename_spec
   163)      mfilt(sat_tape_num) = sathist_mfilt
   164)      fcnt=0
   165)      do f=1, pflds
   166)         fincl(f,sat_tape_num) = sathist_fincl(f)
   167)         if(len_trim(sathist_fincl(f)) > 0) then
   168)            fcnt=fcnt+1
   169)         end if
   170)      enddo
   171)      
   172)      nhtfrq(sat_tape_num) = 1
   173)      avgflag_pertape(sat_tape_num) = 'I'
   174) 
   175)      if(masterproc) then
   176)         write(iulog,*) 'sathist_track_infile: ',trim(sathist_track_infile)
   177)         write(iulog,*) 'sathist_hfilename_spec: ',trim(sathist_hfilename_spec)
   178)         write(iulog,*) 'sathist_fincl: ',(trim(sathist_fincl(f))//' ', f=1,fcnt)
   179)         write(iulog,*) 'max columns per file sathist_mfilt: ',sathist_mfilt
   180)         write(iulog,*) 'sathist_nclosest: ',sathist_nclosest
   181)         write(iulog,*) 'sathist_ntimestep: ',sathist_ntimestep
   182)      end if
   183) 
   184)    end subroutine sat_hist_readnl
   185) 
   186)   
   187) !-------------------------------------------------------------------------------
   188) !-------------------------------------------------------------------------------
   189)   subroutine sat_hist_init
   190)     use cam_pio_utils, only: cam_pio_openfile
   191)     use ioFileMod,     only: getfil
   192)     use spmd_utils,    only: npes
   193)     use time_manager,  only: get_step_size
   194)     use string_utils,  only: to_lower, GLC
   195) 
   196)     implicit none
   197) 
   198)     character(len=max_string_len)  :: locfn       ! Local filename
   199)     integer :: ierr, dimid, i
   200) 
   201)     character(len=128) :: date_format
   202) 
   203)     if (.not.has_sat_hist) return
   204) 
   205)     call getfil (sathist_track_infile, locfn)
   206)     call cam_pio_openfile(infile, locfn, PIO_NOWRITE)
   207) 
   208)     ierr = pio_inq_dimid(infile,'profs',dimid)
   209)     ierr = pio_inq_dimlen(infile, dimid, n_profiles)
   210) 
   211)     ierr = pio_inq_varid( infile, 'time', time_vid )
   212)     ierr = pio_inq_varid( infile, 'date', date_vid )
   213) 
   214)     ierr = pio_get_att( infile, date_vid, 'long_name', date_format)
   215)     date_format = to_lower(trim( date_format(:GLC(date_format))))
   216) 
   217)     if ( index( date_format, 'yyyymmdd') > 0 ) then
   218)        doy_format = .false.
   219)     else if  ( index( date_format, 'yyyyddd') > 0 ) then
   220)        doy_format = .true.
   221)     else
   222)        call endrun('sat_hist_init: date_format not recognized : '//trim(date_format))
   223)     endif
   224) 
   225)     ierr = pio_inq_varid( infile, 'lat', lat_vid )
   226)     ierr = pio_inq_varid( infile, 'lon', lon_vid )
   227) 
   228)     call pio_seterrorhandling(infile, PIO_BCAST_ERROR)
   229)     ierr = pio_inq_varid( infile, 'instr_num', instr_vid )
   230)     if(ierr/=PIO_NOERR) instr_vid=-1
   231) 
   232)     ierr = pio_inq_varid( infile, 'orbit_num', orbit_vid )
   233)     if(ierr/=PIO_NOERR) orbit_vid=-1
   234) 
   235)     ierr = pio_inq_varid( infile, 'prof_num',  prof_vid )
   236)     if(ierr/=PIO_NOERR) prof_vid=-1
   237) 
   238)     ierr = pio_inq_varid( infile, 'instr_sza', zenith_vid )
   239)     if(ierr/=PIO_NOERR) zenith_vid=-1
   240) 
   241)     ierr = pio_inq_varid( infile, 'julian', in_julian_vid )
   242)     if(ierr/=PIO_NOERR) in_julian_vid=-1
   243) 
   244)     ierr = pio_inq_varid( infile, 'local_time', in_localtime_vid )
   245)     if(ierr/=PIO_NOERR) in_localtime_vid=-1
   246) 
   247)     ierr = pio_inq_varid( infile, 'doy', in_doy_vid )
   248)     if(ierr/=PIO_NOERR) in_doy_vid=-1
   249) 
   250)     ierr = pio_inq_varid( infile, 'occ_type', in_occ_type_vid )
   251)     if(ierr/=PIO_NOERR) in_occ_type_vid=-1
   252) 
   253)     call pio_seterrorhandling(infile, PIO_INTERNAL_ERROR)
   254) 
   255)     call read_datetime( first_datetime, 1 )
   256)     call read_datetime( last_datetime, n_profiles )
   257)     last_start_index = -1
   258)     t_buffer_size = min(1000,n_profiles)
   259)     allocate( date_buffer(t_buffer_size), time_buffer(t_buffer_size) )
   260)     if (masterproc) write(iulog,*) "sathist_init:", n_profiles, first_datetime, last_datetime
   261)     if ( last_datetime<first_datetime ) then
   262)        call endrun('sat_hist_init: satellite track file has invalid date time info')
   263)     endif
   264) 
   265)     time_ndx = 1
   266)     half_step = get_step_size()*0.5_r8
   267) 
   268)   end subroutine sat_hist_init
   269) 
   270) !-------------------------------------------------------------------------------
   271) !-------------------------------------------------------------------------------
   272)   subroutine read_datetime( datetime, index )
   273) 
   274)     real(r8), intent( out ) :: datetime
   275)     integer,  intent( in )  :: index
   276) 
   277)     integer :: ierr
   278)     integer :: cnt(1)
   279)     integer :: start(1)
   280)     integer :: date(1), time(1)
   281) 
   282)     cnt = (/ 1 /)
   283)     start = (/index/)
   284) 
   285)     ierr = pio_get_var( infile, time_vid, start, cnt, time )
   286)     ierr = pio_get_var( infile, date_vid, start, cnt, date )
   287)     
   288)     datetime = convert_date_time( date(1),time(1) )
   289) 
   290)   end subroutine read_datetime
   291) 
   292) !-------------------------------------------------------------------------------
   293) !-------------------------------------------------------------------------------
   294)   subroutine read_buffered_datetime( datetime, index )
   295) 
   296)     real(r8), intent( out ) :: datetime
   297)     integer,  intent( in )  :: index
   298) 
   299)     integer :: ii
   300) 
   301)     integer :: ierr
   302)     integer :: cnt
   303)     integer :: start
   304)     integer :: date, time
   305)     
   306)     ! If the request is outside of the buffer then reload the buffer.
   307)     if ((last_start_index == -1) .or. (index < last_start_index) &
   308)          .or. (index >= (last_start_index + t_buffer_size))) then
   309) 
   310)        start = (index - 1) / t_buffer_size * t_buffer_size + 1
   311)        if ( start+t_buffer_size-1 <= n_profiles ) then
   312)           cnt = t_buffer_size 
   313)        else
   314)           cnt = n_profiles-start+1
   315)        endif
   316)        ierr = pio_get_var( infile, time_vid, (/ start /), (/ cnt /), time_buffer(1:cnt) )
   317)        ierr = pio_get_var( infile, date_vid, (/ start /), (/ cnt /), date_buffer(1:cnt) )
   318) 
   319)        last_start_index = start
   320)     endif
   321) 
   322)     ii = mod( index - 1, t_buffer_size ) + 1
   323)     time = time_buffer(ii)
   324)     date = date_buffer(ii)
   325)     datetime = convert_date_time( date,time )
   326) 
   327)   end subroutine read_buffered_datetime
   328) 
   329) !-------------------------------------------------------------------------------
   330) !-------------------------------------------------------------------------------
   331)   function convert_date_time( date,time )
   332)     use time_manager, only: set_time_float_from_date
   333) 
   334)     integer, intent(in) :: date,time
   335)     real(r8) :: convert_date_time
   336) 
   337)     real(r8) :: datetime
   338)     integer :: yr, doy, mon, dom
   339) 
   340)     if ( doy_format ) then
   341)        yr = date/1000
   342)        doy = date - yr*1000
   343)        call set_time_float_from_date( datetime, yr, 1, doy, time )
   344)     else 
   345)        yr = date/10000
   346)        mon = (date - yr*10000)/100
   347)        dom = date - yr*10000 - mon*100
   348)        call set_time_float_from_date( datetime, yr, mon, dom, time )
   349)     endif
   350)     convert_date_time = datetime
   351) 
   352)   end function convert_date_time
   353) !-------------------------------------------------------------------------------
   354)   subroutine sat_hist_define(outfile)
   355)     use pio, only : pio_inquire
   356)     type(file_desc_t), intent(inout) :: outfile
   357) 
   358)     integer :: coldim
   359)     integer :: ierr
   360)     
   361)     ierr = pio_inquire(outfile, unlimitedDimId=coldim)
   362) 
   363)     call pio_seterrorhandling(outfile, PIO_BCAST_ERROR)
   364)     ierr = define_var( 'instr_lat', coldim, infile, lat_vid,  outfile, out_instr_lat_vid )
   365)     ierr = define_var( 'instr_lon', coldim, infile, lon_vid,  outfile, out_instr_lon_vid )
   366)     ierr = define_var( 'obs_time', coldim, infile, time_vid,  outfile, out_obs_time_vid )
   367)     ierr = define_var( 'obs_date', coldim, infile, date_vid,  outfile, out_obs_date_vid )
   368) 
   369)     ierr = pio_inq_varid( outfile, 'distance', out_dstid )
   370)     if (ierr /= PIO_NOERR) then
   371)        ierr = pio_def_var  ( outfile, 'distance', PIO_REAL, (/coldim/), out_dstid )
   372)        ierr = pio_put_att  ( outfile, out_dstid, "long_name", "distance from midpoint to observation")
   373)        ierr = pio_put_att  ( outfile, out_dstid, "units", "km")
   374)     end if
   375) 
   376)     if (orbit_vid>0) then
   377)        ierr = define_var( 'orbit_num', coldim, infile, orbit_vid,  outfile, out_orbid )
   378)     endif
   379)     if (prof_vid>0) then
   380)        ierr = define_var( 'prof_num', coldim, infile, prof_vid,  outfile, out_profid )
   381)     endif
   382)     if (instr_vid>0) then
   383)        ierr = define_var( 'instr_num', coldim, infile, instr_vid,  outfile, out_instrid )
   384)     endif
   385)     if (zenith_vid>0) then
   386)        ierr = define_var( 'instr_sza', coldim, infile, zenith_vid,  outfile, out_zenithid )
   387)     endif
   388)     if (in_occ_type_vid>0) then
   389)        ierr = define_var( 'occ_type', coldim, infile, in_occ_type_vid,  outfile, out_occ_type_vid )
   390)     endif
   391)     if (in_julian_vid>0) then
   392)        ierr = define_var( 'julian', coldim, infile, in_julian_vid,  outfile, out_julian_vid )
   393)     endif
   394)     if (in_localtime_vid>0) then
   395)        ierr = define_var( 'local_time', coldim, infile, in_localtime_vid,  outfile, out_localtime_vid )
   396)     endif
   397)     if (in_doy_vid>0) then
   398)        ierr = define_var( 'doy', coldim, infile, in_doy_vid,  outfile, out_doy_vid )
   399)     endif
   400) 
   401)     call pio_seterrorhandling(outfile, PIO_INTERNAL_ERROR)
   402)     ierr=pio_put_att (outfile, PIO_GLOBAL, 'satellite_track_file', sathist_track_infile)
   403)   end subroutine sat_hist_define
   404) 
   405) 
   406) !-------------------------------------------------------------------------------
   407)   subroutine sat_hist_write( tape , nflds, nfils)
   408) 
   409)     use ppgrid,   only : pcols, begchunk, endchunk
   410)     use phys_grid, only: phys_decomp
   411)     use dyn_grid, only: dyn_decomp
   412)     use cam_history_support, only : active_entry
   413)     use pio, only : pio_file_is_open
   414)     implicit none
   415)     type(active_entry) :: tape
   416)     integer, intent(in) :: nflds
   417)     integer, intent(inout) :: nfils
   418) 
   419)     integer :: t, f, i, ncols, nocols    
   420)     integer :: ierr
   421) 
   422)     integer, allocatable :: col_ndxs(:)
   423)     integer, allocatable :: chk_ndxs(:)
   424)     integer, allocatable :: fdyn_ndxs(:)
   425)     integer, allocatable :: ldyn_ndxs(:)
   426)     integer, allocatable :: phs_owners(:)
   427)     integer, allocatable :: dyn_owners(:)
   428)     real(r8),allocatable :: mlats(:)
   429)     real(r8),allocatable :: mlons(:)
   430)     real(r8),allocatable :: phs_dists(:)
   431) 
   432)     integer :: coldim
   433) 
   434)     integer :: io_type
   435)     logical :: has_dyn_flds
   436) 
   437)     if (.not.has_sat_hist) return
   438) 
   439)     call read_next_position( ncols )
   440) 
   441)     if ( ncols < 1 ) return
   442) 
   443)     call t_startf ('sat_hist_write')
   444) 
   445)     ! The n closest columns to the observation will be output,
   446)     ! so increase the size of the columns used for output/
   447)     nocols = ncols * sathist_nclosest
   448) 
   449)     allocate( col_ndxs(nocols) )
   450)     allocate( chk_ndxs(nocols) )
   451)     allocate( fdyn_ndxs(nocols) )
   452)     allocate( ldyn_ndxs(nocols) )
   453)     allocate( phs_owners(nocols) )
   454)     allocate( dyn_owners(nocols) )
   455)     allocate( mlats(nocols) )
   456)     allocate( mlons(nocols) )
   457)     allocate( phs_dists(nocols) )
   458) 
   459)     has_dyn_flds = .false.
   460)     dyn_flds_loop: do f=1,nflds
   461)        if ( tape%hlist(f)%field%decomp_type == dyn_decomp ) then
   462)           has_dyn_flds = .true.
   463)           exit dyn_flds_loop
   464)        endif
   465)     enddo dyn_flds_loop
   466) 
   467)     call get_indices( obs_lats, obs_lons, ncols, nocols, has_dyn_flds, col_ndxs, chk_ndxs, &
   468)          fdyn_ndxs, ldyn_ndxs, phs_owners, dyn_owners, mlats, mlons, phs_dists )
   469) 
   470)     if ( .not. pio_file_is_open(tape%File) ) then
   471)        call endrun('sat file not open')
   472)     endif
   473) 
   474)     ierr = pio_inq_dimid(tape%File,'ncol',coldim )
   475)     
   476)     ierr = pio_inq_varid(tape%File, 'lat', out_latid )
   477)     ierr = pio_inq_varid(tape%File, 'lon', out_lonid )
   478)     ierr = pio_inq_varid(tape%File, 'distance', out_dstid )
   479) 
   480)     call write_record_coord( tape, mlats(:), mlons(:), phs_dists(:), ncols, nfils )
   481) 
   482)     do f=1,nflds
   483) 
   484)        select case (tape%hlist(f)%field%decomp_type)
   485)        case (phys_decomp)
   486)           call dump_columns(tape%File, tape%hlist(f), nocols, nfils, col_ndxs(:), chk_ndxs(:), phs_owners(:) )
   487)        case (dyn_decomp)
   488)           call dump_columns(tape%File, tape%hlist(f), nocols, nfils, fdyn_ndxs(:), ldyn_ndxs(:), dyn_owners(:) )
   489)        end select
   490) 
   491)     enddo
   492) 
   493)     deallocate( col_ndxs, chk_ndxs, fdyn_ndxs, ldyn_ndxs, phs_owners, dyn_owners )
   494)     deallocate( mlons, mlats, phs_dists )
   495)     deallocate( obs_lons, obs_lats )
   496) 
   497)     nfils = nfils + nocols
   498) 
   499)     call t_stopf ('sat_hist_write')
   500) 
   501)   end subroutine sat_hist_write
   502) 
   503) !-------------------------------------------------------------------------------
   504)   subroutine dump_columns( File, hitem, ncols, nfils, fdims, ldims, owners  )
   505)     use cam_history_support,  only: field_info, hentry, hist_coords, fillvalue
   506)     use pio,            only: pio_initdecomp, pio_freedecomp, pio_setframe, pio_iam_iotask, pio_setdebuglevel, pio_offset_kind
   507) 
   508)     type(File_desc_t),intent(inout)  :: File
   509)     type(hentry),     intent(in), target     :: hitem
   510)     integer,          intent(in)     :: ncols
   511)     integer,          intent(in)     :: nfils
   512)     integer,          intent(in)     :: fdims(:)
   513)     integer,          intent(in)     :: ldims(:)
   514)     integer,          intent(in)     :: owners(:)
   515) 
   516)     type(field_info), pointer :: field
   517)     type(var_desc_t) :: vardesc
   518)     type(iosystem_desc_t), pointer :: sat_iosystem
   519)     type(io_desc_t) :: iodesc
   520)     integer :: t, ierr, ndims
   521)     integer, allocatable :: dimlens(:)
   522) 
   523)     real(r8), allocatable :: buf(:)
   524)     integer,  allocatable :: dof(:)
   525)     integer :: i,k, cnt
   526) 
   527)     call t_startf ('sat_hist::dump_columns')
   528) 
   529)     sat_iosystem => File%iosystem
   530)     field => hitem%field
   531)     vardesc = hitem%varid(1)
   532) 
   533) 
   534)     ndims=1
   535)     if(associated(field%mdims)) then
   536)        ndims = size(field%mdims)+1
   537)     else if(field%numlev>1) then
   538)        ndims=2
   539)     end if
   540)     allocate(dimlens(ndims))
   541)     dimlens(ndims)=ncols
   542)     if(ndims>2) then
   543)        do i=1,ndims-1
   544)           dimlens(i)=hist_coords(field%mdims(i))%dimsize
   545)        enddo
   546)     else if(field%numlev>1) then
   547)        dimlens(1) = field%numlev
   548)     end if
   549)    
   550) 
   551)     allocate( buf( product(dimlens) ) )
   552)     allocate( dof( product(dimlens) ) )
   553) 
   554)     cnt = 0
   555)     buf = fillvalue
   556)     dof = 0
   557) 
   558)     do i = 1,ncols
   559)        do k = 1,field%numlev
   560)           cnt = cnt+1
   561)           if ( iam == owners(i) ) then
   562)              buf(cnt) = hitem%hbuf( fdims(i), k, ldims(i) )
   563)              dof(cnt) = cnt
   564)           endif
   565)        enddo
   566)     enddo
   567) 
   568)     call pio_setframe(File, vardesc, int(-1,kind=PIO_OFFSET_KIND))
   569) 
   570)     call pio_initdecomp(sat_iosystem, pio_double, dimlens, dof, iodesc )
   571) 
   572)     call pio_setframe(File, vardesc, int(nfils,kind=PIO_OFFSET_KIND))
   573) 
   574)     call pio_write_darray(File, vardesc, iodesc, buf, ierr, fillval=fillvalue)
   575) 
   576)     call pio_freedecomp(sat_iosystem, iodesc)
   577) 
   578)     deallocate( buf )
   579)     deallocate( dof )
   580)     deallocate( dimlens )
   581) 
   582)     call t_stopf ('sat_hist::dump_columns')
   583) 
   584)   end subroutine dump_columns
   585) 
   586) !-------------------------------------------------------------------------------
   587) !-------------------------------------------------------------------------------
   588)   subroutine read_next_position( ncols )
   589)     use time_manager, only: get_curr_date, get_prev_date
   590)     use time_manager, only: set_time_float_from_date
   591)    
   592)     implicit none
   593) 
   594)     integer,  intent(out) :: ncols
   595) 
   596)     integer :: ierr
   597)     integer :: yr, mon, day, tod
   598)     real(r8) :: begdatetime, enddatetime
   599)     integer :: beg_ndx, end_ndx, i
   600) 
   601)     real(r8) :: datetime
   602) 
   603)     call get_curr_date(yr, mon, day, tod)
   604)     call set_time_float_from_date(begdatetime, yr, mon, day, tod-half_step*sathist_ntimestep)
   605)     call set_time_float_from_date(enddatetime, yr, mon, day, tod+half_step*sathist_ntimestep)
   606) 
   607)     ncols = 0
   608) 
   609)     if ( first_datetime > enddatetime ) then
   610)        if (masterproc) write(iulog,'(a,2f16.6)') &
   611)             'sat_hist->read_next_position: all of the satellite date times are after the time window', first_datetime, enddatetime
   612)        return
   613)     endif
   614)     if ( last_datetime < begdatetime ) then
   615)        if (masterproc) write(iulog,'(a,2f16.6)') &
   616)             'sat_hist->read_next_position: all of the satellite date times are before the time window', begdatetime, last_datetime
   617)        return
   618)     endif
   619) 
   620)     call t_startf ('sat_hist::read_next_position')
   621) 
   622)     beg_ndx = -99
   623)     end_ndx = -99
   624) 
   625)     bnds_loop: do i = time_ndx,n_profiles
   626) 
   627)        call read_buffered_datetime( datetime, i )
   628) 
   629)        if ( datetime>begdatetime .and. beg_ndx<0 ) beg_ndx = i
   630)        if ( datetime>enddatetime ) exit bnds_loop
   631)        end_ndx = i
   632) 
   633)     enddo bnds_loop
   634) 
   635)     if (beg_ndx == -99 .and. end_ndx== -99) then
   636)        if (masterproc) write(iulog,'(a)')  'sat_hist->read_next_position: must be beyond last position -- returning.'
   637)        return
   638)     endif
   639) 
   640)     ! Advance the search forward, but because of ntimesteps, it is possible
   641)     ! for observations used here to be used again. However, we should not go
   642)     ! back before the previous beginning time.
   643)     if (beg_ndx>0) time_ndx = beg_ndx
   644) 
   645)     ncols = end_ndx-beg_ndx+1
   646) 
   647)     if (ncols > 0) then
   648)        allocate( obs_lats(ncols), obs_lons(ncols) )
   649)        in_start_col = beg_ndx
   650) 
   651)        ierr = pio_get_var( infile, lat_vid, (/beg_ndx/), (/ncols/), obs_lats )
   652)        ierr = pio_get_var( infile, lon_vid, (/beg_ndx/), (/ncols/), obs_lons )
   653) 
   654)     endif
   655) 
   656)     call t_stopf ('sat_hist::read_next_position')
   657)   end subroutine read_next_position
   658)   
   659) !-------------------------------------------------------------------------------
   660) !-------------------------------------------------------------------------------
   661)   subroutine write_record_coord( tape, mod_lats, mod_lons, mod_dists, ncols, nfils )
   662) 
   663)     use time_manager,  only: get_nstep, get_curr_date, get_curr_time
   664)     use cam_history_support, only : active_entry
   665)     implicit none
   666)     type(active_entry), intent(inout) :: tape
   667) 
   668)     integer,  intent(in) :: ncols
   669)     real(r8), intent(in) :: mod_lats(ncols * sathist_nclosest)
   670)     real(r8), intent(in) :: mod_lons(ncols * sathist_nclosest)
   671)     real(r8), intent(in) :: mod_dists(ncols * sathist_nclosest)
   672)     integer,  intent(in) ::  nfils
   673) 
   674)     integer :: t, ierr, i
   675)     integer :: yr, mon, day      ! year, month, and day components of a date
   676)     integer :: nstep             ! current timestep number
   677)     integer :: ncdate            ! current date in integer format [yyyymmdd]
   678)     integer :: ncsec             ! current time of day [seconds]
   679)     integer :: ndcur             ! day component of current time
   680)     integer :: nscur             ! seconds component of current time
   681)     real(r8) :: time             ! current time
   682)     integer, allocatable  :: itmp(:)
   683)     real(r8), allocatable :: rtmp(:)
   684)     real(r8), allocatable :: out_lats(:)
   685)     real(r8), allocatable :: out_lons(:)
   686) 
   687)     call t_startf ('sat_hist::write_record_coord')
   688) 
   689)     nstep = get_nstep()
   690)     call get_curr_date(yr, mon, day, ncsec)
   691)     ncdate = yr*10000 + mon*100 + day
   692)     call get_curr_time(ndcur, nscur)
   693) 
   694) 
   695)     time = ndcur + nscur/86400._r8
   696) 
   697)     allocate( itmp(ncols * sathist_nclosest) )
   698)     allocate( rtmp(ncols * sathist_nclosest) )
   699)     
   700)     itmp(:) = ncdate
   701)     ierr = pio_put_var(tape%File, tape%dateid,(/nfils/), (/ncols * sathist_nclosest/),itmp)
   702)     itmp(:) = ncsec
   703)     ierr = pio_put_var(tape%File, tape%datesecid,(/nfils/),(/ncols * sathist_nclosest/),itmp)
   704)     rtmp(:) = time
   705)     ierr = pio_put_var(tape%File, tape%timeid, (/nfils/),(/ncols * sathist_nclosest/),rtmp)
   706)     
   707)     deallocate(itmp)
   708)     deallocate(rtmp)
   709) 
   710)     ! output model column coordinates
   711)     ierr = pio_put_var(tape%File, out_latid, (/nfils/),(/ncols * sathist_nclosest/), mod_lats)
   712)     ierr = pio_put_var(tape%File, out_lonid, (/nfils/),(/ncols * sathist_nclosest/), mod_lons)
   713)     ierr = pio_put_var(tape%File, out_dstid, (/nfils/),(/ncols * sathist_nclosest/), mod_dists / 1000._r8)
   714)     
   715)     ! output instrument location
   716)     allocate( out_lats(ncols * sathist_nclosest) )
   717)     allocate( out_lons(ncols * sathist_nclosest) )
   718)     
   719)     do i = 1, ncols
   720)       out_lats(((i-1)*sathist_nclosest)+1 : (i*sathist_nclosest)) = obs_lats(i)
   721)       out_lons(((i-1)*sathist_nclosest)+1 : (i*sathist_nclosest)) = obs_lons(i)
   722)     enddo
   723) 
   724)     ierr = pio_put_var(tape%File, out_instr_lat_vid, (/nfils/),(/ncols * sathist_nclosest/), out_lats)
   725)     ierr = pio_put_var(tape%File, out_instr_lon_vid, (/nfils/),(/ncols * sathist_nclosest/), out_lons)
   726) 
   727)     deallocate(out_lats)
   728)     deallocate(out_lons)
   729)     
   730)     
   731)     ierr = copy_data( infile, date_vid, tape%File, out_obs_date_vid, in_start_col, nfils, ncols )
   732)     ierr = copy_data( infile, time_vid, tape%File, out_obs_time_vid, in_start_col, nfils, ncols )
   733)     
   734)     ! output observation identifiers
   735)     if (instr_vid>0) then
   736)        ierr = copy_data( infile, instr_vid, tape%File, out_instrid, in_start_col, nfils, ncols )
   737)     endif
   738)     if (orbit_vid>0) then
   739)        ierr = copy_data( infile, orbit_vid, tape%File, out_orbid, in_start_col, nfils, ncols )
   740)     endif
   741)     if (prof_vid>0) then
   742)        ierr = copy_data( infile, prof_vid, tape%File, out_profid, in_start_col, nfils, ncols )
   743)     endif
   744)     if (zenith_vid>0) then
   745)        ierr = copy_data( infile, zenith_vid, tape%File, out_zenithid, in_start_col, nfils, ncols )
   746)     endif
   747)     if (in_julian_vid>0) then
   748)        ierr = copy_data( infile, in_julian_vid, tape%File, out_julian_vid, in_start_col, nfils, ncols )
   749)     endif
   750)     if (in_occ_type_vid>0) then
   751)        ierr = copy_data( infile, in_occ_type_vid, tape%File, out_occ_type_vid, in_start_col, nfils, ncols )
   752)     endif
   753)     if (in_localtime_vid>0) then
   754)        ierr = copy_data( infile, in_localtime_vid, tape%File, out_localtime_vid, in_start_col, nfils, ncols )
   755)     endif
   756)     if (in_doy_vid>0) then
   757)        ierr = copy_data( infile, in_doy_vid, tape%File, out_doy_vid, in_start_col, nfils, ncols )
   758)     endif
   759) 
   760)     call t_stopf ('sat_hist::write_record_coord')
   761)   end subroutine write_record_coord
   762) 
   763) !-------------------------------------------------------------------------------
   764) !-------------------------------------------------------------------------------
   765) 
   766)   subroutine get_indices( lats, lons, ncols, nocols, has_dyn_flds, col_ndxs, chk_ndxs, &
   767)        fdyn_ndxs, ldyn_ndxs, phs_owners, dyn_owners, mlats, mlons, phs_dists )
   768) 
   769)     use dyn_grid, only : dyn_grid_get_colndx
   770)     use phys_grid, only: get_rlat_p, get_rlon_p
   771) 
   772)     integer,  intent(in)  :: ncols
   773)     real(r8), intent(in)  :: lats(ncols)
   774)     real(r8), intent(in)  :: lons(ncols)
   775)     integer,  intent(in)  :: nocols
   776)     logical,  intent(in)  :: has_dyn_flds
   777)     integer,  intent(out) :: col_ndxs(nocols)
   778)     integer,  intent(out) :: chk_ndxs(nocols)
   779)     integer,  intent(out) :: fdyn_ndxs(nocols)
   780)     integer,  intent(out) :: ldyn_ndxs(nocols)
   781)     integer,  intent(out) :: phs_owners(nocols)
   782)     integer,  intent(out) :: dyn_owners(nocols)
   783)     real(r8), intent(out) :: mlats(nocols)
   784)     real(r8), intent(out) :: mlons(nocols)
   785)     real(r8), intent(out) :: phs_dists(nocols)
   786) 
   787)     integer :: i, j, ndx
   788)     real(r8) :: lat, lon
   789)     
   790)     integer,  allocatable :: ichks(:),icols(:),idyn1s(:),idyn2s(:), iphs_owners(:), idyn_owners(:)
   791)     real(r8), allocatable :: rlats(:), rlons(:), plats(:), plons(:), iphs_dists(:)
   792) 
   793)     integer :: gcols(sathist_nclosest)
   794) 
   795)     call t_startf ('sat_hist::get_indices')
   796) 
   797)     allocate(ichks(sathist_nclosest),icols(sathist_nclosest),idyn1s(sathist_nclosest), &
   798)          idyn2s(sathist_nclosest),iphs_owners(sathist_nclosest),idyn_owners(sathist_nclosest))
   799)     allocate(rlats(sathist_nclosest), rlons(sathist_nclosest), plats(sathist_nclosest), &
   800)          plons(sathist_nclosest), iphs_dists(sathist_nclosest) )
   801) 
   802)     col_ndxs = -1
   803)     chk_ndxs = -1
   804)     fdyn_ndxs = -1
   805)     ldyn_ndxs = -1
   806)     phs_owners = -1
   807)     dyn_owners = -1
   808)     phs_dists = -1
   809) 
   810)     ndx = 0
   811)     do i = 1,ncols
   812) 
   813)        lat = lats(i)
   814)        lon = lons(i)
   815) 
   816)        if ( lon >= 360._r8) then
   817)          lon = lon-360._r8
   818)        endif
   819)        if ( lon < 0._r8) then
   820)          lon = lon+360._r8
   821)        endif
   822)        if (lat<-90._r8 .or. lat>90._r8) then
   823)           write(iulog,*) 'sat_hist::get_indices lat = ',lat
   824)           call endrun('sat_hist::get_indices : lat must be between -90 and 90 degrees (-90<=lat<=90)')
   825)        endif
   826)        if (lon<0._r8 .or. lon>=360._r8) then
   827)           write(iulog,*) 'sat_hist::get_indices lon = ',lon
   828)           call endrun('sat_hist::get_indices : lon must be between 0 and 360 degrees (0<=lon<360)')
   829)        endif
   830)        
   831)        call find_cols( lat, lon, sathist_nclosest, iphs_owners, ichks, icols, &
   832)                        gcols, iphs_dists, plats, plons )
   833) 
   834)        if (has_dyn_flds) then
   835)           call dyn_grid_get_colndx( gcols, sathist_nclosest, idyn_owners, idyn1s, idyn2s )
   836)        endif
   837) 
   838)        do j = 1, sathist_nclosest
   839)           
   840)           if (debug .and. iam==iphs_owners(j) ) then
   841)              if ( abs(plats(j)-rlats(j))>1.e-3_r8 ) then
   842)                 write(*,'(a,3f20.12)') ' lat, plat, rlat = ', lat, plats(j), rlats(j)
   843)                 write(*,'(a,3f20.12)') ' lon, plon, rlon = ', lon, plons(j), rlons(j)
   844)                 call endrun('sat_hist::get_indices: dyn lat is different than phys lat ')
   845)              endif
   846)              if ( abs(plons(j)-rlons(j))>1.e-3_r8 ) then
   847)                 write(*,'(a,3f20.12)') ' lat, plat, rlat = ', lat, plats(j), rlats(j)
   848)                 write(*,'(a,3f20.12)') ' lon, plon, rlon = ', lon, plons(j), rlons(j)
   849)                 call endrun('sat_hist::get_indices: dyn lon is different than phys lon ')
   850)              endif
   851)           endif
   852)           
   853)           ndx = ndx+1
   854)           
   855)           chk_ndxs(ndx)   = ichks(j)
   856)           col_ndxs(ndx)   = icols(j)
   857)           fdyn_ndxs(ndx)  = idyn1s(j)
   858)           ldyn_ndxs(ndx)  = idyn2s(j)
   859)           mlats(ndx)      = plats(j)
   860)           mlons(ndx)      = plons(j)
   861)           phs_owners(ndx) = iphs_owners(j)
   862)           dyn_owners(ndx) = idyn_owners(j)
   863)           phs_dists(ndx)  = iphs_dists(j)
   864)        enddo
   865)     enddo
   866) 
   867)     deallocate(ichks, icols, idyn1s, idyn2s, iphs_owners, idyn_owners)
   868)     deallocate(rlats, rlons, plats, plons, iphs_dists )
   869) 
   870)     call t_stopf ('sat_hist::get_indices')
   871)   end subroutine get_indices
   872) 
   873) !-------------------------------------------------------------------------------
   874) ! utility function
   875) !-------------------------------------------------------------------------------
   876)   integer function define_var( var_name, coldim, infile, in_vid, outfile, out_id ) result(res)
   877) 
   878)     use pio, only: pio_inq_vartype
   879) 
   880)     character(len=*), intent(in) :: var_name
   881)     integer,          intent(in) :: coldim
   882)     type(File_desc_t),intent(inout) :: infile
   883)     type(File_desc_t),intent(inout) :: outfile
   884)     integer,          intent(in) :: in_vid
   885)     type(var_desc_t), intent(out):: out_id
   886) 
   887)     integer :: type
   888) 
   889)     res = pio_inq_varid( outfile, var_name, out_id )
   890)     if(res/=PIO_NOERR) then
   891) 
   892)        res = pio_inq_vartype( infile, in_vid, type )
   893) 
   894)        res = pio_def_var ( outfile, var_name, type, (/coldim/), out_id )
   895) 
   896)        res = copy_att( infile, in_vid, 'long_name', outfile, out_id )
   897)        res = copy_att( infile, in_vid, 'units',     outfile, out_id )
   898) 
   899)     endif
   900) 
   901)   end function define_var
   902) 
   903) !-------------------------------------------------------------------------------
   904) ! utility function
   905) !-------------------------------------------------------------------------------
   906)   integer function copy_data( infile, in_vid, outfile, out_id, instart, outstart, ncols ) result(res)
   907) 
   908)     type(File_desc_t),intent(in) :: infile
   909)     type(File_desc_t),intent(inout) :: outfile
   910)     integer,          intent(in) :: in_vid
   911)     type(var_desc_t), intent(in) :: out_id
   912)     integer,          intent(in) :: instart, outstart, ncols
   913) 
   914)     real(r8), allocatable :: data(:)
   915)     real(r8), allocatable :: outdata(:)
   916)     integer               :: i
   917) 
   918)     allocate( data(ncols) )
   919) 
   920)     res = pio_get_var( infile,  in_vid, (/instart/),  (/ncols/), data )
   921) 
   922)     allocate( outdata(ncols * sathist_nclosest) )
   923)     
   924)     do i = 1, ncols
   925)       outdata(((i-1)*sathist_nclosest)+1 : (i*sathist_nclosest)) = data(i)
   926)     enddo
   927)   
   928)     res = pio_put_var( outfile, out_id, (/outstart/), (/ncols * sathist_nclosest/), outdata )
   929) 
   930)     deallocate(outdata)
   931)     deallocate(data)
   932) 
   933)   end function copy_data
   934) 
   935) !-------------------------------------------------------------------------------
   936) ! utility function
   937) ! -- should be able to use pio_copy_att which does not seem to work
   938) !-------------------------------------------------------------------------------
   939)   integer function copy_att( infile, in_vid, att_name, outfile, out_id ) result(res)
   940) 
   941)     type(File_desc_t),intent(inout) :: infile
   942)     type(File_desc_t),intent(inout) :: outfile
   943)     character(len=*), intent(in) :: att_name
   944)     integer,          intent(in) :: in_vid
   945)     type(var_desc_t), intent(in) :: out_id
   946) 
   947)     character(len=1024) :: att
   948)     
   949) 
   950)     res = pio_get_att( infile, in_vid, trim(att_name), att )
   951)     if (res==PIO_NOERR) then
   952)        res = pio_put_att ( outfile, out_id, trim(att_name), trim(att))
   953)     endif
   954) 
   955) 
   956)   end function copy_att
   957)   
   958)   !-------------------------------------------------------------------------------
   959)   !-------------------------------------------------------------------------------
   960)   subroutine find_cols(lat, lon, nclosest, owner, lcid, icol, gcol, distmin, mlats, mlons)
   961)     use physconst,  only: rearth
   962)     use phys_grid,  only: get_rlon_all_p, get_rlat_all_p, get_gcol_p, get_ncols_p
   963)     use spmd_utils, only: iam, npes, mpi_integer, mpi_real8, mpicom
   964) 
   965)     real(r8),intent(in)  :: lat, lon            ! requested location in degrees
   966)     integer, intent(in)  :: nclosest            ! number of closest points to find
   967)     integer, intent(out) :: owner(nclosest)     ! rank of chunk owner
   968)     integer, intent(out) :: lcid(nclosest)      ! local chunk index
   969)     integer, intent(out) :: icol(nclosest)      ! column index within the chunk
   970)     integer, intent(out) :: gcol(nclosest)      ! global column index 
   971)     real(r8),intent(out) :: distmin(nclosest)   ! the distance (m) of the closest column(s)
   972)     real(r8),intent(out) :: mlats(nclosest)     ! the latitude of the closest column(s)
   973)     real(r8),intent(out) :: mlons(nclosest)     ! the longitude of the closest column(s)
   974) 
   975)     real(r8) :: dist
   976)     real(r8) :: rlats(pcols), rlons(pcols)
   977)     real(r8) :: latr, lonr
   978) 
   979)     integer :: my_owner(nclosest)
   980)     integer :: my_lcid(nclosest)
   981)     integer :: my_icol(nclosest)
   982)     integer :: my_gcol(nclosest)
   983)     real(r8) :: my_distmin(nclosest)
   984)     real(r8) :: my_mlats(nclosest)
   985)     real(r8) :: my_mlons(nclosest)
   986) 
   987)     integer  :: c, i, j, k, ierr, ncols, mindx(1)
   988)     real(r8) :: sendbufr(3)
   989)     real(r8) :: recvbufr(3,npes)
   990)     integer  :: sendbufi(4)
   991)     integer  :: recvbufi(4,npes)
   992) 
   993)     call t_startf ('sat_hist::find_cols')
   994) 
   995)     latr = lat/rad2deg              ! to radians
   996)     lonr = lon/rad2deg              ! to radians
   997)     
   998)     my_owner(:)   = -999
   999)     my_lcid(:)    = -999
  1000)     my_icol(:)    = -999
  1001)     my_gcol(:)    = -999
  1002)     my_mlats(:)   = -999
  1003)     my_mlons(:)   = -999
  1004)     my_distmin(:) = 1.e10_r8
  1005) 
  1006)     chk_loop: do c=begchunk,endchunk
  1007)        ncols = get_ncols_p(c)
  1008)        call get_rlat_all_p(c, pcols, rlats)
  1009)        call get_rlon_all_p(c, pcols, rlons)
  1010) 
  1011)        col_loop: do i = 1,ncols
  1012)           ! Use the Spherical Law of Cosines to find the great-circle distance.
  1013)           dist = acos(sin(latr) * sin(rlats(i)) + cos(latr) * cos(rlats(i)) * cos(rlons(i) - lonr)) * rearth       
  1014) 
  1015)           closest_loop: do j = nclosest, 1, -1
  1016)              if (dist < my_distmin(j)) then
  1017) 
  1018)                 if (j < nclosest) then
  1019)                    my_distmin(j+1) = my_distmin(j)
  1020)                    my_owner(j+1)   = my_owner(j)
  1021)                    my_lcid(j+1)    = my_lcid(j)
  1022)                    my_icol(j+1)    = my_icol(j)
  1023)                    my_gcol(j+1)    = my_gcol(j)
  1024)                    my_mlats(j+1)   = my_mlats(j)
  1025)                    my_mlons(j+1)   = my_mlons(j)
  1026)                 end if
  1027) 
  1028)                 my_distmin(j) = dist
  1029)                 my_owner(j)   = iam
  1030)                 my_lcid(j)    = c
  1031)                 my_icol(j)    = i
  1032)                 my_gcol(j)    = get_gcol_p(c,i)
  1033)                 my_mlats(j)   = rlats(i) * rad2deg
  1034)                 my_mlons(j)   = rlons(i) * rad2deg
  1035)              else
  1036)                 exit 
  1037)              end if
  1038)           enddo closest_loop
  1039) 
  1040)        enddo col_loop
  1041)     enddo chk_loop
  1042) 
  1043)     k = 1
  1044) 
  1045)     do j = 1, nclosest
  1046) 
  1047)        sendbufr(1) = my_distmin(k)
  1048)        sendbufr(2) = my_mlats(k)
  1049)        sendbufr(3) = my_mlons(k)
  1050) 
  1051)        call mpi_allgather( sendbufr, 3, mpi_real8, recvbufr, 3, mpi_real8, mpicom, ierr )
  1052) 
  1053)        mindx = minloc(recvbufr(1,:))
  1054)        distmin(j) = recvbufr(1,mindx(1))
  1055)        mlats(j)   = recvbufr(2,mindx(1))
  1056)        mlons(j)   = recvbufr(3,mindx(1))
  1057) 
  1058)        sendbufi(1) = my_owner(k)
  1059)        sendbufi(2) = my_lcid(k)
  1060)        sendbufi(3) = my_icol(k)
  1061)        sendbufi(4) = my_gcol(k)
  1062) 
  1063)        call mpi_allgather( sendbufi, 4, mpi_integer, recvbufi, 4, mpi_integer, mpicom, ierr )
  1064) 
  1065)        owner(j)   = recvbufi(1,mindx(1))
  1066)        lcid(j)    = recvbufi(2,mindx(1))
  1067)        icol(j)    = recvbufi(3,mindx(1))
  1068)        gcol(j)    = recvbufi(4,mindx(1))
  1069) 
  1070)        if ( iam == owner(j) ) then
  1071)           k = k+1
  1072)        endif
  1073) 
  1074)     enddo
  1075) 
  1076)     call t_stopf ('sat_hist::find_cols')
  1077) 
  1078)   end subroutine find_cols
  1079) 
  1080) end module sat_hist

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